vuecli中引入videojs進行m3u8視頻播放以及分欄切換唯鸭,內(nèi)容涉及視頻播放哑了、宮格切換舱馅、選中窗口視頻替換功能缰泡。
依賴:videojs、flv.js代嗤、videojs-contrib-hls棘钞、videojs-flvjs-es6、vue-video-player
環(huán)境:node : 14版本干毅,可使用v14.19.1宜猜;vue2
頁面效果
說明:只針對本人項目中用到的功能,代碼較多
1. 示例代碼運行時硝逢,請先把左邊列表里面的視頻地址改成自己的姨拥,代碼視頻鏈接目前為空
- 視頻選擇時判斷是否有鏈接,無鏈接時走提示
- 根據(jù)分欄數(shù)目以及選中窗口判斷視頻是添加渠鸽、直接替換叫乌、二次替換(涉及到窗口切換時使用)
- 監(jiān)聽視頻播放狀態(tài),自定義播放出錯占位徽缚;視頻上遮蓋蒙層進行自定義內(nèi)容顯示和點擊事件
部分代碼
列表視頻點擊選擇的視頻賦值播放
// 判斷分欄情況
// 只有一欄 ==== 沒有數(shù)據(jù)進行添加憨奸,有數(shù)據(jù)進行編輯替換
if (this.layoutNum == 1) {
if (!this.playCodeList.length) {
this.$refs.hlsVideoPlayer.handelVideoUrl(vcode, vurl, vname, 0)
// 把當(dāng)前的鏈接放進去
this.playCodeList.push(vcode)
this.playUrlList.push(vurl)
this.playNameList.push(vname)
} else {
// 如果已經(jīng)有正在播放的視頻,進行視頻的替換
this.playCodeList = [vcode]
this.playUrlList = [vurl]
this.playNameList = [vname]
this.$refs.hlsVideoPlayer.editUrl(vcode, vurl, vname, 0)
}
} else {
// 多欄情況
// 還有播放窗口:當(dāng)選選中窗口數(shù)大于已選中播放的列表
if (this.layoutNum > this.playCodeList.length) {
// 選中切換的是正在播放的凿试,直接編輯替換
if (this.chooseIndex < this.playCodeList.length) {
this.$refs.hlsVideoPlayer.editIsPlay(this.chooseIndex, true)
this.$set(this.playCodeList, this.chooseIndex, vcode)
this.$set(this.playUrlList, this.chooseIndex, vurl)
this.$set(this.playNameList, this.chooseIndex, vname)
this.$refs.hlsVideoPlayer.resetEdit(vcode, vurl, vname, this.chooseIndex)
} else {
// 判斷是否是已經(jīng)添加過的
// 沒有添加過排宰,直接添加
if (this.chooseIndex > this.chooseMaxIndex) {
this.playCodeList.push(vcode)
this.playUrlList.push(vurl)
this.playNameList.push(vname)
this.$refs.hlsVideoPlayer.handelVideoUrl(vcode, vurl, vname)
} else {
this.$refs.hlsVideoPlayer.editIsPlay(this.chooseIndex, true)
this.$set(this.playCodeList, this.chooseIndex, vcode)
this.$set(this.playUrlList, this.chooseIndex, vurl)
this.$set(this.playNameList, this.chooseIndex, vname)
this.$refs.hlsVideoPlayer.resetEdit(vcode, vurl, vname, this.chooseIndex)
}
}
} else {
// 添加到最后一個的時候,判斷是否是從少窗口切換來的
this.$refs.hlsVideoPlayer.editIsPlay(this.chooseIndex, true)
this.$set(this.playCodeList, this.chooseIndex, vcode)
this.$set(this.playUrlList, this.chooseIndex, vurl)
this.$set(this.playNameList, this.chooseIndex, vname)
this.$refs.hlsVideoPlayer.resetEdit(vcode, vurl, vname, this.chooseIndex)
}
this.$refs.hlsVideoPlayer.thisCodeLength = this.playCodeList.length
}
分欄窗口切換
問題
如果選中切換的窗口屏幕小于當(dāng)前展示的屏幕數(shù)那婉,直接替換已經(jīng)存在的板甘,把多余的隱藏播放
說明:為什么是隱藏而不是直接銷毀刪除
答:直接刪除會造成再次賦值視頻無法播放的問題
// 分欄管理選中改變
changeLayout({ name, nums }) {
// 當(dāng)前分欄重復(fù)選擇
if (this.layoutName == name) return
// 沒有選中視頻的時候,不允許切換分欄
if (!this.playCodeList.length) return
// 賦值上一個分欄窗口數(shù)详炬,用作對比
this.oldLayoutNum = this.layoutNum
// 賦值頁面的窗口數(shù)
this.$refs.hlsVideoPlayer.layoutNum = nums
let hadCodeList = []
let hadUrlList = []
let hadNameList = []
// TODO 暫時沒必要進行虾啦,無鏈接的視頻添加時已進行了判斷處理,此步驟無用
this.playCodeList.forEach((item, index) => {
// 剔除為空的情況痕寓,進行數(shù)據(jù)重新添加
if (item != '') {
hadCodeList.push(item)
hadUrlList.push(this.playUrlList[index])
hadNameList.push(this.playNameList[index])
}
})
// 如果選中切換的窗口屏幕小于當(dāng)前展示的屏幕數(shù)傲醉,直接替換已經(jīng)存在的,把多余的隱藏播放
// 說明:為什么是隱藏而不是直接銷毀刪除
// 答:直接刪除會造成再次賦值視頻無法播放的問題
if (nums < this.layoutNum) {
// 截取當(dāng)前展示的前幾個
hadCodeList = hadCodeList.slice(0, nums)
hadUrlList = hadUrlList.slice(0, nums)
hadNameList = hadNameList.slice(0, nums)
// 賦值當(dāng)前
this.playCodeList = [...hadCodeList]
this.playUrlList = [...hadUrlList]
this.playNameList = [...hadNameList]
this.$refs.hlsVideoPlayer.thisCodeLength = hadCodeList.length
setTimeout(() => {
let chooseMaxIndex = this.chooseMaxIndex
chooseMaxIndex = chooseMaxIndex + 1
if (chooseMaxIndex == 3 || chooseMaxIndex == 5 || chooseMaxIndex == 7) {
chooseMaxIndex = chooseMaxIndex + 1
} else {
chooseMaxIndex = chooseMaxIndex
}
for (let i = 0; i < chooseMaxIndex; i++) {
if (hadCodeList[i] && hadCodeList[i] != '') {
// 修改賦值
this.$refs.hlsVideoPlayer.editIsPlay(i, true)
} else {
this.$refs.hlsVideoPlayer.editIsPlay(i, false)
}
}
}, 400)
} else {
this.playCodeList = hadCodeList
this.playUrlList = hadUrlList
this.playNameList = hadNameList
this.$refs.hlsVideoPlayer.thisCodeLength = hadCodeList.length
for (let i = 0; i < hadCodeList.length; i++) {
this.$refs.hlsVideoPlayer.editIsPlay(i, true)
}
}
if (nums == this.playCodeList.length) {
this.$refs.hlsVideoPlayer.chooseIndex = this.playCodeList.length - 1
this.chooseIndex = this.playCodeList.length - 1
} else {
this.$refs.hlsVideoPlayer.chooseIndex = this.playCodeList.length
this.chooseIndex = this.playCodeList.length
}
this.layoutName = name
this.layoutNum = nums
},
},
鏈接選擇替換的幾種處理(子組件頁面)
// 進行視頻替換
editUrl(code, src, name, index) {
this.isCanPlay = true
this.$set(this.urlList[index], 'isPlay', true)
this.$set(this.urlList[index], 'isEdit', true)
// this.$set(this.urlList[index], 'isError', false)
this.$set(this.urlList[index], 'code', code)
this.$set(this.urlList[index], 'url', src)
this.$set(this.urlList[index], 'name', name)
this.$nextTick(() => {
this.playerList[index].src(this.makeUrlSource(src))
this.playerList[index].load()
})
},
// 編輯替換:字段設(shè)置
editIsPlay(index, isPlay) {
console.log(index)
if (this.urlList[index]) {
if (isPlay && this.urlList[index]['isEdit']) {
this.$set(this.urlList[index], 'isPlay', isPlay)
} else {
this.$set(this.urlList[index], 'isPlay', isPlay)
}
if (!isPlay) {
this.$set(this.urlList[index], 'isEdit', false)
}
}
},
// 編輯替換:視頻替換
resetEdit(code, src, name, index) {
if (this.urlList[index]) {
if (this.urlList[index]['isEdit']) {
// 可直接編輯
this.editUrl(code, src, name, index)
} else {
// 走銷毀后添加
this.handelVideoUrl2(code, src, name, index)
}
}
},
videojs官網(wǎng):https://docs.videojs.com/
樣式相關(guān)參考鏈接:https://blog.csdn.net/maofengwoaini/article/details/120786907
videojs事件監(jiān)聽參考鏈接:https://blog.csdn.net/zhu_zhu_xia/article/details/122577153