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

PCM16音频转WAV再转Base64遇解码错误,求解决方案

问题分析与解决方案

你的思路存在关键错误:decodeAudioData API是用来解码带格式头的编码音频数据(如WAV、MP3等),但你传入的是裸PCM16原始数据,没有文件头标识格式信息,浏览器无法识别,因此报错。

不需要绕AudioContext解码,直接将PCM16数据包装成AudioBuffer,再转WAV即可,具体实现如下:

正确代码示例

import toWav from 'audiobuffer-to-wav';

const audioPromise = sdk.getRecordedAudioPcm16Samples();
audioPromise.then((pcm16Audio) => {
  // 替换为SDK实际采集的参数:采样率、声道数(需和SDK一致)
  const sampleRate = 16000; // 示例:16kHz采样率
  const channelCount = 1; // 示例:单声道

  const audioContext = new (window.AudioContext || window.webkitAudioContext)({ sampleRate });
  // 创建对应参数的AudioBuffer
  const audioBuffer = audioContext.createBuffer(channelCount, pcm16Audio.length, sampleRate);
  
  // 将Int16格式的PCM数据转为AudioBuffer所需的Float32格式
  const channelData = audioBuffer.getChannelData(0);
  for (let i = 0; i < pcm16Audio.length; i++) {
    // 16位PCM范围是[-32768, 32767],转成AudioBuffer要求的[-1, 1]浮点值
    channelData[i] = pcm16Audio[i] / 32768;
  }

  // 将AudioBuffer编码为WAV格式的ArrayBuffer
  const wavBuffer = toWav(audioBuffer);
  
  // 把WAV数据转为Base64字符串
  const wavBlob = new Blob([wavBuffer], { type: 'audio/wav' });
  const fileReader = new FileReader();
  fileReader.onloadend = () => {
    // 移除data URI前缀,只保留Base64内容
    const base64Str = fileReader.result.split(',')[1];
    // 此处可将base64Str发送至API
    console.log(base64Str);
  };
  fileReader.readAsDataURL(wavBlob);
});

关键注意事项

  • 参数一致性:采样率、声道数必须和SDK采集时的参数完全一致,否则生成的WAV会出现速度异常、杂音等问题。
  • 格式转换逻辑:AudioBuffer使用Float32格式存储音频数据,因此需要将Int16的PCM值转换为[-1, 1]范围的浮点值。
  • 替代方案:如果不想依赖第三方包,也可以手动拼接WAV文件头(包含采样率、声道数、位深等信息)+ PCM原始数据,实现裸PCM到WAV的转换,但使用audiobuffer-to-wav更省心高效。

内容的提问来源于stack exchange,提问作者Chris Oppedal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:43:19