Browse Source

[FE]视频回放接口联调完成

luoxu5 4 years ago
parent
commit
afa49867a7

+ 7 - 1
security-protection-platform/src/api/videoSurveillance/index.js

@ -16,7 +16,7 @@ const api = {
16 16
    return $http.get('/videoSurveillance/getDistinguishData', params)
17 17
  },
18 18
  // 获取监控场景列表
19
  getMonitorScene() {
19
  getMonitorScene () {
20 20
    return $default.get('/sp/monitorSceneManagement/queryPageMonitorScene', 0)
21 21
  },
22 22
  // 视频回放
@ -25,6 +25,12 @@ const api = {
25 25
      resp.data = keysMappingReverse(resp.data, videoMapping)
26 26
      return resp
27 27
    }).catch((err) => { return err })
28
  },
29
  // 根据视频id/图片id查询地址
30
  getFileUrl (id) {
31
    return $default.get(`/sp/uploadFile/getFileUrl?fileName=${id}`).then(resp => {
32
      return resp
33
    }).catch((err) => { return err })
28 34
  }
29 35
}
30 36
export default api

+ 22 - 53
security-protection-platform/src/modules/videoSurveillance/components/ReplayDialog/index.vue

@ -15,7 +15,7 @@
15 15
          </div>
16 16
        </div>
17 17
        <t-tabs v-model="currentTab" mode="scrollY" orientation="vertical" width="100%" @change="handleTabChange">
18
          <t-tab-panel v-for="item in list" :key="item.monitorVideoLogId" :label="item.fileName|formatDateTime" :panel-id="item.fileId" />
18
          <t-tab-panel v-for="item in list" :key="item.monitorVideoLogId" :label="item.fileName" :panel-id="item.fileId" />
19 19
        </t-tabs>
20 20
      </div>
21 21
@ -40,9 +40,12 @@ export default {
40 40
  },
41 41
  components: { VideoPlayer },
