vue3使用flv.js播放推流視頻的示例代碼
更新時間:2023年05月10日 14:19:41 作者:山野里的小菊花
本文主要介紹了vue3使用flv.js播放推流視頻的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
前言
本人是在vue3中使用flv.js處理推流時,遇到的一些問題,以及處理辦法,歸納總結(jié)為一個組件,僅限于推流使用。
目前只貼出部分關(guān)鍵代碼,若需要完整的代碼,請往github下載
1、構(gòu)建
/** * @description: 構(gòu)建播放器 * @return {*} * @Author: liuxin */ function flvCreated() { try { const videoElement = flvPlayerVideo.value; if (flvjs.isSupported() && videoElement) { addLog(`flv created,address:${prop.url}`); const flvOption = { url: prop.url, // 播放地址 hasAudio: false, // 是否有音頻 hasVideo: true, //是否有視頻 isLive: true, // 是否是直播流,默認 true type: "flv", // 是否是直播流,默認 true stashInitialSize: 128, // 減少首幀顯示等待時長 ...prop.option, }; state.flvPlayer = flvjs.createPlayer(flvOption, { enableWorker: false, // 不啟用分離的線程進行轉(zhuǎn)換,之前為true enableStashBuffer: false, // 關(guān)閉IO隱藏緩沖區(qū) stashInitialSize: 128, // 減少首幀顯示等待時長 autoCleanupSourceBuffer: true, // 打開自動清除緩存 fixAudioTimestampGap: false, //false才會音視頻同步,新增 lazyLoad: false, // 去掉懶加載,新增 }); state.flvPlayer.attachMediaElement(videoElement); state.flvPlayer.load(); state.flvPlayer.play(); state.endedReloadFlag = true; // 重置畫面停滯的播放狀態(tài),下次停滯了會再次打開 videoElementEvent(); // 手動跳幀,防止延時 flvPlayerEvent(); // 斷流、卡頓處理 } } catch (error) { console.error("構(gòu)建錯誤", error); } }
2、銷毀
/** * @description: 銷毀播放器 * @return {*} * @Author: liuxin */ function flvDestory() { if (state.delayTimer) { clearTimeout(state.delayTimer); // 清除推遲打開播放器定時器 } if (state.flvPlayer == null) return; // 空對象,不執(zhí)行銷毀 /* ----- 銷毀開始 ----- */ addLog(`flv destory,address:${prop.url}`); try { state.flvPlayer.off(flvjs.Events.ERROR, errorHandle); if (state.flvPlayer._hasPendingLoad) { state.flvPlayer.pause(); state.flvPlayer.unload(); } state.flvPlayer.detachMediaElement(); state.flvPlayer.destroy(); state.flvPlayer = null; } catch (error) { console.error("銷毀錯誤"); } }
3、斷流、卡頓重連
state.flvPlayer.on(flvjs.Events.STATISTICS_INFO, statisticsInfoHanle); // 斷流重連 /** * @description: 視頻卡頓,銷毀后重建 * @param {*} errorType * @param {*} errorDetail * @param {*} errorInfo * @return {*} * @Author: liuxin */ function statisticsInfoHanle(res) { // 初始化播放 if (state.lastDecodedFrame == 0) { state.lastDecodedFrame = res.decodedFrames; return; } // 正常播放 if (state.lastDecodedFrame != res.decodedFrames) { state.lastDecodedFrame = res.decodedFrames; state.loading = false; // 去掉loading動畫 state.errorCount = 0; // 錯誤連接次數(shù)歸0 } // 播放異常 else { if (state.player) { addLog(`Reconnect after video freezes, address:${prop.url}`); // 添加日志 state.errorCount = 0; // 錯誤連接次數(shù)歸0 state.lastDecodedFrame = 0; // 最后播放編碼號 flvDestory(); // 銷毀對象 flvCreated("statistics_info"); // 創(chuàng)建對象 } } }
4、報錯、停滯重連
state.flvPlayer.on(flvjs.Events.ERROR, errorHandle); // 監(jiān)聽出錯消息后,銷毀后重連 state.flvPlayer.on(flvjs.Events.LOADING_COMPLETE, errorHandle); // ctrl+f5刷新,會莫名因為停止end不播放 /** * @description: 錯誤回調(diào)事件 * @param {*} errorType * @param {*} errorDetail * @param {*} errorInfo * @return {*} * @Author: liuxin */ function errorHandle() { //視頻出錯后銷毀重新創(chuàng)建 網(wǎng)絡錯誤 if (state.flvPlayer && state.errorCount <= state.maxReconnectCount) { addLog(`Video error ${state.errorCount} reconnection, address:${prop.url}`); // 視頻報錯N重連 state.loading = true; // 添加loading動畫 state.errorCount++; //錯誤重連次數(shù)+1 flvDestory(); flvCreated("ERROR"); } if (state.errorCount > state.maxReconnectCount) { state.loading = false; // 去掉loading } }
5、累計延時處理
/** * @description: 瀏覽器下載流事件,手動跳幀,防止累計延時 * @return {*} * @Author: liuxin */ videoElement.onprogress = (e) => { // 不需要跳幀,如:異常視頻 或者沒有數(shù)據(jù)流,則不進行跳幀 if (!prop.isBufferedEnd || state.flvPlayer.buffered.length <= 0) { return; } state.loading = false; /* ----- 跳幀操作 ----- */ let end = state.flvPlayer.buffered.end(0); //獲取當前時間值 let diff = end - state.flvPlayer.currentTime; //獲取相差差值 // 延遲過大或幀率不正常,通過跳幀的方式更新視頻 if (diff > 20 || diff < 0) { // addLog(`Manual frame skipping,address:${prop.url}`); // 添加日志 state.flvPlayer.currentTime = state.flvPlayer.buffered.end(0) - 0.5; // 手動跳幀到最后 return; } // 正常幀率,正常播放 if (diff <= 1) { videoElement.playbackRate = 1; } // 10秒內(nèi)的延時,1.1倍速播放 else if (diff <= 10) { // addLog(`Chase frames manually 1.1,address:${prop.url}`); // 手動追幀 videoElement.playbackRate = 1.1; } // 20秒內(nèi)的延時,1.2倍速播放 else if (diff <= 20) { // addLog(`Chase frames manually 1.2,address:${prop.url}`); // 手動追幀 videoElement.playbackRate = 1.2; } };
6、手動全屏
/** * @description: 全屏 / 退出全屏 * @return {*} * @Author: liuxin */ function fullscreenHandle() { state.isFlullscreen = !state.isFlullscreen; document.addEventListener("keydown", function (e) { //此處填寫你的業(yè)務邏輯即可 if (e.key == "Escape") { e.stopPropagation(); state.isFlullscreen = false; } });
到此這篇關(guān)于vue3使用flv.js播放推流視頻的示例代碼的文章就介紹到這了,更多相關(guān)vue3 flv.js播放推流視頻內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:
相關(guān)文章
Vue data的數(shù)據(jù)響應式到底是如何實現(xiàn)的
這篇文章主要介紹了Vue data的數(shù)據(jù)響應式到底是如何實現(xiàn)的,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-02-02vue3中使用router路由實現(xiàn)跳轉(zhuǎn)傳參的方法
這篇文章主要介紹了vue3中使用router路由實現(xiàn)跳轉(zhuǎn)傳參的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03詳解vue-cli開發(fā)環(huán)境跨域問題解決方案
本篇文章主要介紹了vue-cli開發(fā)環(huán)境跨域問題解決方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-06-06