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

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

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

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

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

В идеале я не хочу устанавливать что-либо, что требует реального «процесса установки» … т. Е. Удаление исполняемого файла в папку с моим веб-приложением в порядке, но я бы предпочел не запускать установщик. Кроме того, решение должно иметь возможность запускать на Mac, Linux и Windows (хотя Linux – главный приоритет).

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

Благодарю.

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

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

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

ffmpeg -ss 00:03:00 -i Underworld.Awakening.avi -frames: v 1 out1.jpg

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

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

Редактировать 14.06.10 :

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

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