2011-10-22 3 views
6

새로운 웹 오디오 API를 사용하여 (XMLHTTPRequest를 통해) 3 개의 사운드 파일을로드하고 각각을 개별적으로 재생하는 Chrome의 기본 스크립트를 작성했습니다. 사용자가 각 사운드를 시작하고 중지 할 수 있도록 각 사운드에 대해 별도의 버튼을 제공했습니다.웹 오디오 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> 

: 여기

내 코드? 이러한 사운드를 비 루핑으로 설정할 수 있다면 멋지 겠지만 사운드 재생이 끝나면 해당 이벤트를 사용하여 레이블을 전환하십시오. 스펙에는 아무 것도 보이지 않지만 더 좋은 방법이 있을까요?

감사합니다. Brad.

+1

해결해 봤습니까? 비슷한 문제가 있습니다. – mdm

+1

나는 똑같은 문제를 여기에서 가지고있다! : 어떤 아이디어? – asheinfeld

답변

5

웹 오디오 API를 직접 배우십시오. 언뜻 나는 사운드를 재생할 때마다 BufferSource를 생성해야하기 때문에 그것이라고 말하고 싶습니다. 처음에는 사운드를 재생하는 것처럼 보입니다. 여기에 예를 체크 아웃 : http://www.html5rocks.com/en/tutorials/webaudio/intro/

6

을 나는이 늦게 년 알지만, 내가 여기에, 비슷한 문제를 가지고 몇 가지 간단한 검색을했고 것은 내가 찾은 것입니다 : http://updates.html5rocks.com/2012/01/Web-Audio-FAQ

:이 페이지에서

그런 다음 질문을 참조하십시오.

  • "AudioSourceNode의 재생이 끝나면 어떻게 확인할 수 있습니까?"
  • "noteOn()으로 방금 재생 한 AudioBufferSourceNode가 있는데 다시 재생하고 싶지만 noteOn()은 아무 것도하지 않습니다!"라는 메시지가 나타납니다.

나는 이해 : createBufferSource()로 만든 소스는 한 번만 재생할 수 있습니다. 일단 멈 추면 새 것을 만들어야합니다. 특정 사운드의 재생이 중단 된 시점을 알고 싶다면 해당 사운드가 디스패치되는 이벤트가 없습니다. 그래서 타임 아웃을 사용해야합니다.

희망이 도움이됩니다.

+1

Re. 소스가 재생을 끝내면 이벤트가 발생하지 않습니다. 이제 'onended'콜백이 있습니다. 방금 Chrome v35에서 작동하는지 확인했습니다. audioSource.onended = function() { playingSound = false; }; Anders Lauritsen에게 감사의 말을 전합니다. http://updates.html5rocks.com/2012/01/Web-Audio-FAQ – poshaughnessy

관련 문제