最稳方式是用 canplaytype() 主动检测,返回 "probably" 或 "maybe" 才支持;需按 mp4→webm 顺序写 ,type 属性宜简不宜繁;flash 已淘汰,gif 降级成本高,应优先 html/css/js 方案。

浏览器不支持 <video></video> 或 <audio></audio> 怎么检测
不能等用户点开才报错,得在加载时就知道当前环境撑不撑得住。最稳的方式是用 canPlayType() 主动试探,而不是靠 onerror 被动捕获——后者可能已触发加载失败、甚至空白区域卡住。
-
<video></video>元素创建后立即调用video.canPlayType('video/mp4; codecs="avc1.42E01E"'),返回"probably"或"maybe"才算有基本支持 - 别只测一种格式:Safari 对
webm返回空字符串,Chrome 对老版 IE 的asf也直接不认,得按目标格式逐个试 - 注意:
canPlayType()不校验网络或权限(比如摄像头被禁),它只管 MIME + 编解码器是否在浏览器白名单里
<source></source> 标签的 fallback 顺序怎么写才有效
浏览器按 <source></source> 出现顺序尝试,遇到第一个 canPlayType() 返回非空值的就停,后面全跳过。所以要把兼容性最好、体积适中、编码最通用的放最前。
- MP4(H.264 + AAC)放第一,95%+ 主流浏览器原生支持,iOS/iPadOS 必须靠它
- WebM(VP9 + Opus)放第二,Chrome/Firefox/Edge 新版本表现好,但 Safari 16.4 之前完全不支持
- 不要把
type写错:写成type="video/webm"比type="video/webm; codecs=..."更安全,后者一旦编解码器名小写/空格/引号不匹配,整条<source></source>就被忽略
降级到 Flash 或 GIF 的实际成本和风险
Flash 已全平台终止支持,2021 年起所有主流浏览器强制禁用;GIF 表面能“显示”,但本质是位图序列,10 秒视频转 GIF 可能暴涨到 20MB+,且无音轨、无控制条、无法暂停。
- 真要降级,优先考虑纯 HTML/CSS/JS 方案:比如用
<img alt="HTML浏览器不支持媒体怎么提示_HTML标签降级方法【汇总】" >显示首帧 + 文字提示“视频暂不可用”,比硬塞一个假播放器更诚实 - 若必须模拟播放器 UI,用
<canvas></canvas>逐帧绘制静态图 + 自定义按钮,至少不触发安全拦截或资源加载失败 - 任何依赖插件(Flash/Java/ActiveX)的方案,在现代 Chrome/Firefox/Safari 中会直接被阻止,控制台报
net::ERR_BLOCKED_BY_CLIENT
服务端做格式协商比前端判断更可靠吗
不推荐。HTTP Accept 请求头里根本没有视频编解码器信息,服务器无法知道客户端能不能播 VP9;而且 CDN 和中间代理经常抹掉或改写 Accept,导致误判。
立即学习“前端免费学习笔记(深入)”;
- 唯一可行的服务端辅助是:根据
User-Agent粗筛(如识别 iOS 15+ 就默认给 MP4),但 UA 可伪造、可被压缩,不能作为唯一依据 - 真正可靠的路径是“前端探测 + 后备兜底”:先用
canPlayType()试本地支持,再发一个轻量HEAD请求验证视频 URL 是否可访问(避免 404 或 CORS 阻断) - 注意:Safari 在私密模式下,
canPlayType()对某些格式可能返回""(空字符串),不是 bug,是故意限制,这时候得靠try/catch加载<source></source>后监听onstalled事件来二次确认
最常被忽略的一点:很多人以为只要写了多个 <source></source>,浏览器就会自动选最优解。其实不会——它只选第一个“看起来能播”的,哪怕画质差、体积大、解码慢。要不要播、播哪个,最终决定权始终在前端脚本手里,不是标签堆得多就有用。











