2015-04-26 16 views
5

Non riesco a trovare una risposta chiara a questa domanda da nessuna parte. Sto cercando il modo più semplice per eseguire il ciclo continuo di un file .wav automaticamente sul carico del documento in chrome. Sembra che l'API di webaudio sia la migliore pratica, ma non riesco a trovare una documentazione semplice. Il supporto per Safari e altri sarebbe fantastico ma non altrettanto importante.Come eseguire il looping senza interruzioni audio con web audio api

ho guardato l'esempio w3.org ma non ha aiutato

Penso che questo è il più vicino a quello che voglio oltre al on.click per i pulsanti: https://forestmist.org/blog/web-audio-api-loops/

qui ho implementato la Forestmist per il mio audio che funziona perfettamente in Safari, ma si ferma in cromo: http://infinitelimitations.us/mess-motion/web-audio-api-loops-demo/index.html

Ecco il codice sorgente per la pagina:

<!doctype html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <title>Web Audio API Loops Demo</title> 
</head> 
<body> 

    <form> 
     <button id="button-loop-1" type="button" value="1">Loop 1</button> 
    </form> 

    <script> 
    //-------------- 
    // Audio Object 
    //-------------- 
    var audio = { 
     buffer: {}, 
     compatibility: {}, 
     files: [ 
      'hoodie_robot_clipped.wav', 
      'beat.wav' 
     ], 
     proceed: true, 
     source_loop: {}, 

    }; 

    //----------------- 
    // Audio Functions 
    //----------------- 
    audio.findSync = function(n) { 
     var first = 0, 
      current = 0, 
      offset = 0; 

     // Find the audio source with the earliest startTime to sync all others to 
     for (var i in audio.source_loop) { 
      current = audio.source_loop[i]._startTime; 
      if (current > 0) { 
       if (current < first || first === 0) { 
        first = current; 
       } 
      } 
     } 

     if (audio.context.currentTime > first) { 
      offset = (audio.context.currentTime - first) % audio.buffer[n].duration; 
     } 

     return offset; 
    }; 

    audio.play = function(n) { 
     if (audio.source_loop[n]._playing) { 
      audio.stop(n); 
     } else { 
      audio.source_loop[n] = audio.context.createBufferSource(); 
      audio.source_loop[n].buffer = audio.buffer[n]; 
      audio.source_loop[n].loop = true; 
      audio.source_loop[n].connect(audio.context.destination); 

      var offset = audio.findSync(n); 
      audio.source_loop[n]._startTime = audio.context.currentTime; 

      if (audio.compatibility.start === 'noteOn') { 
       /* 
       The depreciated noteOn() function does not support offsets. 
       Compensate by using noteGrainOn() with an offset to play once and then schedule a noteOn() call to loop after that. 
       */ 
       audio.source_once[n] = audio.context.createBufferSource(); 
       audio.source_once[n].buffer = audio.buffer[n]; 
       audio.source_once[n].connect(audio.context.destination); 
       audio.source_once[n].noteGrainOn(0, offset, audio.buffer[n].duration - offset); // currentTime, offset, duration 
       /* 
       Note about the third parameter of noteGrainOn(). 
       If your sound is 10 seconds long, your offset 5 and duration 5 then you'll get what you expect. 
       If your sound is 10 seconds long, your offset 5 and duration 10 then the sound will play from the start instead of the offset. 
       */ 

       // Now queue up our looping sound to start immediatly after the source_once audio plays. 
       audio.source_loop[n][audio.compatibility.start](audio.context.currentTime + (audio.buffer[n].duration - offset)); 
      } else { 
       audio.source_loop[n][audio.compatibility.start](0, offset); 
      } 

      audio.source_loop[n]._playing = true; 
     } 
    }; 

    audio.stop = function(n) { 
     if (audio.source_loop[n]._playing) { 
      audio.source_loop[n][audio.compatibility.stop](0); 
      audio.source_loop[n]._playing = false; 
      audio.source_loop[n]._startTime = 0; 
      if (audio.compatibility.start === 'noteOn') { 
       audio.source_once[n][audio.compatibility.stop](0); 
      } 
     } 
    }; 

    //----------------------------- 
    // Check Web Audio API Support 
    //----------------------------- 
    try { 
     // More info at http://caniuse.com/#feat=audio-api 
     window.AudioContext = window.AudioContext || window.webkitAudioContext; 
     audio.context = new window.AudioContext(); 
    } catch(e) { 
     audio.proceed = false; 
     alert('Web Audio API not supported in this browser.'); 
    } 

    if (audio.proceed) { 
     //--------------- 
     // Compatibility 
     //--------------- 
     (function() { 
      var start = 'start', 
       stop = 'stop', 
       buffer = audio.context.createBufferSource(); 

      if (typeof buffer.start !== 'function') { 
       start = 'noteOn'; 
      } 
      audio.compatibility.start = start; 

      if (typeof buffer.stop !== 'function') { 
       stop = 'noteOff'; 
      } 
      audio.compatibility.stop = stop; 
     })(); 

     //------------------------------- 
     // Setup Audio Files and Buttons 
     //------------------------------- 
     for (var a in audio.files) { 
      (function() { 
       var i = parseInt(a) + 1; 
       var req = new XMLHttpRequest(); 
       req.open('GET', audio.files[i - 1], true); // array starts with 0 hence the -1 
       req.responseType = 'arraybuffer'; 
       req.onload = function() { 
        audio.context.decodeAudioData(
         req.response, 
         function(buffer) { 
          audio.buffer[i] = buffer; 
          audio.source_loop[i] = {}; 
          var button = document.getElementById('button-loop-' + i); 
          button.addEventListener('click', function(e) { 
           e.preventDefault(); 
           audio.play(this.value); 
          }); 
         }, 
         function() { 
          console.log('Error decoding audio "' + audio.files[i - 1] + '".'); 
         } 
        ); 
       }; 
       req.send(); 
      })(); 
     } 
    } 
    </script> 

</body> 
</html> 

risposta

14

Ha preso una notte di ricerca, ma ho finalmente trovato la soluzione più semplice:

<script type="text/javascript"> 
    //this is the webaudio loooooppppppp 
    //enter url in the next line 
    var url = 'hoodie_robot_clipped.wav'; 

    /* --- set up web audio --- */ 
    //create the context 
    var context = new AudioContext(); 
    //...and the source 
    var source = context.createBufferSource(); 
    //connect it to the destination so you can hear it. 
    source.connect(context.destination); 

    /* --- load buffer --- */ 
    var request = new XMLHttpRequest(); 
    //open the request 
    request.open('GET', url, true); 
    //webaudio paramaters 
    request.responseType = 'arraybuffer'; 
    //Once the request has completed... do this 
    request.onload = function() { 
     context.decodeAudioData(request.response, function(response) { 
      /* --- play the sound AFTER the buffer loaded --- */ 
      //set the buffer to the response we just received. 
      source.buffer = response; 
      //start(0) should play asap. 
      source.start(0); 
      source.loop = true; 
     }, function() { console.error('The request failed.'); }); 
    } 
    //Now that the request has been defined, actually make the request. (send it) 
    request.send(); 
</script> 
+2

Questa è la prima soluzione che ho visto online che mi ha dato ciclo senza pause, anche con un file wav. '

Problemi correlati