好吧,我得到了视频格式的基础 - 有一些容器格式,然后你有核心的视频/音频格式。我想编写一个基于Web的应用程序来确定文件正在使用的视频/音频编解码器。以编程方式确定视频文件格式?
如何以编程方式确定视频编解码器的最佳方式?最好是通过系统调用使用标准库并解析其输出? (例如ffmpeg,转码等?)
好吧,我得到了视频格式的基础 - 有一些容器格式,然后你有核心的视频/音频格式。我想编写一个基于Web的应用程序来确定文件正在使用的视频/音频编解码器。以编程方式确定视频文件格式?
如何以编程方式确定视频编解码器的最佳方式?最好是通过系统调用使用标准库并解析其输出? (例如ffmpeg,转码等?)
mplayer -identify
会做伎俩。只需在文件上调用ffmpeg
也将起作用 - 它将在输入文件的开始处自动打印一组信息,无论您是在告诉ffmpeg实际执行什么操作。
当然,如果你想从你的程序没有exec调用外部程序来完成它,你可以直接包含avcodec库并运行它自己的识别程序。
尽管您可以实现自己的检测,但由于libav *支持绝对数量的格式,它肯定会劣于现有的例程。这将是一个相当愚蠢的重新发明车轮的情况。
Linux的“文件”命令也可以做到这一点,但打印出的数据量取决于视频格式。例如,在AVI上,它提供了关于分辨率,FOURCC,fps等各种数据,而对于MKV文件,它只是说“Matroska数据”,不会告诉你关于内部,甚至是所用的视频和音频格式。
您需要开始更进一步。您需要知道容器格式以及它如何指定编解码器。
因此,我将从一个程序开始,该程序标识容器格式(不仅仅来自扩展,进入标题并确定真正的容器)。
然后找出你的程序将支持哪些容器,并且放入解析存储在容器中的元数据所需的函数,其中将包括编解码器。
- 亚当
你真的想二进制识别标识的一个大的数据库,以查找文件的开头附近。幸运的是,你的问题被标记为“Linux”,并且这样一个dabase已经存在那里;文件(1)将为你完成这项工作。
我已经在perl脚本中使用了FFMPEG来实现这一点。
$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`;
如果您想捕获更多信息,可以解析由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],
);
}
这不够远。文件告诉你一点,但不是OP所要求的编解码器。 – 2008-09-21 06:08:03