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

火狐浏览器停止录制后如何将navigator.getMediaStream音频blob下载为.wav格式

问题根因

你现在的用法是无效的:仅修改Blob的MIME类型并不会改变媒体数据本身的编码格式,你传入的blobDataInWebaFormat本质还是OGG/Vorbis编码的音频数据,火狐会识别到实际编码和你声明的audio/wav不匹配,自动修正后缀为对应编码的默认格式.ogx。
另外你代码里存在基础变量引用错误:你定义的Blob变量名为blobDataInWavFormat,但window.URL.createObjectURL传入的是未定义的blob,需要先修正这个问题。

修复方案

你需要先将录制得到的音频数据解码为PCM裸流,再手动封装为WAV格式,再触发下载,示例实现如下:

// 传入你录制得到的weba格式Blob,返回封装好的wav格式Blob
async function convertWebaToWav(webaBlob: Blob): Promise<Blob> {
  const arrayBuffer = await webaBlob.arrayBuffer();
  const audioCtx = new AudioContext();
  const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
  
  // 提取PCM数据
  const numberOfChannels = audioBuffer.numberOfChannels;
  const sampleRate = audioBuffer.sampleRate;
  const length = audioBuffer.length * numberOfChannels * 2 + 44;
  const buffer = new ArrayBuffer(length);
  const view = new DataView(buffer);
  
  // 写入WAV头
  const writeString = (offset: number, str: string) => {
    for (let i = 0; i < str.length; i++) {
      view.setUint8(offset + i, str.charCodeAt(i));
    }
  };
  writeString(0, 'RIFF');
  view.setUint32(4, 36 + audioBuffer.length * numberOfChannels * 2, true);
  writeString(8, 'WAVE');
  writeString(12, 'fmt ');
  view.setUint32(16, 16, true);
  view.setUint16(20, 1, true);
  view.setUint16(22, numberOfChannels, true);
  view.setUint32(24, sampleRate, true);
  view.setUint32(28, sampleRate * numberOfChannels * 2, true);
  view.setUint16(32, numberOfChannels * 2, true);
  view.setUint16(34, 16, true);
  writeString(36, 'data');
  view.setUint32(40, audioBuffer.length * numberOfChannels * 2, true);
  
  // 写入PCM采样数据
  let offset = 44;
  for (let i = 0; i < audioBuffer.length; i++) {
    for (let channel = 0; channel < numberOfChannels; channel++) {
      const sample = Math.max(-1, Math.min(1, audioBuffer.getChannelData(channel)[i]));
      view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true);
      offset += 2;
    }
  }
  
  return new Blob([view], { type: 'audio/wav' });
}

// 调用示例
const wavBlob = await convertWebaToWav(blobDataInWebaFormat);
const anchor = document.createElement('a');
document.body.appendChild(anchor);
anchor.style.display = 'none';
const url = window.URL.createObjectURL(wavBlob);
anchor.href = url;
anchor.download = 'audio.wav';
anchor.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(anchor);

封装完成后的Blob数据本身就是标准WAV格式,火狐会识别到编码和MIME类型匹配,就不会自动修改后缀为.ogx了。

内容的提问来源于stack exchange,提问作者Manraj Parmar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:15:05