React中MediaRecorder自动触发下载时音频数据为空的问题解决
问题原因及修复方案
核心问题
MediaRecorder.stop() 不是同步完成的,它只是触发停止录制的指令,真正的音频数据收集完成、audioChunks 状态更新要等到 onstop 事件回调触发后才会完成。你现在在调用 stop() 后立刻执行 handleDownload(),此时 React 状态还没来得及更新,audioChunks 还是空数组,所以生成的 base64 数据自然为空。
修复步骤
把
handleDownload()移到MediaRecorder的onstop回调中
只有当onstop触发时,才说明音频数据已经完整收集完毕,这时候再更新状态并调用转换函数,才能拿到有效数据。调整
handleStopRecording函数
只保留停止录制的逻辑,移除同步调用handleDownload()和setRecording(false)的代码,把这些逻辑移到onstop回调里。
代码示例
初始化 MediaRecorder 时绑定正确的 onstop 回调
const startRecording = async () => { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const recorder = new MediaRecorder(stream); let chunks: BlobPart[] = []; recorder.ondataavailable = (e) => { if (e.data.size > 0) { chunks.push(e.data); } }; // 在这里处理停止后的逻辑 recorder.onstop = () => { setAudioChunks(chunks); // 确保音频数据已存入状态 setRecording(false); handleDownload(); // 此时调用转换函数,能拿到完整数据 }; recorder.start(); setMediaRecorder(recorder); setRecording(true); };
修改后的 handleStopRecording 函数
const handleStopRecording = () => { if (mediaRecorder) { mediaRecorder.stop(); // 不再在这里调用 handleDownload 或修改 recording 状态 } };
为什么这样能解决问题
MediaRecorder 的 onstop 事件是在录制完全停止、所有音频数据都通过 ondataavailable 收集完毕后才会触发的。这时候更新 audioChunks 状态,React 会完成状态更新,之后调用 handleDownload() 就能获取到完整的音频 Blob,进而生成正确的 base64 数据。
内容的提问来源于stack exchange,提问作者Cameron
相关产品推荐
相关产品推荐

