【问题标题】:How do you get the regular <audio> features when using AudioContext?使用 AudioContext 时如何获得常规的 <audio> 功能?
【发布时间】:2017-07-09 03:13:11
【问题描述】:

以下代码用作从远程 url 加载声音并通过一些音高转换循环播放的方法。即使我将 AudioContext 附加到 &lt;audio&gt; 节点并且它正在播放声音,但我没有播放/暂停、搜索、音量、下载等 UI 功能。

屏幕截图(声音正在播放,但 HTML5 &lt;audio&gt; 功能均不起作用):

我有这个几乎是空的 HTML:

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

然后我有一个添加&lt;audio&gt;元素的函数:

 $ -> 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)。最后,我创建了一个 MediaElementAudioSourceNode 连接音频上下文和 DOM &lt;audio&gt;,但它似乎没有效果,我不知道我应该用它做什么。

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()

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

 Mixer.add_audio "https://mixer-music.s3.amazonaws.com/tPEE9ZwTmy0.mp3"

我可以获得标准的 UI 功能吗?或者有没有办法我可以用AudioBufferSourceNode 重新实现它?

【问题讨论】:

    标签: javascript html audio coffeescript html5-audio


    【解决方案1】:

    原来我需要解决 3 件事:

    1. &lt;audio&gt; 中包含&lt;source&gt; 标记,即将其更改为:

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

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

    此外,由于我添加了&lt;source&gt; 标签,因此无需通过 HTTP 加载歌曲。所以我删除了那个。

    【讨论】:

    • 很好......你能在gist.github.com或其他地方发布一个工作版本,以便其他人可以看到这个吗?
    猜你喜欢
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多