摆脱使用jQuery播放声音时的延迟时间

时间:2013-11-05 01:50:19

标签: javascript jquery html

我试图在jQuery中使用.keydown()事件播放声音。我希望声音能够快速播放,但是当我执行keydown事件的速度超过每秒约3次时似乎存在延迟时间。

以下是我的示例代码的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。以上只是一个例子。

感谢您的帮助,
保罗

1 个答案:

答案 0 :(得分:1)

您将无法使用audio元素执行此操作。这是因为设置和填充缓冲区的成本将花费太多时间。

但好消息是你可以使用 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来启用样本加载小提琴)。