使用 AudioContext 时如何获得常规 <audio> 功能?
How do you get the regular <audio> features when using AudioContext?
以下代码可作为从远程 url 加载声音并通过一些音高移动循环播放的方法。尽管我将 AudioContext 附加到 <audio>
节点并且它正在播放声音,但我有 none 的 UI 功能,例如 play/pause、搜索、音量、下载等
屏幕截图(声音正在播放,但 HTML5 <audio>
功能的 none 有效):
我有这个几乎是空的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
)。最后,我正在创建一个 MediaElementAudioSourceNode
连接音频上下文和 DOM <audio>
,但它似乎没有效果,我不知道我应该做什么它。
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()
调用它(这是一个 public url 并且页面最终循环播放这个 1 秒的示例并提高每个循环的音调):
Mixer.add_audio "https://mixer-music.s3.amazonaws.com/tPEE9ZwTmy0.mp3"
我可以获得标准的 UI 功能吗?或者有什么方法可以用 AudioBufferSourceNode
?
重新实现它
原来我需要修复 3 个问题:
在 <audio>
中包含 <source>
标签,即将其更改为:
<div class="audio">
<audio controls loop>
<source src="#{url}"></source>
</audio>
</div>
在pitchShift.connect(audio_context.destination)
之前添加source.connect(pitchShift)
。
运行 audio.crossOrigin = "anonymous"
在音频元素上
此外,由于我添加了 <source>
标签,因此无需通过 HTTP 加载歌曲。所以我删除了它。
以下代码可作为从远程 url 加载声音并通过一些音高移动循环播放的方法。尽管我将 AudioContext 附加到 <audio>
节点并且它正在播放声音,但我有 none 的 UI 功能,例如 play/pause、搜索、音量、下载等
屏幕截图(声音正在播放,但 HTML5 <audio>
功能的 none 有效):
我有这个几乎是空的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
)。最后,我正在创建一个 MediaElementAudioSourceNode
连接音频上下文和 DOM <audio>
,但它似乎没有效果,我不知道我应该做什么它。
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()
调用它(这是一个 public url 并且页面最终循环播放这个 1 秒的示例并提高每个循环的音调):
Mixer.add_audio "https://mixer-music.s3.amazonaws.com/tPEE9ZwTmy0.mp3"
我可以获得标准的 UI 功能吗?或者有什么方法可以用 AudioBufferSourceNode
?
原来我需要修复 3 个问题:
在
<audio>
中包含<source>
标签,即将其更改为:<div class="audio"> <audio controls loop> <source src="#{url}"></source> </audio> </div>
在
pitchShift.connect(audio_context.destination)
之前添加source.connect(pitchShift)
。运行
audio.crossOrigin = "anonymous"
在音频元素上
此外,由于我添加了 <source>
标签,因此无需通过 HTTP 加载歌曲。所以我删除了它。