web-dev-qa-db-ja.com

HTML5ビデオでフレーム番号を取得する

ビデオの各フレーム番号をキャプチャしようとしていますが、それを達成する方法がないようです。そこで、ビデオのフレーム番号に合わせて自分の時計を始めましたが、フレーム番号が一致することはなく、ビデオが進むにつれて差が大きくなり続けます。

私のゴミ箱を見てください。 http://jsbin.com/dopuvo/4/edit

Adobe After Effectのビデオの各フレームにフレーム番号を追加したので、違いをより正確に知ることができます。ビデオは29.97fpsで実行されており、requestAnimationFrameも同じ速度で数を増やすように設定されていますが、この違いがどこから来ているのかわかりません。

一致する場合と一致しない場合があります。オフラインでもやってみましたが、同じ結果になりました。どんな助けでも。

14
SayedTaqui

私はこれのためにgithubで何かを見つけました。 https://github.com/allensarkisyan/VideoFrame

私はそれをこのフィドルに実装しました: https://jsfiddle.net/k0y8tp2v/

var currentFrame = $('#currentFrame');
var video = VideoFrame({
    id : 'video',
    frameRate: 25,
    callback : function(frame) {
        currentFrame.html(frame);
    }
});

$('#play-pause').click(function(){
    if(video.video.paused){
        video.video.play();
        video.listen('frame');
        $(this).html('Pause');
    }else{
        video.video.pause();
        video.stopListen();
        $(this).html('Play');
    }
});

EDIT:フィドルを新しいビデオに更新して、再び機能するようにしました。

EDIT:指摘されているように、ビデオは25 fpsなので、更新し、そこにいる間にjQueryへの依存を取り除きました。
jQuery以外のバージョン:
https://jsfiddle.net/k0y8tp2v/1/

var currentFrame = document.getElementById('currentFrame');
var video = VideoFrame({
    id : 'video',
    frameRate: 25,
    callback : function(frame) {
        currentFrame.innerHTML = frame ;
    }
});

document.getElementById('play-pause').addEventListener('click', function(e){
    if(video.video.paused){
        video.video.play();
        video.listen('frame');
        e.target.innerHTML = 'Pause';
    }else{
        video.video.pause();
        video.stopListen();
        e.target.innerHTML = 'Play';
    }
});
14
2pha

問題は、setTimeoutが実際には予測できないため、関数を実行するたびに正確に1つの新しいフレームが表示されているかどうかを確認できないことです。フレーム表示を更新するたびにビデオのcurrentTimeを確認し、それにフレームレートを掛ける必要があります。

実用的な例を次に示します。 http://jsbin.com/xarekice/1/edit 1フレームずれていますが、最初に「000000」とマークされたフレームが2つあるようです。

あなたが知っておくべきかもしれないビデオ要素についてのいくつかの事柄:

  1. 発見したようですが、フレームレートを決定する信頼できる方法はないため、他の場所で発見してハードコーディングする必要があります。 ビデオメトリック で起こっているいくつかの興味深いことがありますが、それらは非標準であり、広くサポートされておらず、私の経験では、実際のフレームレートを決定するのに完全に効果がありません。

  2. currentTimeは、必ずしも画面の内容を正確に表すとは限りません。特にシークする場合は、少し先に進むことがあります(そのため、私のJSBinでは、シーク中にフレームを更新しません)。

currentTimeは、実際のビデオ描画とは別のスレッドで更新されると思います。そのため、それは、それ自体の時計のように機能し続けます。それはビデオがなりたい場所であり、必ずしもそれがどこにあるかではありません。そのため、近づくことはできますが、フレーム計算の結果を丸める必要があり、たまに1フレームずれることがあります。

7
brianchirls