Запрос аудио / видео файла для информации - PullRequest
5 голосов
/ 14 октября 2010

Мне нужна функция PHP, которая получает путь к файлу и возвращает массив информации о нем. Файл PHP может вызывать FFmpeg.

Возвращаемые данные должны выглядеть примерно так:

Array(
    [mime]          => video/ogg
    [container]     => Ogg
    [video]         => Theora
    [audio]         => Vorbis
    [duration]      => 20.3 // in seconds
)

Array(
    [mime]          => audio/ogg
    [container]     => Ogg
    [video]         =>
    [audio]         => FLAC
    [duration]      => 3
)

Array(
    [mime]          => image/gif
    [container]     => GIF
    [video]         => Animated GIF
    [audio]         =>
    [duration]      => 2
)

Array(
    [mime]          => video/webm
    [container]     => WebM
    [video]         => VP8
    [audio]         => Vorbis
    [duration]      => 900.7
)

false // not a media file

Я никогда не работал с FFmpeg или с функцией PHP shell_exec(), но кажется, что FFmpeg будет предоставлять информацию о видео (или аудиофайлах) в довольно сложном для анализа формате. Я предполагаю, что что-то подобное возможно, однако.

Ответы [ 4 ]

10 голосов
/ 15 октября 2010

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.

2 голосов
/ 18 октября 2010

Я бы посмотрел на 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>
1 голос
/ 15 октября 2010

Могу попробовать этого парня.Всегда хорошо, когда вы можете использовать библиотеку: http://www.phpclasses.org/browse/file/1582.html

0 голосов
/ 07 октября 2011

Найдено http://getid3.sourceforge.net/ при поиске аудио-парсера php

Надеюсь, это поможет,

Chears

...