mediarecorder 必须使用 mediastream 实例作为输入源,不支持 htmlmediaelement、blob 或 arraybuffer;需确保流含音频轨道、手动停止轨道释放设备,并注意跨浏览器特别是 ios 对 capturestream() 的限制。

HTML 录音本身不直接“兼容”媒体流,而是依赖 MediaStream 作为输入源——没有它,MediaRecorder 根本无法启动。
MediaRecorder 必须接 MediaStream 实例
MediaRecorder 构造函数的第一个参数强制要求是 MediaStream 对象,不能是 HTMLMediaElement(如 <video></video> 或 <audio></audio>)、Blob 或 ArrayBuffer。常见错误是试图传入 document.querySelector('audio').srcObject 却没检查是否已赋值,或误用 URL.createObjectURL(mediaElement.captureStream()) 在不支持的浏览器中(如 Safari 旧版)返回 null。
- 必须先调用
navigator.mediaDevices.getUserMedia()或从HTMLMediaElement.captureStream()获取有效MediaStream - 检查
stream.getAudioTracks().length > 0,避免静音流或无音频轨道导致录制无声 - Safari 16.4+ 才支持
captureStream()录制<video></video>;iOS Safari 仍不支持该方法
录音期间 MediaStream 会持续活跃,影响性能与权限
只要 MediaStream 还被 MediaRecorder 持有(或页面中其他地方引用),摄像头/麦克风设备就保持开启状态,系统指示灯常亮,且持续占用 CPU/GPU 资源。这不是 bug,而是规范行为。
- 调用
mediaRecorder.stop()后,MediaRecorder不会自动stream.getTracks().forEach(t => t.stop()) - 务必手动执行
stream.getTracks().forEach(track => track.stop())释放设备 - 若在
MediaRecorder的dataavailable事件中反复生成Blob但未及时URL.revokeObjectURL(),会造成内存泄漏
不同来源的 MediaStream 行为差异极大
来自 getUserMedia() 和 captureStream() 的流,在轨道类型、时间戳、同步性上完全不同,直接影响录音质量与可用性。
-
getUserMedia({ audio: true }):提供原始麦克风音频,延迟低,适合语音采集;但无法录系统声音(Chrome 限制) -
videoEl.captureStream():仅 Chromium 系支持音频捕获(需video有audio属性且播放中),且音频可能滞后于视频帧 -
canvas.captureStream()+ Web Audio:可合成音频流,但需手动连接AudioContext输出到MediaStreamAudioDestinationNode,复杂度高
真正麻烦的是跨浏览器对 captureStream() 的支持断层,以及 iOS 上几乎无法绕过限制获取系统音频——这些不是代码能修的,得提前在架构里规避。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











