Запрос аудио/видео файла для получения информации


Мне нужна функция 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 предоставит информацию о видео (или аудиофайлах) в довольно сложном для анализа формате. Однако я предполагаю, что нечто подобное возможно.

Author: TRiG, 2010-10-14

4 answers

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), найдет слово "Длительность" и выведет только строку, содержащую это слово.

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. Хватаю первую порцию, если бы мне пришлось делить время на каждую двоеточие (:)

Я делаю то же самое с минутами, затем я делаю то же самое с секундами, только я отрубаю любую десятичную дробь в конце. Это десятичное число должно быть удалено, если вы работаете в оболочке, так как команда 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.

 9
Author: stevendesu, 2010-10-15 16:09:06

Я бы взглянул на 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>
 2
Author: Henrik Lied, 2010-10-18 10:33:24

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

 1
Author: UltimateBrent, 2010-10-14 22:48:21

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

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

Чирс

 0
Author: Radu, 2011-10-07 14:53:43