Web Audio API - multiple synchronized tracks - stopping previous track when new track starts

前端 未结 2 2025
闹比i
闹比i 2021-01-21 22:33

I\'m trying to mimic the Web Audio API multitrack demo from the \'Mozilla Web Audio API for games\' Web doc.

https://developer.mozilla.org/en-US/docs/Games/Techniques/Au

2条回答
  •  既然无缘
    2021-01-21 22:52

    Simply store the BufferSources somewhere in the outer scope and then call their stop() method.

    I took the liberty to rewrite a bit your loading logic, you shouldn't create a new request every time you start a new track, in that case you loose the main advantages of AudioBuffers against Audio element: they're truly fast to instantiate.

    var active_source = null;
    
    function stopActiveSource() {
      if (active_source) {
        active_source.onended = null; // manual stop, no event
        active_source.stop(0);
      }
    }
    // instead of requesting a new ArrayBuffer every time
    // store them in a dictionnary
    var buffers = {};
    var context = new(window.AudioContext || window.webkitAudioContext)();
    
    function playTrack(url) {
      // get fom our dictionnary
      var buffer = buffers[url];
      // stop the active one if any
      stopActiveSource();
      // create a new BufferSource
      var source = context.createBufferSource();
      // it is now the active one
      active_source = source;
      source.onended = function() {
        active_source = null;
      };
    
      source.buffer = buffer;
      source.connect(context.destination);
    
      source.start(0);
    }
    
    // start by getting all AudioBuffers
    var tracks = document.getElementsByClassName('track');
    
    for (var i = 0, len = tracks.length; i < len; i++) {
      tracks[i].addEventListener('click', function(e) {
        playTrack(this.href);
        e.preventDefault();
      });
      getBuffer(tracks[i].href);
    }
    
    
    function getBuffer(url) {
      var request = new XMLHttpRequest();
      request.open('GET', url, true);
      request.responseType = 'arraybuffer';
      request.onload = function(evt) {
        context.decodeAudioData(request.response, store);
      };
      request.send();
    
      function store(buffer) {
        buffers[url] = buffer;
      }
    }
    
    

提交回复
热议问题