canvas实现视频进度预览条需按需抽帧、seeked后截图、处理跨域与尺寸;抽帧间隔100–300ms,缩略图建议64×36;rtsp等需后端截图。

用 Canvas 实现 HTML5 视频进度预览条,核心是“按需抽帧 + 精准触发 + 高效渲染”,不是简单截图拼接。关键在于跳转完成后再画帧,而不是靠时间估算;同时要避开跨域、尺寸未就绪、绘制时机错误这三类高频问题。
必须等 seeked 事件再截图
用户拖动进度条时,timeupdate 可能滞后或被节流,画面还没真正切换过去。只有 seeked 被触发,才表示 currentTime 已生效、视频帧已解码并可渲染。此时调用 drawImage 才能拿到真实画面。
- 监听
video.addEventListener('seeked', () => { drawFrameAtCurrentTime(); }) - 不要在
input或change事件里直接截图——那时画面还没跳转 - 如果想预览某固定时间点(如第 3.2 秒),先设
video.currentTime = 3.2,再等seeked
canvas 尺寸和跨域必须提前处理
截图黑屏、报 SecurityError,90% 是因为这两点没做对:视频没设置 crossorigin="anonymous",或者 canvas 宽高取的是 0。
-
<video crossorigin="anonymous" src="https://xxx.com/video.mp4"></video>—— 缺这个属性,跨域视频一画就失败 - canvas 宽高必须用
video.videoWidth和video.videoHeight,不能写死,也不能靠 CSS 拉伸 - 确保在
loadedmetadata或更稳妥的canplay后再初始化 canvas 尺寸,否则videoWidth是 0
缩略图序列要控制密度和尺寸
每秒抽 10 帧?页面会卡顿。横向铺开几百张图?内存爆炸。得按实际需要平衡清晰度与性能。
- 推荐抽帧间隔:100–300ms 一帧(即每秒 3–10 帧),足够人眼识别内容变化
- 单张缩略图尺寸建议 64×36 或 96×54(保持 16:9),太大会撑满容器、拖慢滚动
- 预览条容器用
overflow-x: auto+scrollWidth控制滚动,别用transform: translateX—— 否则鼠标坐标计算错乱
移动端和 RTSP 流要特别注意
不是所有视频都能前端实时抽帧。有些场景必须换思路。
- iOS Safari 对
poster加载有延迟,加preload="metadata"提前触发 - RTSP 地址浏览器根本播不了,
<video></video>标签不支持。所谓“前端生成缩略图”都是假的,实际靠后端 ffmpeg 定时拉流截图,前端只轮询一张图 - 本地
File对象可用URL.createObjectURL(file)赋值给video.src,避免跨域污染
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











