最近开发手机端的功能类似飞机大战,页面上的音效有多个:背景音乐、子弹、爆炸,本地测试没有问题,在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();
由于项目时间比较紧没有时间仔细研究,等后面有时间再来深入研究这个东西。