How does one go about getting specific pieces of information, like the \'duration\' from the output of ffmpeg -i /var/thismovie.avi
?
I need frame heigh
Based on ffprobe
solution suggested by @blahdiblah and inspired by another question answer: https://github.com/paulofreitas/php-ffprobe
Note: requires ffmpeg 0.9+, supports ALL ffmpeg supported file types
// Example 1
$info = new ffprobe($filename);
var_dump($info->format->format_long_name); // e.g. string(10) "AVI format"
var_dump($info->streams[0]->duration); // e.g. string(11) "5674.674675"
// Example 2 (prettified)
$info = new ffprobe($filename, true);
var_dump($info->format->format_long_name); // e.g. string(10) "AVI format"
var_dump($info->streams[0]->duration); // e.g. string(14) "1:34:34.674675"
class ffprobe_ext extends ffprobe
{
public function __construct($filename)
{
parent::__construct($filename);
}
public function getVideoStream()
{
foreach ($this->streams as $stream) {
if ($stream->codec_type == 'video') {
return $stream;
}
}
}
public function getVideoInfo()
{
$stream = $this->getVideoStream();
$info = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
$info->duration = (float) $stream->duration;
$info->frame_height = (int) $stream->height;
$info->frame_width = (int) $stream->width;
eval("\$frame_rate = {$stream->r_frame_rate};");
$info->frame_rate = (float) $frame_rate;
return $info;
}
}
$ffprobe = new ffprobe_ext($filename);
$info = $ffprobe->getVideoInfo();
var_dump($info->duration); // e.g. float(5674.674675)
Welcome to further improvements! :-)
Use ffprobe
instead.
ffprobe is the tool packaged with FFmpeg for exactly the sort've purpose you're after: extracting video info. It outputs a variety of easily parsed formats and will be far easier than parsing the incidental information that FFmpeg outputs.
For example:
$ ffprobe -show_format -loglevel quiet mptestsrc.mp4
[FORMAT]
filename=mptestsrc.mp4
nb_streams=1
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime/MPEG-4/Motion JPEG 2000 format
start_time=0.000000
duration=12.040000
size=237687
bit_rate=157931
TAG:major_brand=isom
TAG:minor_version=512
TAG:compatible_brands=isomiso2avc1mp41
TAG:encoder=Lavf54.20.100
[/FORMAT]
$output = `ffmpeg -i /var/thismovie.avi`; //note that back quote is like exec
preg_match('/Duration: (.*?),.*?Video:.*?0x.*?([0-9]+)x([[0-9]+).*?([0-9]+) fps/i'
,$output , $result);
output of $result array should be like this:
Array
(
[0] => Duration: 00:00:10.76, start: 0.000000, bitrate: 5180 kb/s Stream #0:0: Video: h264 (High) (H264 / 0x34363248), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 25 fps
[1] => 00:00:10.76
[2] => 1280
[3] => 720
[4] => 25
)
UPDATE
The actual output is multi line, so please update the pattern into
/Duration: (.*?),.*?([0-9]+)x([0-9]+) \[.*?([0-9]+) fps/is
You can use ffprobe which has an option to output JSON format.
Take a look at this example:
ffprobe -v quiet -print_format json -show_format Ramp\ -\ Apathy.mp3
Which produces the follwing output:
{
"format": {
"filename": "Ramp - Apathy.mp3",
"nb_streams": 2,
"format_name": "mp3",
"format_long_name": "MP2/3 (MPEG audio layer 2/3)",
"start_time": "0.000000",
"duration": "203.638856",
"size": "4072777",
"bit_rate": "159999",
"tags": {
"title": "Apathy",
"artist": "Ramp",
"album": "Evolution Devolution Revolution",
"date": "1999",
"genre": "Metal"
}
}
}
I'm using ffprobe version 1.0.7.