前端实现flv拉流以及相关优化

<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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值