我正在使用语音捕获 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”:无法解码音频数据”
我走在正确的道路上吗?谢谢您的帮助!
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 文件。