安裝vlc 地址https://www.videolan.org/vlc/
打開網絡串流測試視頻流是否可用
安裝 npm install --save flv.js
1.單個flv.js dome
<template> <div> <video class="demo-video" ref="player" muted autoplay></video> </div> </template> <script> import flvjs from "flv.js"; export default { data () { return { player: null } }, mounted () { if (flvjs.isSupported()) { let video = this.$refs.player; if (video) { this.player = flvjs.createPlayer({ type: "flv", isLive: true, url: `http://1011.hlsplay.aodianyun.com/demo/game.flv` }); this.player.attachMediaElement(video); try { this.player.load(); this.player.play(); } catch (error) { console.log(error); }; } } }, beforeDestroy () { this.player.destory(); } } </script> <style> .demo-video { max-width: 880px; max-height: 660px; } </style>
原文鏈接:https://blog.csdn.net/weixin_42536639/article/details/102870788
2.點擊列表顯示相應flv流 (注:瀏覽器頁面最多顯示6個flv流 )
功能:點擊右邊菜單出現實時監控畫面,頁面有四個窗體,每個窗體播放不同的視頻,當四個窗體都在播放時,點擊下一個會依次替換每個窗體,隨機點四個頁面會出現對應的實時視頻
這段代碼解決了
開發問題1:離開頁面視頻會暫停(就沒有實時性)
開發問題2:頁面會瘋狂報錯(不影響功能,但是瀏覽器受不了)
開發問題3:怎么當四個窗體都在播放時,點擊下一個會依次替換每個窗體
開發問題4:怎么斷掉上一個視頻的推流(視頻會卡頓)
開發問題5:怎么斷開重新連接
<template> <div class="videobox"> <div class="videolist"> <div class="search"> <ul> <li v-for="(item, index) in rtsplist" :key="index" @click="clickhandleitem(item, index)" > <i class="el-icon-video-camera-solid"></i> 列表{{index}} </li> </ul> </div> </div> <div class="video"> <video autoplay muted width="400px" height="300px" v-for="(i,index) in 4" :id="'videoElement' + i" :key="index" ></video> </div> </div> </template> <script> import flvjs from "flv.js"; export default { data() { return { rtsplist: [ { rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv", player: null }, { rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv", player: null }, { rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv", player: null }, { rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv", player: null }, { rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv", player: null }, { rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv", player: null }, { rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv", player: null }, { rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv", player: null }, ], flvPlayer: null, inputvalue: "", devicename: "60", url: "", list: [], count: 1, // 當前點擊標識 flvPlayerList: [], datalist:[] }; }, methods: { clickhandleitem(data, index) { let ip = data.ipAddress; let admin = data.videoname; let password = data.videopas; this.url =this.rtsplist[index].rtsp console.log(this.flvPlayerList,'flvPlayerList') if (this.flvPlayerList.length > 3) { this.destoryVideo(this.flvPlayerList[0]); this.flvPlayerList.shift(); } this.createVideo(); console.log(index) this.count > 3 ? (this.count = 1) : this.count++; console.log(this.count) }, createVideo() { if (flvjs.isSupported()) { var videoElement = document.getElementById("videoElement" + this.count); this.flvPlayer = flvjs.createPlayer( { type: "flv", isLive: true, hasAudio: false, url: this.url }, { enableWorker: false, //不啟用分離線程 enableStashBuffer: false, //關閉IO隱藏緩沖區 reuseRedirectedURL: true, //重用301/302重定向url,用於隨后的請求,如查找、重新連接等。 autoCleanupSourceBuffer: true //自動清除緩存 } ); this.flvPlayer.attachMediaElement(videoElement); // this.flvPlayer.load(); if (this.url !== "" && this.url !== null) { this.flvPlayer.load(); this.flvPlayer.play(); } } //定時方法是為了用戶離開頁面視頻是實時播放的,暫停按鈕無用 setInterval(function() { // console.log(videoElement.buffered,"idididid"); if (videoElement.buffered.length > 0) { const end = videoElement.buffered.end(0); // 視頻結尾時間 const current = videoElement.currentTime; // 視頻當前時間 const diff = end - current; // 相差時間 // console.log(diff); const diffCritical = 4; // 這里設定了超過4秒以上就進行跳轉 const diffSpeedUp = 1; // 這里設置了超過1秒以上則進行視頻加速播放 const maxPlaybackRate = 4; // 自定義設置允許的最大播放速度 let playbackRate = 1.0; // 播放速度 if (diff > diffCritical) { // this.flvPlayer.load(); // console.log("相差超過4秒,進行跳轉"); videoElement.currentTime = end - 1.5; playbackRate = Math.max(1, Math.min(diffCritical, 16)); } else if (diff > diffSpeedUp) { // console.log("相差超過1秒,進行加速"); playbackRate = Math.max(1, Math.min(diff, maxPlaybackRate, 16)); } videoElement.playbackRate = playbackRate; if (videoElement.paused) { videoElement.play(); } } // if (videoElement.buffered.length) { // let end = this.flvPlayer.buffered.end(0);//獲取當前buffered值 // let diff = end - this.flvPlayer.currentTime;//獲取buffered與currentTime的差值 // if (diff >= 0.5) {//如果差值大於等於0.5 手動跳幀 這里可根據自身需求來定 // this.flvPlayer.currentTime = this.flvPlayer.buffered.end(0);//手動跳幀 // } // } }, 1000); this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => { // alert("網絡波動,正在嘗試連接中..."); if (this.flvPlayer) { this.reloadVideo(this.flvPlayer); } // errType是 NetworkError時,對應errDetail有:Exception、HttpStatusCodeInvalid、ConnectingTimeout、EarlyEof、UnrecoverableEarlyEof // errType是 MediaError時,對應errDetail是MediaMSEError 或MEDIA_SOURCE_ENDED }); this.flvPlayerList.push(this.flvPlayer); }, reloadVideo(flvPlayer) { this.destoryVideo(flvPlayer); this.createVideo(); }, destoryVideo(flvPlayer) { flvPlayer.pause(); flvPlayer.unload(); flvPlayer.detachMediaElement(); flvPlayer.destroy(); flvPlayer = null; }, } }; </script> <style lang="scss" scoped> .videobox { display: flex; /* justify-content: space-between; */ /* flex-wrap: wrap; */ } .videolist { width: 550px; height: 906px; display: flex; .search { margin-left: 50px; .el-input { width: 300px; margin-top: 20px; } ul { width: 100%; height: 777px; overflow: hidden; overflow-y: auto; list-style: none; li { padding: 7px; margin: 1px 0; text-decoration: none; white-space: nowrap; font-size: 14px; cursor: pointer; &:hover { background: #fff; } .el-icon-video-camera-solid { font-size: 16px; color: #67c23a; } } } } } .video { display: flex; flex-wrap: wrap; width: 100%; justify-content: space-evenly; video { object-fit: contain; width: 600px; height: 390px; } } </style>
原文鏈接:https://blog.csdn.net/weixin_45906632/article/details/115031633
遇到的問題
第一種報錯情況:谷歌瀏覽器控制台出現的報錯
使用報錯如下:Failed to read the ‘buffered’ property from ‘SourceBuffer’: This SourceBuffer has been removed from the parent media source.
這種錯誤提示一般是在flv源發生異常中斷的時候產生的。錯誤提示大多數都在 mse-controller.js 這個模塊中。
解決辦法:在 mse-controller.js中(flv.js/src/core/mse-controller.js),appendMediaSegment()、_needCleanupSourceBuffer()這些方法的入口處調用檢查以下MediaSource的合法性。
if (!this._mediaSource || this._mediaSource.readyState !== 'open') { return; }
原文鏈接:https://blog.csdn.net/xyy1234567891/article/details/110005429