真正管用的视频错误处理需区分四类MediaError.code:1(用户中止,仅记录日志)、2(网络失败,提示重试)、3(解码失败,建议换浏览器或清晰度)、4(格式全不支持,fallback或引导更新浏览器),并交叉验证networkState、stalled事件等信号,配合多格式source、正确MIME类型和autoplay策略。

直接在 error 事件里弹个“加载失败”是最低效的做法。真正管用的处理,得先搞清错在哪——是网络断了、格式不认、用户点了暂停,还是服务器压根没返回视频文件?再按类型给不同提示,让用户知道能做什么。
区分四类错误码,对应不同提示策略
video.error.code 是关键入口,但它只告诉你“出错了”,不告诉你“为什么”。必须结合上下文判断:
- code = 1(用户中止):比如页面跳转、标签页关闭导致加载取消,不用提示用户,只记录日志即可
-
code = 2(网络失败):可能是 404、跨域、CORS 拒绝或弱网超时。应在播放器内显示底部 toast,文字如“视频资源暂不可用,请检查网络或稍后重试”,并带「重试」按钮,点击后执行
video.load()+video.play() - code = 3(解码失败):常见于编码不兼容(如 H.265 在 Safari 中)、文件损坏。提示“当前设备暂不支持该视频格式”,建议切换清晰度(如有),或引导用户换 Chrome/Firefox
-
code = 4(格式全不支持):所有
<source></source>都被浏览器跳过。提示“浏览器不支持此视频格式”,自动 fallback 到备用源;若无可用源,引导更新浏览器或安装基础解码组件
不能只靠 error 事件,要交叉验证状态信号
error 事件只在加载阶段触发,很多问题它根本捕获不到。需搭配多个信号一起看:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 检查
video.networkState === HTMLMediaElement.NETWORK_NO_SOURCE:说明连一个<source></source>都没匹配上,大概率是 MIME 类型错或服务器返回 text/html - 监听
stalled事件持续超 3 秒且buffered.length === 0:首帧卡死,应归为网络问题,不是格式问题 - iOS Safari 中
play()被静音策略拦截时,readyState为 0 且paused为 true,需单独检测并提示“请手动点击播放并允许声音” - 用
fetch(url, { method: 'HEAD' })快速探测 URL 是否可达,区分是 404 还是弱网超时
提前兜底:多格式 source + 主动降级
错误处理不是等崩了再补,而是从一开始就把路铺好:
立即学习“前端免费学习笔记(深入)”;
-
<source></source>按兼容性优先级排列:例如av1.webm → vp9.webm → h264.mp4,避免低效试探 - 弱网环境(
navigator.connection.effectiveType === '2g')下,主动切换至低清 MP4 源,并轻量提示“已切换至流畅模式” - 所有降级操作后,保留“手动选择清晰度”入口,列出当前可用源(含格式标识,如“MP4(H.264)”),并提供“复制视频地址”供用户外链验证
别忽略基础但致命的细节
很多“加载失败”其实和代码无关,而是环境配置不到位:
- 确保服务器返回正确的 Content-Type:MP4 必须是
video/mp4,WebM 是video/webm,否则 Safari 和部分 Chrome 版本会静默失败 - 本地开发别用
file://协议双击打开 HTML,Chrome 默认禁用 video 加载,要用python3 -m http.server启本地服务 - autoplay 必须加
muted,否则现代浏览器一律拦截;若需有声,必须等用户首次点击后再调用play(),且要处理 Promise 拒绝 - iOS Safari 必须加
playsinline webkit-playsinline,否则强制跳原生播放器,手势也会失效


















