2011-10-22 2 views
6

Я написал базовый скрипт в Chrome, который использует новый Web Audio Api для загрузки 3 звуковых файлов (через XMLHTTPRequest) и воспроизведения каждого из них по отдельности. Я предоставил отдельную кнопку для каждого звука, которая позволяет пользователю запускать и останавливать каждый звук.Web Audio API: как я могу возобновить воспроизведение звука?

Сценарий сразу загружает все три звуковых файла и, когда это будет сделано, разглаживает кнопки воспроизведения, чтобы пользователь мог нажимать воспроизведение только после того, как звуки готовы. Кроме того, звуки циклируются, поэтому на каждой кнопке меняется кнопка «Воспроизвести» и «Стоп» при нажатии кнопки.

Все это прекрасно работает ... Когда вы нажимаете кнопку «Воспроизведение», вы слышите звук цикла и когда вы нажимаете «Стоп», звук останавливается. Однако, когда вы пытаетесь повторно воспроизвести тот же звук во второй раз, звук не начнет воспроизводиться снова. Каждый раз, когда вы нажимаете кнопку Play/Stop, вызываются соответствующие функции playSound() или stopSound(), и соответствующие параметры передаются, но по какой-то причине я просто не могу воспроизвести звуки во второй раз. Я делаю что-то неправильно?

Вот мой код:

<body> 

<label for="playBtn1">Moog:</label> 
<input id="playBtn1" type="button" value="Play" disabled /> 
<label for="playBtn1">Drums:</label> 
<input id="playBtn2" type="button" value="Play" disabled /> 
<label for="playBtn1">Choir:</label> 
<input id="playBtn3" type="button" value="Play" disabled /> 

<script> 
    var playBtn1 = document.getElementById("playBtn1"); 
    var playBtn2 = document.getElementById("playBtn2"); 
    var playBtn3 = document.getElementById("playBtn3"); 

    var context = new webkitAudioContext(); 

    var soundBuffer1 = null; 
    var soundBuffer2 = null; 
    var soundBuffer3 = null; 

    var soundBufferSourceNode1 = context.createBufferSource(); 
    soundBufferSourceNode1.looping = true; 
    var soundBufferSourceNode2 = context.createBufferSource(); 
    soundBufferSourceNode2.looping = true; 
    var soundBufferSourceNode3 = context.createBufferSource(); 
    soundBufferSourceNode3.looping = true; 

    loadSound('micromoog.wav', 1); 
    loadSound('breakbeat-drum-loop.wav', 2); 
    loadSound('choir.wav', 3); 

    playBtn1.addEventListener("click", function(e) { 
    if(this.value == "Play") { 
     this.value = "Stop"; 
     playSound(soundBuffer1, soundBufferSourceNode1); 
    } else if(this.value == "Stop") { 
     this.value = "Play"; 
     stopSound(soundBufferSourceNode1); 
    } 
    }, false); 
    playBtn2.addEventListener("click", function(e) { 
    if(this.value == "Play") { 
     this.value = "Stop"; 
     playSound(soundBuffer2, soundBufferSourceNode2); 
    } else if(this.value == "Stop") { 
     this.value = "Play"; 
     stopSound(soundBufferSourceNode2); 
    } 
    }, false); 
    playBtn3.addEventListener("click", function(e) { 
    if(this.value == "Play") { 
     this.value = "Stop"; 
     playSound(soundBuffer3, soundBufferSourceNode3); 
    } else if(this.value == "Stop") { 
     this.value = "Play"; 
     stopSound(soundBufferSourceNode3); 
    } 
    }, false); 

    function loadSound(url, bufferNum) { 
    var request = new XMLHttpRequest(); 
    request.open('GET', url, true); 
    request.responseType = 'arraybuffer'; 

    // Decode asynchronously 
    request.onload = function() { 
     var successCallback = function(buffer) { 
     switch(bufferNum) { 
      case 1: 
      soundBuffer1 = buffer; 
      playBtn1.disabled = false; 
      break; 
      case 2: 
       soundBuffer2 = buffer; 
      playBtn2.disabled = false; 
      break; 
      case 3: 
      soundBuffer3 = buffer; 
      playBtn3.disabled = false; 
      break; 
     } 
     } 
     var errorCallback = function(e) { 
     console.log(e); 
     } 
     context.decodeAudioData(request.response, successCallback, errorCallback); 
    } 

    request.send(); 
    } 

    function playSound(buffer, bufferSourceNode) { 
    bufferSourceNode.buffer = buffer; 
    bufferSourceNode.connect(context.destination); 
    bufferSourceNode.noteOn(0); 
    } 

    function stopSound(bufferSourceNode) { 
    bufferSourceNode.noteOff(0); 
    } 
</script> 

</body> 

Кроме того, кто-нибудь в курсе любого события, которые могут стрелять раз в без зацикливания звук делается играть? Было бы здорово, если бы я мог отключить эти звуки, и как только звук будет воспроизводиться, используйте такое событие для переключения его метки. Я ничего не вижу в спецификации, но, может быть, есть лучший способ?

Thanks, Brad.

+1

Вы когда-нибудь исправляли это? У меня такая же проблема. – mdm

+1

У меня такая же проблема здесь! : S какие-нибудь идеи? – asheinfeld

ответ

5

Просто изучите API веб-аудио. На первый взгляд, я бы сказал, это потому, что вы должны создаватьBufferSource каждый раз, когда вы воспроизводите звук, и кажется, что вы делаете это только в первый раз. проверить примеры здесь: http://www.html5rocks.com/en/tutorials/webaudio/intro/

6

Я знаю, что это год поздно, но у меня была аналогичная проблема, сделал несколько быстрых поисков, и вот что я нашел:

На этой странице: http://updates.html5rocks.com/2012/01/Web-Audio-FAQ

Затем обратитесь к вопросам:

  • «Как проверить, когда AudioSourceNode закончил играть?»
  • «У меня есть AudioBufferSourceNode, который я только что воспроизвел с помощью noteOn(), и я хочу снова воспроизвести его, но noteOn() ничего не делает! Help!"

Из чего я понимаю: источник, созданный из createBufferSource(), может воспроизводиться только один раз. Как только вы остановите его, вы должны создать новый. Если вы хотите знать, когда какой-то звук перестает играть, нет события, которое отправляет его; поэтому вам нужно использовать таймаут.

Надеюсь, это поможет!

+1

Re. не имея события, когда источник заканчивает игру - теперь есть «переложенный» обратный вызов. Я просто проверил, что он работает в Chrome v35: audioSource.onended = function() { playingSound = false; }; Спасибо Anders Lauritsen за отзыв в комментариях здесь: http://updates.html5rocks.com/2012/01/Web-Audio-FAQ – poshaughnessy

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

  • Нет связанных вопросов^_^