#!/usr/bin/perl
use File::Find;
use Video::Info;

$exclude = "";
while (@ARGV>=1 && substr($ARGV[0],0,1) eq '-') {
    $opt = shift;
    if($opt eq '-e' || $opt eq '--exclude') { $exclude=shift; }
    else { print "unknown option $opt\n"; exit 1; }
}

if (@ARGV<1) {
    print qq~Usage: avinfo.pl 'FORMAT_STRING' [FILES | DIRECTORIES]
Print FORMAT_STRING with substitutions:

%c - Number of audio channels
%a - Name of the audio codec
%R - Bits/second dedicated to an audio stream
%N - Number of audio streams
%Q - Sampling rate of the audio stream, in Hertz
%q - Sampling rate of the audio stream, in KHz

%v - Name of the video codec
%j - Number of video frames 
%r - Average bits/second dedicated to a video stream
%n - Number of video streams (0 for audio only)
%F - How many frames/second are displayed
%w - Video frame width, in pixels
%h - Video frame height, in pixels

%f - Filename without path
%p - Path to the file used to create the video object 
%s - File size in bytes
%H - File size in human readable form (Kb/Mb/Gb/Tb)
%t - File type (RIFF, ASF, MPEG, etc)
%S - File length in seconds 
%M - File length in minutes + seconds, in the format MM:SS 

%T - Title of the file content. Not the filename
%A - Author of the file content
%C - Copyright, if any
%D - Freetext description of the content
%P - Number of data packets in the file

%% - A single percent sign

Escape Sequences: \\n - new line, \\r - carriage return, \\t - tab, \\\\ - single backslash

~;
    exit;
}

my $format = shift;
my @FILES = @ARGV ? @ARGV : (".");
my $video;

sub info {
    my ($width, $char, $file, $path) = @_;

    if($char eq "%") { return "%"; }
    elsif($char eq 'a') { $val=$video->acodec(); }
    elsif($char eq 'c') { $val=$video->achans(); }
    elsif($char eq 'R') { $val=$video->arate(); }
    elsif($char eq 'N') { $val=$video->astreams(); }
    elsif($char eq 'Q') { $val=$video->afrequency(); }
    elsif($char eq 'q') { $val=$video->afrequency()/1024; }

    elsif($char eq 'v') { $val=$video->vcodec(); }
    elsif($char eq 'r') { $val=$video->vrate(); }
    elsif($char eq 'n') { $val=$video->vstreams(); }
    elsif($char eq 'F') { $val=$video->fps(); }
    elsif($char eq 'w') { $val=$video->width(); }
    elsif($char eq 'h') { $val=$video->height(); }

    elsif($char eq 'T') { $val=$video->title(); }
    elsif($char eq 'A') { $val=$video->author(); }
    elsif($char eq 'C') { $val=$video->copyright(); }
    elsif($char eq 'D') { $val=$video->description(); }
    elsif($char eq 'P') { $val=$video->packets(); }

    elsif($char eq 't') { $val=$video->type(); }
    elsif($char eq 'S') { $val=$video->duration(); }
    elsif($char eq 'M') {
	# BUGFIX: $video->MMSS() undefined for MPEG
	if($video->type() eq 'MPEG') { 
	    my $s = int($video->duration());
	    $val=sprintf("%02u:%02u", int($s/60), $s%60);
	} else { $val=$video->MMSS(); }
    }
    elsif($char eq 'f') { $val=$file; }
#	$path =~ /^(.*\/)?([^\/]*)$/;
#	$val = $2;
    elsif($char eq 'p') { $val=$path; }
    elsif($char eq 's') { $val= -s $file; }
    elsif($char eq 'H') { 
	$sz = -s $file; 
	#%H - file size in human readable form (Kb/Mb/Gb)
	$val = ($sz<1024 ? $sz :
	    ($sz<1048576 ? int(($sz+1023)/1024) ."Kb" : 
	    ($sz<1073741824 ? int(($sz+1048575)/1048576) ."Mb" :
		int(($sz+1073741823)/1073741824) ."Gb" )));
    }

    if($width =~ /^([0-9\.])*$/ ) {
	    return sprintf("%${width}s", $val);
    } else {
	    return $val;
    }
}


# substitute escape sequences
my %subs = (n=>"\n",r=>"\r",t=>"\t","\\"=>"\\");
$format =~ s/\\([nrt\\])/$subs{$1}/eg;

# find files
find (sub {
	# BTW: what's about mov,rm,ogm support?
	if( -f && /\.(avi|asf|mpe?g)$/ && (!$exclude || $File::Find::name !~ /$exclude/) ) { 
	    if($format =~ /%[0-9]*[caRNQqvjrnFwhtSMTACD]/) {
		#initialize video info
		$video = Video::Info->new(-file => $_);
	    }
	    $res = $format;
	    $res =~ s/%([0-9\.]*)([%a-zA-Z])/info($1,$2,$_,$File::Find::name)/eg;
	    print $res;
	}
    }, @FILES);


syntax highlighted by Code2HTML, v. 0.9.1