undToEng.pl 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use IPC::System::Simple qw(capturex $EXITVAL EXIT_ANY);
  5. my $INFO_BIN = 'mkvinfo';
  6. my $LABEL_BIN = 'mkvpropedit';
  7. # Sanity check
  8. if (scalar(@ARGV) < 1 || !-r $ARGV[0]) {
  9. print STDERR 'Usage: ' . $0 . " input_file\n";
  10. exit(1);
  11. }
  12. if (!($ARGV[0] =~ /\.mkv$/i)) {
  13. print STDERR 'Error: This utility can only be used with MKV-format files: ' . $ARGV[0] . "\n";
  14. exit(2);
  15. }
  16. # Analyze the file
  17. my @output = capturex($INFO_BIN, $ARGV[0]);
  18. # Parse the output
  19. my $inTracks = 0;
  20. my $track = undef();
  21. my @tracks = ();
  22. foreach my $str (@output) {
  23. # End track
  24. if (defined($track) && $str =~ /^\| ?\+\s+/) {
  25. push(@tracks, $track);
  26. $track = undef();
  27. }
  28. # End tracks section
  29. if ($inTracks && $str =~ /^\|\+\s+/) {
  30. $inTracks = 0;
  31. }
  32. # Start tracks section
  33. if (!$inTracks && $str =~ /^\|\+\s+Segment tracks/) {
  34. $inTracks = 1;
  35. next;
  36. }
  37. # Skip lines not in the tracks section
  38. if (!$inTracks) {
  39. next;
  40. }
  41. # Start track
  42. if (!defined($track) && $str =~ /^\| \+\s+A track/) {
  43. my %tmp = ();
  44. $track = \%tmp;
  45. next;
  46. }
  47. # Skip lines not in a track section
  48. if (!defined($track)) {
  49. next;
  50. }
  51. # Parse
  52. if ($str =~ /^\| \+\s+Track number\: \d+ \(track ID for mkvmerge \& mkvextract\: (\d+)\)/) {
  53. $track->{'id'} = $1;
  54. } elsif ($str =~ /\| \+\s+Track UID\:\s+(\d+)/) {
  55. $track->{'uid'} = $1;
  56. } elsif ($str =~ /\| \+\s+Track type\:\s+(\w+)/) {
  57. $track->{'type'} = $1;
  58. } elsif ($str =~ /\| \+\s+Language\:\s+(\w+)/) {
  59. $track->{'lang'} = $1;
  60. } elsif ($str =~ /\| \+\s+Codec ID\:\s+(\w+)/) {
  61. $track->{'codec'} = $1;
  62. } elsif (exists($track->{'type'}) && $track->{'type'} eq 'audio') {
  63. if ($str =~ /^\| \+\s+Sampling frequency\:\s+(\d+)/) {
  64. $track->{'samples'} = $1;
  65. } elsif ($str =~ /^\| \+\s+Channels\:\s+(\d+)/) {
  66. $track->{'channels'} = $1;
  67. }
  68. } elsif (exists($track->{'type'}) && $track->{'type'} eq 'video') {
  69. if ($str =~ /^\| \+\s+Pixel width\:\s+(\d+)/) {
  70. $track->{'width_raw'} = $1;
  71. } elsif ($str =~ /^\| \+\s+Pixel height\:\s+(\d+)/) {
  72. $track->{'height_raw'} = $1;
  73. } elsif ($str =~ /^\| \+\s+Display width\:\s+(\d+)/) {
  74. $track->{'width'} = $1;
  75. } elsif ($str =~ /^\| \+\s+Display height\:\s+(\d+)/) {
  76. $track->{'height'} = $1;
  77. }
  78. }
  79. }
  80. # We only care about valid audio tracks with langauges
  81. my @audio = ();
  82. foreach my $track (@tracks) {
  83. if (!exists($track->{'uid'})) {
  84. next;
  85. }
  86. if (!exists($track->{'lang'})) {
  87. next;
  88. }
  89. if (!exists($track->{'type'})) {
  90. next;
  91. }
  92. if ($track->{'type'} ne 'audio') {
  93. next;
  94. }
  95. push(@audio, $track);
  96. }
  97. # Release master tracks data
  98. undef(@tracks);
  99. # Determine if we have any English audio tracks
  100. my $noEng = 1;
  101. foreach my $track (@audio) {
  102. if ($track->{'lang'} eq 'eng') {
  103. $noEng = 0;
  104. last;
  105. }
  106. }
  107. # Nothing to do if there are already English tracks
  108. if (!$noEng) {
  109. exit(0);
  110. }
  111. # Re-label any 'und' tracks to 'eng' (i.e. don't overwrite valid langauge labels)
  112. my @relabel = ();
  113. foreach my $track (@audio) {
  114. if ($track->{'lang'} eq 'und') {
  115. push(@relabel, $track->{'uid'});
  116. }
  117. }
  118. # Nothing to do if there aren't any tracks to re-label
  119. if (scalar(@relabel) < 1) {
  120. exit(0);
  121. }
  122. # Execute
  123. my @args = ($ARGV[0]);
  124. foreach my $uid (@relabel) {
  125. push(@args, '--edit', 'track:=' . $uid, '--set', 'language=eng');
  126. }
  127. my $err = capturex(EXIT_ANY, $LABEL_BIN, @args);
  128. if ($EXITVAL != 0) {
  129. print STDERR $0 . ': Error while processing ' . $ARGV[0] . "\n\n" . $err;
  130. exit(4);
  131. }
  132. # Debug
  133. #print $LABEL_BIN . " '" . join("' '", @args) . "'\n";
  134. # Cleanup
  135. exit(0);