使用flv.js的踩坑记录及解决方法
安装
npm install --save flv.js
使用
<template> <div> <video id="videoElement" ref="videoRef" autoplay controls width="100%" height="100%" muted /> <div> </template> <script> import flvjs from flv.js // 实现播放 async createPlayer(pid) { const { data } = await findVideo(pid) const preUrl = http://192.168.0.176:7016 if (data[0]) { const testUrl1 = preUrl + data[0].urls const videoElement1 = this.$refs.videoRef let flvPlayer1 = flvjs.createPlayer({ type: flv, // 类型 isLive: true, // 数据源是否为直播流 stashInitialSize: 128, // 减少首帧显示等待时长 url: testUrl1 // 数据源地址 }, { enableStashBuffer: false, // 关闭IO隐藏缓冲区 enableWorker: false, // 启用分离的线程进行转换 autoCleanupSourceBuffer: true, // 自动清除缓存 fixAudioTimestampGap: false // 音视频同步 }) this.flvPlayer = flvPlayer1 // 使用typescript支持基于类的vue组件格式可能导致attachMediaElement()方法报错 flvPlayer1.attachMediaElement(videoElement1) flvPlayer1.load() // 加载数据流 flvPlayer1.play() // 播放数据流 } } // 关闭视频播放 closePlay() { this.flvPlayer.pause() // 暂停播放数据流 this.flvPlayer.unload() // 取消数据流加载 this.flvPlayer.detachMediaElement() // 将播放实例从节点中取出 this.flvPlayer.destroy() // 销毁播放实例 } </script>
踩坑
警告:[FlvPlayer] > Playback seems stuck at 0, seek to 1.32
解决方法:
data() { return { interval: 0, flvPlayer: } }, mounted() { let lastDecodedFrames = 0 let stuckTime = 0 if(this.interval && clearInterval(this.interval)) { this.interval = setInterval(() => { const decodeedFrames = this.flvPlayer.statisticsInfo.decodedFrames if (!decodedFrames) return if (lastDecodedFrames === decodedFrames && !this.videoElement.paused) { stuckTime++ if (stuckTime > 1) { this.closePlay() this.createPlayer() } } else { lastDecodedfRAMES = decodedFrames stuckTime = 0 } }, 1000) } }
报错1: Uncaught (in promise) DOMException: Failed to read the ‘buffered’ property from ‘SourceBuffer’: This SourceBuffer has been removed from the parent media source.
介绍: 我使用的是flv.js1.6.2版本的,报错后使用了以下的方法但仍然无法解决,降低到了flv.js1.5.0版本后再使用以下方法才能解决这个报错。
解决方法:
进入node_modules/flv.js/src/core/mse-controller.js文件中 在appendMediaSegment()和_needCleanupSourceBuffer()两个方法下第一行加入以下代码:
if (!this._mediaSource || this._mediaSource.readyState !== open) { return; }
报错2: Error while initialize transmuxing worker, fallback to inline transmuxing
解决方法:
添加以下配置:
enableWorker: false, // 是否启用分离的线程进行转换
报错3: The play() request was interrupted by a call to pause().
play()请求被pause()调用中断
解决方法:
给播放数据流的地方添加一个定时器,如下:
setTimeout(function() { flvPlayer1.play() // 播放数据流 }, 300)
注意区分上下两个错误
报错4: The play() request was interrupted by a new load request
play()被新的请求中断
解决方法:
建立新的连接前先销毁之前的连接
async switchPlay() { this.closePlay() this.createPlayer(pid) }