video poster属性需设为可访问的http/https网络URL,配合preload="metadata"和有效src才能显示;播放结束后需监听ended事件手动恢复封面。

直接用 poster 属性就行,别一上来就写 JS 截帧。绝大多数场景下它更轻量、可靠,且不触发跨域或解码时机问题。
video poster 属性怎么设才不踩坑
很多人以为只要写上 poster="cover.jpg" 就完事了,结果在 iOS 或某些安卓 WebView 里压根不显示,或者画面突然“跳一下”。关键点不在有没有设,而在怎么设:
- 图片尺寸必须和视频原始分辨率完全一致,否则 iOS Safari 会拉伸变形
- 如果视频是 letterbox(上下黑边),封面图也得保留相同黑边,否则播放瞬间画面缩放错位
-
poster路径 404 不报错,浏览器静默 fallback 到黑屏或首帧——务必手动验证图片能正常访问 - 部分旧版 UC、QQ 浏览器会忽略
poster,直接渲染首帧,这是已知限制,不能当作兜底的唯一手段
JS 截首帧为什么 canvas 画出来是黑的
常见错误是:设了 video.currentTime = 0 就立刻 drawImage,结果 canvas 是黑的或空白。这不是代码写错了,而是视频编码本身决定的:
- H.264/H.265 视频的 IDR 帧通常不在时间轴 0ms,而是在 0.03–0.1s 之间;
currentTime = 0实际读到的是未解码的空帧 - 必须监听
seeked事件(不是loadeddata或canplay),等 seek 完成再绘图 - 跨域视频必须加
crossOrigin="anonymous",且服务端要返回Access-Control-Allow-Origin,否则 canvas 被污染,toDataURL()返回空字符串 - 移动端 Safari 需要先
play()再pause()才能触发解码,否则videoWidth可能为 0
toDataURL 还是 toBlob?选哪个导出首帧
toDataURL() 看起来方便,但实际在生产环境容易翻车:
- 返回 base64 字符串,体积比原始 PNG 大约 33%,iOS WebKit 下可能触发内存警告或截断
- 大分辨率视频(如 4K)调用后卡顿明显,甚至白屏
- 推荐用
toBlob():生成Blob后可直接赋给video.poster,也可塞进FormData上传,更轻量、可控性更强 - 格式选
image/jpeg(无透明需求时),质量参数设0.9,兼顾清晰度与体积;低于0.7易出压缩噪点
真正难的不是“怎么截”,而是“什么时候截”和“截哪一帧”。很多团队卡在 seeked 事件没等稳就绘图,或忽略了移动端 Safari 的 play/pause 解码触发机制——这些细节不处理,JS 截帧功能在真机上大概率只在开发机上跑得通。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











