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 ;
}

加wav头

拼接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;
}
posted @ 2020-10-15 21:47  Shaw_喆宇  阅读(1017)  评论(0编辑  收藏  举报