Задача, и почему это сложнее, чем кажется?
«Дайте мне один кадр в секунду из этого клипа» — одна из самых распространенных видеоработ. Тестировщику QA нужны скриншоты, расположенные на равном расстоянии друг от друга, чтобы прикрепить их к отчету об ошибке. Исследователю нужна выборочная последовательность изображений для использования в инструменте аннотаций. Социальному редактору нужно двадцать кадров-кандидатов из двухминутной версии, не перебирая хронологию вручную.
Сама задача проста. Что делает его неудобным, так это то, что «один кадр в секунду» становится двусмысленным, если присмотреться. Вы имеете в виду один кадр на каждую секунду времени воспроизведения или на каждую? Нет-й кадр закодированного потока? Это разные вещи: клип со скоростью 24 кадра в секунду и клип со скоростью 60 кадров в секунду дают одинаковый результат при первом чтении и совершенно разные значения при втором. Выберите неправильный, и вы либо получите папку с почти дубликатами, либо последовательность слишком разреженная, чтобы быть полезной.
Оба подхода ниже создают идентичные пиксели. Они отличаются тем, как вы выражаете то, что хотите, и тем, как быстро вы обнаруживаете, что выразили это неправильно.
Метод 1: FFmpeg, параметр за параметром
Каноническая команда короткая:
ffmpeg -i input.mp4 -vf fps=1 -q:v 2 frame_%04d.jpg
Каждая деталь имеет значение:
-i input.mp4— исходный файл. FFmpeg читает его один раз, от начала до конца; он не ищет каждую временную метку индивидуально.-vf fps=1— видеофильтр, который выполняет фактическую работу.fps=1означает один выходной кадр в секунду во время воспроизведения, независимо от частоты кадров источника. Использованиеfps=1/5для одного кадра каждые пять секунд илиfps=2для двух в секунду. Это показания времени воспроизведения.-q:v 2— качество JPEG в инвертированной шкале, где 2 — почти без потерь, а 31 — сильное сжатие. Опустите его, и вы получите значение по умолчанию FFmpeg, которое заметно мягче, чем ожидает большинство людей. Если вам нужен вывод без потерь, напишитеframe_%04d.pngвместо этого и полностью отбросьте этот флаг.frame_%04d.jpg— шаблон вывода.%04dдополняет счетчик нулями до четырех цифр:frame_0001.jpg,frame_0002.jpg. Набивка не является косметической; см. проблему нумерации ниже.
Если вам нужно другое чтение — каждый Нет-й закодированный кадр, а не каждый Нет секунды — фильтр меняется:
ffmpeg -i input.mp4 -vf "select=not(mod(n\,10))" -vsync vfr frame_%04d.png
Это сохраняет кадры, в которых индекс кадра n делится на 10 и -vsync vfr не позволяет FFmpeg дублировать кадры, чтобы обеспечить постоянную скорость вывода. Оставьте этот флаг выключенным, и вы получите гораздо больше файлов, чем запрашивали, что является частым и запутанным первым результатом.
Чтобы ограничить работу сегментом, добавьте -ss до -i поэтому FFmpeg выполняет поиск перед декодированием, а не декодированием и удалением:
ffmpeg -ss 00:01:30 -to 00:02:15 -i input.mp4 -vf fps=1 frame_%04d.png
Метод 2: то же задание в браузере
Frame Extractor на этом сайте сопоставляется с одними и теми же двумя показаниями, причем двусмысленность явно выражена в интерфейсе, а не скрыта в строке фильтра.
- Закиньте файл. Он считывается прямо с диска в память браузера — загрузка отсутствует, поэтому источник размером 3 ГБ начинает обрабатываться сразу, а не после передачи.
- Выберите метод извлечения. «Интервал времени» эквивалентен
fps=1/N— вы вводите промежуток в секундах. «Частота кадров (FPS)» эквивалентнаselect/modфильтр — вы вводите Нет чтобы сохранить каждый Нет-й кадр. - Прочитайте подсказку о количестве кадров перед извлечением. Это та часть, которая экономит больше всего времени. Интерфейс показывает, сколько изображений создадут ваши текущие настройки. до все работает, поэтому ошибка в 4000 файлов становится числом, которое вы видите, а не папкой, которую вы обнаруживаете.
- Установить формат и качество. PNG для без потерь, JPG или WebP с ползунком 10–100 %, когда размер имеет значение. Положение ползунка соответствует тому, что
-q:vэлементы управления выражали то, как об этом думает большинство людей. - При необходимости обрежьте диапазон. Ползунок с двумя ручками — это
-ss/-toэквивалент, с метками времени, отображаемыми при перетаскивании. - Экспорт. Кадры отображаются в сетке предварительного просмотра; щелкните один, чтобы сохранить его отдельно, или возьмите весь набор как один ZIP.
Правило Удобный выбор интервала: для говорящей головы или записи экрана, захватывается 1 кадр каждые 2–5 секунд каждое значимое изменение состояния. Для спорта или чего-либо с быстрым движением — 2–5 кадров в секунду. Зарезервируйте «каждый кадр» для подлинного анализа с точностью до кадра: минута со скоростью 60 кадров в секунду — это 3600 изображений и несколько гигабайт PNG.
Три проблемы, которые на самом деле стоят людям времени
1. На выходе — тысячи почти идентичных кадров.
Почти всегда путаница единиц: вы имели в виду "каждый 10-й кадр" и написали fps=10, что означает десять кадров в секунду — на источнике с частотой 30 кадров в секунду, что дает в 3 раза больше изображений, чем наивное ожидание, а не в 3 раза меньше.
Прежде чем что-либо запускать, сделайте арифметику. Режим времени воспроизведения: duration ÷ interval. Индексный режим кадра: duration × source_fps ÷ N. 10-минутный клип со скоростью 30 кадров в секунду на «каждом 10-м кадре» — это 600 × 30 ÷ 10 = 1800 изображений. Если это число вас удивляет, скорректируйте его до начала, а не после. В браузере та же цифра автоматически появляется под полем интервала.
2. В середине длинного видео эвакуация останавливается.
Разные причины с каждой стороны, поэтому и способы устранения тоже различаются.
При использовании FFmpeg зависание обычно связано с диском — тысячи PNG приземляются в одном каталоге, и узким местом становится файловая система, а не декодер. Запишите в новый пустой каталог, выберите JPG, если вам не нужен формат без потерь, и разбейте очень длинные источники на сегменты с -ss/-to.
В браузере ограничение составляет ОЗУ: каждый извлеченный кадр хранится в памяти до тех пор, пока вы не загрузите ZIP. Несколько сотен 4K PNG — это несколько гигабайт и за это можно убить вкладку. Надежный шаблон — работать порциями: используйте ползунок временного диапазона, чтобы выбрать 0:00–2:00, загрузите ZIP, а затем переместите диапазон на 2:00–4:00. Закрытие других вкладок перед выполнением большого задания действительно помогает, а JPG с качеством 85–90 % снижает нагрузку на память в несколько раз без видимой разницы для большинства применений.
3. Нумерация кадров нарушает порядок импорта.
Этот фрагмент после экспорта выглядит нормально. Инструменты, которые сортируют имена файлов в виде текста — и большинство из них — упорядочивают frame_10.png до frame_2.png, поскольку "1" сортируется перед "2" посимвольно. Ваша последовательность воспроизводится в зашифрованном виде, и непонятно почему.
Исправление — это заполнение нулями, достаточно широкое для максимального количества, которое вы когда-либо видели. производить. Вот что %04d предназначено для; use %05d если вы можете превысить 9999 кадров. Инструмент браузера автоматически дополняет данные, что является основной причиной того, что его выходные данные имеют тенденцию передаваться прямо в импортер последовательности изображений без переименования.
Когда FFmpeg по-прежнему является правильным выбором
Множество время. Это не тот случай, когда браузер выигрывает по всем показателям:
- Все, что запланировано или запланировано. Задание cron, этап CI, серверный конвейер — браузер вообще не может участвовать в них.
- Пакеты по многим файлам. Цикл оболочки более 200 клипов тривиален в FFmpeg и утомителен где-либо еще.
- Кодеки, которые браузер не декодирует. ProRes, DNxHD, необработанные форматы камеры, необычные контейнеры. Если браузер не может воспроизвести его, он не сможет извлечь из него данные. FFmpeg обрабатывает практически все.
- Фильтрация во время экстракции. Деинтерлейсинг, масштабирование, преобразование цветового пространства, обрезка, обнаружение смены сцены — все это доступно в виде фильтров за один проход.
- Воспроизводимость. Команда в README точна. «Установить ползунок примерно здесь» — нет.
Инструмент браузера лучше подходит для разовых задач, для всех, кто не хочет устанавливать и поддерживать набор инструментов для случайных задач, когда источник достаточно конфиденциальен, и важна только локальная обработка, и когда вы хотите просмотреть кадры перед экспортом. Это действительно разные ситуации, а не рейтинг.
Краткая справка
| Что вы хотите | FFmpeg | Браузерный инструмент |
|---|---|---|
| Один кадр в секунду | -vf fps=1 |
Time Interval = 1 |
| Один кадр каждые 5 секунд | -vf fps=1/5 |
Time Интервал = 5 |
| Каждый 10-й закодированный кадр | -vf "select=not(mod(n\,10))" -vsync vfr |
Режим частоты кадров, N = 10 |
| Только от 1:30 до 2:15 | -ss 00:01:30 -to 00:02:15 |
Ползунок временного диапазона |
| Вывод без потерь | .png шаблон вывода |
Формат = PNG |
| Файлы меньшего размера | -q:v 5 with .jpg |
JPG + ползунок качества |
| Просмотрите счетчик перед запуском | Рассчитать вручную | Отображается под полем интервала |
| Предварительный просмотр перед сохранением | Откройте папку вывода | Встроенная сетка предварительного просмотра |
| Автоматизация / пакетная обработка | Цикл оболочки, cron, CI | Нет возможно |
| ProRes, DNxHD, raw | Поддерживается | Только то, что декодирует браузер |
Какой бы маршрут вы ни выбрали, на первом месте принимается решение об интервале, а на втором — инструмент. Определите, сколько кадров вам действительно нужно, подтвердите подсчет перед началом, а все остальное - механическое дело.