Самый быстрый способ извлечь определенный кадр из видео (PHP/ffmpeg/что угодно)
У меня есть веб-страница, на которой (помимо прочего) необходимо извлечь определенный кадр из загруженного пользователем видео. Пользователь ищет определенную часть файла .mp4 в плеере, затем нажимает кнопку, и вызов ajax запускается в php-скрипт, который берет файл.mp4 и точное время из видео и использует его для извлечения кадра "миниатюры".
Мое текущее решение заключается в использовании команды php exec
:
exec("ffmpeg -i $videoPath -ss $timeOffset -vframes 1 $jpgOutputPath");
...который работает просто отлично, за исключением того, что он такой же медленный, как меласса. Я предполагаю, что ffmpeg немного чересчур для этой работы, и я мог бы добиться большего успеха, используя базовые библиотеки или что-то в этом роде... однако я понятия не имею, как это сделать.
В идеале я не хочу устанавливать ничего, что требует реального "процесса установки"... т.Е. Удаление исполняемого файла в папку с моим веб-приложением - это нормально, но я бы предпочел не запускать установщик. Кроме того, решение должно быть способно работать на mac, linux и Windows (хотя linux является главным приоритетом).
Что я могу сделать, чтобы ускорить этот процесс?
Спасибо.
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 ...
).