最近开发手机端的功能类似飞机大战,页面上的音效有多个:背景音乐、子弹、爆炸,本地测试没有问题,在iphone下发下,另外两个声音破音(重叠),而且播放的时候会卡顿,经过一番研究发现:1、iso是不支持多个audio同时播放的;2、同一个音频多次播放(间隔时间很短)也会有问题。
最近开发手机端的功能类似飞机大战,页面上的音效有多个:背景音乐、子弹、爆炸,本地测试没有问题,在iphone下发下,另外两个声音破音(重叠),而且播放的时候会卡顿,经过一番研究发现:1、iso是不支持多个audio同时播放的;2、同一个音频多次播放(间隔时间很短)也会有问题。
最终的解决方案是使用AudioContext进行音频的管理和播放,问题解决,代码如下:
const audioContext = new window.AudioContext();
class AudioPlayer {
constructor() {
this.sources = {};
}
pause(name) {
let source = this.sources[name];
let soundBuf = source.soundBuf;
if (soundBuf) {
soundBuf.stop(0);
soundBuf.loop = false;
}
}
play(name, loop = false) {
let source = this.sources[name];
let soundBuf = source.soundBuf;
if (soundBuf && soundBuf.loop) {
return;
}
soundBuf = audioContext.createBufferSource();
soundBuf.buffer = source.buffer;
soundBuf.loop = loop;
soundBuf.connect(audioContext.destination);
soundBuf.start(0);
source.soundBuf = soundBuf;
}
muted(name, muted) {
let source = this.sources[name];
let soundBuf = source.soundBuf;
if (soundBuf) {
soundBuf.muted = muted;
}
}
preload(name) {
this.muted(name, true);
this.play(name);
this.pause(name);
this.muted(name, false);
}
init(name, arrayBuffer) {
audioContext
.decodeAudioData(arrayBuffer)
.then(buffer => {
this.sources[name] = { buffer: buffer };
})
.catch(e => {
console.log("error decoding audio", e);
});
}
load(name, url) {
fetch(url)
.then(res => res.arrayBuffer())
.then(data => {
this.init(name, data);
});
}
}
export default new AudioPlayer();由于项目时间比较紧没有时间仔细研究,等后面有时间再来深入研究这个东西。