Мне нужна функция PHP, которая получает путь к файлу и возвращает массив информации об этом. Файл PHP может вызывать FFmpeg.
Возвращенные данные должны быть чем-то вроде
Array( [mime] => video/ogg [container] => Ogg => Theora => Vorbis [duration] => 20.3 // in seconds ) Array( [mime] => audio/ogg [container] => Ogg => => FLAC [duration] => 3 ) Array( [mime] => image/gif [container] => GIF => Animated GIF => [duration] => 2 ) Array( [mime] => video/webm [container] => WebM => VP8 => Vorbis [duration] => 900.7 ) false // not a media file
Я никогда не работал с FFmpeg или с shell_exec()
функции shell_exec()
PHP, но кажется, что FFmpeg предоставит информацию о видео (или аудиофайлах) в довольно жестком формате. Я предполагаю, что что-то подобное возможно.
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/,//
ffmpeg -i MOVIE.AVI 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//
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
Другими словами, четвертая «секция» строки, содержащая «Продолжительность», является фактической продолжительностью … В часах, минутах и секундах (с 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
echo $fulltime | cut -d ':' -f 1
. Захватив первую часть, если бы я разделил время в каждом двоеточии (:)
Я делаю то же самое с минутами, затем я делаю то же самое с секундами, только я отрубаю любую цифру в конце. Это десятичное значение следует удалить, если вы работаете в оболочке, так как команда expr
(которую я использовал для вычисления секунд с часов, минут и секунд) выполняет только целую математику. Если вы хотите сохранить десятичное значение для продолжительности, вы должны в этот момент вернуть часы, минуты и секунды в PHP и провести синтаксический анализ. Это было бы легче всего сделать, заменив выше:
echo $fulltime
Это вернет строку, такую как «00: 30: 00.1», в PHP после 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.
Я посмотрю на Mediainfo . Если вы перейдете в –Output = XML, он даст вам что-то вроде этого:
<?xml version="1.0" encoding="UTF-8"?> <Mediainfo> <File> <track type="General"> <Complete_name>Movie.webm</Complete_name> <Format>Matroska</Format> <File_size>215 MiB</File_size> <Duration>28mn 39s</Duration> <Overall_bit_rate>1 049 Kbps</Overall_bit_rate> <Movie_name>Safari</Movie_name> <Writing_application>Lavf52.78.0</Writing_application> <Writing_library>Lavf52.78.0</Writing_library> </track> <track type="Video"> <ID>1</ID> <Format>V_VP8</Format> <Codec_ID>V_VP8</Codec_ID> <Duration>28mn 39s</Duration> <Bit_rate>529 Kbps</Bit_rate> <Width>768 pixels</Width> <Height>432 pixels</Height> <Display_aspect_ratio>16:9</Display_aspect_ratio> <Frame_rate>25.000 fps</Frame_rate> <Bits__Pixel_Frame_>0.064</Bits__Pixel_Frame_> <Stream_size>108 MiB (50%)</Stream_size> <Language>Norwegian</Language> </track> <track type="Audio"> <ID>2</ID> <Format>Vorbis</Format> <Format_settings__Floor>1</Format_settings__Floor> <Codec_ID>A_VORBIS</Codec_ID> <Duration>28mn 39s</Duration> <Bit_rate_mode>Constant</Bit_rate_mode> <Bit_rate>500 Kbps</Bit_rate> <Channel_s_>2 channels</Channel_s_> <Sampling_rate>48.0 KHz</Sampling_rate> <Resolution>16 bits</Resolution> <Stream_size>102 MiB (48%)</Stream_size> <Writing_library>libVorbis 20090709 (UTC 2009-07-09)</Writing_library> <Language>Norwegian</Language> </track> </File> </Mediainfo>
Мог бы попробовать этого парня. Всегда хорошо, когда вы можете использовать библиотеку: http://www.phpclasses.org/browse/file/1582.html