【问题标题】:Getting rid of lag time when playing sound with jQuery使用 jQuery 播放声音时摆脱延迟时间
【发布时间】:2013-11-05 01:50:19
【问题描述】:

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

这是我的示例代码的 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;
     }
  });
});

有人知道摆脱这种滞后的方法吗?此外,我将播放的实际文件是 mpeg。以上只是一个例子。

感谢您的帮助,
保罗

【问题讨论】:

  • 什么浏览器?我正在一台糟糕的带有 chrome 的 windows 机器上测试它,它很好。
  • @Paul 它在这里也可以,很好。
  • 我正在使用 Safari。是的,它播放的声音很好,但我希望它走得更快。有什么办法可以做到吗?

标签: javascript jquery html


【解决方案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 使样本能够通过小提琴加载)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多