You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中MediaRecorder自动触发下载时音频数据为空的问题解决

问题原因及修复方案

核心问题

MediaRecorder.stop() 不是同步完成的,它只是触发停止录制的指令,真正的音频数据收集完成、audioChunks 状态更新要等到 onstop 事件回调触发后才会完成。你现在在调用 stop() 后立刻执行 handleDownload(),此时 React 状态还没来得及更新,audioChunks 还是空数组,所以生成的 base64 数据自然为空。

修复步骤

  1. 把 handleDownload() 移到 MediaRecorder 的 onstop 回调中
    只有当 onstop 触发时,才说明音频数据已经完整收集完毕,这时候再更新状态并调用转换函数,才能拿到有效数据。

  2. 调整 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:31:01