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

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

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

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

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

2 ответа

Решение

Я нашел что-то на GitHub для этого. https://github.com/allensarkisyan/VideoFrame

Я реализовал это в этой скрипке: http://jsfiddle.net/Ck6Zq/184/

var currentFrame = $('#currentFrame');
var video = VideoFrame({
    id : 'video',
    frameRate: 29.97,
    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');
    }
});

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

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

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

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

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

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

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

Начиная с M83, Chromium имеет API requestVideoFrameCallback (), который может решить вашу проблему. Вы можете использовать mediaTime для получения согласованной метки времени, как описано в этой проблеме Github. Оттуда вы можете попробовать что-то вроде этого:

var frameCounter = (time, metadata) => {
   let count = metadata.mediaTime * frameRate;
   console.log("Got frame: " + Math.round(count));

   // Capture code here.

   video.requestVideoFrameCallback(frameCounter);
}

video.requestVideoFrameCallback(frameCounter)

Это будет срабатывать только на новых кадрах, но вы можете иногда пропустить один (который вы можете обнаружить по разрыву в metadata.presentedFramesкол). Вы также можете немного опоздать в захвате кадра (обычно 16 мс или один вызовwindow.requestAnimationFrame() позже, чем когда доступен кадр видео).

Если вы заинтересованы в высокоуровневом обзоре API, вот сообщение в блоге или вы можете взглянуть на официальный github API.

Другие вопросы по тегам