Как определить предполагаемую частоту кадров в элементе видео html

Есть ли способ определить предполагаемую частоту кадров контента, воспроизводимого в элементе видео html?

Знает ли видео элемент даже предполагаемое количество FPS или кадров, или просто "угадывает" (может быть, 24 кадра в секунду) и играет на угадываемой скорости?

Вот мои неудачные попытки:

  • Найдите свойство FPS или FrameCount на самом элементе видео - Nope!

  • Посмотрите информацию заголовка кросс-видео в формате FPS или FrameCount - Ничего не последовательного!

  • Ищите событие, которое запускается при смене кадра - Nope!

Моя следующая попытка сложнее: пример видео, захватив кадры в элемент холста и подсчитывая кадры, определяя, когда пиксели меняются.

У кого-нибудь есть более простой ответ, прежде чем я сделаю сложную попытку?

Ответ 1

Знание частоты кадров видео не так полезно, как вы думаете.
Браузеры используют некоторые трюки, чтобы сделать совпадение между частотой кадров фильма и частотой обновления экрана, поэтому, если вы посмотрите на свойство currentTime, вы увидите, что фактическая длительность кадра (== currentTime - предыдущий currentTime) не является константой, она меняется от кадра к кадру.

На этом примере видео: http://jsfiddle.net/3qs46n4z/3/ шаблон:
   4-1-5-1:
   4 кадра в 21.3 + 1 кадр при 32 + 5 кадров при 21.3 + 1 кадр при 32.

Поэтому, если вы хотите всегда отображать последний кадр на холсте, избегая при этом переустановки, решение может быть:
- На каждом rAF просмотрите текущее время видео:
    • Одна и та же? → ничего не делать.     • Изменено? → обновить фрейм.

И что бы вы ни делали, сравнивая два currentTime ===, два числа могут быть быстрее, чем сравнение двух imageDatas;-)

Изменить: изучая спецификации, чтобы найти доказательства моего высказывания, я нашел нюанс с этой запиской:

 Which frame in a video stream corresponds to a particular playback position is defined by the video stream format.

(Примечание 4.8.6 на http://www.w3.org/TR/2011/WD-html5-20110113/video.html)

Так что строго говоря, мы можем только сказать, что (текущее время одно и то же) подразумевает (рамки одинаковы).
Могу только утверждать, что обратное истинно = > другое время означает другой кадр.
В приведенном выше примере Chrome пытается сопоставить 24 Гц фильма на моем компьютере с частотой 60 Гц, пытаясь получить 45 Гц (= 60/2 + 60/4), ближайший от 48 = 2 * 24. Для 21 созданных фреймов я не знаю, интерполирует ли он или просто дублирует кадры. Это, безусловно, меняется в зависимости от браузера/устройства (особенно Gpu). Я уверен, что любой недавний рабочий стол или мощный смартфон интерполируют.

В любом случае, учитывая высокую стоимость проверки с помощью imageData, вы бы лучше рисовали дважды, чем проверку.

Rq1: Интересно, в какой степени использование режима Xor + тестирование против 0 32 бит за раз может увеличить время сравнения. (getImageData работает медленно.)

Rq2: Я уверен, что есть хакерский способ использовать скорость воспроизведения для "синхронизации" видео и дисплея и знать, какой кадр является подлинным (== не интерполированным) фреймом. (так что два проходят здесь 1) синхронизация 2) перемотка назад и извлечение кадров).

Rq3: Если ваша цель состоит в том, чтобы получить каждый видеокадр и только видеокадр, браузер не подходит. Как объяснялось выше, браузеры (настольные) интерполируют так, чтобы максимально приблизить частоту кадров отображения. Эти рамки не были в исходном потоке. Есть даже некоторые высококачественные "3D" (2D + time) интерполяционные устройства, где исходные кадры даже не предназначены для отображения (!). С другой стороны, если вы согласны с (интерполированным) потоком вывода, опрос на rAF предоставит все кадры, которые вы видите (вы не можете пропустить фрейм (кроме, очевидно, ваше приложение занято чем-то другим).

Rq4: интерполяция (== no duplicate frames) составляет 99,99%, вероятно, на недавнем/достойном рабочем столе с графическим процессором.

Rq5: обязательно согрейте свои функции (назовите их 100 раз при запуске) и не создавайте мусор, чтобы избежать пауз jit/gc.