X-Git-Url: http://git.pippins.net/embedvideo/.git/static/gitweb.js?a=blobdiff_plain;f=mkv_extract_chapter;h=ca3321561205cff894acfc4917ff594b2c066164;hb=aea4af9869a2086c5085afb34a1bd790940c8b7d;hp=53d3cb741d016820b0ebef43cd21370d2b9a55a1;hpb=75451c9e69007a30fbbff4573a787a8b3fa09f62;p=videoscripts%2F.git diff --git a/mkv_extract_chapter b/mkv_extract_chapter index 53d3cb7..ca33215 100755 --- a/mkv_extract_chapter +++ b/mkv_extract_chapter @@ -1,6 +1,14 @@ #!/usr/bin/perl # Author: Alan J. Pippin # 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 @@ -36,7 +44,7 @@ my $tmpfile = `tempfile`; 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"; } @@ -56,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; } @@ -64,7 +73,7 @@ sub usage { # SUBROUTINES sub detect_ext { - my ($ffmpeg_info) = @_; + my ($ffmpeg_info, $progressive) = @_; my $h264 = 0; my $h264_high = 0; @@ -82,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"; } @@ -106,32 +118,57 @@ 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 $end = $3; $duration = $end - $start; if($duration < 0) { die "-E- Unexpected negative duration detected for chapter $chapter\n"; } 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"; } + } + } } } }