第一步:引入mpegts.js

npm install --save mpegts.js

第二步:在vue文件中引入mpegts.js的依赖

js MediaRecorder 实时推流_javascript

第三步:编写展示视频的盒子

我这里是使用循环遍历的方式创建video标签,这样方便后面随机展示视频使用

<template>
	<div>
		<el-row>
			<el-col :span="24">
				<div class="play-video-box">
					<input id="tag" v-model="tag" />
					<el-button @click="load">重新加载</el-button>
					<el-button @click="start">开始播放</el-button>
					<el-button @click="pause">暂停</el-button>
					<el-button @click="destory">全部销毁</el-button>
				</div>
			</el-col>
		</el-row>
		<el-row>
			<el-col :span="12" v-for="item in 4" :key="item">
				<div class="grid-content">
					<video
						class="video"
						:id="getDivClassName(item)"
						autoplay="true"
						muted="false"
						controls="false"
						@click="saveMap(item)">
						{{ item }}
					</video>
				</div>
			</el-col>
		</el-row>
	</div>
</template>

第四步:编写播放视频和销毁视频的方式

<script setup lang="ts">
import mpegts from 'mpegts.js';
import { ref, onUnmounted } from 'vue';

const flvPlayer: any = ref();
const tag = ref(null);
const videoMap = new Map();
/**
 * 创建 mpegts 实例
 */
const initFlv = (ops: { URL: string; elementId: string }) => {
	if (tag.value != null && mpegts.isSupported()) {
		// 根据id名称创建对应的video
		const ele = document.getElementById(ops.elementId);
		flvPlayer.value = mpegts.createPlayer(
			{
				type: 'flv', // 指定媒体类型
				isLive: true, // 开启直播(是否为实时流)
				hasAudio: false, // 关闭声音(如果拉过来的视频流中没有音频一定要把这里设置为fasle,否则无法播放)
				cors: true, // 开启跨域访问
				url: ops.URL // 指定流链接(这里是传递过过来的视频流的地址)
			},
			{
				enableWorker: false, //启用分离的线程进行转换(如果不想看到控制台频繁报错把它设置为false,官方的回答是这个属性还不稳定,所以要测试实时视频流的话设置为true控制台经常报错)
				enableStashBuffer: false, //关闭IO隐藏缓冲区(如果需要最小延迟,则设置为false,此项设置针对直播视频流)
				stashInitialSize: 128, //减少首帧等待时长(针对实时视频流)
				lazyLoad: false, //关闭懒加载模式(针对实时视频流)
				lazyLoadMaxDuration: 0.2, //懒加载的最大时长。单位:秒。建议针对直播:调整为200毫秒
				deferLoadAfterSourceOpen: false, //在MediaSource sourceopen事件触发后加载。在Chrome上,在后台打开的标签页可能不会触发sourceopen事件,除非切换到该标签页。
				liveBufferLatencyChasing: true, //追踪内部缓冲区导致的实时流延迟
				liveBufferLatencyMaxLatency: 1.5, //HTMLMediaElement 中可接受的最大缓冲区延迟(以秒为单位)之前使用flv.js发现延时严重,还有延时累加的问题,而mpegts.js对此做了优化,不需要我们自己设置快进追帧了
				liveBufferLatencyMinRemain: 0.3 //HTMLMediaElement 中可接受的最小缓冲区延迟(以秒为单位)
			}
		);
		// mpegts
		flvPlayer.value.attachMediaElement(ele);
		videoMap.set(ops.elementId, flvPlayer.value);
		play(flvPlayer.value);
		flvEvent();
	}
};

const play = (flv: any) => {
	flv.load();
	flv.play();
};

// mpegts
const flvEvent = () => {
	// 视频错误信息回调
	flvPlayer.value.on(mpegts.Events.ERROR, (errorType: any, errorDetail: any, errorInfo: any) => {
		console.log(
			'类型:' + JSON.stringify(errorType),
			'报错内容' + errorDetail,
			'报错信息' + errorInfo
		);
	});
	//【重要事件监听】http 请求建立好后,该事件会一直监听 mpegts 实例
	flvPlayer.value.on(mpegts.Events.STATISTICS_INFO, () => {
		const end = flvPlayer.value.buffered.end(0); //获取当前buffered值(缓冲区末尾)
		const differTime = end - flvPlayer.value.currentTime; //获取bufferend与当前播放位置的差值
		console.log('差值为:' + differTime);
	});
};

/**
 * 重新加载视频
 */
const load = () => {
	for (let index = 1; index < 5; index++) {
		if (!videoMap.has('video-contianer-' + index)) {
			initFlv({
				URL: 'http://localhost:1010/video/' + tag.value,//这里改成自己要拉流的视频地址,我这里放的是自己后端推送的1078视频的flv实时视频流
				elementId: 'video-contianer-' + index
			});
			break;
		}
	}
};
/**
 * 播放
 */
const start = () => flvPlayer.value.play();
/**
 * 暂停
 */
const pause = () => flvPlayer.value.pause();
/**
 * 销毁
 */
const destory = () => {
	if (videoMap.size > 0) {
		for (let [key, flv] of videoMap) {
			flv.pause;
			flv.unload();
			flv.detachMediaElement();
			flv.destroy();
			flv = null;
			videoMap.delete(key);
			console.log('销毁掉视频:' + key);
		}
	} else {
		console.log('没有要销毁的视频');
	}
};
const getDivClassName = (index: any) => {
	return 'video-contianer-' + index;
};

const saveMap = (index: any) => {
	test001.value = '-' + index;
	videoMap.set(index, test001.value);
};

onUnmounted(() => {
	destory();
});
</script>

第五步:设置展示样式

<style scoped lang="less">
.play-video-box {
	height: 45px;
	margin-top: 10px;
	margin-left: 200px;
}
.grid-content {
	height: 315.5px;
	margin-top: 5px;
	margin-left: 5px;
}
#tag {
	width: 280px;
	height: 30px;
}
//所有控件
video::-webkit-media-controls-enclosure {
	display: none;
}
.video {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
</style>

第六步:效果图

(我的是在输入框中输入想要拉取的设备和通道号点击重新加载即可,多次点击会将四个窗格都展示同样的视频)

js MediaRecorder 实时推流_实时视频_02