X-Git-Url: http://git.pippins.net/embedvideo/.git/?a=blobdiff_plain;f=mkv_extract_chapter;h=273484b82c7ed0cb299e39d8f3ff5303e5fe36bd;hb=HEAD;hp=9f5fd81a5949d6a70a0d71e4a712095bbd6a55c2;hpb=3a3bb78c7414ec15e6b557522792069eca34530a;p=videoscripts%2F.git diff --git a/mkv_extract_chapter b/mkv_extract_chapter index 9f5fd81..273484b 100755 --- a/mkv_extract_chapter +++ b/mkv_extract_chapter @@ -3,6 +3,13 @@ # Description: Extract the given chapter(s) from an mkv file into separate video files # Requires: Newer version of ffmpeg to be installed that supports MKV chapters +# Howto compile the latest FFMPEG from src under Linux +# FFMPEG - http://ubuntuforums.org/showthread.php?t=786095 + +# Howto eliminate the non-monotonically increasing dts to muxer error +# Comment out the error message in ffmpeg src tree in libavformat/utils.c +# http://ffmpeg.zeranoe.com/forum/viewtopic.php?f=7&t=49 + # MOV: # major_brand : qt # Video: h264 (avc1 / 0x31637661) @@ -32,12 +39,12 @@ use Getopt::Std; #################################################################################################### # Configuration parameters - CHANGE THESE TO SUITE YOUR NEEDS my $ffmpeg=`which ffmpeg`; chomp($ffmpeg); -my $tmpfile = `tempfile`; chomp($tmpfile); +my $tmpfile = `mktemp`; chomp($tmpfile); #################################################################################################### #################################################################################################### # Command Line Options -getopts("c:i:o:se:"); +getopts("c:i:o:kse:"); if(! -x $ffmpeg) { die "-E- Unable to find required program: ffmpeg\n"; } if(! defined $opt_i) { &usage(); die "-E- Missing required argument input video name: -i \n"; } @@ -57,6 +64,7 @@ sub usage { print " -e Specify the extension that should be used on the output files.\n"; print " This is automatically determined. You only need to specify it if autodetection fails.\n"; print " -s Simulate mode. Don't actually make the video, but tell us what you will do\n"; + print " -k Keep intermediate mkv file created during the extraction/conversion of mp4 clips\n"; print "\n"; return 1; } @@ -65,7 +73,7 @@ sub usage { # SUBROUTINES sub detect_ext { - my ($ffmpeg_info) = @_; + my ($ffmpeg_info, $progressive) = @_; my $h264 = 0; my $h264_high = 0; @@ -83,9 +91,12 @@ sub detect_ext { } } + # Quicktime/MOV if($h264 && $pcm_s16le) { return "mov"; } - if($h264_high && $ac3) { return "mts"; } - if($h264 && $aac) { return "mp4"; } + # MTS + if($h264_high && $ac3) { if(!$progressive) { return "mkv"; } else { return "mp4"; } } + # 3GP/MP4 + if($h264 && $aac) { if(!$progressive) { return "mkv"; } else { return "mp4"; } } return "UNKNOWN"; } @@ -107,11 +118,18 @@ my $all_chapters = 0; if($opt_c =~ /all/) { $all_chapters = 1; } print "-> Extracting the following chapters from $opt_i: @chapters\n"; +my $progressive = system('ffmpeg -i "$opt_i" 2>&1 | grep -q "frame rate differs"'); +if(!$progressive) { + print " Detected interlaced video content\n"; +} else { + print " Detected progressive video content\n"; +} + # Use ffmpeg to extract the list of chapters available to rip # For each chapter specified on the command line, use ffmpeg to extract a video clip from that chapter my @ffmpeg_info = `$ffmpeg -i $opt_i 2>&1`; foreach $line (@ffmpeg_info) { - if($line =~ /Chapter #\d+\.(\d+): start (\S+), end (\S+)/) { + if($line =~ /Chapter #\d+\:(\d+): start (\S+), end (\S+)/) { $chapter = $1; $start = $2; if($start > 0) { $start += 1; } # Add some margin to prevent taking a piece of the previous clip @@ -121,19 +139,36 @@ foreach $line (@ffmpeg_info) { if($all_chapters || &export_chapter(\@chapters,$chapter)) { $ext = "UNKNOWN"; if(defined $opt_e) { $ext = $opt_e; } - else { $ext = &detect_ext(\@ffmpeg_info); } + else { $ext = &detect_ext(\@ffmpeg_info, $progressive); } if($ext =~ /UNKNOWN/) { die "-E- Unable to determine the file type/extension to use for the output videos. Specify it with the -e option.\n"; } $dstfile = $opt_o . ".c" . sprintf("%03d",$chapter) . "." . $ext; - print "-> Exporting $chapter to $dstfile: "; + print "-> Exporting $chapter to $dstfile:\n"; $cmd = "ffmpeg -ss $start -t $duration -i $opt_i -map 0 -vcodec copy -acodec copy $dstfile 2>&1"; if(defined $opt_s) { print "$cmd\n"; } else { print "\n"; + print "$cmd\n"; $errno = system("$cmd"); $errno = $errno >> 8; if($errno > 0) { die "-E- ffmpeg encountered some errors with exit code $errno\n"; } } + if(!$progressive && $ext =~ /mkv/i) { + $ext = "mp4"; + $srcfile = $dstfile; + $dstfile = $dstfile = $opt_o . ".c" . sprintf("%03d",$chapter) . "." . $ext; + $cmd = "mencoder -oac copy -ovc copy -of lavf -lavfopts format=mp4 -o $dstfile $srcfile"; + if(defined $opt_s) { + print "$cmd\n"; + } else { + print "\n"; + print "$cmd\n"; + $errno = system("$cmd"); + $errno = $errno >> 8; + if(! defined $opt_k) { unlink "$srcfile"; } + if($errno > 0) { die "-E- mencoder encountered some errors with exit code $errno\n"; } + } + } } } }