Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何手动停止 videojs 直播视频流 m3u8 请求?

如何手动停止 videojs 直播视频流 m3u8 请求?

原创
作者头像
喵喵侠
修改于 2024-06-10 09:40:44
修改于 2024-06-10 09:40:44
1.1K3
举报

问题描述

在公司某个可视化大屏项目中,大屏页面会有多个 videojs 组件,每个组件都会对应一个视频流地址。每当视频开始播放,视频流m3u8 会不断请求,即便是暂停了播放,这个请求也不会终止。大量的请求会导致页面卡顿,长此以往会带来性能问题,导致浏览器卡死甚至崩溃。

而大屏操作中,经常会用到组件联动,点击百度地图的点位,出现一个视频弹窗,点击关闭视频,其实是隐藏了视频,而视频的请求还在继续。为了解决这个问题,我花了一些时间研究,找到了解决办法。

解决办法

从videojs官方文档可以查到,有一个 dispose 方法。这个方法是用来销毁 videojs 对象的。但这个方法不能直接使用,直接使用会导致一个新的问题,那就是销毁实例后 ,原本的 video 标签dom 元素也一并销毁了,这个特性从官方文档中可以看出。

Videojs Removing Players

其实我个人觉得,这个方法的操作 2 的特性非常不好,这样导致关闭后组件直接被销毁,导致下次触发视频弹窗(业务需求是点击百度地图图例,出现弹窗播放视频直播流),没有视频组件可以显示播放。

于是我针对这个项目组件,写了一个 Vue 的watch,用来监听监听 display 属性。在这个项目中,这个属性每个组件都有,display 为 false 是显示,true 是隐藏(别问为什么是反的,我也不知道)。代码示例如下:

代码语言:vue
AI代码解释
复制
<template>
  <div :style="styleObject" ref="myvideojs">
    <!-- <video
      :id="videojsId"
      class="video-js vjs-big-play-centered vjs-fluid"
      style="width: 100%; height: 100%; object-fit: fill"
    ></video> -->
    <!-- padding-top: 0,解决减小高度到一定数值后,高度不能自适应的问题 -->
    <video :id="videojsId" class="video-js vjs-big-play-centered vjs-fluid" style="width: 100%; height: 100%; object-fit: fill; padding-top: 0" ref="videoPlayer"></video>
  </div>
</template>
代码语言:vue
AI代码解释
复制
 watch: {
    ...
    display: {
      handler(newVal) {
        // true 代表隐藏
        if (newVal) {
          console.log("隐藏 :>> ")
          if (this.myVideo) {
            this.$nextTick(() => {
              // 必须先暂停,后销毁,销毁后 dom 元素也会被移除,所以需要手动添加相同 id 的 dom
              this.myVideo.dispose()
              // 下面这个 dom 跟 video 标签属性一致
              const videoElement = document.createElement("video")
              videoElement.setAttribute("id", this.videojsId) //注意 id 要一致
              videoElement.setAttribute("class", "video-js vjs-big-play-centered vjs-fluid")
              videoElement.setAttribute("style", "width: 100%; height: 100%; object-fit: fill; padding-top: 0")
              videoElement.setAttribute("ref", "videoPlayer")
              this.$refs.myvideojs.appendChild(videoElement) //添加相同 DOM
              this.myVideo = null
            })
          }
        } else {
          console.log("显示 :>> ")
        }
      },
    },
  }

下面是绘制组件的方法:

代码语言:vue
AI代码解释
复制
methods: {
    // 绘制方法
    drawChar(result) {
      let that = this
      if (result.length > 1) {
        console.log(this.MapPoiChange)
        console.log(this.option.Playtype)
        let key = this.MapPoiChange ? this.MapPoiChange : this.option.Playtype ? this.option.Playtype : "SXT"
        result = result.filter(v => {
          return v.key == key
        })[0]
      } else {
        result = result[0]
      }
      // 这些options属性也可直接设置在video标签上,见 muted
      // 实例化过,修改最新的url
      if (this.myVideo) {
        this.myVideo.src({ type: result.type, src: result.value })
      } else {
        let options = {
          autoplay: this.option.autoplay, // 设置自动播放
          controls: true, // 显示播放的控件
          width: this.component.width,
          height: this.component.height,
          sources: [
            {
              src: result.value,
              type: result.type, // 告诉videojs,这是一个hls流
            },
          ],
        } // videojs的第一个参数表示的是,文档中video的id
        this.myVideo = Videojs(this.videojsId, options, function onPlayerReady() {
          this.on("error", function () {
            // 报错信息
            var mediaError = this.error()
            console.log("mediaError", mediaError)
            // 异常处理
            that.updateData()
          })
        })
      }
    },
  },

