Added a workaround for a bug in mkv tool's ability to handle 1080i (interlaced HD...
[videoscripts/.git] / make_mkv
index 042e38eaca0eed66ede829b9c8f4a05f8ddaf0eb..04556e523fca95ddf1c500130cb2fdd4c31f7a49 100755 (executable)
--- a/make_mkv
+++ b/make_mkv
@@ -106,8 +106,44 @@ print "$chapter_file_contents\n";
 print "-> Creating the MKV video file '$opt_o'\n";
 
 my $cmd = "$mkvmerge --title \"$opt_t\" $output_file_options -o \"$opt_o\"";
+
+# Make our input file command line options for all the videos
 my $video_count = 0;
+my @video_tmp_files;
 foreach my $video (sort{$videos{$a} <=> $videos{$b}} keys %videos) {
+    # Detect if the input file is interlaced or not.
+    # There is a bug in mkvmerge 5.0.1 and earlier where if the video content is 1080i, it doesn't mux it properly, and it stutters.
+    # The quick solution to this issue is to run the interlaced video file through ffmpeg and tell it to copy the video/audio streams to a mkv container.
+    # We will then merge this temporarily created mkv container into the final mkv container instead of the original interlaced video.
+    # http://ubuntuforums.org/showthread.php?t=1627194
+    # http://forum.doom9.org/showthread.php?t=155732&page=31
+    my $interlaced = system('ffmpeg -i "$video" 2>&1 | grep -q "frame rate differs"');
+    if($interlaced != 0) {
+       my $video_mkv = $video;
+       my $video_ext = $video;
+       $video_ext =~ s/.*\.(\S+)$/$1/;
+       print "   Detected interlaced video content: $video\n";
+       if($video_ext !~ /mkv/i) {
+           $video_mkv =~ s/\.[^.]*$//; $video_mkv .= ".mkv";
+           print "   Re-muxing the interlaced video content as an mkv file: $video_mkv\n";
+           my $make_mkv_cmd = "ffmpeg -i \"$video\" -scodec copy -acodec copy -vcodec copy -f matroska \"$video_mkv\" > /dev/null 2>&1";
+           if(! defined $opt_s) { 
+               my $errno = system("$make_mkv_cmd");
+               $errno = $errno >> 8;
+               if($errno > 1) {
+                   unlink "$video_mkv";
+                   die "-E- ffmpeg encountered some errors with exit code $errno\n";
+               }
+           }
+           # Push the name of our intermediate video file onto a list of files to delete on exit
+           push(@video_tmp_files, "$video_mkv");
+           # Update the name of our video file to equal the name of our new intermediate video file name
+           $video = $video_mkv;
+       }
+    } else { 
+       print "   Detected progressive video content: $video\n";
+    }
+    # Create our intput file command line options for this video
     if($video_count == 0) {
        $cmd .= " $input_file_options \"$video\"";
     } else {
@@ -115,7 +151,9 @@ foreach my $video (sort{$videos{$a} <=> $videos{$b}} keys %videos) {
     }
     $video_count++;
 }
-print "$cmd\n";
+
+# Execute our command line
+print "\n$cmd\n";
 if(! defined $opt_s) { 
     my $errno = system("$cmd");
     $errno = $errno >> 8;
@@ -128,5 +166,10 @@ if(! defined $opt_s) {
 # Remove the temporary file used for the chapter generation
 if(-e "$tmpfile") { unlink "$tmpfile"; }
 
+# Remove any temporary video files created during the merge process
+foreach my $video (@video_tmp_files) {
+    if(-e "$video") { unlink "$video"; }
+}
+
 ####################################################################################################