Подтвердить что ты не робот

Получить номера кадров в HTML5 Video

Я пытаюсь захватить каждый номер кадра видео, но похоже, что его невозможно достичь. Поэтому я начал свои собственные часы, чтобы соответствовать номерам кадров видео, но они никогда не совпадают, и разница продолжает увеличиваться по мере продвижения видео.

Пожалуйста, взгляните на мой мусор. http://jsbin.com/dopuvo/4/edit

Я добавил номер кадра в каждый кадр видео из Adobe After Effect, поэтому у меня есть более точная информация о различии. Видео работает со скоростью 29,97 кадров в секунду, а requestAnimationFrame также увеличивает число с той же скоростью, однако я не уверен, откуда эта разница.

Иногда они совпадают, а иногда и нет. Я также пробовал делать это в автономном режиме, но получаю те же результаты. Любая помощь.

4b9b3361

Ответ 1

Я нашел что-то на 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');
    }
});

РЕДАКТИРОВАТЬ: обновил скрипку для нового видео, чтобы он снова работал.

РЕДАКТИРОВАТЬ: Как указывалось, видео является 25fps, поэтому я обновил его, и пока я там был удален зависимость от 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';
    }
});

Ответ 2

Проблема в том, что setTimeout не является предсказуемым, поэтому вы не можете быть уверены, что каждый раз при запуске вашей функции отображается ровно один новый кадр. Вам нужно проверять currentTime время видео каждый раз, когда вы обновляете отображение кадров, и умножать его на частоту кадров.

Вот рабочий пример: http://jsbin.com/xarekice/1/edit Он отключен на один кадр, но, похоже, у вас может быть два кадра в начале, помеченных как "000000".

Несколько вещей об элементе видео, о которых вы, возможно, захотите знать:

  1. Как вы, похоже, обнаружили, нет надежного способа определить частоту кадров, поэтому вам нужно обнаружить ее в другом месте и жестко закодировать. Есть несколько интересных вещей, которые происходят с метриками видео, но они нестандартны, широко не поддерживаются и, по моему опыту, совершенно неэффективны при определении фактической частоты кадров.

  2. currentTime не всегда точно отражает то, что на экране. Иногда это немного впереди, особенно при поиске (вот почему в моем JSBin я не обновляю фрейм, пока вы ищете).

Я полагаю, что currentTime обновляется в отдельном потоке от реального видео, поэтому он вроде работает как собственные часы, которые просто продолжают работать. Это где видео хочет быть, не обязательно, где это. Таким образом, вы можете приблизиться, но вам нужно округлить результаты расчета фрейма, и время от времени вы можете быть выключены на один фрейм.