Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Get size and bitrate of video with perl and ffmpeg

by lancer (Beadle)
on Jul 30, 2012 at 19:14 UTC ( #984494=CUFP: print w/replies, xml ) Need Help??

Here is one way to get the size and bitrate of a video using ffmpeg:

getvideosize.pl
#!/usr/bin/perl -w use strict; use warnings; my $file = $ARGV[0]; die "usage: arg1 must be a video file\n" unless $file; sub trim { my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } open (FILE, "ffmpeg -i \"$file\" 2>&1 |"); while (<FILE>) { my $line = $_; next unless ($line =~ m/^\s+Stream #.+?: Video/); my @pieces = split (',', $line); my @vsize = split (' ', trim ($pieces[2])); my @vbits = split (' ', trim ($pieces[3])); my $video_size = trim (shift @vsize); my $video_bits = trim (shift @vbits); print "$video_size $video_bits\n"; last; }


Example usage:
./getvideosize.pl http://bennugd-vlc.googlecode.com/files/sintel_trail +er-480p.mp4

Output: 854x480 537

Replies are listed 'Best First'.
Re: Get size and bitrate of video with perl and ffmpeg
by zengargoyle (Deacon) on Jul 30, 2012 at 20:35 UTC
    Check out using ffprobe instead of ffmpeg. It doesn't try to play the video and you can pick an output format that suits you.
    $ ffprobe -i http://bennugd-vlc.googlecode.com/files/sintel_trailer-48 +0p.mp4 -show_streams -print_format csv 2>/dev/null stream,0,h264,H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10,video,1/48,avc +1,0x31637661,854,480,2,N/A,N/A,yuv420p,30,N/A,1,4,N/A,24/1,24/1,1/24, +0.000000,52.208333,537875,1253,N/A,N/A,1970-01-01 00:00:00,und,VideoH +andler stream,1,aac,Advanced Audio Coding,audio,1/48000,mp4a,0x6134706d,s16,4 +8000,2,0,N/A,0/0,0/0,1/48000,0.000000,51.946667,126694,2435,N/A,N/A,1 +970-01-01 00:00:00,und,SoundHandler
Re: Get size and bitrate of video with perl and ffmpeg
by jwkrahn (Monsignor) on Jul 31, 2012 at 04:06 UTC
    while (<FILE>) { my $line = $_;

    That is usually written as:

    while (my $line = <FILE>) {


    my @vsize = split (' ', trim ($pieces[2])); my @vbits = split (' ', trim ($pieces[3])); my $video_size = trim (shift @vsize); my $video_bits = trim (shift @vbits);

    split ' ' removes ALL whitespace so the use of the trim function is superfluous.

    my ( $video_size ) = split ' ', $pieces[ 2 ]; my ( $video_bits ) = split ' ', $pieces[ 3 ]
Re: Get size and bitrate of video with perl and ffmpeg
by aitap (Deacon) on Aug 04, 2012 at 14:38 UTC
    Also, running subprocesseses using list context is safer in case of some special characters in the file name: open(FILE,"-|",qw(ffprobe -i),$file).
    Unfortunately, it will be necessary to use some special tricks to hide the STDERR, for example, (untested; written for ugly avconv output)
    use IPC::Run 'run'; my $file = $ARGV[0] || die; my $line; run [ qw(ffprobe -show_streams),$file ], '&>', \$line || die "$!\n"; my ($width,$height); for (split /\n/,$line) { $width = $1 if /width=(\d+)/; $height = $1 if /height=(\d+)/; # ... $_ eq '[/STREAM]' && defined $width && defined $height && print "$ +{width}x${height}\n" && last }
    Sorry if my advice was wrong.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://984494]
Front-paged by Corion
help
Chatterbox?
[SuicideJunkie]: Just wait; someday soon, you'll be given a DB with unicode emojis in the column names.
[Corion]: marinersk: Well, I have done select statements like select sum(foo) as "Total Amount", ..., but to have a table like that makes me shudder
[Corion]: SuicideJunkie: :-D
[marinersk]: SuicideJunkie LOL
[choroba]: Woohoo! Fixed a test that hasn't run for 3 years.
[marinersk]: Corion Yes, sometimes whitespace in column headers is acceptable, but I still consider it be less than desireable if that query might get revectored for an ETL-esque process...
[marinersk]: choroba++
[choroba]: it's a long running test, so it's normally skipped unless an env var is set
[choroba]: nobody has been bothered to set the variable in the last 3 years
[marinersk]: sub newtest{my $expected_result = &target('foo'); my $actual_result = &target('foo'); if ($actual_result eq $expected_result) { &tdd_success(); } else { &tdd_fail(); } } # Test works after three years!

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (10)
As of 2017-05-25 15:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?