vue3videplayer播放m3u8视频流注意事项

前言

使用vue3开发项目时,碰上需要做一个视频流列表的页面,最开始是想获取所有列表数据后创建对应的video标签,这样默认获取第一帧作为封面,同时暂停视频减轻不断请求的压力。但开发后发现视频就算暂停后也会继续请求视频流,多个视频反而会导致页面卡顿。

方案

手动获取视频的第一帧,通过canvas将其绘画出来后作为封面,隐藏销毁video标签。

部分代码块

<div ref="videoContainerRef" absolute top-5px bottom-5px left-5px right-5px> <vue3VideoPlay v-if="!video.isSingleShowPoster" :id="video.id" v-bind="createVideoParams(video.name, video.url, false, 'auto')" @loadeddata="getVideoPoster(video)" /> <img v-else w-full h-full :src="video.poster" alt="preview"> </div> <script setup lang="ts"> const video = reactive({ name: "video", id: "id", // 用作video标签的id isSingleShowPoster: false, // 是否显示poster poster: '', // 自动获取poster第一帧 url:"", }) // 由于修改数据后dom树能够及时变化,涉及到双向绑定,所以数据需要是响应式 // preload要选择 auto 预加载,否则可能会获取不到第一帧 function createVideoParams(title: string, url: string, autoPlay: boolean = false, preload: 'auto' | 'metadata' | 'none' = 'none') { return { width: "100%", // 播放器高度 height: "100%", // 播放器高度 color: "#5B8BB3", // 主题色 title: title, // 视频名称 type: "m3u8", src: url, // 视频源 muted: true, // 静音 webFullScreen: false, autoPlay: autoPlay, // 自动播放 volume: 0, // 默认音量大小 control: false, // 是否显示控制 preload: preload, controlBtns: ["fullScreen"], // 显示所有按钮, }; } const videoDialogContainerRef = ref() async function getVideoPoster(info: any) { const video = document.getElementById(info.id)! as HTMLVideoElement; video.currentTime = 0 const canvas = document.createElement('canvas'); // 绘制时画布大小最好和video标签大小一样(大小不一样可能绘制出来会糊)(代码关系可能会导致获取不到video大小导致canvas宽高为0, // 如果画布的高度或宽度是0,那么绘制出来的图片字符为"data:,") // 如果获取不到video标签的 绘制出来的图片会黑屏 // 如果能直接获取获取video大小最好,这里通过video外部容器的高度近似获取video大小 const { clientWidth, clientHeight } = videoDialogContainerRef.value; canvas.width = clientWidth; canvas.height = clientHeight; const ctx = canvas.getContext('2d', { alpha: false })! ctx?.drawImage(video, 0, 0, clientWidth, clientHeight); const img = canvas.toDataURL('image/jpeg', 1); canvas.remove(); video.src = ""; // 绘制完成后停止video流请求,通过v-if移除dom树 info.isSingleShowPoster = true; info.poster = img; } </script>

注意

监听函数一定得是"onloadeddata",如果preload=none: 页面加载时视频不加载可能绘制出来的图片就会使纯黑。
虽然设置了onloadeddata事件才去画它的第一帧,按理说应该视频已经加载出了第一帧了,但是由于没有设置preload=auto并没有截图到第一帧。(好像不管有没有preload都会执行onloadeddata)
所以要想截图第一帧就必须让它自动加载。因为各浏览器对preload不设置时的默认值可能不同还是手动设置一下比较好。

相关文章


__EOF__

本文作者damarkday知识库
本文链接https://www.cnblogs.com/GoodMemoryBlog/p/17705171.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   DAmarkday  阅读(1040)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示