HTML5多媒体API落地需坚持实测+特性检测+分层降级:格式兼容依赖容器与编解码器双重匹配,自动播放须满足muted+用户手势+平台特有属性,MediaRecorder需校验API存在性与isTypeSupported,轨道控制应优先调用stop()而非enabled赋值。

HTML5 多媒体 API 看似简单,实际落地时处处是隐性约束。真正卡住项目的往往不是功能写不出来,而是浏览器行为不一致、权限策略突变、编码细节错配这些“看不见的墙”。避开它们的关键,在于放弃假设,坚持实测 + 特性检测 + 分层降级。
格式与编码兼容性不是后缀问题,而是容器+编解码器双重匹配
仅提供 .mp4 文件远远不够。浏览器判断能否播放,取决于文件内部封装(MP4)是否包含它能解码的视频流(如 H.264)和音频流(如 AAC)。H.265(HEVC)在 Safari 14+ 支持,但在 Chrome 旧版或 Firefox 中直接失败;VP9 在 Chrome 和 Firefox 表现好,Safari 完全不认。
- 必须用
<source>提供至少两种格式:MP4(H.264+AAC) + WebM(VP9+Opus),并按浏览器支持度排序 - 服务端转码时明确指定编码参数,例如 FFmpeg 命令中加
-c:v libx264 -profile:v baseline -level 3.0保证兼容老设备 - 前端用
video.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')主动探测,而非依赖后缀或 UA
自动播放限制远比“加 muted”复杂
Chrome 要求 muted + 用户手势触发;iOS Safari 还额外要求 playsinline + 页面可见 + 非后台标签页;某些安卓 WebView 甚至无视 muted 仍拦截。单纯写 video.play() 在多数场景下注定失败。
- 播放操作必须绑定在明确用户交互之后(如按钮点击、触摸开始),且不能跨 tick 延迟调用
- 对 iOS 设备,
playsinline、webkit-playsinline、x5-playsinline(微信)需同时设置 - 捕获
play()返回的 Promise,失败时降级提示:“请轻触屏幕开始播放”
MediaRecorder 并非“有就可用”,状态与格式支持需双重校验
Safari 14.1+ 才原生支持 MediaRecorder,且仅限视频轨道;IE11 完全无支持;Android Webview 53–61 版本虽有 API 但 start() 会静默失败。更隐蔽的是,即使 API 存在,isTypeSupported('audio/webm;codecs=opus') 也可能返回 false。
立即学习“前端免费学习笔记(深入)”;
- 初始化前先检查:
navigator.mediaDevices?.getUserMedia可用 →MediaRecorder && MediaRecorder.isTypeSupported(...) - 不支持时立即降级:Web Audio API 录制 PCM + JS 编码(如 lamejs),或引导使用桌面客户端
- 录制中监听
onerror和onstop,避免因设备断开导致 blob 为空
音视频轨道控制在 Safari 和旧 Android 上极易失效
track.enabled = false 在 Safari 13 及更早版本中无效;track.applyConstraints({ width: { ideal: 640 } }) 在部分安卓 7.x 设备上抛出 NotSupportedError;contentHint 属性几乎全平台不识别。
- 禁用轨道优先用
stream.getAudioTracks().forEach(t => t.stop()),而非依赖enabled - 分辨率约束失败时回退到无约束
getUserMedia({ video: true }),再用 Canvas 绘制缩放 - 所有轨道操作后,用
track.readyState和track.muted实际读取状态,不信任赋值结果



















