1.HLS.js 使用:pnpm add hls.js 安装了hls.js,然后通过导入 hls 可以使用这个东西。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 <template> <div class="monitor-dialog" v-if="dataState.currentMonitor"> <div class="header"> <div class="title">{{ dataState.deviceName }}</div> <div class="close" @click="closeHandle"> <CloseOutlined /> </div> </div> <div class="content"> <video class="monitor-video" controls="controls" autoplay="autoplay" x-webkit-airplay="true" x5-video-player-fullscreen="true" preload="auto" playsinline="true" webkit-playsinline x5-video-player-typ="h5" ref="monitorVideo" > </video> </div> </div> </template> <script setup lang="ts"> import { onMounted, shallowReactive, defineEmits,ref,onBeforeUnmount } from 'vue'; import eventBus from '/@/utils/map/eventBus'; // 事件总线 import { CloseOutlined } from '@ant-design/icons-vue'; import { getChannels } from '../api/map.ts'; import hlsjs from 'hls.js' const dataState = shallowReactive({ currentMonitor: null, deviceName: '', // 设备名称 channelUrl: '', // 隧道地址 }); const emit = defineEmits(['close']); const monitorVideo=ref(null); // dom 引用 let hlsjsVideo =null ; // 视频播放组件 /** * 显示视频对话框 */ const showMonitor = (item) => { dataState.currentMonitor = item; dataState.deviceName = item.deviceName; // 获取播放通道 getMonitorChannels(); }; /** * */ const closeHandle = () => { dataState.currentMonitor = null; dataState.channelUrl = ''; dataState.deviceName = ''; // 取消视频播放 if(monitorVideo.value){ monitorVideo.value.pause(); hlsjsVideo.destroy(); hlsjsVideo = null; } emit('close'); }; function getMonitorChannels() { let device = dataState.currentMonitor; let deviceId = device.deviceId; getChannels({ deviceId: deviceId, }).then((res) => { let channels = res[0]; dataState.channelUrl = channels.hls; // 显示视频 showChannel(); }); } /** * 显示视频隧道 */ function showChannel(){ if (hlsjs.isSupported()) { hlsjsVideo = new hlsjs(); hlsjsVideo.loadSource(dataState.channelUrl);//设置播放路径 hlsjsVideo.attachMedia(monitorVideo.value);//解析到video标签上 hlsjsVideo.on(hlsjs.Events.MANIFEST_PARSED, () => { monitorVideo.value.play(); }); hlsjsVideo.on(hlsjs.Events.ERROR, (event, data) => { console.log(event, data); // 监听出错事件 console.log("加载失败"); }); } } onMounted(() => { eventBus.on('showMonitor', showMonitor); }); onBeforeUnmount(()=>{ closeHandle(); }) </script> <style lang="less" scoped> .monitor-dialog { position: fixed; left: 50%; transform: translateX(-50%); top: 120px; width: 500px; height: 400px; border: 1px solid #aaa; border-radius: 8px; background: rgba(9, 62, 122, 0.9); padding: 10px 20px 20px 20px; display: flex; flex-direction: column; .header { font-size: 18px; color: #fff; padding: 0 0 10px 0; .close { position: absolute; right: 10px; top: 10px; cursor: pointer; } } .content { flex: 1; video { width: 100%; height: 100%; object-fit: fill } } } </style>
参考文章: 1.Vue 之 视频流 - Hls.js 2.实时视频流库 hls.js 重载切换资源的方式 hls 播放需要先 attachMedia,然后 loadSource。如果切换 resource,需要先执行 hls.destroy(),否则会出现混乱。destroy 之后再依次进行 hls 实例化、attach、load 操作。
问题 (1)”Failed to execute ‘appendBuffer’ on ‘SourceBuffer’: This SourceBuffer has been removed from the parent media source.” 我在执行 m3u8 文件播放的时候,出现了这个问题,就是后端已经请求了 ts ,无论切片大小,都是无法播放的。
参考文章: 【1】.Failed to execute ‘appendBuffer’ on ‘SourceBuffer’: The HTMLMediaElement.error attribute is not null 【2】.SourceBuffer parent being removed 【3】.使用flv.js遇到的问题(含vue中使用flv.js的简单教程) 这种错误提示一般是在flv源发生异常中断的时候产生的。
2.Xgplay 西瓜视频播放器 (1)安装
1 pnpm add xgplay xgplay-hls
(2)使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import 'xgplayer/dist/index.min.css' let videoUrl = item || this .videoUrl let m3u8Url = BASE_API_URL + '/drone/api/v1/files/getM3U8File?filename=' + videoUrl + '&x-auth-token=' + sessionStorage .getItem ('droneToken' ) let player if (document .createElement ('video' ).canPlayType ('application/vnd.apple.mpegurl' )) { player = new Player ({ el : this .$el .querySelector ('.player' ), url : m3u8Url }) } else if (HlsPlugin .isSupported ()) { player = new Player ({ el : this .$el .querySelector ('.player' ), isLive : false , url : m3u8Url, plugins : [HlsPlugin ] }) } player.on ('error' , event => { console .log (event) })
参考文章: 【1】.xgplayer-hls.js v2.32播放hls m3u8直播流 西瓜视频网页播放器 demo 示例教程 【2】.快速上手 【3】.xgplayer-hls 【4】.西瓜播放器 这是一个播放器的示例代码 【5】.配置 西瓜视频配置
问题 (1)”CHUNK_DEMUXER_ERROR_APPEND_FAILED: Unsupported VisualSampleEntry type mp4v”
参考文章: 1.MP4V File Extension
(2)没有样式信息 我用的是 xgplay 3.0.11 版本,结果样式全部错误了。
【引入样式】
1 import 'xgplayer/dist/index.min.css'
参考文章: 【1】.使用过程中没有样式,界面全部变样
3.Jswebrtc 使用 jswebrtc 播放 rtmp 我在上面其实已经写过了,关键就是这个地址,因为我用的是改造后的 jswebrtc.min.js,所以要注意端口号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let url = "webrtc://" + window .location .hostname + "xxx" ; let videoDom = document .getElementById ('webrtc' ); this .player = new JSWebrtc .Player (url, { video : videoDom, autoplay : true , onPlay : () => { videoDom.addEventListener ('canplay' , function ( ) { videoDom.play (); }) } })
参考文章: 【1】.vue使用JSWebrtc播放webrtc视频流 【2】.『前端日记』—— 基于WebRTC的浏览器跨端传输 【3】.jswebrtc 拉流 webrtc://xxx 【4】.jswebrtc播放无人机直播视频 【5】.H5播放Rtmp之videojs播放 我们看到了HLS播放视频实时性非常差,好的在6-7s,差点的就要10-12s了,也就是人走了,估计视频上还能看到,这对观感效果造成了很大的影响!但是好处就是它是基于http协议文件下载的,所以不需要任何插件,到处播放,处处兼容,所以rtmp和hls在web端的特点如下 【6】.Web端rtmp视频流的预览 方案1:基于video.min@5.4.3.js 。方案2:基于Aliplayer。