2013-11-05 62 views
2

我正尝试在jQuery中使用.keydown()事件播放声音。我希望声音能够快速播放,但是当我以每秒3次的速度执行keydown事件时,似乎存在滞后时间。使用jQuery播放声音时摆脱滞后时间

这里是我的示例代码的jsfiddle:http://jsfiddle.net/pfrater/FRudg/3/

我使用的声音和播放音频html标签:

<audio controls id="sound" preload="auto"> 
<source src="http://www.wavlist.com/soundfx/011/duck-baby.wav" type="audio/wav"/> 
</audio> 

<audio controls id="sound2" preload="auto"> 
<source src="http://rezound.sourceforge.net/examples/chirp.wav" type="audio/wav"/> 
</audio> 

<audio controls id="sound3" preload="auto"> 
<source src="http://www.all-birds.com/Sound/downychirp.wav" type="audio/wav"/> 
</audio> 

,这里是我的jQuery:

$(document).ready(function() { 
var playing; 
$(document).bind("keydown", function(key) { 
    playing = undefined; 
    switch(parseInt(key.which, 10)) { 
     case 65: 
      playing = $("#sound").get(0); 
      break; 
     case 83: 
      playing = $("#sound2").get(0); 
      break; 
     case 68: 
      playing = $("#sound3").get(0); 
      break; 
    }; 
    if (playing) { 
     playing.play(); 
    } 
    }).on("keyup", function() { 
    if(playing){ 
     playing.pause(); 
     playing.currentTime=50; 
     playing = undefined; 
    } 
    }); 
}); 

有谁知道摆脱这种滞后的方法吗?另外,我将要播放的实际文件是mpegs。上面的只是一个例子。

感谢您的帮助,
保罗

+0

什么浏览器?我正在使用铬合金在一台蹩脚的Windows机器上测试它,这很好。 – epascarello

+0

@保罗它也适用于这里,就好了。 – AbdelElrafa

+0

我正在使用Safari。是的,它播放声音很好,但我希望它变得更快。有什么办法可以做到吗? – logicForPresident

回答

1

您将无法与音频元素来做到这一点。这是因为设置和填充缓冲区的成本将花费太多时间。

好消息是,您可以使用Web Audio API来代替。

我让你根据this code from HTML5 rocks(你应该检查更多细节)和你原来的小提琴的例子。

目前这个API是supported in Chrome, Firefox, Safari and Opera将能够使用此:

Fiddle demo

window.AudioContext = window.AudioContext || window.webkitAudioContext; 

/// custom buffer loader 
/// see http://www.html5rocks.com/en/tutorials/webaudio/intro/ 
function BufferLoader(context, urlList, callback) { 
    this.context = context; 
    this.urlList = urlList; 
    this.onload = callback; 
    this.bufferList = new Array(); 
    this.loadCount = 0; 
} 

BufferLoader.prototype.loadBuffer = function (url, index) { 
    var request = new XMLHttpRequest(); 
    request.open("GET", url, true); 
    request.responseType = "arraybuffer"; 

    var loader = this; 

    request.onload = function() { 
     // Asynchronously decode the audio file data in request.response 
     loader.context.decodeAudioData(
     request.response, 

     function (buffer) { 
      if (!buffer) { 
       alert('error decoding file data: ' + url); 
       return; 
      } 
      loader.bufferList[index] = buffer; 
      if (++loader.loadCount == loader.urlList.length) 
       loader.onload(loader.bufferList); 
     }, 

     function (error) { 
      console.error('decodeAudioData error', error); 
     }); 
    } 

    request.onerror = function (e) { 
     alert('BufferLoader: XHR error'); 
    }  
    request.send(); 
} 

BufferLoader.prototype.load = function() { 
    for (var i = 0; i < this.urlList.length; ++i) 
    this.loadBuffer(this.urlList[i], i); 
} 

的主要代码:

/// setup audio context and start loading samples 
var actx = new AudioContext(), 
    blst, 
    bLoader = new BufferLoader(
    actx, [ 
     'duck-baby.wav', 'chirp.wav', 'downychirp.wav'], 
    done), 
    isReady = false; 

/// start loading the samples 
bLoader.load(); 

function done(bl) { 
    blst = bl;       /// buffer list 
    isReady = true;      /// enable keys 
    $('#status').html('Ready!');   /// update statusw 
} 

/// this sets up chain so we can play audio 
function play(i) { 
    var src = actx.createBufferSource(); /// prepare sample 
    src.buffer = blst[i];    /// set buffer from loader 
    src.connect(actx.destination);  /// connect to speakers 
    src.start(0);      /// play sample now 
} 

/// check keys 
$(window).bind("keydown", function (key) { 
    if (!isReady) return; 
    switch (parseInt(key.which, 10)) { 
     case 65: 
      play(0); 
      return; 
     case 83: 
      play(1); 
      return; 
     case 68: 
      play(2); 
      return; 
    }  
}) 

注:当使用外部样本,必须确保它们可以交叉使用或否则加载将失败(我使用我的DropBox来启用样本加载小提琴)。