html5 的 error 事件是捕获播放失败的唯一可靠入口,但 media_err_decode(code=3)需结合 readystate≤have_metadata、networkstate=network_no_source 等状态交叉验证,区分真实解码失败与格式不支持或误报。

HTML5 <video></video> 标签的 error 事件是捕获播放失败的**唯一可靠入口**,但不同浏览器对解码失败(MEDIA_ERR_DECODE)的触发时机、条件和配套状态差异很大——不能只靠 error.code === 3 就下结论,必须结合上下文交叉验证。
识别真实解码失败,而非误报
Chrome 和 Edge 在 H.264 流关键帧损坏、色彩空间不匹配(如 BT.2020 视频在旧设备上)、硬件解码器崩溃时,较大概率触发 MEDIA_ERR_DECODE;Firefox 则更倾向静默丢帧或卡在 stalled;Safari(尤其是 iOS)常把解码问题归为 MEDIA_ERR_SRC_NOT_SUPPORTED 或直接不抛 error,而是让 readyState 停留在 0 或 1。
- 先确认
video.error?.code === MediaError.MEDIA_ERR_DECODE(即 3) - 再检查
video.readyState ,排除已开始播放后因缓冲不足导致的中断 - 同时验证
video.networkState === HTMLMediaElement.NETWORK_NO_SOURCE,确保不是网络层未加载就报错 - 若以上都成立,才可初步判定为真实解码失败
区分解码失败与格式不支持
很多“解码失败”实际是浏览器根本没尝试解码——因为 <source></source> 的 type 声明不准确,或文件内部编码与声明不符。例如:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- Safari 拒绝播放
type="video/mp4"但实际含 HEVC 编码的 MP4 文件,会走MEDIA_ERR_SRC_NOT_SUPPORTED(4),而非 3 - Android Chrome 加载 VP9 WebM 时若含不兼容的音频轨道(如 Opus 超出采样率范围),可能报 3,也可能静默失败
- 务必为每个
<source></source>显式写全codecs参数,如type="video/mp4; codecs="avc1.64001f""
补充信号辅助判断(绕过 error.code 的局限)
由于 MediaError.message 在所有主流浏览器中基本为空或不可靠,需依赖运行时行为组合推断:
- 监听
stalled事件:连续触发 2 次以上且间隔 video.buffered.length === 0,高度提示解码器卡死 - 调用
getVideoPlaybackQuality()(Chrome/Edge 支持):若corruptedVideoFrames > 0或droppedVideoFrames短时突增,说明解码输出异常 - 检查
video.videoWidth和video.videoHeight:长期为 0,配合readyState === 0,大概率是解码器未初始化成功
降级与用户反馈策略
确认是解码失败后,不要仅提示“视频无法播放”,而应给出可操作路径:
- 自动切换到备用格式源(如从 WebM 切回 MP4),并设置
data-attempted-fallback防止循环 - 显示静态封面图 + 文字提示:“当前设备暂不支持该视频编码,已为您准备标准清晰度版本”
- 提供下载链接(MP4 Baseline Profile),尤其对移动端 Safari 用户有效
- 记录错误上下文(
currentSrc、canPlayType()返回值、userAgent片段)用于后续分析
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










