web前端(Vue2.x)接收H264实时视频码流(二进制)进行播放
1、安装 jmuxer
npm install jmuxer@2.0.5
2、.vue文件中使用
<template> <div> <video id="dom_id" muted="muted" controls class="video_box"></video> <div v-if="!has_data" v-loading="!has_data && player" element-loading-text="加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 1)" id="backgroud_color" ></div> </div> </template> <script> import JMuxer from 'jmuxer' export default { name: 'Video', data() { return { ws: null, video: null, player: null, has_data: false, } }, methods: { // 初始化 websocket initWebSocket() { let wsuri = 'ws://127.0.0.1:8080' this.ws = new WebSocket(wsuri) this.ws.binaryType = 'arraybuffer' this.ws.onopen = this.websocketonopen this.ws.onmessage = this.websocketonmessage this.ws.onerror = this.websocketonerror this.ws.onclose = this.websocketclose }, // 连接成功的回调 websocketonopen() { console.log('连接成功') setTimeout(() => { this.handle_preview('start_preview') }, 300) }, // 开始/结束预览 handle_preview(cmd) { let send_data = { cmd, taskname: "测试", } this.init_player() this.ws.send(JSON.stringify(send_data)) }, // 接收到的数据 websocketonmessage(e) { let re_msg = e.data if (re_msg instanceof Object) { // 二进制时往video中push console.log(`二进制`) try { this.player.feed({ video: new Uint8Array(re_msg), }) } catch (err) {} } else { // 判断是否成功 re_msg = JSON.parse(re_msg) console.log('字符串') switch (re_msg.cmd) { case 'preview_status': if (re_msg.code != 200) return this.layer_msg(re_msg.msg) break } } }, // 弹窗提示 layer_msg(msg) { this.$notify({ type: 'warning', showClose: true, title: '提示', dangerouslyUseHTMLString: true, message: msg, position: 'top-right', duration: 3000, }) }, // 初始化播放器 init_player() { this.player = new JMuxer({ node: "video_box", mode: 'video', flushingTime: 30, maxDelay: 16, clearBuffer: true, debug: false, onReady: () => { return this.get_paused() }, }) }, // 获取是否在播放的状态 get_paused() { this.video = document.getElementById("video_box") if (this.video.paused) { this.video.click() this.video.play() this.toggle_bg() } else { setTimeout(() => { return this.get_paused() }, 300) } }, // 切换黑色背景显隐 toggle_bg() { let timer = setInterval(() => { if (this.video.currentTime > 0) { clearInterval(timer) this.has_data = true this.video.currentTime = 0 // 不要去掉,作用重要 } else { this.has_data = false } }, 1000) }, // websocket 连接中断 websocketonerror(e) { console.log('error', e) }, // websocket 断开 websocketclose(e) { console.log('断开连接') }, // 手动关闭ws close_ws() { console.log('关闭', this.ws) if (this.ws && this.ws.readyState == 1) { // 停止预览 this.handle_preview('stop_preview') this.video.src = null this.player.destroy() this.player = null this.has_data = false this.ws.close() this.ws = null } }, }, mounted() {}, } </script> <style lang="scss" scoped> .video_box { width: 100%; height: 480px; border-radius: 8px; } #backgroud_color { position: absolute; background: black; width: 100%; height: 480px; right: 0; top: 0; border-radius: 8px; } video::-webkit-media-controls { /*禁用播放器控制栏的样式*/ display: none !important; } </style>