2

私はピアノアプリケーションを開発しています。ノート名とその再生時間のjson配列があります。

var data= [{"duration":300,"value":"2C"},{"duration":400,"value":"2D"},{"duration":420,"value":"2E"},{"duration":600,"value":"2F"},{"duration":400,"value":"2G"}];

2C ノートを 300 マイクロ秒、2D ノートを 400 マイクロ秒、2E を 420 マイクロ秒という順序で再生する必要があります。つまり、前のノートの完了後に次のノートを再生します。

すべてのノートに .ogg 形式のオーディオ ファイルがあり、すべてのノートの長さが同じ 1018.776 マイクロ秒です。

上記の json データのメモを再生するために、javascript の setTimeout 関数を試しました。

$.each( data, function( key, value ) {
    setTimeout(function(){
        var audioElement = document.createElement('audio');
        audioElement.setAttribute('src', './audio/'+value.value+'.ogg');
        audioElement.play();

    }, value.duration*key); 
});

しかし、これは機能していません。主な問題は持続時間です。console.log(value.value) を使用すると、結果は 2C、2D、2E、2G、2F でした。ここでは、2F と 2G の順序が正しくありません。では、これらの音符をそれぞれの長さで正しい順序で再生するにはどうすればよいでしょうか?

4

4 に答える 4

4

ループの代わりに再帰関数を使用する必要があります。

function playNotes(notes) {
    var i = 0;
    playNextNote();
    function playNextNote() {
        if (i < notes.length) {
            var value = notes[i];
            var audioElement = document.createElement('audio');
            audioElement.setAttribute('src', './audio/'+value.value+'.ogg');
            audioElement.play();
            i++;
            setTimeout(playNextNote, value.duration);
        }
    }
}

このようにして、現在のノートが完了するまで、次のノートの再生が開始されません。

于 2013-10-16T14:05:21.870 に答える
0

このコードでは、いくつかの仮定があります。最初に確認したのは、サウンド ファイルが即座に読み込まれるということです。おそらくあなたが抱えている問題は、ループがこれまでの遅延を追跡していないことです.つまり、基本的には setTimeout({play}, 400) を呼び出し、 setTimeout({play}, 500) の直後に呼び出すので、それらは終了します500ms から 800ms までオーバーラップします。

あなたが探していると思うものを私が書く方法は次のようなものです:

var audio = $.map(data, function(key,val) {return $("<audio>",{src:val.value})});
audio.each(function(indx, $ele) {
      if(indx !=0){
          audio[indx-1].on("ended", function(){$ele.get().play()});//play next sound when previous one finishes playing
      }
});
于 2013-10-16T14:20:34.410 に答える