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

标签 javascript jquery html

我正在尝试在 jQuery 中使用 .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;
     }
  });
});

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

感谢您的帮助,
保罗

最佳答案

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

不过,好消息是您可以使用 Web Audio API 来做到这一点 代替。

我给你做了一个基于this code from HTML5 rocks的例子(您应该查看更多详细信息)和您的原始 fiddle 。

目前这个 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 使示例能够通过 fiddle 加载)。

关于javascript - 使用 jQuery 播放声音时摆脱延迟时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19780670/

相关文章:

javascript - React with Firebase - 在 CRUD 操作之间分割授权

javascript - 使用 .split() 将宽度和高度与 data-src 分开不起作用(未定义)

html - 在 <body> 中使用 HTML5+Microdata 的 &lt;meta&gt; 标签

javascript - 2 个相同的选择列表,但不允许在其中选择相同的值

jquery - 如何让 JQuery UI 自动完成与项目 id 配合使用

javascript - JQM 页面更改后 jQuery 验证插件不起作用

html - <div> 不会内联

javascript - 问题搜索 NetSuite - nlapiSearchRecord

javascript - 数组中每天都有一个不同的项目 - javascript

javascript - 使 fancybox 元素保持在它们的位置