Самый быстрый способ извлечь определенный кадр из видео (PHP/ffmpeg/что угодно)


У меня есть веб-страница, на которой (помимо прочего) необходимо извлечь определенный кадр из загруженного пользователем видео. Пользователь ищет определенную часть файла .mp4 в плеере, затем нажимает кнопку, и вызов ajax запускается в php-скрипт, который берет файл.mp4 и точное время из видео и использует его для извлечения кадра "миниатюры".

Мое текущее решение заключается в использовании команды php exec:

exec("ffmpeg -i $videoPath -ss $timeOffset -vframes 1 $jpgOutputPath");

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

В идеале я не хочу устанавливать ничего, что требует реального "процесса установки"... т.Е. Удаление исполняемого файла в папку с моим веб-приложением - это нормально, но я бы предпочел не запускать установщик. Кроме того, решение должно быть способно работать на mac, linux и Windows (хотя linux является главным приоритетом).

Что я могу сделать, чтобы ускорить этот процесс?

Спасибо.

Author: DanM, 2013-08-30

1 answers

Конечно, вы могли бы написать код на C/C++ и связать его с -lav*, в основном создав упрощенную версию ffmpeg только для извлечения кадров, и, возможно, даже сделать это как расширение php (также я бы не стал запускать его от имени того же пользователя, не говоря уже о том же процессе). Но результат вряд ли будет быстрее, потому что вы избежите только некоторых накладных расходов на разветвление и настройку, но ваша вероятная проблема на самом деле заключается в декодировании, которое все равно будет таким же.

Вместо этого вам следует сначала изучить использование ffmpeg в режиме быстрого поиска (или быстром/точном гибридном режиме). Их вики-состояния о быстром поиске:

Параметр -ss необходимо указать перед -i:

Ffmpeg -ss 00:03:00 - я Преступный мир.Пробуждение.avi -кадры: v 1 out1.jpg

В этом примере будет создан один кадр изображения (out1.jpg ) где-то примерно на третьей минуте от начала фильма. Входные данные будут проанализированы с использованием ключевых кадров, что очень быстро. Недостатком является что он также завершит поиск на некотором ключевом кадре, не обязательно расположенном в указанное время (00:03:00), поэтому поиск будет не таким точным , как ожидалось.

Быстрый поиск менее точен, но чертовски намного быстрее, так как ffmpeg на самом деле не нужно будет декодировать (большую часть) фильма во время поиска, в то время как быстрый/точный гибридный режим является хорошим компромиссом. Прочитайте вики-страницу для всех доступных опций.

Редактировать 14/06/10:

По состоянию на FFmpeg 2.1, при перекодировании с помощью ffmpeg (т. Е. без копирования потока), -ss теперь является точным, даже если используется в качестве опции ввода. Предыдущее поведение можно восстановить с помощью параметра -noaccurate_seek. (источник)

Таким образом, с 2.1+ "гибридный" поиск больше не должен требоваться для получения точных результатов, когда дело доходит до перекодирования (и сохранение в .jpeg является перекодированием). Достаточно выполнить обычный быстрый поиск (-ss ... -i ...) вместо медленного поиска (-i ... -ss ...).

 69
Author: nmaier, 2014-06-10 16:36:10