JavaScript 拼接audio
拼接audiobuffer
获取一个audiobuffer数组,然后把audiobuffer拼接起来。(我没尝试成功)
export const mergeAudios = (buffers: AudioBuffer[], sampleRate: number) => {
const context = new AudioContext();
let output = context.createBuffer(
1, // numberOfChannels
totalLength(buffers),
sampleRate
);
let offset = 0;
buffers.map(buffer => {
output.getChannelData(0).set(buffer.getChannelData(0), offset);
offset += buffer.length;
});
return output;
};
const totalLength = (buffers: AudioBuffer[]) => {
let length = 0;
for (let i = 0; i < buffers.length; i++) {
length += buffers[i].length;
}
return length;
};
拼接arraybuffer
ArrayBuffer 代表二进制数据结构,只读。需要转化为 TypedArray 进行操作。
TypedArray 没有像数组那样的 Array.prototype.concat 方法用来连接多个 TypedArray。不过它提供了 TypedArray.prototype.set 可以用来间接连接字符串。原理就是先分配一块空间足以容纳需要连接的 TypedArray,然后逐一在对应位置叠加。
export function getAudioFromArrayBuffers(fragments: ArrayBuffer[], sampleRate: number): Blob {
const audioCtx = new AudioContext();
let byteCount = 0;
for (let i = 0; i < fragments.length; i++) {
byteCount += fragments[i].byteLength;
}
// Output array.
const sentAudio = new Uint8Array(byteCount);
byteCount = 0;
for (var i = 0; i < fragments.length; i++) {
sentAudio.set(new Uint8Array(fragments[i]), byteCount);
byteCount += fragments[i].byteLength;
}
const audioWithWAV = AddRiffHeader(sentAudio.buffer, sampleRate);//加wav头
return audioWithWAV ;
}
拼接Blob
Blob拼接最简单了,直接const audio = new Blob(audios, { type: "audio/wav" });
解决。
拼接Float32Array
export function decompress32(inputData: Float32Array[]) {
let size = 0;
for (let i = 0; i < inputData.length; i++) {
size += inputData[i].length;
}
var data = new Float32Array(size);
var offset = 0;
for (var i = 0; i < inputData.length; i++) {
data.set(inputData[i], offset);
offset += inputData[i].length;
}
return data;
}