|
<template>
<div class="replayer">
<div class="replayer-video">
<t-loading v-model="loadVideo">
<span class="text-md text-info">获取视频资源...</span>
</t-loading>
<video-player :sources="videoList" :autoadvance="0" :style="{opacity: loadVideo ? 0: 1}" @player-inited="handlePlayerInited" @playlistitem="handlePlayerCurrentChange" />
</div>
</div>
</template>
<script>
import VideoPlayer from '@/components/VideoPlayer'
export default {
components: { VideoPlayer },
props: {
list: {
type: Array,
default: () => []
},
visibled: {
type: Boolean,
default: false
}
},
data () {
return {
currentTab: null,
loadVideo: false,
videoList: [],
$player: null
}
},
computed: {
visible: {
get () { return this.visibled },
set (val) {
if (!val) this.$player.pause()
this.$emit('update:visibled', val)
}
}
},
watch: {
list: {
handler (val) {
console.warn(`list Change`)
this.resetVideoList()
if (val.length > 0) {
this.currentTab = val[0].fileId
// 手动触发第一个tab点击事件
this.handleTabChange(null, 0)
}
},
immediate: true
}
},
methods: {
// 初始化
handlePlayerInited (player) {
this.$player = player
window.player = this
let distinguishBtn = player.controlBar.addChild('button')
distinguishBtn.addClass('aidicon')
distinguishBtn.addClass('aidicon-image-outline')
distinguishBtn.setAttribute('title', '识别记录')
distinguishBtn.size = '20'
distinguishBtn.on('click', () => {
this.$emit('goDistinguishRecord')
})
let repalyBtn = player.controlBar.addChild('button')
repalyBtn.addClass('aidicon')
repalyBtn.addClass('aidicon-piechart-outline')
repalyBtn.setAttribute('title', '视频回放')
repalyBtn.on('click', () => {
this.$emit('videoReplay', this.list[0].id)
})
},
async handleTabChange (name, index) {
this.$player.pause()
await this.preloadOriVideoUrl(index)
this.play(index)
},
handlePlayerCurrentChange (e, item) {
const { index, fileId } = item
this.currentTab = fileId
this.preloadOriVideoUrl(index)
},
resetVideoList () {
const videoList = this.list.map((item, index) => {
const { fileId, fileType } = item
return {
index,
fileId,
fileType,
loaded: false
}
})
this.videoList = videoList
},
play (index) {
console.log(`播放:index=${index}`)
// 调用额外的currentItem方法以避免currentItem在首次不生效
// https://github.com/brightcove/videojs-playlist/blob/master/docs/api.md
this.$player.playlist.currentItem()
this.$player.playlist.currentItem(index)
this.$player.play()
},
/**
* 从index开始预载videoList的视频地址
* 此方法将在获取index对应的地址后就立即返回
*/
preloadOriVideoUrl (index = 0, maxLength = 5) {
return new Promise((resolve, reject) => {
for (let i = index; i in this.videoList && i - index < maxLength; i++) {
console.log(`预载地址:index=${i}`)
const item = this.videoList[i]
const task = item.loaded
? Promise.resolve()
: this.getOriVideoUrl(item.fileId).then(resp => {
console.log(`预载完成,更新播放源:index=${i}`)
item.loaded = true
item.sources = [{
src: resp.url,
type: item.fileType
}]
})
if (i === index) {
this.loadVideo = !item.loaded
task.then(() => {
resolve()
}).finally(() => {
this.loadVideo = false
})
}
}
})
},
/*
* 获取真实视频地址
*/
getOriVideoUrl (fileId) {
console.log(`请求地址:${fileId}`)
// fake
return new Promise((resolve, reject) => {
setTimeout(() => {
const url = fileId || 'rtmp://10.19.90.34:2935/live?token=039b6232ce6548210722a4c0de19c62e/1'
resolve({
url
})
}, 1000)
})
}
}
}
</script>
<style lang="scss">
.replayer {
display: flex;
&-list {
margin-right: 20px;
// width: 200px;
}
&-video {
position: relative;
flex: auto;
}
}
</style>
|