摆脱使用jQuery播放声音时的延迟时间 [英] Getting rid of lag time when playing sound with jQuery

查看:95
本文介绍了摆脱使用jQuery播放声音时的延迟时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是一个jsFiddle我的示例代码: http://jsfiddle.net/pfrater/FRudg/3/ / p>

我正在使用音频html标签进行声音和播放:

 < audio controls id =soundpreload =auto> 
< source src =http://www.wavlist.com/soundfx/011/duck-baby.wavtype =audio / wav/>
< / audio>

< audio controls id =sound2preload =auto>
< source src =http://rezound.sourceforge.net/examples/chirp.wavtype =audio / wav/>
< / audio>

< audio controls id =sound3preload =auto>
< source src =http://www.all-birds.com/Sound/downychirp.wavtype =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);
休息;
案例83:
play = $(#sound2)。get(0);
break;
case 68:
playing = $( #sound3)。get(0);
break;
};
if(play){
playing.play();
}
})。on(keyup,function(){
if(playing){
playing.pause();
playing.currentTime = 50;
playing = undefined;
}
});
});

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



感谢您的帮助,

Paul

解决方案

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



但好消息是你可以使用 Web Audio API



我根据来自HTML5摇滚的代码(你就是一个例子)应该查看更多细节)和你原来的小提琴。



目前这个API是将能够使用此功能:



小提琴演示

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

///自定义缓冲区加载器
///请参阅http://www.html5rocks.com/en/tutorials/webaudio/intro/
函数BufferLoader(context,urlList ,回调){
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(){
//异步解码request.response中的音频文件数据
loader.context.decodeAudioData(
request.response,

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

函数(错误){
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);
}

主要代码:

  ///设置音频上下文并开始加载样本
var actx = new AudioContext(),
blst,
bLoader = new BufferLoader(
actx,[
'fun-baby.wav','chirp.wav','downychirp.wav'],
完成),
isReady = false;

///开始加载样本
bLoader.load();

功能完成(bl){
blst = bl; ///缓冲列表
isReady = true; ///启用键
$('#status')。html('Ready!'); ///更新statusw
}

///这设置了链接所以我们可以播放音频
函数播放(i){
var src = actx.createBufferSource (); ///准备样本
src.buffer = blst [i]; ///从loader中设置缓冲区
src.connect(actx.destination); ///连接到扬声器
src.start(0); ///现在播放样本
}

///检查键
$(窗口).bind(keydown,函数(键){
if( !isReady)return;
switch(parseInt(key.which,10)){
case 65:
play(0);
return;
case 83:
play(1);
return;
case 68:
play(2);
return;
}
})

注意:使用外部样品时,必须确保它们可以交叉使用原始或加载将失败(我使用我的DropBox使样本加载小提琴)。


I am trying to play sounds with a .keydown() event in jQuery. I would like the sounds to play quickly, but there seems to be a lag time when I perform the keydown event faster than about 3 times per second.

Here is a jsFiddle of my sample code: http://jsfiddle.net/pfrater/FRudg/3/

I am using the audio html tags for the sound and playing:

<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>

and here's my 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;
     }
  });
});

Does anyone know of a way to get rid of this lag? Also, the actual files that I'll be playing are mpegs. The ones above are just an example.

Thanks for any help,
Paul

解决方案

You won't be able to do this with the audio element. This is because the cost setting up and filling the buffers will take too much time.

The good news though is that you can do it using the Web Audio API instead.

I made you an example based on this code from HTML5 rocks (which you should check out for more details) and your original fiddle.

Currently this API is supported in Chrome, Firefox, Safari and Opera will be able to use this:

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);
}

The main code:

/// 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;
    }    
})

NOTE: When using external samples you must make sure they can be used cross-origin or else loading will fail (I used my DropBox to enable the samples to be loaded with fiddle).

这篇关于摆脱使用jQuery播放声音时的延迟时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