如何将 pcm16Audio 转换为 .wav,然后转换为 base64 字符串

问题描述 投票:0回答:1

我正在使用语音捕获 SDK,它返回捕获的 pcm16Audio 表示形式。我需要将其转换为 wav,然后将 wav 转换为 base64 以发送到 API。

这是SDK中返回pcm16Audio的函数:

async getRecordedAudioPcm16Samples() {
let audio = new Int16Array(this.numRecordedSamples);
    let offset = 0;
    for (let i = 0; i < this.audioBuffers.length; i++) {
      audio.set(this.audioBuffers[i], offset);
      offset += this.audioBuffers[i].length;
    }
    return audio;
  }

我相信做到这一点的方法是使用 npm 中的“audiobuffer-to-wav”,然后将 wav 转换为 base64:

import toWav from 'audiobuffer-to-wav';

const audio = sdk.getRecordedAudioPcm16Samples();
audio.then((pcm16Audio) => {

    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    audioContext.decodeAudioData(pcm16Audio.buffer, (buffer) => {
              // encode AudioBuffer to WAV
              const wav = toWav(buffer);
              // convert wav to base64...

在Firefox中调用decodeAudioData时出现此错误:“DOMException:传递给decodeAudioData的缓冲区包含未知的内容类型。”

我在 Chrome 中收到此错误:“DOMException:无法在“BaseAudioContext”上执行“decodeAudioData”:无法解码音频数据”

我走在正确的道路上吗?谢谢您的帮助!

javascript base64 wav pcm audiobuffer
1个回答
0
投票

decodeAudioData()
非常有限。它仅适用于少数文件类型,并且跨浏览器的支持非常不一致。据我所知,没有浏览器可以解码原始 PCM 数据。

但它可以以相当简单的方式手动完成。例如,可以这样创建

AudioBuffer
为 48kHz、长度为一秒的
sampleRate

new AudioBuffer({ length: 48000, sampleRate: 48000 });

然后,您可以通过在

Float32Array
中填充 -1 到 1 之间的值来复制样本。存储为 int16 的值通常可以这样转换:

const f32 = int16 < 0 ? int16 / 32768 : int16 / 32767;

最后一步是使用

Float32Array
将样本复制到
AudioBuffer
上。这是存储为
int16
的一秒音频的完整示例。

const length = 48000;
const audioBuffer = new AudioBuffer({ length, sampleRate: 48000 });
const channelData = new Float32Array(length);

for (let i = 0; i < length; i += 1) {
    const int16 = THE_VALUES_AS_INT_16[i];
    const f32 = int16 < 0 ? int16 / 32768 : int16 / 32767;

    channelData[i] = f32;
}

audioBuffer.copyFromChannel(channelData, 0);

然后您可以使用它

audioBuffer
并使用上面提到的包将其转换为 wav 文件。

© www.soinside.com 2019 - 2024. All rights reserved.