以上代码的核心有3点:

  1. 关闭的时候,销毁 videojs;
  2. 销毁后立即创建一个与先前videojs 相同的 dom,尤其是 id 要保持一致;
  3. 显示时候重新初始化渲染 videojs(因为全局方法默认会调用绘制 drawChar,否则需要再显示逻辑里面新增绘制方法)

只要注意到这三个核心点,类似的问题也能迎刃而解。

注意事项

1. 销毁要包裹在\$nextTick里面,不然会出现报错。

代码语言:vue
AI代码解释
复制
Error:Invalid target for nutl#on;must be a DOM node or evented object
  1. 需要通过 appendChild,添加一个跟之前 videojs 一样的根 dom,不然会报错找不到这个元素的 id:
代码语言:vue
AI代码解释
复制
TypeError: The element or ID supplied is not valid. (videojs)

总结

关于 videojs,实际项目用到的比较多,坑也是真的坑。文档不太好找,搜索查询了好长时间,才摸索出一套可行的解决方案。面对这类问题,需要善用搜索,从别人的文章和问答中寻找解决问题的思路和方案。查阅官方文档也是个不错的选择,但并不是每个类库框架的官方文档写的都易于理解。videojs 新版的文档和旧版本有些区别,很多 API 看起来并不十分直观,所以版本问题也要注意下。

以上是我解决这个问题的经验分享,欢迎评论区交流。

参考

vue使用videojs控制后台m3u8数据请求 - bomdeyada - 博客园


