好的,我得到了视频格式的基础知识 - 有一些容器格式,然后你有核心视频/音频格式。我想编写一个基于Web的应用程序来确定文件正在使用的视频/音频编解码器。
如何以编程方式确定视频编解码器?是否最好通过系统调用使用标准库并解析其输出? (例如ffmpeg,转码等?)
答案 0 :(得分:7)
mplayer -identify
会做到这一点。只需在文件上调用ffmpeg
也可以 - 它会在开始时自动打印一组关于输入文件的信息,无论你告诉ffmpeg实际做什么。
当然,如果你想在没有exec调用外部程序的情况下从你的程序中执行它,你可以直接包含avcodec库并运行它自己的识别例程。
虽然你可以实现自己的检测,但鉴于libav *支持绝对庞大的格式,它肯定会不如现有的例程。重新发明轮子将是一个相当愚蠢的案例。
Linux的“文件”命令也可以解决问题,但打印出来的数据量取决于视频格式。例如,在AVI上,它提供了有关分辨率,FOURCC,fps等的各种数据,而对于MKV文件,它只是说“Matroska数据”,不会告诉您内部,甚至是所使用的视频和音频格式。< / p>
答案 1 :(得分:4)
我在perl脚本中使用了FFMPEG来实现这一点。
$info = `ffmpeg -i $path$file 2>&1 /dev/null`;
@fields = split(/\n/, $info);
然后找出你需要提取的@fields中的哪些项目。
答案 2 :(得分:1)
你需要从头开始。您需要知道容器格式以及它如何指定编解码器。
所以我从一个识别容器格式的程序开始(不只是从扩展名,进入标题并确定真正的容器)。
然后找出程序将支持哪些容器,并输入解析存储在容器中的元数据所需的函数,其中包括编解码器。
- 亚当
答案 3 :(得分:1)
您真的想要一个二进制识别标记的大型数据库,以便在文件开头附近查找。幸运的是,你的问题被标记为“Linux”,而且这样的数据库已经存在; file(1)将为您完成工作。
答案 4 :(得分: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
答案 5 :(得分:0)
您可以使用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],
);
}