Programmatically determine the video file format?

Ok, I get the basics of the video format - there are some container formats, and then you have the basic video / audio formats. I would like to write a web application that determines which video / audio codec the file uses.

What is the best way I can programmatically detect a video codec? Would it be better to use the standard library through system calls and analyze its output? (e.g. ffmpeg, transcode, etc.?)

+6
linux php file-io video binaryfiles
source share
6 answers

mplayer -identify will do the trick. Only the ffmpeg call in the file will also work - it will automatically print the set of information at the beginning about the input file, regardless of what you actually say ffmpeg.

Of course, if you want to do this from your program without calling exec in an external program, you can simply include avcodec libraries and run your own authentication procedure directly.

While you can implement your own discovery, it will certainly be worse than existing routines, given the huge number of formats supported by libav *. And that would be a pretty stupid case when reinventing the wheel.

The Linux file command can also do the trick, but the amount of data it prints depends on the video format. For example, in AVI it provides all kinds of resolution data, FOURCC, fps, etc. While for the MKV file it just says โ€œMatroska dataโ€, without reporting anything about the internal components or even the video and audio formats used.

+7
source share

I used FFMPEG in a perl script to achieve this.

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

And just find out what elements in @fields you need to extract.

+4
source share

You need to start down the line. You need to know the format of the container and how it defines the codec.

So, I would start with a program that identifies the format of the container (not just from the extension, go to the header and define the real container).

Then find out in which containers your program will be supported, and enter the functions necessary to analyze the metadata stored in the container, which will include codecs.

-Adam

+1
source share

You really need a large database of binary identification tokens to search near the beginning of the file. Fortunately, your question is marked as "Linux", and such a dabase already exists; file (1) will do the job for you.

+1
source share

I would recommend using ffprobe and force json output format. It would be much easier to parse. The simplest example:

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

Please note that in case of a damaged file, you will get null as a result and warning, depending on the settings for error reporting. Full example with correct error handling:

 $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 
0
source share

You can use mediainfo:

 sudo apt-get install mediainfo 

If you just want to get a video / audio codec, you can do the following:

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

If you want more information, you can parse the XML output returned by mediainfo. Here is an example function:

 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], ); } 
0
source share

All Articles