使用AudioContext时如何获得常规<audio>功能?

时间:2017-02-19 23:59:07

标签: javascript html5 audio coffeescript html5-audio

以下代码用作从远程网址加载声音并通过一些音高变换循环播放的方法。即使我将AudioContext附加到<audio>节点并播放声音,我也没有播放/暂停,搜索,音量,下载等UI功能。

屏幕截图(播放声音,但HTML5 <audio>功能均无效):

non-functionaling HTML audio element

我有几乎空的HTML:

<div id="audios"></div>

然后我有一个添加<audio>元素的函数:

 $ -> Mixer.$audios = $("#audios")

 Mixer.add_audio = (url) ->
    $audio_box = $ """
      <div class='audio'>
        <audio controls loop></audio>      
      </div>
    """
    Mixer.$audios.append($audio_box)
    audio = $audio_box.find("audio")[0]
    Mixer.source_with_pitch_shift(audio, url).then (args) ->
      [audio_context, source, buffer_src] = args
      Mixer.start_playing(buffer_src)

  Mixer.start_playing = (buffer_src) ->
    buffer_src.loop = true
    buffer_src.start()

Mixer.source_with_pitch_shift从缓冲区源(通过HTTP请求的音频文件)创建AudioContext。它还创建了一个附加到该上下文的PitchShift节点(引擎盖下的GainNode)。最后,我创建了一个连接音频上下文和DOM MediaElementAudioSourceNode的{​​{1}},但似乎没有任何效果,我也不知道我应该做什么做它。

<audio>

调用它(这是一个公共网址,页面最终会循环播放这个1秒的样本并在每个循环中提高音高):

Mixer.source_with_pitch_shift = (audio, url) ->
    Mixer.build_audio_context(url).then (args) ->
        [audio_context, buffer_src] = args
        # Not sure what to do with this:
        source = audio_context.createMediaElementSource(audio)
        pitchShift = PitchShift(audio_context)
        pitchShift.transpose = 12
        pitchShift.connect(audio_context.destination)
        Promise.resolve([audio_context, source, buffer_src])

Mixer.build_audio_context = (url) ->
    audioSrc = url
    audio_context = new AudioContext()    
    Mixer.bufferSound(audio_context, audioSrc).then (buffer) ->
        g = audio_context.createGain()
        g.gain.value = 5
        g.connect(audio_context.destination)
        bq = audio_context.createBiquadFilter()
        bq.detune.value = 0
        setInterval ->
          bq.detune.value += 200
        , 1000
        bq.connect(g)
        buffer_src = audio_context.createBufferSource()
        buffer_src.buffer = buffer
        buffer_src.connect(bq)
        Promise.resolve([audio_context, buffer_src])

Mixer.bufferSound = (ctx, url) ->
    new Promise (resolve, reject) ->
        req = new XMLHttpRequest()
        req.open('GET', url, true)
        req.responseType = 'arraybuffer'
        req.onload = ->
          ctx.decodeAudioData(req.response, resolve, reject)
        req.send()

我可以获得标准的UI功能吗?或者有没有办法可以用 Mixer.add_audio "https://mixer-music.s3.amazonaws.com/tPEE9ZwTmy0.mp3" 重新实现它?

1 个答案:

答案 0 :(得分:1)

事实证明我需要解决三件事:

  1. <source>中包含<audio>标记,即将其更改为:

    <div class="audio">
      <audio controls loop>
        <source src="#{url}"></source>
      </audio>  
    </div>
    
  2. source.connect(pitchShift)之前添加pitchShift.connect(audio_context.destination)

  3. 在音频元素上运行audio.crossOrigin = "anonymous"

  4. 此外,由于我添加了<source>标记,因此无需通过HTTP加载歌曲。所以我删除了。