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

后来项目更新采用的是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

 页面结构
   <div class="video"><videov-for="i in 4":id="'videoElement' + i"controlsautoplaymuted></video></div>

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

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

附上页面所有代码

<template><div class="videobox"><div class="videolist"><div class="search"><el-inputclearablev-model="inputvalue"placeholder="请输入内容"size="mini"></el-input><el-button type="primary" size="mini" @click="clicksearch">查询</el-button><ul><liv-for="(item, index) in list"@click="clickhandleitem(item, index)"><i class="el-icon-video-camera-solid"></i>{{ item.devicename + item.deviceAddr }}</li></ul></div></div><div class="video"><videov-for="i in 4":id="'videoElement' + i"controlsautoplaymuted></video></div></div>
</template><script>
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;});}}
};
</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>

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

  1. VUE项目中优雅使用EasyPlayer实时播放摄像头多种格式视频

    EasyPlayer 介绍 简介:集播放http-flv, hls, websocket 于一身的H5视频直播/视频点播播放器, 使用简单, 功能强大: 功能支持: 支持 MP4 播放 支持 m3u8 ...

  2. vue项目中通过WebSocket实现实时消息提示及遇到的问题

    vue项目中通过WebSocket实现实时消息提示(前端代码) 需求说明 后台有新增消息通知,并实时推送给用户端,用websocket可以很方便的解决这个问题,但是websocket有个弊端不兼容IE ...

  3. Vue项目中利用pdf.js实现pdf内容滑选文字展示与搜索功能

    Vue项目中利用pdf.js实现pdf内容滑选文字展示与搜索功能 需求:在pdf中鼠标滑动选中一段文字,将选中文字展示到input框中(pdf在iframe中) 完成效果: 关于pdf的引用:我是直接 ...

  4. vue 项目中使用three.js实现vr360度全景图片预览

    vue 项目中使用three.js实现vr360度全景图片预览 当前demo使用的three.js为0.115.0版本 项目中安装three npm install three 安装完成再组件如下导入 ...

  5. VUE 项目中引入外部js文件(CND引入)

    以VUE项目中引入echarts文件为例: 第一步在VUE项目中找到index.html文件 引入 :<script src="https://cdnjs.cloudflare.com ...

  6. jsencrypt vue使用_在Vue项目中使用jsencrypt.js对数据进行加密传输

    项目需求中需要对用户登录时的密码进行加密,在网上查询些许文章后,最终与后端协商使用jsencrypt.js. 使用yarn安装至Vue项目 yarn add jsencrypt --dev 或者使用n ...

  7. vue项目中使用ckplayer.js封装视频播放组件

    1.在index.html中引入ckplayer.js <script src="ckplayer/ckplayer.js" charset="utf-8" ...

  8. 在vue项目中使用video.js实现视频播放和视频进度条打点

    一.用video.js实现视频播放 1.安装video.js插件 // 安装video.js插件 npm install video.js -S // 如果需要播放rtmp直播流,需安装一下插件 np ...

  9. 一、在vue项目中使用mock.js(详解)

    步骤1.搭建测试项目 步骤1.1创建项目 命令: vue create mock-demo 步骤1.2安装依赖 命令: #使用axios发送ajax cnpm install axios--save ...

最新文章

  1. Git 常用命令速查表(图文+表格)
  2. 2021牛客OI赛前集训营-提高组(第五场)D-牛牛的border【SAM】
  3. matlab寻找闭合,MatLab求取多个闭合区域的轮廓、面积和bbox
  4. 一位湖北大学的学生作品,看后久久不能平静
  5. Glassnode:比特币正迎来多年以来最大的流动性枯竭
  6. HTML5基本知识小测验
  7. LXC基本架构及用法(六)
  8. 20191202_2_识别偷税漏税人
  9. 【转载】StreamInsight系列-QueryTemplate\QueryBinder\Query
  10. Markdown 标记语言指北
  11. git学习笔记-(15-远程跟踪分支)
  12. 报错 mysql 1194
  13. 你不知道的常用 代码分析 规范
  14. HMS Core AR Engine 2D图片/3D物体跟踪技术 助力打造更智能AR交互体验
  15. 【建议收藏】6款高质量Windows软件,好用到无法拒绝
  16. JS 超大文件上传解决方案:分片断点上传(一)
  17. js简单实现百度地图雷达探测效果
  18. 某讯T9程序员推荐,Linux C/C++ 学习路线(内附资料)
  19. 你是人间的四月天---林徽因
  20. 搭建ZeroTier的Moon服务器

热门文章

  1. 汶川大地震随感谢摘录
  2. 学计算机当导演吗,学计算机8年 80岁老荣民当“导演”
  3. 微信小程序 —— 模块化方法的总结
  4. canpcb阻抗_PCB阻抗匹配与0欧电阻设计说明
  5. 3.GoolgeProtoBuffer序列化反序列化
  6. mysql计算折纸_折纸飞机实验报告.doc
  7. 折纸飞机的12种方法【转】
  8. 1rem等于多少px (rem和px怎样转换)
  9. 生命不可承受之重, 请关爱过劳人员
  10. 承志医疗管理系统技术解析住院管理(六)