前端实现视频/直播预览_前端大视频预览
有一个需求:后端返回视频的预览地址,不仅要支持这个视频的预览,还需要设置视频封面。
这里有两种情况:
- 如果是类似.mp4,.mov等格式的视频可以选用原生 video 进行视频展示,并且原生的 video 也支持全屏、音量调节、倍速调节、视频下载、封面设置等等...
- 如果是类似.m3u8等格式的直播不推荐使用 video,可以使用 Plyr 等实现, 这个我会放在后面讲。(一开始我使用的是 ckPlayer, 但它在 ios 系统中无法播放带有一些携带 token 等参数的视频地址,因此换了 Plyr)
一、.mp4,.mov 视频预览
- src为视频地址,poster为封面图地址, controls为显示浏览器默认的视频控制栏(播放/暂停,音量调节,进度调节,倍速控制,全屏播放,视频下载...);
- 如果不加 controls,用户无法控制视频。
样式方面不过多赘述,可根据实际情况进行调整:
.video-player { max-width: 100%; max-height: 100%; object-fit: contain;}
如果需要支持更多格式的视频播放并进行具体的类型控制,可以用下面的写法:
注意:有些 .mp4 视频是 HEVC 编码的(如下图),这类视频在谷歌浏览器中可以播放,但在 Edge 等的浏览器会无法播放,这与内核浏览器的视频格式支持有关,不是 video 标签的问题,如果要做兼容性处理,可以进行转码、使用播放插件,或推荐使用谷歌浏览器访问。
二、直播预览
这里模拟一个场景:在某段时间内进行直播,直播开始前和直播结束后将播放器替换为封面图。
页面结构:
![]()
注意:这里不要写成自闭合的 !!!
- v-show=\"showPlayer\":仅在满足直播时间条件时显示视频容器
- id=\"live-header-video\":用于 JS 中获取 video DOM
- playsinline:在移动设备上避免自动全屏播放
- :poster:设置视频封面
变量定义:
import Plyr from \'plyr\';import Hls from \'hls.js\';import \'plyr/dist/plyr.css\'const showPlayer = ref(false)const header_url = ref(\'\')const live_start_time = ref(\'\')const live_end_time = ref(\'\')const cover_url = ref(\'\')let videoPlayer = nulllet div_video = null
- showPlayer:控制是否显示播放器
- header_url:视频地址
- cover_url:封面地址
- live_start_time和live_end_time:直播开始和结束时间
- videoPlayer:保存 Plyr 播放器实例
- div_video:video DOM 元素,用于绑定 Hls 或 Plyr
核心函数:
const setVideoPlayer = () =>{ if (header_url.value){ div_video = document.getElementById(\'live-header-video\') videoPlayer = new Plyr(div_video, { controls: [\'play-large\', \'play\', \'mute\', \'volume\', \'captions\', \'pip\', \'airplay\', \'fullscreen\' ], settings: [], fullscreen: { enabled: true, fallback: true, iosNative: true } }) const urlObj = new URL(header_url.value); if (urlObj.pathname.endsWith(\'.m3u8\')) { if (Hls.isSupported()) { const hls = new Hls(); hls.loadSource(header_url.value); hls.attachMedia(div_video); videoPlayer.play() hls.on(Hls.Events.MANIFEST_PARSED, () => { console.log(\'HLS 流准备就绪\'); }); hls.on(Hls.Events.ERROR, (event, data) => { console.error(\'HLS 错误:\', data); }); } else if (div_video.canPlayType(\'application/vnd.apple.mpegurl\')) { console.log(\"不支持Hls.isSupported\") div_video.src = header_url.value; } else { console.error(\'不支持 HLS 播放\'); } } else { div_video.src = header_url.value div_video.load(); div_video.addEventListener(\'loadeddata\', () => { videoPlayer.play(); }); } if(live_start_time.value && live_end_time.value) { const startDate = new Date(live_start_time.value.replace(\" \", \"T\")); const endDate = new Date(live_end_time.value.replace(\" \", \"T\")); const currentDate = new Date(); showPlayer.value = currentDate >= startDate && currentDate <= endDate; } }}
代码解析:
div_video = document.getElementById(\'live-header-video\')videoPlayer = new Plyr(div_video, { ... })
- 获取 video 元素并初始化 Plyr
- Plyr 是视频播放器库,初始化后控制按钮等都由它管理
if (urlObj.pathname.endsWith(\'.m3u8\')) {
- 判断是否是 .m3u8 流地址
如果是 .m3u8:
- 使用 Hls.js 加载并绑定流:
if (Hls.isSupported()) { const hls = new Hls(); hls.loadSource(header_url.value); hls.attachMedia(div_video); videoPlayer.play() ...}
- 若不支持 Hls.js,但浏览器原生支持 .m3u8(如 Safari):
else if (div_video.canPlayType(\'application/vnd.apple.mpegurl\')) { div_video.src = header_url.value;}
- 否则提示不支持 HLS 播放。
- 如果是普通视频文件(非 .m3u8)
div_video.src = header_url.valuediv_video.load();div_video.addEventListener(\'loadeddata\', () => { videoPlayer.play();});
- 当视频数据加载完成后自动播放
if(live_start_time.value && live_end_time.value) { const startDate = new Date(live_start_time.value.replace(\" \", \"T\")); const endDate = new Date(live_end_time.value.replace(\" \", \"T\")); const currentDate = new Date(); showPlayer.value = currentDate >= startDate && currentDate <= endDate;}
- 判断是否在直播时间段:时间格式转为 Date 对象后进行比较,控制 showPlayer 的值,从而决定是否显示播放器。