使用 MediaRecorder API 在浏览器端实现音视频录制,需通过以下步骤完成:获取媒体流、初始化 MediaRecorder、控制录制过程、处理数据并生成文件,同时需注意兼容性问题。以下是具体实现方法:
1. 获取音视频媒体流调用 navigator.mediaDevices.getUserMedia() 请求用户摄像头和麦克风权限,获取媒体流对象(MediaStream)。
- 绑定流到 <video> 标签可实时预览。
- 捕获错误(如权限拒绝或设备不可用)。
const videoElement = document.createElement('video');navigator.mediaDevices.getUserMedia({ video: true, audio: true }) .then(stream => { videoElement.srcObject = stream; // 预览视频 videoElement.play(); // 后续初始化 MediaRecorder }) .catch(err => { console.error("无法获取媒体设备:", err); });2. 初始化 MediaRecorder创建 MediaRecorder 实例,需指定媒体流和可选的 MIME 类型(如 video/webm)。
- 兼容性处理:通过 MediaRecorder.isTypeSupported() 检测支持的格式,优先选择通用类型(如 webm)。
- 数据收集:监听 ondataavailable 事件,将分块数据存入数组。
function getSupportedMimeTypes() { const types = ['video/webm', 'video/mp4', 'video/x-matroska']; return types.filter(type => MediaRecorder.isTypeSupported(type));}let chunks = [];const mimeType = getSupportedMimeTypes()[0] || 'video/webm'; // 默认使用 webmconst recorder = new MediaRecorder(stream, { mimeType });recorder.ondataavailable = event => { if (event.data.size > 0) chunks.push(event.data);};3. 控制录制过程通过 start() 和 stop() 方法控制录制开始与结束。
- 自动停止:可用 setTimeout 或用户交互(如按钮点击)触发停止。
- 手动停止:绑定按钮事件更灵活。
// 开始录制recorder.start(100); // 可选参数:分块间隔(毫秒)// 10秒后自动停止(示例)setTimeout(() => { recorder.stop();}, 10000);// 或通过按钮手动停止document.getElementById('stopBtn').addEventListener('click', () => { recorder.stop();});4. 处理录制数据并生成文件在 onstop 事件中,将收集的 chunks 合并为 Blob 对象,生成下载链接。
- 使用 URL.createObjectURL() 创建临时 URL。
- 通过 <a> 标签触发下载,最后释放内存。
recorder.onstop = () => { const blob = new Blob(chunks, { type: mimeType }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'recording.webm'; // 默认文件名 a.click(); URL.revokeObjectURL(url); // 释放内存 chunks = []; // 清空数据块};5. 兼容性处理- 浏览器支持:现代浏览器(Chrome、Firefox、Edge)原生支持,但 Safari 旧版本可能受限。建议检测 MediaRecorder 是否存在。
- MIME 类型降级:优先使用 video/webm,若不支持则回退到其他格式。
if (!navigator.mediaDevices || !MediaRecorder) { alert("当前浏览器不支持音视频录制!");}完整代码示例<video id="preview" autoplay playsinline></video><button id="startBtn">开始录制</button><button id="stopBtn">停止录制</button><script> const videoElement = document.getElementById('preview'); const startBtn = document.getElementById('startBtn'); const stopBtn = document.getElementById('stopBtn'); let recorder, stream, chunks = []; startBtn.addEventListener('click', async () => { try { stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true }); videoElement.srcObject = stream; const mimeType = getSupportedMimeTypes()[0] || 'video/webm'; recorder = new MediaRecorder(stream, { mimeType }); recorder.ondataavailable = e => { if (e.data.size > 0) chunks.push(e.data); }; recorder.onstop = () => { const blob = new Blob(chunks, { type: mimeType }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'recording.webm'; a.click(); URL.revokeObjectURL(url); chunks = []; }; recorder.start(100); console.log("录制开始..."); } catch (err) { console.error("错误:", err); } }); stopBtn.addEventListener('click', () => { if (recorder && recorder.state !== 'inactive') { recorder.stop(); stream.getTracks().forEach(track => track.stop()); // 关闭媒体流 console.log("录制已停止。"); } }); function getSupportedMimeTypes() { const types = ['video/webm', 'video/mp4', 'video/x-matroska']; return types.filter(type => MediaRecorder.isTypeSupported(type)); }</script>关键点总结- 媒体流获取:通过 getUserMedia() 获取摄像头/麦克风权限。
- 数据分块收集:监听 ondataavailable 事件存储 chunks。
- 文件生成:在 onstop 中合并 chunks 为 Blob 并下载。
- 兼容性:检测支持的 MIME 类型,处理浏览器差异。
通过以上步骤,即可在浏览器端实现无插件的音视频录制功能。