IOS下H5音频播放不支持多个,多个音频同时播放卡顿破音的问题
分类:实战技巧 浏览:1095 时间:2021-12-09 09:09

最近开发手机端的功能类似飞机大战,页面上的音效有多个:背景音乐、子弹、爆炸,本地测试没有问题,在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();

由于项目时间比较紧没有时间仔细研究,等后面有时间再来深入研究这个东西。

蛋疼集锦