实现vue3通过videojs接入m3u8视频,一天多总算搞成功了。下面就扒一扒我在实现过程中踩的那些坑。。。。。。

前言

我们最常见的mp4类型的视频,直接通过vue原生的video引入就可以了。

<video :src="video" autoPlay controls muted loop />

但是当接入的视频是直播视频流时,video是不支持的,所以我们需要通过一定的插件辅助,在实现功能前先介绍几个概念。

1.HLS,M3U8

一听需求是要接入海康的视频,什么hls,m3u8视频,孤陋寡闻的我立马去找度娘。

HLS是一个基于http的流媒体网络传输协议,传输内容包括两部分,M3U8描述文件和TS媒体文件。

M3U8文件是指UTF-8编码格式的M3U文件。M3U文件是一个文本文件,记录视频文件的索引。

概括说,hls协议将流媒体切片成的ts文件和m3u8文件,通过m3u8索引文件按序访问ts文件,客户端不停地从服务器获取视频文件,进而实现在线播放音视频的功能。

本文是通过videojs插件来实现视频接入的。

功能实现

1.安装依赖和引入

npm install --save video.js
npm install --save videojs-contrib-hls

在index.html引入

    <!-- 视频取流 --><link href="https://cdn.bootcss.com/video.js/7.20.3/alt/video-js-cdn.min.css" rel="stylesheet"><script src="https://cdn.bootcss.com/video.js/7.20.3/video.js"></script><script src="https://cdn.bootcss.com/videojs-contrib-hls/5.15.0/videojs-contrib-hls.min.js"></script>

注:这里是第一个坑,看了很多方法都是直接安装依赖就可以,没有这一步。但是,如果不引入请求是成功的,但是视频却加载不出来。

加上后就能正常显示了

文件内局部引入

import videojs from 'video.js';
import 'videojs-contrib-hls';
import 'video.js/dist/video-js.css';

2.代码实现

template代码

  <div id="video-box" class="video-item" v-show="showFlag"><videoid="my-video"class="video-js vjs-default-skin"controlspreload="auto"style="width: 100%;height:100%"><source id="source" :src="xxxx视频请求网址xxxx" type="application/x-mpegURL" /></video></div>

初始化

const myPlayer = ref(null);
const initVideo = () => {
//初始化配置myPlayer.value = videojs('my-video',{bigPlayButton: false,textTrackDisplay: false,posterImage: true,errorDisplay: false,controlBar: true,});// 播放myPlayer.value.play();
};onMounted(() => {setTimeout(() => {initVideo();}, 300);
});

注:第二个坑来了!当视频组件放到弹窗里,如果报错
TypeError: The element or ID supplied is not valid. (videojs)

这时就需要注意两点:

  1. 组件外层的div不能使用v-if,要使用v-show控制显隐
  2. videojs的初始化要在dom全部挂载后的,所以可以采用使用setTimeout延迟加载

以上是固定地址的写法,但是需求是要切换不同视频地址来源,还需要进一步优化

先将视频地址设为变量

 <source id="source" :src="cameraURL" type="application/x-mpegURL" />const srcPath = ref<string>('');const initVideo = (url:string) => {myPlayer.value = videojs('my-video',{bigPlayButton: false,textTrackDisplay: false,posterImage: true,errorDisplay: false,controlBar: true,});// 设置urlmyPlayer.value.src(url);myPlayer.value.play();
};

注:第三个坑来了!在网上学习的过程中有些是下面这种写法,直接赋值属性值并且不在template里写source部分。我开始用这种方法,发现怎么都不生效。最后换成了上面的写法。(如果有大神知道原因还请指教)

    myPlayer.src([{type: "application/x-mpegURL",src: url }]);

注:紧接着问题又来了,切换url后视频加载不出来,查看网络发现切换url后的第一个请求会显示已取消

