Программно определить формат видеофайла?

Хорошо, я получил основы видеоформатов - есть несколько форматов контейнеров, а затем у вас есть основные форматы видео / аудио. Я хотел бы написать веб-приложение, которое определяет, какой видео / аудиокодек использует файл.

Как лучше всего программно определить видеокодек? Было бы лучше использовать стандартную библиотеку через системные вызовы и анализировать ее вывод? (например, ffmpeg, перекодирование и т. д.?)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
6
0
6 317
6

Ответы 6

mplayer -identify сделает свое дело. Просто вызов ffmpeg для файла также будет работать - он автоматически распечатает в начале набор информации о входном файле, независимо от того, что вы говорите ffmpeg на самом деле.

Конечно, если вы хотите сделать это из своей программы без вызова exec к внешней программе, вы можете просто включить библиотеки avcodec и напрямую запустить собственную процедуру идентификации.

Хотя вы можете реализовать собственное обнаружение, оно наверняка будет хуже существующих подпрограмм, учитывая огромное количество форматов, поддерживаемых libav *. И изобретать велосипед было бы довольно глупо.

Команда Linux «file» также может помочь, но объем распечатываемых ею данных зависит от формата видео. Например, в AVI он предоставляет всевозможные данные о разрешении, FOURCC, fps и т. д., В то время как для файла MKV он просто говорит «данные Matroska», ничего не говоря вам о внутреннем устройстве или даже об используемых видео и аудио форматах.

Вам нужно начать дальше. Вам необходимо знать формат контейнера и то, как он определяет кодек.

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

Затем выясните, какие контейнеры будет поддерживать ваша программа, и добавьте функции, необходимые для анализа метаданных, хранящихся в контейнере, которые будут включать кодеки.

-Адам

Вам действительно нужна большая база данных двоичных идентифицирующих маркеров, которые нужно искать в начале файла. К счастью, ваш вопрос помечен как «Linux», и такая база данных уже существует; file (1) сделает всю работу за вас.

Этого недостаточно. файл немного сообщает вам, но не кодеки, которые запрашивает OP.

Stu Thompson 21.09.2008 10:08

Для этого я использовал FFMPEG в сценарии Perl.

$info = `ffmpeg -i $path$file 2>&1 /dev/null`;
@fields = split(/\n/, $info);

И просто узнайте, какие элементы в @fields вам нужно извлечь.

Я бы рекомендовал использовать ffprobe и принудительно использовать формат вывода в json. Было бы намного проще разобрать. Самый простой пример:

$meta = json_decode(join(' ', `ffprobe -v quiet -print_format json -show_format -show_streams /path/to/file 2>&1`));

Имейте в виду, что в случае поврежденного файла вы получите null как результат и предупреждение в зависимости от ваших настроек отчетов об ошибках. Полный пример с правильной обработкой ошибок:

$file = '/path/to/file';
$cmd = 'ffprobe -v quiet -print_format json -show_format -show_streams ' . escapeshellarg($file).' 2>&1';

exec($cmd, $output, $code);
if ($code != 0) {
    throw new ErrorException("ffprobe returned non-zero code", $code, $output);
}

$joinedOutput = join(' ', $output);
$parsedOutput = json_decode($joinedOutput);
if (null === $parsedOutput) {
    throw new ErrorException("Unable to parse ffprobe output", $code, $output);
}

//here we can use $parsedOutput as simple stdClass

Вы можете использовать mediainfo:

sudo apt-get install mediainfo

Если вы просто хотите получить видео / аудиокодек, вы можете сделать следующее:

$videoCodec = `mediainfo --Inform = "Video;%Format%" $filename`;
$audioCodec = `mediainfo --Inform = "Audio;%Format%" $filename`;

Если вы хотите получить больше информации, вы можете проанализировать вывод XML, возвращаемый mediainfo. Вот пример функции:

function getCodecInfo($inputFile)
{
    $cmdLine = 'mediainfo --Output=XML ' . escapeshellarg($inputFile);

    exec($cmdLine, $output, $retcode);
    if ($retcode != 0)
        return null;

    try
    {
        $xml = new SimpleXMLElement(join("\n",$output));
        $videoCodec = $xml->xpath('//track[@type = "Video"]/Format');
        $audioCodec = $xml->xpath('//track[@type = "Audio"]/Format');
    }
    catch(Exception $e)
    {
        return null;
    }

    if (empty($videoCodec[0]) || empty($audioCodec[0]))
        return null;

    return array(
        'videoCodec' => (string)$videoCodec[0],
        'audioCodec' => (string)$audioCodec[0],
    );
}

Другие вопросы по теме