zoukankan      html  css  js  c++  java
  • 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()
    })
    
    为之则易,不为则难。
  • 相关阅读:
    Java实现 蓝桥杯 算法提高 小X的购物计划
    Java实现 蓝桥杯 算法提高 小X的购物计划
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    129. Sum Root to Leaf Numbers
    117. Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/coderDemo/p/14105323.html
Copyright © 2011-2022 走看看