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

React项目中audio-recorder-polyfill在Safari下无音频数据问题求助

解决Safari中audio-recorder-polyfill无法触发dataavailable事件的问题

嘿,我之前也踩过这个坑!Safari本身不支持原生MediaRecorder,用audio-recorder-polyfill的时候得注意几个关键细节,不然就会出现录制能执行但拿不到数据的情况。咱们一步步来解决:

首先,确保polyfill正确生效

你得先确认polyfill已经正确导入并替换了全局的MediaRecorder——毕竟Safari没有这个原生API,必须让polyfill接管:

import AudioRecorderPolyfill from 'audio-recorder-polyfill';

// 在组件初始化或者项目入口处执行这个替换
if (!window.MediaRecorder) {
  window.MediaRecorder = AudioRecorderPolyfill;
}

你的代码里的核心问题

1. 没有指定MIME类型

audio-recorder-polyfill只支持audio/wav格式,实例化MediaRecorder时必须明确指定这个类型,否则polyfill可能无法正常工作,也就不会触发dataavailable:

// 错误写法:缺少mimeType配置
recorder = new MediaRecorder(stream);

// 正确写法:补上mimeType参数
this.recorder = new MediaRecorder(stream, { mimeType: 'audio/wav' });

2. 变量作用域问题

你代码里的recorder看起来是全局变量?在React类组件里,应该用实例变量(比如this.recorder)来存储,不然在stopFunc里可能访问不到正确的录制实例,导致停止操作无效,自然也不会触发数据事件。

3. 媒体流停止的时机

你现在是先调用recorder.stop()再停止tracks,但最好等stop事件触发后再关闭媒体流,避免提前切断导致数据还没生成完成。

修改后的完整代码示例

// 先导入并配置polyfill
import AudioRecorderPolyfill from 'audio-recorder-polyfill';

if (!window.MediaRecorder) {
  window.MediaRecorder = AudioRecorderPolyfill;
}

// 类组件中的方法
recordFunc() { 
  navigator.mediaDevices.getUserMedia({ audio: true })
    .then(stream => { 
      // 使用实例变量存储recorder和stream
      this.recorder = new MediaRecorder(stream, { mimeType: 'audio/wav' }); 
      this.stream = stream;

      // 监听dataavailable事件
      this.recorder.addEventListener('dataavailable', (e) => { 
        this.audio.current.src = URL.createObjectURL(e.data); 
        console.log('拿到音频数据了:', e.data);
      });

      // 监听stop事件做后续清理
      this.recorder.addEventListener('stop', () => {
        console.log('录制已停止');
      });

      // 开始录制
      this.recorder.start(); 
    })
    .catch(err => {
      console.error('获取麦克风权限失败:', err);
    });
} 

stopFunc() { 
  if (!this.recorder) return;

  // 停止录制,会触发dataavailable和stop事件
  this.recorder.stop(); 

  // 等stop事件触发后再关闭媒体流,确保数据生成完成
  this.recorder.addEventListener('stop', () => {
    this.stream.getTracks().forEach(track => track.stop());
    // 清理变量
    this.stream = null;
    this.recorder = null;
  }, { once: true }); // 只执行一次监听,避免内存泄漏
}

额外注意事项

  • HTTPS环境:生产环境必须用HTTPS,否则Safari会阻止媒体设备访问;本地开发用localhost是可以的。
  • polyfill版本:确保你安装的是最新版的audio-recorder-polyfill,旧版本可能有兼容性问题。
  • 权限检查:用户必须允许麦克风权限,否则getUserMedia会失败,记得加上错误处理。

这样修改后,应该就能在Safari里正常触发dataavailable事件,拿到录制的音频数据了!

内容的提问来源于stack exchange,提问作者display-name-is-missing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 22:03:16