vue项目中使用flv.js实时播放 断流重连 关闭断流开发心得

您所在的位置:网站首页 暂停一会怎么回来 vue项目中使用flv.js实时播放 断流重连 关闭断流开发心得

vue项目中使用flv.js实时播放 断流重连 关闭断流开发心得

2023-12-23 09:04| 来源: 网络整理| 查看: 265

第一次碰这个东西肯定会碰壁的,问百度人都问傻了(关键还骗人),其中心酸不必多描述,只为成长

后来项目更新采用的是EasyPlayer插件 文章地址: VUE项目中优雅使用EasyPlayer

后端是流媒体服务 **

用的是宇视的摄像头(对于前端就是拼接的地址不同)

**

简单介绍下: Flv.js 是 HTML5 Flash 视频(FLV)播放器,纯原生 JavaScript 开发,没有用到 Flash。由 bilibili 网站开源。 开源地址: https://github.com/Bilibili/flv.js/

先看一下页面效果: 在这里插入图片描述

功能:点击右边菜单出现实时监控画面,页面有四个窗体,每个窗体播放不同的视频,当四个窗体都在播放时,点击下一个会依次替换每个窗体,随机点四个页面会出现对应的实时视频

开发问题1:离开页面视频会暂停(就没有实时性) 开发问题2:页面会疯狂报错(不影响功能,但是浏览器受不了) 开发问题3:怎么当四个窗体都在播放时,点击下一个会依次替换每个窗体 开发问题4:怎么断掉上一个视频的推流(视频会卡顿) 开发问题5:怎么断开重新连接

关于报错

Uncaught (in promise): The play() request was interrupted by a call to pause().

在调用 video的 play() 方法之后就立即被之后一次调用 pause() 方法中断了。错误提示中明确指出了调用 play 方法是返回了一个Promise对象。那么上述的问题就有了解决方法: 在 play() 执行成功后,播放视频,然后执行后续操作。

上才艺:

下载包 cnpm install --save flv.js

页面结构

js部分

data() { return { flvPlayer: null, url: "", count: 1, // 当前点击标识 flvPlayerList: [] }; },

创建实例

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); },

断开重连机制

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 });

销毁断流方法

destoryVideo(flvPlayer) { flvPlayer.pause(); flvPlayer.unload(); flvPlayer.detachMediaElement(); flvPlayer.destroy(); flvPlayer = null; }, reloadVideo(flvPlayer) { this.destoryVideo(flvPlayer); this.createVideo(); },

左边菜单点击的方法

clickhandleitem(data, index) { let ip = data.ipAddress; let admin = data.videoname; let password = data.videopas; this.url = "ws://服务地址:端口号/live?url=rtsp://" + admin + ":" + password + "@" + ip + "/media/video2/multicast"; if (this.flvPlayerList.length > 3) { this.destoryVideo(this.flvPlayerList[0]); this.flvPlayerList.shift(); } this.createVideo(); this.count > 3 ? (this.count = 1) : this.count++; },

代码没有封装,如有大佬有更好的办法,请指教

附上页面所有代码

查询 {{ item.devicename + item.deviceAddr }} import flvjs from "flv.js"; import { mapGetters } from "vuex"; import { findAlllist } from "@/api/admin/equipmentlist"; export default { data() { return { flvPlayer: null, inputvalue: "", devicename: "60", url: "", list: [], count: 1, // 当前点击标识 flvPlayerList: [] }; }, computed: { ...mapGetters(["communityId"]) }, created() { this.findAlllistApi(); }, methods: { //查询 clicksearch() { this.findAlllistApi(); }, clickhandleitem(data, index) { let ip = data.ipAddress; let admin = data.videoname; let password = data.videopas; this.url = "ws://服务地址:端口/live?url=rtsp://" + admin + ":" + password + "@" + ip + "/media/video2/multicast"; if (this.flvPlayerList.length > 3) { this.destoryVideo(this.flvPlayerList[0]); this.flvPlayerList.shift(); } this.createVideo(); this.count > 3 ? (this.count = 1) : this.count++; }, play(flvPlayer) { flvPlayer.play(); }, 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; }, findAlllistApi() { findAlllist(this.communityId, this.inputvalue, this.devicename).then( res => { this.list = res.data; } ); } } }; .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; } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3