movInfo.pl 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. # Prototypes
  5. sub run_mplayer(@);
  6. # Includes and paramters
  7. use IPC::Open3;
  8. use File::Basename;
  9. my @exec_args = ('mplayer', '-identify', '-vo', 'null', '-ao', 'null', '-frames', '1');
  10. my $MAX_AUDIO = 10;
  11. # Command line parameters
  12. my ($infile, $MODE) = @ARGV;
  13. if (!-f $infile) {
  14. die('Usage: ' . basename($0) . "input_file [mode]\n");
  15. }
  16. if ($MODE) {
  17. $MODE = uc($MODE);
  18. }
  19. # Run mplayer
  20. my @args = @exec_args;
  21. push(@args, $infile);
  22. my $data = run_mplayer(@args);
  23. # Sanity check
  24. if (!defined($data->{'VIDEO_FORMAT'}) || length($data->{'VIDEO_FORMAT'}) < 1) {
  25. die(basename($0) . ': Unable to find video streams in: ' . $infile . "\n");
  26. }
  27. # Duplicate the audio data for track 0 with the appropriate index
  28. foreach my $key (keys(%{$data})) {
  29. if ($key =~ /AUDIO/) {
  30. $data->{ $key . '_0' } = $data->{$key};
  31. }
  32. }
  33. # Run mplayer again for each audio track
  34. if (!defined($data->{'AUDIO_ID'})) {
  35. $data->{'AUDIO_ID'} = -1;
  36. }
  37. for (my $i = 0 ; $i <= $data->{'AUDIO_ID'} && $i < $MAX_AUDIO ; $i++) {
  38. my @args = @exec_args;
  39. push(@args, '-aid', $i, $infile);
  40. my $audio = run_mplayer(@args);
  41. foreach my $key (keys(%{$audio})) {
  42. if ($key =~ /AUDIO/) {
  43. $data->{ $key . '_' . $i } = $audio->{$key};
  44. }
  45. }
  46. }
  47. # Output
  48. if (defined($MODE) && length($MODE) > 0) {
  49. if (defined($data->{$MODE})) {
  50. print $data->{$MODE} . "\n";
  51. } else {
  52. die(basename($0) . ': No such data: ' . $MODE . "\n");
  53. }
  54. } else {
  55. foreach my $key (keys(%{$data})) {
  56. print $key . '=' . $data->{$key} . "\n";
  57. }
  58. }
  59. # Cleanup
  60. exit(0);
  61. # Run mplayer and return a hash of all lines that start with ID_
  62. # Timeout after 30 seconds or 100 non-matching lines
  63. sub run_mplayer(@) {
  64. my %data = ();
  65. eval {
  66. my $child_in = '';
  67. my $child_out = '';
  68. my $pid = open3($child_in, $child_out, $child_out, @_);
  69. # Timeout after 30 seconds
  70. local $SIG{ALRM} = sub { kill(9, $pid); die("Timeout\n"); };
  71. alarm(30);
  72. # Read the output
  73. my $errcnt = 0;
  74. while (<$child_out>) {
  75. if (/^ID_(.+)\=(.*)/) {
  76. $data{$1} = $2;
  77. } else {
  78. $errcnt++;
  79. }
  80. if ($errcnt > 100) {
  81. kill(9, $pid);
  82. die("Too many errors\n");
  83. }
  84. }
  85. # Cleanup and cancel the alarm
  86. waitpid($pid, 0);
  87. close($child_out);
  88. alarm(0);
  89. };
  90. if ($@ ne "") {
  91. print(STDERR $@);
  92. }
  93. return \%data;
  94. }