<template>
<div>
<video ref="videoRef" class="video" preload="auto" muted autoplay></video>
</div>
</template>
<script>
import flv from 'flv.js';
export default {
data() {
return {
player: null,
videoUrl: 'http://localhost:8000/live/STREAM_NAME.flv',
changeDevice: false, // 是否切换设备
destroy: false, // 是否即将销毁组件
};
},
mounted() {
this.$nextTick(() => {
this.initPlayer();
});
// 优化3 - 实时更新(前后台切换影响实时性)
window.addEventListener('focus', () => {
this.player ? (this.player.currentTime = this.player.buffered.end(0) - 1) : '';
});
},
beforeDestroy() {
this.destroy = true; // 销毁组件前销毁
// 移除事件监听
window.removeEventListener('focus', () => {
this.player ? (this.player.currentTime = this.player.buffered.end(0) - 1) : '';
});
},
watch: {
device(val) {
if (val) {
this.changeDevice = true; // 切换设备时销毁
}
},
},
methods: {
initPlayer() {
if (flv.isSupported()) {
const videoElement = this.$refs.videoRef;
this.player = flv.createPlayer(
{
type: 'flv',
url: this.videoUrl,
isLive: true,
hasAudio: false,
hasVideo: true,
},
{
// 优化1 - 追帧(解决延迟累计问题) - config配置部分
// enableWorker: true, // 启用分离的线程进行转换(暂时不稳定可能会报错)
enableStashBuffer: false, // 关闭IO隐藏缓冲区
stashInitialSize: 128, // 减少首帧显示等待时长
}
);
this.player.attachMediaElement(videoElement);
this.player.load();
this.player.play();
// 优化1 - 追帧(解决延迟累计问题) - 追帧设置
videoElement.addEventListener('progress', () => {
const endTime = this.player.buffered.end(0); // 缓冲时间范围的结束时间
const difference = endTime - this.player.currentTime; // 结束时间与当前播放时间的差值
console.log(endTime, 'endTime');
console.log(difference, 'difference');
// 延迟较大 更新当前播放时间(缺点:频繁更新导致跳帧)
if (difference > 10 || difference < 0)
return (this.player.currentTime = this.player.buffered.end(0) - 1);
// 追帧 (缺点:延迟较大 追帧缓慢)
videoElement.playbackRate = difference > 1 ? 1.1 : 1;
});
this.player.on(flv.Events.STATISTICS_INFO, () => {
if (this.changeDevice || this.destroy) {
// 销毁播放器实例
destroyPlayer(this.player);
}
});
// 优化2 - 断线重连
this.player.on(flv.Events.ERROR, (e) => {
// 先销毁播放器实例 再进行初始化
destroyPlayer(this.player);
this.initPlayer();
console.log(e, '播放失败');
});
}
},
// 销毁播放器
destroyPlayer(player) {
player.pause();
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
},
},
};
</script>
<style lang="scss" scoped>
.video {
width: 500px;
height: 300px;
}
</style>
前端实现flv拉流以及相关优化
于 2024-06-24 16:54:51 首次发布