flv.js视频流出错,断流处理
flv.js视频流出错,断流处理
- 场景:前端使用flv.js播放视频流
Bug表现:
- 视频流播放两分钟左右video标签出现暂停按钮,控制台flv.js报错:Failed to execute 'appendBuffer' on 'SourceBuffer': The HTMLMediaElement.error attribute is not null
Bug原因:
- 百度出来是flv.js内部原因
Bug修复:
- 网上大部分解决方案是修改浏览器视频编解码配置(Chrome浏览器输入chrome://flags/,搜索video,选择disabled,如下图),但是此方法在我项目中无效,遂继续翻阅百度,终于找到破解之法。
- 修复之法:监听视频播放错误信息,出错时销毁重建,就是如此简单,我之前怎么没有想到
完整代码
js
复制代码
<template>
<div v-if="propValue.rtspUrl === 'src'">
<span>视频加载中</span>
</div>
<video
v-else
muted
autoplay
controls
class="videoPlayer"
:id="propValue.id"
></video>
</template>
<script>
import flvjs from "flv.js";
export default {
props: {
propValue: {
type: Object,
default: () => {
return {
id: "player",
rtspUrl: "",
};
},
},
},
data() {
return {
player: null,
lastDecodedFrames: 0
};
},
watch: {
propValue: {
handler(newVal, oldVal) {
if (newVal && newVal != oldVal) {
this.init();
}
},
deep: true,
immediate: true,
},
},
mounted() {
this.init();
},
beforeDestroy() {
this.destroyFlv();
},
methods: {
init() {
if (!flvjs.isSupported()) return;
if (this.propValue.rtspUrl === "") return;
const videoContainer = document.getElementById(this.propValue.id);
if (videoContainer) {
this.player = flvjs.createPlayer(
{
type: "flv", // flv,mp4
isLive: true,
// url: `ws://localhost:80/rtsp/${this.id}/?url=${this.rtsp}`,
url: this.propValue.rtspUrl,
hasAudio: false,
},
{
autoCleanupSourceBuffer: true,
enableWorker: false, //不启用分离线程
enableStashBuffer: true, //关闭IO隐藏缓冲区
isLive: true,
lazyLoad: false,
}
);
this.player.attachMediaElement(videoContainer);
try {
this.player.load();
this.player.play();
this.listenVideo();
} catch (error) {
console.log(error);
}
}
},
destroyFlv() {
if (this.player) {
this.player.pause();
this.player.unload();
this.player.detachMediaElement();
this.player.destroy();
this.player = null;
}
},
// 监听视频流是否断流或者卡顿