解决方法是将这条请求过滤

  videojs.hook('beforeerror', (player, err) => {// Video.js 在切换/指定 source 后立即会触发一个 err=null 的错误,这里过滤一下if (err !== null) {myPlayer.value.src(url);}// 清除错误,避免 error 事件在控制台抛出错误return null;});

请求都正常发现视频还是加载不出来,还会报错
解决办法:只能在切换来源的时候销毁原来的组件,再重新添加一个videojs并赋值。

补充:控制台报错但不影响视频正常显示。原因:video.js and videojs-contrib-hls版本冲突,解决:将videojs版本从7.20.3降为videojs 7.5.5\videojs-contrib-hls 5.15.0,无报错。

最后附上成功实现的完整代码

template部分

<template><div id="video-box" class="video-item" v-show="showVideo"></div>
</template>

Js部分

const myPlayer = ref<any>(null);
const mountedFlag = ref<boolean>(false);
// 初始化视频组件
const initVideo = (url:string) => {if (myPlayer.value) {myPlayer.value.pause();myPlayer.value.dispose();}// 向Dom中写入视频组件document.getElementById('video-box').innerHTML = '';const html = `<video id="fire-video" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" style="width: 100%;height:100%"><source id="source" src="${url}" type="application/x-mpegURL"></video>`;document.getElementById('video-box').innerHTML = html;// 初始化声明myPlayer.value = videojs('fire-video',{autoplay: 'muted',bigPlayButton: false,textTrackDisplay: false,posterImage: true,errorDisplay: false,controlBar: true,});videojs.hook('beforeerror', (player, err) => {// Video.js 在切换/指定 source 后立即会触发一个 err=null 的错误,这里过滤一下if (err !== null) {myPlayer.value.src(url);}// 清除错误,避免 error 事件在控制台抛出错误return null;});myPlayer.value.play();
};// 监听,需要视频url由其他方法赋值且组件挂载完成后,才能进行初始化
watch([cameraURL,mountedFlag,], ([url,flag,]): void => {if (url && flag) {initVideo(url);}
});onMounted(() => {setTimeout(() => {mountedFlag.value = true;}, 500);
});
// 组件销毁
onUnmounted(() => {if (myPlayer.value) {mountedFlag.value = false;}
});

参考文档:

https://cloud.tencent.com/developer/article/1782402
https://blog.csdn.net/u012961419/article/details/120989905

实现videojs接入m3u8视频,踩了多少坑啊相关推荐

  1. 使用videojs播放m3u8视频

    vue3使用videojs 播放m3u8格式视频 videojs是一个播放视频的js库,可以通过videojs结合videojs-contrib-hls实播放m3u8格式视频.流媒体传输协议(hls) ...

  2. 使用videojs播放m3u8视频监控。

    一 . 实现过程中解决的问题 : 1. 全屏播放 2.切换页面后进入视频无法再次播放,解决方法利用生命周期函数beforeDestroy或onUnload里面销毁创建的video实例. 二.主要代码: ...

  3. android xlog崩溃日志,腾讯Xlog接入指南与踩过的坑

    一 为什么要接入日志打印系统? 相信大家在开发应用的时候,总会遇到bug,这个时候,如果bug是在我们本地开发的过程中发现的,那么我们把手机插入android studio进行联调,就可以马上定位到出 ...

  4. videojs播放m3u8后缀视频Demo

    videojs播放m3u8后缀视频Demo 转载自:https://segmentfault.com/a/1190000024447688 <!DOCTYPE html><html ...

  5. vue关于videojs一个页面多个视频且一个播放器多个视频源的写法(播放m3u8视频格式的视频监控)

    前言 突然接到一个任务是需要做一个视频回放,而且是监控视频那种. 1.首先需要能播m3u8视频 npm install --save video.js npm install --save video ...

  6. vue使用原生videojs 播放m3u8格式的视频——播放m3u8格式视频(一)

    vue使用原生video播放m3u8格式的视频 1.安装依赖 2.页面引入插件(这里我是页面单独引入,减少项目体积) 3.页面中的使用 常见问题 4.实现过程 5.实现.m3u8格式视频播放方法 1. ...

  7. Linux视频切片m3u8,Rtmp转m3u8视频切片系统及方法

    Rtmp转m3u8视频切片系统及方法 [技术领域] [0001]本发明涉及视频数据传输及播放技术领域,尤其涉及一种RTMP转M3U8视频切片系统及方法. [背景技术] [0002]传统的视频监控系统是 ...

  8. video.js播放m3u8视频

    m3u8 是一种基于HTTP Live Streaming(HLS)文件视频格式,它主要是存放整个视频的基本信息和分片(Segment)组成.目前 由 Apple.inc 率先提出的 HLS 协议在 ...

  9. 前端展示m3u8视频

    什么是m3u8视频? m3u8是苹果公司推出的视频播放标准,是m3u的一种,只是编码格式采用的是UTF-8. 在vue框架项目中如何使用?  (将 展示m3u8视频的功能做成组件) 引入video.j ...

最新文章

  1. python读文件的解码方式_跳过Python文件读取中的不可解码字符
  2. python使用matplotlib可视化、使用subplots函数将可视化的画布划分为网格状的若干子区、通过nrows和ncols参数设置设置行数和列数
  3. 如何及时获得AI顶尖科研团队的最新论文与进展?只需要一份AI内参!
  4. SpringBoot集成Eureka导致返回结果由json变为xml解决方案
  5. 【拔刀吧少年】之正则表达式
  6. hashCode()方法的性能优化
  7. CF Gym102059 H. Fractions
  8. java   cxf实现webservice接口方式之不依赖spring
  9. 图论 —— 最短路 —— Floyd 算法
  10. 一起学习C语言:C语言循环结构(二)
  11. android activity 窗口 样式
  12. charles抓手机app的包的操作步骤
  13. 4-0 Software Development OKR
  14. 工具系列————linux系统中安装fortran编译器(ifort)
  15. 网站上部署Live2D模型(moc3格式)
  16. Gliffy confluence插件的破解
  17. 订单系统设计,消息队列幂等处理思路
  18. android 读取wps_Android 默认使用wps打开本地文档
  19. 用于单眼3D物体检测的可学习深度引导卷积
  20. SQL数据库常用语句大全

热门文章

  1. ipad邮件qq收件服务器,iPad自带邮件功能收发邮件的过程
  2. mediasoup 集群_mediasoup介绍
  3. java 字节转字符_Java 字符串 之 字符,字节,字符串的转换
  4. 基于Hexo+Github构建个人博客(一)
  5. java import static作用
  6. mysql怎么进行时间差计算_Mysql时间差计算
  7. 删库不跑路之MySQL数据库备份
  8. 走进徐志摩—(偶然)
  9. AndroidStudio如何快速制作.so
  10. 策略模式+工厂模式的组合使用