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()
    })
    
    为之则易,不为则难。
  • 相关阅读:
    关于华为x1 7.0无法从eclipse发布的更新as发布的apk
    2015-10-29
    Android Exception18(Stuido debug .....)
    阿里巴巴校招运营专员笔试题
    业务性产品经理(商业领域)笔试题
    Android编程之常识
    2015-08-24
    What most young programmers need to learn
    hdu 1556 Color the ball
    跟着实例学习设计模式(3)-工厂方法(创建型)
  • 原文地址:https://www.cnblogs.com/coderDemo/p/14105323.html
Copyright © 2011-2022 走看看