Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 以编程方式确定视频文件格式?_Php_Linux_Video_File Io_Binaryfiles - Fatal编程技术网

Php 以编程方式确定视频文件格式?

Php 以编程方式确定视频文件格式?,php,linux,video,file-io,binaryfiles,Php,Linux,Video,File Io,Binaryfiles,好的,我了解了视频格式的基本知识-有一些容器格式,然后是核心视频/音频格式。我想编写一个基于web的应用程序,用于确定文件使用的视频/音频编解码器 如何最好地以编程方式确定视频编解码器?最好通过系统调用使用标准库并解析其输出吗?(例如ffmpeg、转码等?mplayer-identify会起作用。只要对文件调用ffmpeg,它也会工作——它会在开始时自动打印关于输入文件的一组信息,而不管您告诉ffmpeg实际做什么 当然,如果您想从程序中执行,而不需要对外部程序进行exec调用,那么您可以只包含

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


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

mplayer-identify会起作用。只要对文件调用
ffmpeg
,它也会工作——它会在开始时自动打印关于输入文件的一组信息,而不管您告诉ffmpeg实际做什么

当然,如果您想从程序中执行,而不需要对外部程序进行exec调用,那么您可以只包含avcodec库,并直接运行自己的identify例程

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


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

您需要从更进一步的开始。您需要知道容器格式以及它如何指定编解码器

因此,我将从一个识别容器格式的程序开始(不仅仅从扩展名开始,进入标题并确定真正的容器)

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


-Adam

您确实希望在文件开头附近查找一个包含二进制识别标记的大型数据库。幸运的是,你的问题被标记为“Linux”,这样的数据库已经存在了;文件(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要求的那样使用编解码器。