FFmpeg может делать практически все, что вы хотите, но вы правы, что разобрать формат практически невозможно.На самом деле быстрее, если вы работаете в UNIX-системе и используете операционную систему и функции FFmpeg для анализа, а не для того, чтобы PHP пытался понять вывод.Я разработал следующую команду оболочки несколько месяцев назад для аналогичной цели.
fulltime=`ffmpeg -i MOVIE.AVI 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//`;hour=`echo $fulltime | cut -d ':' -f 1`;minute=`echo $fulltime | cut -d ':' -f 2`;second=`echo $fulltime | cut -d ':' -f 3 | cut -d '.' -f 1`;echo `expr 3600 \* $hour + 60 \* $minute + $second`
Канал (|
) указывает UNIX передавать выходные данные предыдущей команды в качестве входных данных для следующей команды.Точка с запятой (;
) указывает UNIX начать новую команду.Оболочка UNIX также позволяет создавать переменные на лету.Чтобы создать переменную, просто скажите var=value
.Чтобы вызвать эту переменную, вы должны использовать знак доллара, такой как $var
.
Моя команда, по сути, получает вывод ffmpeg -i MOVIE.AVI 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//
и сохраняет его как fulltime
.Эта команда далее разбита:
ffmpeg -i MOVIE.AVI 2>&1
означает отображение информации (-i
) для MOVIE.AVI.2>&1
Я полагаю, перенаправил вывод на канал, а не на экран (сделал это навсегда назад, поэтому я не уверен в этом)
grep 'Duration'
будет принимать вход (который был выходиз ffmpeg -i MOVIE.AVI 2>&1
), найдите слово 'Duration' и выведите только строку, содержащую это слово.
cut -d ' ' -f 4
будет принимать входные данные (выходные данные предыдущего оператора), разбивая их на каждомпробел (' '
) и выведите только четвертое из них.Это связано с тем, что выходные данные FFmpeg выглядят примерно так:
MOVIE.AVI
video encoder, yada yada
audio encoder, yada yada
bitrates and stuff
Duration: hh:mm:ss fulltime: 00:30:00.1
Другими словами, четвертый «раздел» строки, содержащей «Duration», - это фактическая продолжительность ... В часах, минутах и секундах(с 1 десятичным знаком).
sed s/,//
означает заменить ',' ничем.Вероятно, для этого была веская причина.
После этого я создал три переменные hour
, minute
и second
:
hour=`echo $fulltime | cut -d ':' -f 1`;
minute=`echo $fulltime | cut -d ':' -f 2`;
second=`echo $fulltime | cut -d ':' -f 3 | cut -d '.' -f 1`;
Обратите внимание, что я устанавливаючас до выхода echo $fulltime | cut -d ':' -f 1
.Захватив первую часть, если бы я разделил время на каждом двоеточии (:
)
Я делаю то же самое с минутами, затем я делаю то же самое только с секундами, и в конце отрезаю любое десятичное число.Это десятичное число необходимо удалить, если вы работаете в оболочке, поскольку команда expr
(которую я использовал для вычисления секунд из часов, минут и секунд) выполняет только целочисленную математику.Если вы хотите сохранить десятичное число в течение продолжительности, в этот момент вам придется вернуть часы, минуты и секунды в PHP и выполнить там разбор.Это будет проще всего сделать, заменив вышеприведенное на:
echo $fulltime
. Это вернет PHP строку, такую как «00: 30: 00.1», после того, как вы вызвали shell_exec()
, что вы можете легкопарсинг с помощью explode(':',$string)
.
Чтобы продолжить получать секунды непосредственно из оболочки:
После получения часов, минут и секунд появилась волшебная строка:
echo `expr 3600 \* $hour + 60 \* $minute + $second`
Команда expr
говорит выполнить математическое выражение.К сожалению, это довольно глупо.Во-первых, необходимо экранировать специальные символы (*
- это подстановочный знак в UNIX, поэтому вы должны использовать \*
для умножения).Далее он выполняет только целочисленную математику.Как видите, было довольно легко умножить часы на 3600, минуты на 60 и сложить их все вместе.
Вывод всей этой массивной команды будет просто одним числом.Количество секунд, которое длится видео.Это должно работать для всех видеоформатов.
Имейте в виду, это всего лишь продолжительность.Что касается видеокодера и аудиокодера, вы бы хотели использовать аналогичные методы, за исключением математики в конце.Общее решение будет выглядеть следующим образом:
ffmpeg -i MOVIE.AVI 2>&1 | grep 'Something unique to the line you want' | cut -d ' ' -f <the "section" you want>
Вывод этого можно либо продолжить анализировать в оболочке (как я делал выше со временем), либо он может быть передан в PHP.