2

jQuery で .keydown() イベントを使用してサウンドを再生しようとしています。音を速く再生したいのですが、キーダウン イベントを 1 秒あたり約 3 回より速く実行すると、ラグ タイムが発生するようです。

これが私のサンプル コードの jsFiddle です: http://jsfiddle.net/pfrater/FRudg/3/

サウンドと再生に audio 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 です。上記はほんの一例です。

助けてくれてありがとう、
ポール

4

1 に答える 1

1

audio 要素でこれを行うことはできません。これは、コストの設定とバッファの充填に時間がかかりすぎるためです。

良いニュースは、代わりにWeb Audio APIを使用してそれを行うことができるということです。

HTML5 rocks のこのコード(詳細についてはチェックアウトする必要があります) と元のフィドルに基づいて例を作成しました。

現在、この API はChrome、Firefox、Safari でサポートされており、Operaはこれを使用できます。

フィドルのデモ

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 を使用しました)。

于 2013-11-05T04:46:56.600 に答える