如何在录制过程中切换摄像头?使用MediaRecorder API切换user/environment摄像头问询
MediaRecorder切换前后置摄像头实现方案
可以切换,但是默认无法在不中断录制的情况下直接切换摄像头,因为MediaRecorder实例创建时就与传入的MediaStream深度绑定,摄像头切换需要重新获取媒体流、重置录制实例,具体实现逻辑如下:
核心操作步骤
- 停止当前运行的MediaRecorder实例:如果实例状态为
recording或paused,调用stop()方法终止录制,提前缓存已录制的Blob片段避免内容丢失 - 释放当前占用的摄像头资源:遍历当前MediaStream的所有轨道,调用
track.stop()释放硬件占用,避免新的摄像头请求被系统拦截 - 重新请求目标方向的摄像头流:调用
getUserMedia接口,将video.facingMode参数设置为你需要切换的user(前置摄像头)或environment(后置摄像头),拿到新的媒体流 - 重新初始化MediaRecorder:将新的媒体流传入新的MediaRecorder实例,重新启动录制即可
进阶无中断方案(有兼容性限制)
如果业务场景需要尽可能降低切换的感知度,可以使用MediaStreamTrack.replaceTrack()方法直接替换MediaRecorder绑定流中的视频轨道,不需要销毁重建MediaRecorder实例,可实现无停顿切换。该方法的兼容性有限,Safari、部分旧版Chromium内核浏览器不支持,需要做降级兼容处理。
核心代码示例
let currentStream; let mediaRecorder; let recordedChunks = []; async function switchCamera(targetFacingMode) { // 停止当前录制与旧流 if (mediaRecorder?.state !== 'inactive') { mediaRecorder.stop(); } currentStream?.getTracks().forEach(track => track.stop()); // 请求新摄像头流 const newStream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: targetFacingMode }, audio: true }); // 初始化新录制器 recordedChunks = []; mediaRecorder = new MediaRecorder(newStream); mediaRecorder.ondataavailable = (e) => recordedChunks.push(e.data); mediaRecorder.start(); currentStream = newStream; // 可将新流绑定到页面video元素预览 // document.querySelector('video').srcObject = newStream; }
注意事项
- 切换前后生成的多段录制Blob可以通过
new Blob(chunks, { type: 'video/webm' })合并为完整的媒体文件,实现用户无感知的连续录制体验 - 部分安卓机型必须完全释放前一个媒体流的所有轨道后才能请求新的摄像头,需要做好异常捕获处理
- 桌面设备通常只有一个摄像头,
facingMode参数不一定生效,切换逻辑建议仅在移动设备侧开启
内容的提问来源于stack exchange,提问作者Mahen Gandhi
相关产品推荐
相关产品推荐

