2017-02-19 1 views
0

Следующий код работает как способ загрузки звука с удаленного URL-адреса и его петли с некоторым сдвигом высоты тона. Несмотря на то, что я прикрепляю AudioContext к узлу <audio>, и он воспроизводит звуки, у меня нет никаких функций интерфейса, таких как воспроизведение/пауза, поиск, громкость, загрузка и т. Д.Как вы получаете обычные функции <audio> при использовании AudioContext?

Снимок экрана (звук воспроизводится, но ни один из 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 создает AudioContext из источника буфера (аудиофайл запрошенной HTTP). Он также создает узел 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() 

Назвав его (это публичный URL и страница заканчивается цикл этот 1-секундный сэмпл и повышение тона каждый контур):

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

Могу ли я получить стандартные функциональные возможности пользовательского интерфейса? Или есть способ, которым я могу повторно реализовать его с помощью AudioBufferSourceNode?

ответ

1

Оказалось, там было 3 вещи, которые я должен исправить:

  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" на звуковом элементе

Кроме того, поскольку я добавил <source> тег это не нужно, чтобы загрузить песню через HTTP. Поэтому я удалил это.

+0

... вы можете опубликовать рабочую версию на https://gist.github.com/ или где-нибудь, чтобы другие могли видеть это в действии? –

Смежные вопросы