Можно ли создать узел источника звука из фрагмента файла MP3? - PullRequest
0 голосов
/ 20 мая 2019

Я хотел бы создать несколько исходных аудио узлов, каждый из которых будет содержать отдельный фрагмент MP3. Есть ли способ, выбрав файл, создать исходный узел из данного раздела файла? На данный момент у меня есть:

var source1 = audioCtx.createBufferSource();

return fetch('speech.mp3')
  .then(function (response) {
    if (!response.ok) {
      throw new Error("HTTP error, status = " + response.status);
    }
    return response.arrayBuffer();
  })
  .then(function (buffer) {
    return audioCtx.decodeAudioData(buffer);
  })
  .then(function (decodedData) {
    source1.buffer = decodedData;
    source1.connect(audioCtx.destination);
  });

Но я бы хотел, чтобы source1 (а затем source2 и source3) содержали разные фрагменты speech.mp3.

1 Ответ

0 голосов
/ 21 мая 2019

Поскольку вы читаете все "speech.mp3", вы можете создать несколько AudioBufferSourceNode объектов для различных фрагментов mp3-файла.Я могу придумать как минимум два пути.Пожалуй, самый простой (не проверенный):

for (k = 0; k < n; ++k) {
  src[k] = new AudioBufferSourceNode(context, decodedData);
  src[k].connect(context.destination);
  src[k].start(time[k], offset[k], duration[k]);
}

Каждый источник использует один и тот же AudioBuffer, но когда вы вызываете start(), вы указываете смещение offset[k] и продолжительность duration[k] из decodedDataкоторую вы хотите воспроизвести.

В качестве альтернативы, вы можете нарезать оригинал decodeData на множество меньших AudioBuffer объектов, содержащих фрагменты, которые вы хотите использовать.Тогда каждый AudioBufferSourceNode может использовать этот маленький буфер в качестве источника.Это, впрочем, тратит пространство на создание всех маленьких буферов.

Примерно так (не проверено):

for (k = 0; k < n; ++k) {
  // Grab the part of the mp3 that we want.
  d[k] = decodedData.slice(start[k], end[k]);
  b[k] = new AudioBuffer({length: d[k].length, sampleRate: context.sampleRate});
  b[k].copyToChannel(d[k], 0, 0);
  s[k] = new AudioBufferSourceNode(context, {buffer: b[k]);
  // Play back this piece of the mp3 at the appropriate time.
  s[k].start(time[k]);
}
...