Ответ 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.