我想创建几个源音频节点,每个节点包含一个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
的不同片段。
答案 0 :(得分:0)
由于您阅读了所有“ speech.mp3”,因此可以为mp3文件的各个部分创建多个AudioBufferSourceNode
对象。我至少可以想到两种方式。也许最简单(未经测试):
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]);
}
每个src使用相同的AudioBuffer,但是在调用start()
时,要指定要播放的解码数据的偏移量offset[k]
和持续时间duration[k]
。 / p>
或者,您可以将原始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]);
}