美文网首页
手动中断liveplayer播放器直播流

手动中断liveplayer播放器直播流

作者: 我相信是新的开始 | 来源:发表于2022-08-30 14:06 被阅读0次

问题:

在开发视频监控画面相关功能时,发现浏览器总是在一段时间之后崩溃。

通过F12查看网络请求之后发现,监控画面是通过.flv的长连接请求实现,并且在播放器组件销毁之后依旧在后台请求。

因此在多路视频持续播放下,浏览器很快就会因为内存溢出而崩溃(这里使用的是liveplayer播放器,其他播放器暂不知是否有问题)。

官方文档里说置空videoUrl=""可以销毁播放器组件,但是实际并不会中断请求。

由于liveplayer-element.min.js是压缩后的js文件,无法阅读。通过软件格式化后,再由浏览器请求的启动器定位到发起请求的js代码。

self.fetch(o.url, d)

发现使用的是fetch请求,在网上查资料找到一个AbortController对象可以用来手动终止fetch请求(AbortController接口资料)。

由于需要在发起请求的时候带上signal参数,压缩后的js源码也理不清。 所以这里采用了一个取巧的办法:将对象放到window中,在发起请求的地方加一行代码从window中取出对象放到参数中。 但又不能所有请求都用同一个对象,会导致不同业务但同时播放的情况下一起中断,因此需要一个标识来区分。 这里唯一能准确联通的只有一个url,所以实现方式是在url后面追加一个window属性名称字符串来获取正确的对象。

var d = {
    method: "GET",
    headers: a,
    mode: "cors",
    cache: "default",
    referrerPolicy: "no-referrer-when-downgrade",
    //下面是加进去的代码
    signal: window[new URL(o.url).searchParams.get("abortControllerName")] && window[new URL(o.url).searchParams.get("abortControllerName")].signal
};

开发流程

  1. 首先在页面或者vue组件初始化的时候创建一个AbortController对象放到window上。
//不同业务的对象要分开,不然调用方法会一起终止
window["abortControllerObject"] = new AbortController()
//或者绑定到vue组件上,方便使用
window[this.abortControllerName] = new AbortController()
  1. 在播放前处理一下url,追加一个abortControllerName的参数(这个参数名不可变,写死在了liveplayer-element.min.js的源码中)
let url = new URL(flvUrl)
url.searchParams.append("abortControllerName", this.abortControllerName)
this.$refs.player.setAttribute("video-url", url.href)
  1. 在变更播放器videoUrl的值或者组件重新渲染前,都需要中断一下请求。 并且需要重新创建一个AbortController对象!!! 因为它里面signal的值是只读的,如果中断一次后继续使用该对象,那么后面的请求是发不出去的!
window[this.abortControllerName].abort()
window[this.abortControllerName] = new AbortController()
  1. 在组件销毁前中断所有请求
window[this.abortControllerName].abort()

相关文章

网友评论

      本文标题:手动中断liveplayer播放器直播流

      本文链接:https://www.haomeiwen.com/subject/qxsdnrtx.html