WebRTC音频录制问题:停止流媒体后无法恢复录制求助
问题分析与解决方案
核心问题
mediaRecorder.stop()仅终止录制过程,但底层音频流(MediaStream)仍处于活跃状态,所以浏览器的红色录制标识不会消失。- 直接调用
stream.getTracks().forEach(track => track.stop())会彻底销毁音频流,导致已初始化的mediaRecorder失效,无法再次触发录制。
修复方案
- 录制结束后销毁音频流并重置MediaRecorder:在
mediaRecorder.onstop回调中停止音频轨道,同时将mediaRecorder置为null,确保下次录制能重新初始化。 - 修正按钮点击逻辑顺序:先初始化MediaRecorder,再启动录制,避免第一次点击时因
mediaRecorder未创建导致录制不启动。
修改后的完整代码
let mediaRecorder; let recordedChunks = []; let isRecording = false; // 启动录制 function startRecording() { if (mediaRecorder && mediaRecorder.state === 'inactive') { mediaRecorder.start(); isRecording = true; } } // 停止录制 function stopRecording() { if (mediaRecorder && mediaRecorder.state === 'recording') { mediaRecorder.stop(); isRecording = false; } } // 初始化MediaRecorder function initializeMediaRecorder() { // 重置之前的mediaRecorder(如果存在) if (mediaRecorder) { mediaRecorder = null; } navigator.mediaDevices .getUserMedia({ audio: true }) .then((stream) => { mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = (e) => { if (e.data.size > 0) { recordedChunks.push(e.data); } }; mediaRecorder.onstop = () => { const audioBlob = new Blob(recordedChunks, { type: 'audio/wav' }); const audioSize = audioBlob.size; recordedChunks = []; // 渲染录制消息 const messageItem = document.createElement('li'); messageItem.classList.add('message', 'sent'); messageItem.innerHTML = ` <div class="message-text"> <div class="message-sender"> <b>You</b> </div> <div class="message-content"> Audio size: ${audioSize}. Recording state: ${mediaRecorder.state} </div> </div>`; messagesList.appendChild(messageItem); // 停止音频流,消除红色录制标识 stream.getTracks().forEach(track => track.stop()); // 重置mediaRecorder,为下次录制做准备 mediaRecorder = null; }; // 初始化完成后立即启动录制 startRecording(); }) .catch((error) => { console.error('Error accessing audio:', error); isRecording = false; }); } // 录制按钮点击事件 const recordButton = document.querySelector('.btn-record'); recordButton.addEventListener('click', () => { if (!isRecording) { initializeMediaRecorder(); } else { stopRecording(); } });
关键修改点
- 移除
initializeMediaRecorder中的if (!mediaRecorder)判断,改为每次录制前重置mediaRecorder,确保每次录制都使用新的音频流。 - 在
mediaRecorder.onstop中添加mediaRecorder = null,保证下次录制能重新创建MediaRecorder实例。 - 调整按钮点击逻辑:点击开始录制时直接调用
initializeMediaRecorder,并在初始化完成后自动启动录制,解决原逻辑中先调用startRecording但mediaRecorder未就绪的问题。
内容的提问来源于stack exchange,提问作者Enzo Ferrari
相关产品推荐
相关产品推荐

