| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #!/usr/bin/perl
- use warnings;
- use strict;
- # Prototypes
- sub run_mplayer(@);
- # Includes and paramters
- use IPC::Open3;
- use File::Basename;
- my @exec_args = ('mplayer', '-identify', '-vo', 'null', '-ao', 'null', '-frames', '1');
- my $MAX_AUDIO = 10;
- # Command line parameters
- my ($infile, $MODE) = @ARGV;
- if (!-f $infile) {
- die('Usage: ' . basename($0) . "input_file [mode]\n");
- }
- if ($MODE) {
- $MODE = uc($MODE);
- }
- # Run mplayer
- my @args = @exec_args;
- push(@args, $infile);
- my $data = run_mplayer(@args);
- # Sanity check
- if (!defined($data->{'VIDEO_FORMAT'}) || length($data->{'VIDEO_FORMAT'}) < 1) {
- die(basename($0) . ': Unable to find video streams in: ' . $infile . "\n");
- }
- # Duplicate the audio data for track 0 with the appropriate index
- foreach my $key (keys(%{$data})) {
- if ($key =~ /AUDIO/) {
- $data->{ $key . '_0' } = $data->{$key};
- }
- }
- # Run mplayer again for each audio track
- if (!defined($data->{'AUDIO_ID'})) {
- $data->{'AUDIO_ID'} = -1;
- }
- for (my $i = 0 ; $i <= $data->{'AUDIO_ID'} && $i < $MAX_AUDIO ; $i++) {
- my @args = @exec_args;
- push(@args, '-aid', $i, $infile);
- my $audio = run_mplayer(@args);
- foreach my $key (keys(%{$audio})) {
- if ($key =~ /AUDIO/) {
- $data->{ $key . '_' . $i } = $audio->{$key};
- }
- }
- }
- # Output
- if (defined($MODE) && length($MODE) > 0) {
- if (defined($data->{$MODE})) {
- print $data->{$MODE} . "\n";
- } else {
- die(basename($0) . ': No such data: ' . $MODE . "\n");
- }
- } else {
- foreach my $key (keys(%{$data})) {
- print $key . '=' . $data->{$key} . "\n";
- }
- }
- # Cleanup
- exit(0);
- # Run mplayer and return a hash of all lines that start with ID_
- # Timeout after 30 seconds or 100 non-matching lines
- sub run_mplayer(@) {
- my %data = ();
- eval {
- my $child_in = '';
- my $child_out = '';
- my $pid = open3($child_in, $child_out, $child_out, @_);
- # Timeout after 30 seconds
- local $SIG{ALRM} = sub { kill(9, $pid); die("Timeout\n"); };
- alarm(30);
- # Read the output
- my $errcnt = 0;
- while (<$child_out>) {
- if (/^ID_(.+)\=(.*)/) {
- $data{$1} = $2;
- } else {
- $errcnt++;
- }
- if ($errcnt > 100) {
- kill(9, $pid);
- die("Too many errors\n");
- }
- }
- # Cleanup and cancel the alarm
- waitpid($pid, 0);
- close($child_out);
- alarm(0);
- };
- if ($@ ne "") {
- print(STDERR $@);
- }
- return \%data;
- }
|