JavaScript AudioContext 自动播放音频

该方法使用了XHR来加载音乐文件,所以不能以file形式访问,可以使用http-server来构建一个本地服务访问
class Music {
  constructor(url, loop) {
    const AudioCtx = AudioContext || webkitAudioContext || mozAudioContext || msAudioContext
    this.context = new AudioCtx
    this.url = url
    this.handle = {}
    this.loop = loop || false
    this.source = null
    this.audioBuffer = null
    this.loadMusic()
  }

  stop() {
    if (this.source) {
      this.source.stop()
      this.source.playStatus = 1
    }
  }

  // 0 初始化完成未播放 1 已暂停 2 正在播放
  play() {
    if (this.source) {
      switch (this.source.playStatus) {
        case 0:
          this.source.start()
          break
        case 1:
          this.setSource(this.audioBuffer) // 重新设置buffer
          this.source.start()
          break
        case 2:
          return false
      }
      this.source.playStatus = 2
    }
  }

  /* 实例上监听 */
  addEventListener(eventName, callback) {
    if (!this.handle[eventName]) {
      this.handle[eventName] = []
    }
    this.handle[eventName].push(callback)
  }

  setSource(buffer) {
    this.source = null // 销毁掉旧的source
    this.source = this.context.createBufferSource()
    this.source.buffer = buffer
    this.source.loop = this.loop
    this.source.connect(this.context.destination)
    this.source.playStatus = 0
    this.source.onended = () => {
      this.source.playStatus = 1
    }
  }

  /* 创建source */
  initSource(arrayBuffer) {
    const that = this
    that.context.decodeAudioData(arrayBuffer,
      function (buffer) {
        that.audioBuffer = buffer // 缓存起来
        that.setSource(buffer)
        const event = that.handle['load']
        if (event) {
          event.map(v => v.call(that))
        }
      },
      function (error) {
        const event = that.handle['error']
        if (event) {
          event.map(v => v.call(that, error))
        }
      });
  }

  /* 使用xhr加载音乐文件 */
  loadMusic() {
    const that = this
    const xhr = new XMLHttpRequest()
    xhr.open('GET', that.url, true)
    xhr.responseType = 'arraybuffer'
    xhr.send()
    xhr.addEventListener('load', function (e) {
      that.initSource(e.target.response)
    })
    xhr.addEventListener('error', function (error) {
      const event = that.handle['error']
      if (event) {
        event.map(v => v.call(that, error))
      }
    })
  }
}

demo

const music = new Music('./demo.mp3', true)
  music.addEventListener('load', function () {
    this.play()
})
posted @ 2020-12-08 19:54  demo_you  阅读(1274)  评论(0编辑  收藏  举报