mediarecorder api 无法直接录制远程流,需先将直播转为本地可录制流:用 htmlmediaelement.capturestream() 或 canvas.capturestream() 获取流,再用 mediarecorder 录制;注意权限、音画同步、性能及服务端配合。

MediaRecorder API 本身不支持直接录制远程流(如 WebRTC 接收的直播流),它只能录制本地 MediaStream(例如来自 getUserMedia 的摄像头/麦克风,或通过 canvas.captureStream()、mediaElement.captureStream() 获取的页面内音视频流)。因此,“录制网页在线直播”需先将直播内容以合法方式转为本地可录制的流,再用 MediaRecorder 处理。
关键前提:获取可录制的本地媒体流
大多数在线直播(如 YouTube Live、Twitch、自建 WebRTC 推流页)默认不提供直接访问其解码后音视频帧的接口。若你有控制权(如自己开发的播放页),可通过以下方式构造可录制流:
-
使用
HTMLMediaElement.captureStream():适用于通过<video></video>播放的 MSE(Media Source Extensions)流或 HLS(需兼容浏览器支持,Chrome/Safari 支持较好,Firefox 对 HLS 有限制)。调用后返回一个实时捕获播放画面和音频的MediaStream。 -
使用
Canvas.captureStream():将<video></video>绘制到<canvas></canvas>,再对 canvas 调用 captureStream。可规避部分浏览器对 mediaElement.captureStream 的限制,但会引入轻微延迟和画质损耗,且需手动同步音频(canvas 本身不捕获音频,需额外处理 AudioContext 或 MediaStreamAudioSourceNode)。 -
服务端中继 + 客户端拉流:若直播源支持,让服务端将 RTMP/HLS 流转为 WebRTC 可订阅的
RTCPeerConnection,客户端作为“观众”加入并接收远端流(peerConnection.getReceivers().map(r => r.track).filter(t => t)),再将这些 track 合成新 stream 供 MediaRecorder 使用(注意:需用户主动授权,且部分浏览器禁止录制远端流,尤其是无用户手势触发时)。
基础录制流程(以 video 元素为例)
假设你已有一个播放直播的 <video id="liveVideo" autoplay muted></video> 元素,并确认 captureStream() 可用:
- 调用
const stream = liveVideo.captureStream();获取流(推荐传入帧率参数如captureStream(30)控制输出质量)。 - 创建
MediaRecorder实例:const recorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp9,opus' });(优先选 webm/vp9+opus,兼容性好;如需 MP4,需确保浏览器支持video/mp4且编码器可用,目前仅部分 Chrome 版本支持)。 - 监听
dataavailable事件收集Blob分片,用URL.createObjectURL(blob)可临时预览,或通过fetch上传至服务器分段保存。 - 调用
recorder.start(5000)开始录制(5000ms 分片),用recorder.stop()或recorder.pause()/resume()控制过程。
注意事项与常见问题
实际落地时需特别注意:
-
权限与策略限制:调用
captureStream()需页面处于活跃标签页,且 video 必须已加载并开始播放(readyState >= 3);若 video 含 DRM 内容(如 Widevine),则无法捕获。 -
音频同步难题:mediaElement.captureStream() 在部分浏览器中可能丢失音频或音画不同步。建议优先使用带音频的 stream(如播放器本身提供 audio track),或用
AudioContext.createMediaStreamSource()单独捕获音频流,再与视频流合并(new MediaStream([...videoTracks, ...audioTracks]))。 -
性能与资源消耗:持续录制高分辨率直播流会显著增加内存和 CPU 占用,建议设置合理分辨率(如
video.videoWidth = 1280)、关闭非必要 track(stream.getVideoTracks()[0].enabled = false),并及时释放URL.createObjectURL()创建的对象。 - 服务端配合:纯前端录制无法保证长期稳定性(页面关闭即中断)。生产环境应结合服务端接收分片(如 WebSocket 或分块 POST),并做断点续传、格式封装(如将 webm 分片合成完整文件)和存储管理。
替代方案参考
若 MediaRecorder 不满足需求(如需更高精度、低延迟或跨平台一致性),可考虑:
- WebAssembly 解码 + Canvas 渲染 + 自定义编码:用 FFmpeg.wasm 解析直播流(如 HLS 分片),逐帧送入 canvas,再用 MediaRecorder 或 WASM 编码器生成文件——复杂度高,适合特殊场景。
- 桌面端辅助工具:对无源码控制的第三方直播页,更可靠的方式是使用 OBS、ffmpeg 命令行等桌面工具抓取屏幕或系统音频,而非依赖浏览器 API。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











