#javascript #audio #web-audio-api
#javascript #Аудио #web-audio-api
Вопрос:
Мне нужно объединить несколько звуковых дорожек в js, и мне нужно получить ArrayBuffer для выполнения AudioContext.decodeAudioData(). Как я могу это сделать?
это и есть код :
let tracks = []
streamsAudio.forEach((track) => {
let elem = document.createElement('audio')
elem.srcObject = track.src
elem.play()
tracks.push(track.src.getAudioTracks()[0])
})
const ac = new AudioContext();
ac.decodeAudioData(ArrayBuffer, function(data) {
})
Ответ №1:
Непонятно, зачем вам нужен an ArrayBuffer
, чтобы вы могли декодировать данные. Аудио-тег уже может декодировать аудио для вас.
Один из способов — прикрепить свой audio
элемент к a MediaElementAudioSourceNode
. Подключите это к ScriptProcessorNode
или AudioWorkletNode
для получения данных с отдельных дорожек. Быстрый набросок (непроверенный):
// Make elem global instead of local for this to work. Then
let s = new MediaElementAudiouSourceNode(ac, {mediaElement: elem});
// 8192 is just an example. You could choose other values
let spn = ac.createScriptProcessorNode(8192, <number of channels>, 0);
spn.onaudioprocess = (e) => {
let input = e.inputBuffer;
for (let k = 0; k < input.length; k) {
let channel = input.getChannelData(k);
// channel has one channel from the tracks. Process it as you see
// fit.
}
}
s.connect(spn).connect(ac.destination);
Вам нужно будет определить количество каналов для
процессора сценариев. Это может не совпадать с количеством дорожек, если
дорожка содержит, скажем, стереозвук.
Комментарии:
1. Какими были бы шанлели?
2. Допустим, у вас есть две дорожки. Каждая дорожка состоит из стереофонического аудиоклипа. Затем есть 4 канала, по два от каждого трека. Я не думаю, что четко указано, как все каналы в каждой дорожке сопоставляются с входными данными ScriptProcessorNode. Но конечный результат работы скриптового процессора был бы, примерно, таким, какой вы получили бы, если бы у вас был ArrayBuffer для отправки в decodeAudioData