6

好的,我了解了视频格式的基础知识——有一些容器格式,然后你就有了核心视频/音频格式。我想编写一个基于 Web 的应用程序来确定文件使用的视频/音频编解码器。

如何最好地以编程方式确定视频编解码器?最好通过系统调用使用标准库并解析其输出?(例如ffmpeg、转码等?)

4

6 回答 6

8

mplayer -identify会成功的。只需调用ffmpeg一个文件也可以——它会在开始时自动打印一组关于输入文件的信息,而不管你告诉 ffmpeg 实际做什么。

当然,如果您想从您的程序中执行此操作,而不需要对外部程序进行 exec 调用,您可以只包含 avcodec 库并直接运行它自己的识别例程。

虽然您可以实现自己的检测,但考虑到 libav* 支持的绝对大量的格式,它肯定不如现有的例程。这将是一个相当愚蠢的重新发明轮子的案例。

Linux 的“文件”命令也可以做到这一点,但它打印出的数据量取决于视频格式。例如,在 AVI 上,它会提供有关分辨率、FOURCC、fps 等的各种数据,而对于 MKV 文件,它只会显示“Matroska 数据”,而不会告诉您内部结构,甚至是使用的视频和音频格式。

于 2008-09-20T23:58:49.723 回答
5

我在 perl 脚本中使用了 FFMPEG 来实现这一点。

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

只需找出您需要提取的 @fields 中的哪些项目。

于 2008-09-23T08:43:51.957 回答
2

您需要进一步开始。您需要了解容器格式以及它如何指定编解码器。

所以我会从一个识别容器格式的程序开始(不仅仅是从扩展,进入标题并确定真正的容器)。

然后找出您的程序将支持哪些容器,并放入解析存储在容器中的元数据所需的函数,其中将包括编解码器。

-亚当

于 2008-09-20T23:59:29.660 回答
1

您确实需要一个大型二进制识别标记数据库,以便在文件开头附近查找。幸运的是,您的问题被标记为“Linux”,并且那里已经存在这样的数据库;file(1) 将为您完成这项工作。

于 2008-09-21T00:01:32.180 回答
0

我建议使用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
于 2013-10-01T07:57:24.240 回答
0

您可以使用媒体信息:

sudo apt-get install mediainfo

如果您只想获取视频/音频编解码器,可以执行以下操作:

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

如果您想捕获更多信息,可以解析 mediainfo 返回的 XML 输出。这是示例函数:

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],
    );
}
于 2014-05-14T14:19:42.467 回答