1

HTML5 オーディオがサウンドを生成し始める正確な瞬間をキャッチする必要があります。

見た目ほど単純ではないことがわかりました。

onplayまたはonplayingイベントが発生したときにオーディオの再生が開始されることを期待できますか? とんでもない。少なくとも WebKit ファミリでは、この時点で正確に発火するブラウザ イベントはないようです。Chrome、Safari、Firefox では onplayonplayingイベントは単にoncanplay!

その事実を証明する簡単なテストを用意しました。これは、すべてのイベントが既に起動された後、ある程度の時間 (100 ミリ秒から 400 ミリ秒以上) 後にオーディオが実際に再生を開始することを示しています。

コンソールログを見ると、耳と耳でこれに気付くことができます。ログではcurrentTime、15msごとに出力します。実際のオーディオの状態を正しく反映しているようで、イベントが発生した後に 10 ~ 40 のポーリングを変更し始めます。playそのため、が起動された後もオーディオはフリーズしたままです。

テスト コードは次のようになります。

    var audioEl = new Audio('http://www.w3schools.com/tags/horse.ogg');

    audioEl.oncanplay = function () {
        console.log('oncanplay');

        audioEl.currentTime = 1;    

        console.log('ready state is: ' + audioEl.readyState);
        audioEl.play();
    }


    audioEl.oncanplay = function () {
        console.log('oncanplay again');
    }

    audioEl.onplay = function() {
        console.log('onplay -----------------');
    }

    audioEl.onplaying = function() {
        console.log('onplaying ----------------');
    }

    setInterval(function () {
        console.log(audioEl.currentTime);
    }, 15);

Jsフィドル

ビジュアル アニメーションと正確に同期させるには、オーディオの再生が開始される正確な瞬間を知る必要があります。

もちろん、クイックポーリングを使用して、この瞬間を大まかに見つけることができます。これは、リアルタイム アプリ、特にモバイルでのパフォーマンスにとって非常に悪いものです。

誰かがこれに対するより良い解決策を知っているかどうか尋ねています。2014 年になっても、HTML オーディオの実装はまだ不十分なようです :(

4

2 に答える 2

3

@justin が言うように、playingイベントをリッスンして、メディアが実際に再生を開始する (多かれ少なかれ) 正確な瞬間を得ることができます。readyStateしかし、ええ、メディアイベントや一般的には、最新の Chrome でさえ、いくつかのむらのあるサポートを見てきました。

setIntervalこれらのイベントが機能するかどうかにかかわらず、アニメーション (またはそれ以外のこと) には使用しないことをお勧めします。代わりに、requestAnimationFrameより頻繁に起動し、ブラウザおよびビデオ カードの再描画と同期する を使用してください。また、すべてのフレームの値をポーリングしてcurrentTime、アニメーションのどこにいるべきかを計算できます。パフォーマンスは問題になりません。あなたのケースはまさにそのために設計されたものrequestAnimationFrameです。

function update() {
    var currentTime = audioEl.currentTime;
    // update your animation here
    requestAnimationFrame(update);
}

update();

あなたがそれをしている間、5 に設定しないでcurrentTimeください。ブラウザが長さを知るのに十分なビデオ ファイルをロードする前に設定しようとすると、エラーがスローされます。ただし、いつでも呼び出すことができます。待つ必要はありません。readyState > 0loadedmetadatacurrentTimeplay()canplay

于 2014-05-30T02:08:00.433 に答える
-1

代わりに canplaythrough を試してください。いずれにせよ、オーディオを最後まで再生できることを確認することをお勧めします..

audioEl.oncanplay = function () {
      console.log('ready state is: ' + audioEl.readyState);
      audioEl.play();
}
于 2014-05-30T00:11:09.577 に答える