42 42
  props: {
43
    replayId: {
44
      type: String
43
    // 视频列表
44
    list: {
45
      type: Array,
46
      default: () => []
45 47
    },
48
    // 是否显示对话框
46 49
    visibled: {
47 50
      type: Boolean,
48 51
      default: false
@ -50,15 +53,17 @@ export default {
50 53
  },
51 54
  data () {
52 55
    return {
56
      // 当前的tab标签
53 57
      currentTab: null,
54 58
      loadVideo: false,
55
      list: [],
59
      // 视频列表
56 60
      videoList: [],
61
      // 视频播放器对象
57 62
      $player: null,
58
      // beginDay: formatDateTime(new Date(+new Date() - 10 * 60 * 1000), 'yyyy-MM-dd hh:mm:ss'),
59
      // endDay: formatDateTime(new Date(), 'yyyy-MM-dd hh:mm:ss')
60
      beginDay: '2020-12-18 17:19:00',
61
      endDay: '2020-12-18 17:19:59'
63
      // 开始时间
64
      beginDay: '2020-12-19 20:14:00',
65
      // 结束时间
66
      endDay: '2020-12-19 20:14:59'
62 67
    }
63 68
  },
64 69
  computed: {
@ -71,10 +76,6 @@ export default {
71 76
    }
72 77
  },
73 78
  watch: {
74
    replayId (val) {
75
      this.replayId = val
76
      this.getData()
77
    },
78 79
    list: {
79 80
      handler (val) {
80 81
        this.list = val
@ -89,34 +90,8 @@ export default {
89 90
      immediate: true
90 91
    }
91 92
  },
92
  mounted () {
93
    // this.list = [{
94
    //   fileName: '12月14日 16:55',
95
    //   fileId: 'ai-video_5A02296PAKA885B-video20201214165526.mp4',
96
    //   fileType: 'video/mp4'
97
    // }, {
98
    //   fileName: '12月14日 16:56',
99
    //   fileId: 'ai-video_5A02296PAKA885B-video20201214165527.mp4',
100
    //   fileType: 'video/mp4'
101
    // }, {
102
    //   fileName: '12月14日 16:57',
103
    //   fileId: 'ai-video_5A02296PAKA885B-video20201214165528.mp4',
104
    //   fileType: 'video/mp4'
105
    // }, {
106
    //   fileName: '12月14日 16:58',
107
    //   fileId: 'ai-video_5A02296PAKA885B-video20201214165529.mp4',
108
    //   fileType: 'video/mp4'
109
    // }, {
110
    //   fileName: '12月14日 16:59',
111
    //   fileId: 'ai-video_5A02296PAKA885B-video20201214165530.mp4',
112
    //   fileType: 'video/mp4'
113
    // }, {
114
    //   fileName: '12月14日 17:00',
115
    //   fileId: 'ai-video_5A02296PAKA885B-video20201214165531.mp4',
116
    //   fileType: 'video/mp4'
117
    // }]
118
  },
119 93
  methods: {
94
    // 初始化视频
120 95
    handlePlayerInited (player) {
121 96
      this.$player = player
122 97
      window.player = this
@ -133,7 +108,8 @@ export default {
133 108
    },
134 109
    resetVideoList () {
135 110
      const videoList = this.list.map((item, index) => {
136
        const { fileId, fileType } = item
111
        const { fileId } = item
112
        const fileType = 'video/' + item.fileType
137 113
        return {
138 114
          index,
139 115
          fileId,
@ -185,32 +161,25 @@ export default {
185 161
    /*
186 162
   * 获取真实视频地址
187 163
   */
188
    getOriVideoUrl (fileId) {
189
      console.log(`请求地址:${fileId}`)
164
    async getOriVideoUrl (fileId) {
165
      const res = await sysapi.getFileUrl(fileId)
190 166
      // fake
191 167
      return new Promise((resolve, reject) => {
192 168
        setTimeout(() => {
193
          const x = Math.random()
194
          const url = x > 0.5
195
            ? 'http://10.19.90.34:19000/tool-image/tool-image_7d359725fac4464fb248284caf321993.mp4'
196
            : 'http://10.19.90.34:19000/tool-image/tool-image_7fa1f7b30f0640f2a67ac8b4c2e0b574.mp4'
169
          const url = res.data.data.fileUrl
197 170
          resolve({
198 171
            url
199 172
          })
200 173
        }, 1000)
201 174
      })
202 175
    },
203
    async getData () {
204
      const res = await sysapi.queryMonitorVideoLog({ params: { id: this.replayId, beginDay: this.beginDay, endDay: this.endDay } })
205
      if (res.status === 200) {
206
        this.list = res.data.data
207
      } else {
208
        this.$Message.danger('视频列表数据获取失败!')
209
      }
176
    getData () {
177
      this.$emit('get-list', { beginDay: this.beginDay, endDay: this.endDay })
210 178
    },
211 179
    resetData () {
212 180
      this.beginDay = formatDateTime(new Date(+new Date() - 10 * 60 * 1000), 'yyyy-MM-dd hh:mm:ss')
213 181
      this.endDay = formatDateTime(new Date(), 'yyyy-MM-dd hh:mm:ss')
182
      // this.getData()
214 183
    }
215 184
  }
216 185
}

+ 13 - 19
security-protection-platform/src/modules/videoSurveillance/components/rtmpVideoPlay/index.vue

@ -4,13 +4,7 @@
4 4
      <t-loading v-model="loadVideo">
5 5
        <span class="text-md text-info">获取视频资源...</span>
6 6
      </t-loading>
7
      <video-player
8
        :sources="videoList"
9
        :autoadvance="0"
10
        :style="{opacity: loadVideo ? 0: 1}"
11
        @player-inited="handlePlayerInited"
12
        @playlistitem="handlePlayerCurrentChange"
13
      />
7
      <video-player :sources="videoList" :autoadvance="0" :style="{opacity: loadVideo ? 0: 1}" @player-inited="handlePlayerInited" @playlistitem="handlePlayerCurrentChange" />
14 8
    </div>
15 9
  </div>
16 10
</template>
@ -30,7 +24,7 @@ export default {
30 24
      default: false
31 25
    }
32 26
  },
33
  data() {
27
  data () {
34 28
    return {
35 29
      currentTab: null,
36 30
      loadVideo: false,
@ -40,8 +34,8 @@ export default {
40 34
  },
41 35
  computed: {
42 36
    visible: {
43
      get() { return this.visibled },
44
      set(val) {
37
      get () { return this.visibled },
38
      set (val) {
45 39
        if (!val) this.$player.pause()
46 40
        this.$emit('update:visibled', val)
47 41
      }
@ -49,7 +43,7 @@ export default {
49 43
  },
50 44
  watch: {
51 45
    list: {
52
      handler(val) {
46
      handler (val) {
53 47
        console.warn(`list Change`)
54 48
        this.resetVideoList()
55 49
        if (val.length > 0) {
@ -63,26 +57,26 @@ export default {
63 57
  },
64 58
  methods: {
65 59
    // 初始化
66
    handlePlayerInited(player) {
60
    handlePlayerInited (player) {
67 61
      this.$player = player
68 62
      window.player = this
69 63
      var myButton = player.controlBar.addChild('button')
70 64
      myButton.addClass('vjs-play-control')
71 65
      myButton.on('click', () => {
72
        this.$emit('videoReplay')
66
        this.$emit('videoReplay', this.list[0].id)
73 67
      })
74 68
    },
75
    async handleTabChange(name, index) {
69
    async handleTabChange (name, index) {
76 70
      this.$player.pause()
77 71
      await this.preloadOriVideoUrl(index)
78 72
      this.play(index)
79 73
    },
80
    handlePlayerCurrentChange(e, item) {
74
    handlePlayerCurrentChange (e, item) {
81 75
      const { index, fileId } = item
82 76
      this.currentTab = fileId
83 77
      this.preloadOriVideoUrl(index)
84 78
    },
85
    resetVideoList() {
79
    resetVideoList () {
86 80
      const videoList = this.list.map((item, index) => {
87 81
        const { fileId, fileType } = item
88 82
        return {
@ -95,7 +89,7 @@ export default {
95 89
96 90
      this.videoList = videoList
97 91
    },
98
    play(index) {
92
    play (index) {
99 93
      console.log(`播放:index=${index}`)
100 94
      // 调用额外的currentItem方法以避免currentItem在首次不生效
101 95
      // https://github.com/brightcove/videojs-playlist/blob/master/docs/api.md
@ -107,7 +101,7 @@ export default {
107 101
     *  从index开始预载videoList的视频地址
108 102
     *  此方法将在获取index对应的地址后就立即返回
109 103
     */
110
    preloadOriVideoUrl(index = 0, maxLength = 5) {
104
    preloadOriVideoUrl (index = 0, maxLength = 5) {
111 105
      return new Promise((resolve, reject) => {
112 106
        for (let i = index; i in this.videoList && i - index < maxLength; i++) {
113 107
          console.log(`预载地址:index=${i}`)
@ -136,7 +130,7 @@ export default {
136 130
    /*
137 131
     * 获取真实视频地址
138 132
     */
139
    getOriVideoUrl(fileId) {
133
    getOriVideoUrl (fileId) {
140 134
      console.log(`请求地址:${fileId}`)
141 135
      // fake
142 136
      return new Promise((resolve, reject) => {

+ 30 - 10
security-protection-platform/src/modules/videoSurveillance/index.vue

@ -1,10 +1,7 @@
1 1
<template>
2 2
  <div class="page-main">
3 3
    <t-button-group class="top-btn">
4
      <t-button v-for="(item,index) in sceneList" :key="index"
5
                :value="item.monitorSceneId"
6
                :color="item.monitorSceneId === selectedMonitorScene ? 'primary' : 'secondary'"
7
                @click="tabClick(item.monitorSceneId)">{{ item.monitorSceneName }}</t-button>
4
      <t-button v-for="(item,index) in sceneList" :key="index" :value="item.monitorSceneId" :color="item.monitorSceneId === selectedMonitorScene ? 'primary' : 'secondary'" @click="tabClick(item.monitorSceneId)">{{ item.monitorSceneName }}</t-button>
8 5
    </t-button-group>
9 6
    <div class="page-top">
10 7
      <span>风场:</span>
@ -18,7 +15,7 @@
18 15
      </div>
19 16
    </div>
20 17
    <t-pager :page-size="videoPageSize" :current="videoCurrent" :total="videoTotal" :sizer-range="[ 5, 10, 20, 30 ]" class="pager" show-elevator @on-change="onChangeGate"></t-pager>
21
    <replay-dialog :list="replayList" :visibled.sync="showReplayDialog"/>
18
    <replay-dialog :list="replayList" :visibled.sync="showReplayDialog" @get-list="queryMonitorVideoLog" />
22 19
  </div>
23 20
</template>
24 21
<script>
@ -26,6 +23,7 @@ import sysapi from '@/api/videoSurveillance'
26 23
import RtmpVideo from './components/rtmpVideoPlay'
27 24
import ReplayDialog from './components/ReplayDialog'
28 25
import VideoPlayer from '@/components/VideoPlayer'
26
import formatDateTime from '@/utils/formatDateTime.js'
29 27
import videojs from 'video.js'
30 28
window.videojs = videojs
31 29
@ -63,14 +61,18 @@ export default {
63 61
      selectedMonitorScene: '', // 当前选择场景
64 62
      videoPlayList: [],
65 63
      showReplayDialog: false,
66
      replayList: []
64
      replayList: [],
65
      beginDay: formatDateTime(new Date(+new Date() - 10 * 60 * 1000), 'yyyy-MM-dd hh:mm:ss'),
66
      endDay: formatDateTime(new Date(), 'yyyy-MM-dd hh:mm:ss')
67
      // beginDay: '2020-12-19 20:14:00',
68
      // endDay: '2020-12-19 20:14:00'
67 69
    }
68 70
  },
69 71
  mounted () {
70 72
    this.getWindFiledList() // 获取风场列表
71 73
  },
72 74
  methods: {
73
    getVideoPlayList(item) {
75
    getVideoPlayList (item) {
74 76
      return [{
75 77
        fileId: item.videoUrl,
76 78
        fileType: 'rtmp/flv',
@ -78,7 +80,7 @@ export default {
78 80
      }]
79 81
    },
80 82
    // 获取场景列表
81
    getSceneList() {
83
    getSceneList () {
82 84
      this.sceneList = []
83 85
      for (let i = 0; i < this.totalList.length; i++) {
84 86
        if (this.totalList[i].organizationId === this.gateFieldData) {
@ -86,7 +88,25 @@ export default {
86 88
        }
87 89
      }
88 90
    },
89
    async handleReview (id) {
91
    // 向服务器发送请求获取视频回放数据
92
    async queryMonitorVideoLog (data) {
93
      let res = []
94
      // console.log(this.beginDay, this.endDay)
95
      if (data) {
96
        res = await sysapi.queryMonitorVideoLog({ params: { id: this.replayId, ...data } })
97
      } else {
98
        res = await sysapi.queryMonitorVideoLog({ params: { id: this.replayId, beginDay: this.beginDay, endDay: this.endDay } })
99
      }
100
      if (res.status === 200) {
101
        this.replayList = res.data.data
102
      } else {
103
        this.$Message.danger('视频列表数据获取失败!')
104
      }
105
    },
106
    // 显示视频回放对话框
107
    handleReview (id) {
108
      this.replayId = id
109
      this.queryMonitorVideoLog()
90 110
      this.showReplayDialog = true
91 111
    },
92 112
    // 切换场景
@ -119,7 +139,7 @@ export default {
119 139
    // 获得风场大门数据
120 140
    getVideoSurveillanceData (id) {
121 141
      this.paramsObj.page = this.videoCurrent
122
      sysapi.getVideoSurveillanceData({ params: {monitorSceneId: id} }).then(res => {
142
      sysapi.getVideoSurveillanceData({ params: { monitorSceneId: id } }).then(res => {
123 143
        this.videoList = res.data.data
124 144
      })
125 145
    },