我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
3 条评论
热度
最新
面对疑难杂症,通过官方文档,仔细阅读说明,或许有意想不到的发现。
面对疑难杂症,通过官方文档,仔细阅读说明,或许有意想不到的发现。
回复回复2举报
这真是我的华点,盲生……
这真是我的华点,盲生……
回复回复1举报
初看:奇怪的知识又增加了;细看:多看看官方文档有收获
初看:奇怪的知识又增加了;细看:多看看官方文档有收获
回复回复1举报
推荐阅读
编辑精选文章
换一批
Thinking--Promise解决动态挂载静态资源重复问题
🐾 原因分析:在 loadResources() 中,已经追加了前置判断 if (window.videojs) return Promise.resolve(); 来避免重复资源的加载,从而达到只加载一份的目的。没有生效❓
奋飛
2025/05/31
600
Thinking--Promise解决动态挂载静态资源重复问题
videojs播放器插件使用详解
HLS是苹果公司实现的基于 HTTP 的流媒体传输协议,全称 HTTP Live Streaming,可支持流媒体的直播和点播,主要应用在 iOS 系统,为 iOS 设备(如 iPhone、iPad)提供音视频直播和点播方案。
菲宇
2020/04/16
53.9K2
解决video标签播放m3u8格式视频失败问题
前言 什么是m3u8? 效果 效果地址 m3u8视频切换 效果图片 解决方法 采用video.js插件! 引入 引入videoJS插件样式文件; 引入videoJS插件JS文件; 引
Rattenking
2021/01/30
8.5K0
video.js调用
>  一、总结(点击显示或隐藏总结内容) 一句话总结: 网上有各种细致的现成的代码可以拿来用,没必要自己死专 1、video.js有两种初始化方式? 一种是在video的html标签之中 一种是使用j
kirin
2020/06/22
32.9K0
vue使用video.js解决m3u8视频播放格式
今天被这个关于m3u8视频播放不了搞了一下午,这个项目所有的视频流都是m3u8格式的,后台给我们返回的都是m3u8格式的视频流,解决了好长时间,看了好多博客,只有这个博客给我点启发,去解决这个问题,请查看。会使用两种方法来解决这个问题
小周sir
2019/09/23
10.1K0
vue使用video.js解决m3u8视频播放格式
最新版videoJS使用播放M3U8格式直播 视频
JaneYork
2023/10/11
1.6K0
videojs插件使用「建议收藏」
使用整理:使用主要针对于移动端视频播放,考虑的点:视频显示适配手机宽度;适配定义样式;在微信端,安卓、ios视频空间控件不同,定制等会自动被微信视频控件覆盖;播放过程中定制暂停/播放按钮事件等;播放结束后定制重播、下一个视频事件,读秒播放下一个视频
全栈程序员站长
2022/11/01
10.7K0
m3u8格式视频源列表[通俗易懂]
其中需要引入的文件是video.min.js、video-js.min.css、videojs-contrib-hls.min.js文件,就可以进行播放视频了
全栈程序员站长
2022/09/14
4.6K0
m3u8格式视频源列表[通俗易懂]
video.js支持m3u8格式直播
为什么要使用video.js? 1. PC端浏览器并不支持video直接播放m3u8格式的视频 2. 手机端各式各样的浏览器定制的video界面风格不统一,直接写原生的js控制视频兼容性较差 3. v
smy
2018/04/03
12.4K2
video.js支持m3u8格式直播
基于video.js来实现vue的视频播放功能
video.js是一个很好的视频播放插件,但是如果移植到vue上相信很多小伙伴很苦恼,是不是网上搜了一堆,发现不好使,我也是踩坑了,后来发现官方文档上就有,好尴尬,建议以后学习先看看官方文档,会有惊喜的。 1.首先安装video.js,然后在main.js中引入
李维亮
2021/07/08
15K0
rtmp、m3u8直播小记
最近项目做跟视频有关的,一个是直播,一个是播放视频。使用video标签。视频直播有很多协议,rtmp、rtsp、hls等就自己去了解,业务有做到就会了解一些。
wade
2020/04/24
5.9K0
EasyNVR H5无插件直播方案前端架构之:videojs的使用
在引入videojs加载文件的前提下,可以在video标签中添加属性值“data-setup=’{}’”,并且在class属性中添加“video-js”;二者缺一不可;
EasyNVR
2020/04/23
2.6K0
EasyNVR H5无插件直播方案前端架构之:videojs的使用
如何使用H265视频播放器EasyPlayer.JS调用videojs播放EasyNVR转发的视频流?
经过了多年的研发探索,TSINGSEE青犀视频团队开发了三种不同的视频流媒体服务器软件EasyNVR,EasyGBS,EasyDSS,三个平台都可以进行网页无插件直播,有很好的的稳定性和可靠性,同时我们也有自己的网页播放器EasyPlayer.js ,能够很好集成在页面内。
EasyNVR
2021/01/04
6.4K0
如何使用H265视频播放器EasyPlayer.JS调用videojs播放EasyNVR转发的视频流?
Video.js 使用教程 - 手把手教你基于 Vue 搭建 HTML 5 视频播放器
本文首发:《Video.js 使用教程 - 手把手教你基于 Vue 搭建 HTML 5 视频播放器》
蒋川
2022/03/29
12.5K0
Video.js 使用教程 - 手把手教你基于 Vue 搭建 HTML 5 视频播放器
Vue3开发:视频播放器video.js使用详解
Video.js是一个通用的在网页上嵌入视频播放器的JS库,比原生video标签有更强大的功能、更好的兼容性、更美观等优点。是一个比较流行的视频播放器,它的官网是https://videojs.com/
BennuCTech
2023/08/28
11.8K0
Vue3开发:视频播放器video.js使用详解
Nginx+FFmpeg打造自己的视频直播服务
现在很多项目都有视频实时播放的功能需求,例如监控,直播等,原始的摄像头采集的视频流协议一般都是 rtsp 协议,在旧版的浏览器中使用
ruochen
2021/11/24
6.2K0
【直播】nginx搭建rtmp流直播环境
windows下很容易搭建,只需要下载nginx-1.7.11.3-Gryphon就可以了,解压之后运行run_ngnix.bat 能力强的同学自己编译最新版本nginx并使用吧
一朵灼灼华
2022/08/05
4.3K0
【直播】nginx搭建rtmp流直播环境
简单搭建一个直播服务器
1、下载srsv2.0_r8 ,下载地址是:https://codeload.github.com/ossrs/srs/zip/v2.0-r8
全栈程序员站长
2022/09/01
3.6K0
简单搭建一个直播服务器
Cordova插件cordova-plugin-media-capture实现短视频的录制上传和播放
1、网上的教程大部分都是虎头蛇尾的不全的。互相抄来抄去真的感觉就没有一个是真正自己去写一写的,不然这里面这么多的坑就没有一个人出来说说的?下面就写写我实现功能过程中的一些问题吧,代码绝对完整并且按照步骤来一定可以成功!
用户6493868
2022/03/05
2.1K0
移动端自动播放视频
TS(Transport Stream,传输流)是一种封装的格式,它的全称为MPEG2-TS。是一种视频格式,一般用于实时流媒体和广播电视领域。
程序员不务正业
2021/03/03
2.1K0
推荐阅读
相关推荐
Thinking--Promise解决动态挂载静态资源重复问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档