如何用js audio播放多个音频api
how to play multiple audio with js audio api
我正在从服务器读取音频文件。我有一个原始音频文件数组。
const allAudio = [];
然后依次播放
var volumeSeq=1;
function playAudio(){
if(volumeSeq==allAudio.length){ volumeSeq=1;}
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
source = audioCtx.createBufferSource();
audioCtx.decodeAudioData(allAudio[volumeSeq], function(buffer) {
source.buffer = buffer;
console.log(source.buffer);
source.connect(audioCtx.destination);
source.loop = false;});
source.start(0);
source.onended = function () {
volumeSeq++;
playAudio();
}
我发现了问题。但我不知道为什么。问题是,在数组解码 i.element 之后,其中的元素被删除了。我的意思是当我解码 allAudio[1] 然后 allAudio[1] 是空的。
所以我无法为这些音轨创建循环。
我该怎么办?
为什么不在开头解码所有音频文件,然后循环遍历它们?像这样:
var allAudio = [];
var audioCtx = new AudioContext();
var volumeSeq = 0;
var decodedAudio = [];
function decodeAudio() {
allAudio.forEach(function (file, index) {
audioCtx.decodeAudioData(file, function(buffer) {
decodedAudio[index] = buffer;
if (decodedAudio.length >= allAudio.length) {
play();
}
})
})
}
function play() {
if (volumeSeq >= allAudio.length){ volumeSeq=0;}
var source = audioCtx.createBufferSource();
source.buffer = decodedAudio[volumeSeq];
source.connect(audioCtx.destination);
source.start(0);
source.onended = function () {
volumeSeq++;
play();
}
}
decodeAudio();
还有几件事:
- 您不需要每次都创建
AudioContext
。
AudioBufferSourceNode.loop
默认为 false。您可以跳过 source.loop = false;
- 每个新变量都应以
const
、let
或 var
开头。你错过了 source
。顺便说一句,现在最好使用 const
和 let
,而不是 var
。我将在下一个“现代”示例中展示它。
- 我不知道你为什么要从索引 1 开始迭代
allAudio
。数组中的第一个索引是 0。
如果您不喜欢 IE 等旧浏览器,可以使用 Promises
和 async/await
:
使代码更简洁
const audioCtx = new AudioContext();
async function start() {
const decodedAudio = await Promise.all(allAudio.map((file) => audioCtx.decodeAudioData(file)));
let volumeSeq = 0;
function play() {
if(volumeSeq >= allAudio.length) volumeSeq = 0;
const source = audioCtx.createBufferSource();
source.buffer = decodedAudio[volumeSeq];
source.connect(audioCtx.destination);
source.start(0);
source.addEventListener('ended', () => {
volumeSeq++;
play();
}, { once: true })
}
play();
}
start()
我正在从服务器读取音频文件。我有一个原始音频文件数组。
const allAudio = [];
然后依次播放
var volumeSeq=1;
function playAudio(){
if(volumeSeq==allAudio.length){ volumeSeq=1;}
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
source = audioCtx.createBufferSource();
audioCtx.decodeAudioData(allAudio[volumeSeq], function(buffer) {
source.buffer = buffer;
console.log(source.buffer);
source.connect(audioCtx.destination);
source.loop = false;});
source.start(0);
source.onended = function () {
volumeSeq++;
playAudio();
}
我发现了问题。但我不知道为什么。问题是,在数组解码 i.element 之后,其中的元素被删除了。我的意思是当我解码 allAudio[1] 然后 allAudio[1] 是空的。 所以我无法为这些音轨创建循环。
我该怎么办?
为什么不在开头解码所有音频文件,然后循环遍历它们?像这样:
var allAudio = [];
var audioCtx = new AudioContext();
var volumeSeq = 0;
var decodedAudio = [];
function decodeAudio() {
allAudio.forEach(function (file, index) {
audioCtx.decodeAudioData(file, function(buffer) {
decodedAudio[index] = buffer;
if (decodedAudio.length >= allAudio.length) {
play();
}
})
})
}
function play() {
if (volumeSeq >= allAudio.length){ volumeSeq=0;}
var source = audioCtx.createBufferSource();
source.buffer = decodedAudio[volumeSeq];
source.connect(audioCtx.destination);
source.start(0);
source.onended = function () {
volumeSeq++;
play();
}
}
decodeAudio();
还有几件事:
- 您不需要每次都创建
AudioContext
。 AudioBufferSourceNode.loop
默认为 false。您可以跳过source.loop = false;
- 每个新变量都应以
const
、let
或var
开头。你错过了source
。顺便说一句,现在最好使用const
和let
,而不是var
。我将在下一个“现代”示例中展示它。 - 我不知道你为什么要从索引 1 开始迭代
allAudio
。数组中的第一个索引是 0。
如果您不喜欢 IE 等旧浏览器,可以使用 Promises
和 async/await
:
const audioCtx = new AudioContext();
async function start() {
const decodedAudio = await Promise.all(allAudio.map((file) => audioCtx.decodeAudioData(file)));
let volumeSeq = 0;
function play() {
if(volumeSeq >= allAudio.length) volumeSeq = 0;
const source = audioCtx.createBufferSource();
source.buffer = decodedAudio[volumeSeq];
source.connect(audioCtx.destination);
source.start(0);
source.addEventListener('ended', () => {
volumeSeq++;
play();
}, { once: true })
}
play();
}
start()