From: Alan J. Pippin Date: Thu, 23 May 2013 07:14:36 +0000 (-0600) Subject: Added new feature to enable videos to be recompressed. X-Git-Url: http://git.pippins.net/embedvideo/.git/%27%20%20%20%20.%20%24GLOBALS%5B%27phpgw%27%5D-%3Elink%28%27inc/jquery/static/%7Bupdate_day%7D?a=commitdiff_plain;h=9990cf64d87333417ab72d6e106fa53df6ad2943;p=videoscripts%2F.git Added new feature to enable videos to be recompressed. Changed behavior of script to put single videos into mkv file too. --- diff --git a/make_mkv b/make_mkv index c3a2398..c5d1756 100755 --- a/make_mkv +++ b/make_mkv @@ -26,7 +26,7 @@ if( -f "$mydir/organize_videos.conf.local") { require "organize_videos.conf.loca #################################################################################################### # Command Line Options -getopts("sqt:o:i:h"); +getopts("sqzt:o:i:h"); if(! defined $opt_t) { &usage(); die "-E- Missing required title: -t \n"; } if(! defined $opt_o) { &usage(); die "-E- Missing required argument output video names: -o <output.mkv>\n"; } @@ -37,7 +37,8 @@ sub usage { print " -t <title> Sets the general title for the output video file\n"; print " -o <output.mkv> Sets the name of the output mkv file\n"; print " -i <input,input,...> Sets the name of the input files to make into an mkv file\n"; - print " -q Requantize MTS input videos to decrease output video size (requires HandBrakeCLI)\n"; + print " -q Requantize input videos to decrease output video size (requires HandBrakeCLI)\n"; + print " -z Recompress input videos to decrease output video size (requires HandBrakeCLI)\n"; print " -s Simulate mode. Don't actually make the video, but tell us what you will do\n"; print "\n"; return 1; @@ -123,7 +124,7 @@ foreach my $video (sort{$videos{$a} <=> $videos{$b}} keys %videos) { if($video_ext !~ /mkv/i) { $video_mkv =~ s/\.[^.]*$//; $video_mkv .= ".ffmpeg.mkv"; print " Re-muxing the interlaced video content as an mkv file: $video_mkv\n"; - my $make_mkv_cmd = "$ffmpeg -y -i \"$video\" -scodec copy -acodec copy -vcodec copy -f matroska \"$video_mkv\" > /dev/null 2>&1"; + my $make_mkv_cmd = "$ffmpeg -y -i \"$video\" -scodec copy -acodec copy -vcodec copy -f matroska \"$video_mkv\" >> \"$tmpfile\" 2>&1"; if(! defined $opt_s) { my $errno = system("$make_mkv_cmd"); $errno = $errno >> 8; @@ -141,24 +142,42 @@ foreach my $video (sort{$videos{$a} <=> $videos{$b}} keys %videos) { print " Detected progressive video content: $video\n"; } - # Re-quantize the input video to reduce the resulting output filesize + # Re-quantize or re-compress the input video to reduce the resulting output filesize # This also gives us a chance to deinterlace the video as well - # Only do this for .MTS videos - if((defined $opt_q) && ($video_ext =~ /mts/i)) { + # Only re-quantize for .MTS videos + # We can re-compress any input video + if(((defined $opt_q) && ($video_ext =~ /mts/i)) || (defined $opt_z)) { + my $handbrake_options = ""; + + # Set our output video filename + my $video_mp4 = $video; $video_mp4 =~ s/\.[^.]*$//; $video_mp4 .= ".hb.mp4"; + # Set our requantize factor accordingly - my $requantize_option = ""; - if(!$progressive) { $requantize_option = "-q $interlaced_requantize_quality"; } - else { $requantize_option = "-q $progressive_requantize_quality"; } + if(defined $opt_q) { + print " Re-quantizing input video content to: $video_mp4\n"; + $handbrake_options = $handbrake_requantize_options; + if(!$progressive) { $handbrake_options = "-q $interlaced_requantize_quality"; } + else { $handbrake_options = "-q $progressive_requantize_quality"; } + }; + + # Set our recompress options accordingly + if(defined $opt_z) { + print " Re-compressing input video content to: $video_mp4\n"; + $handbrake_options = $handbrake_recompress_options; + # We want our audio to be passed-through by default, so detect how the audio of the input is encoded, and tell handbrake to make the output match + $AUDIO_CODEC=`$ffmpeg -i "$video" 2>&1 | grep "Audio" | sed -r -e 's/.*?Audio: (\\S+),.*?/\\1/'`; chomp($AUDIO_CODEC); + if($AUDIO_CODEC eq "") { die "-E- Unable to extract audio track encoding from input video file: $video\n"; } + $handbrake_options .= " -E copy:$AUDIO_CODEC"; + } # Set our de-interlace option accordingly my $deinterlace_option = ""; if(!$progressive) { $deinterlace_option = "-d"; } - # Use HandBrake to requantize/deinterlace the input video - my $video_mp4 = $video; $video_mp4 =~ s/\.[^.]*$//; $video_mp4 .= ".hb.mp4"; - print " Re-quantizing input video content: $video_mp4\n"; - my $handbrake_cmd = "$handbrake $deinterlace_option $requantize_option $handbrake_options -i \"$video\" -o \"$video_mp4\" > /dev/null 2>&1"; + # Use HandBrake to requantize/recompress/deinterlace the input video + my $handbrake_cmd = "$handbrake $deinterlace_option $handbrake_options -i \"$video\" -o \"$video_mp4\" >> \"$tmpfile\" 2>&1"; + #print " $handbrake_cmd\n"; if(! defined $opt_s) { my $errno = system("$handbrake_cmd"); $errno = $errno >> 8; @@ -194,8 +213,10 @@ if(! defined $opt_s) { } } -# Remove the temporary file used for the chapter generation +# Remove the temporary file used for ffmpeg and handbrake output if(-e "$tmpfile") { unlink "$tmpfile"; } +# Remove the temporary file used for the chapter generation +if(-e "$chapter_file") { unlink "$chapter_file"; } # Remove any temporary video files created during the merge process foreach my $video (@video_tmp_files) { diff --git a/merge_videos_by_day b/merge_videos_by_day index 4cf293d..6e7998c 100755 --- a/merge_videos_by_day +++ b/merge_videos_by_day @@ -9,7 +9,7 @@ use File::stat; use Time::localtime; # Early command line options processing -getopts("qkh:tvs:"); +getopts("qzkh:tvs:"); my $srcpathname = $opt_s; #################################################################################################### @@ -23,19 +23,20 @@ if( -f "$mydir/organize_videos.conf.local") { require "organize_videos.conf.loca #################################################################################################### sub usage { - print "usage: $0 [-tvrh] -s <srcpath>\n"; + print "usage: $0 [-tvrhz] -s <srcpath>\n"; print " -s <srcpath> specify the path to search for videos to merge under\n"; print " -h <compute host> specify the remote compute host to submit the mkvmerge job to\n"; print " -v verbose mode; print extra information about what is being found/merged\n"; print " -t test mode; print what will happen, but don't do anything\n"; print " -k keep the individual video files that are merged. By default, after a merge, individual video files that were merged are removed\n"; - print " -q Requantize MTS input videos to decrease output video size (requires HandBrakeCLI)\n"; + print " -q Requantize input videos to decrease output video size (requires HandBrakeCLI)\n"; + print " -z Recompress input videos to decrease output video size (requires HandBrakeCLI)\n"; return 1; } if(defined $opt_h) { usage(); exit 1; } # Sanity checks -if(defined $opt_q && !$use_compute_host) { die "-E- Unable to find required program: handbrake\n"; } +if((defined $opt_q || defined $opt_z) && !$use_compute_host && ! -x "$handbrake") { die "-E- Unable to find required program: handbrake\n"; } if(! -d $srcpathname) { &usage; print "-E- Can't find srcpath: $srcpathname\n"; exit 1; } if(defined $opt_h) { $compute_host = $opt_h; } @@ -133,24 +134,6 @@ foreach $file (sort `$find_cmd`) { push(@{$videos{"$srcext"}{"$dstfile"}}, "\"$srcdir/$srcfile\""); } -# For single videos, with the re-quantize option given, rename the destination file to mp4 -foreach $ext (sort keys %videos) { - foreach $video (sort keys %{$videos{$ext}}) { - # Get a count of the number of videos for this date - # If we only have a single video, its extension will actually be mp4 if opt_q is specified - my $num_videos = $#{$videos{$ext}{$video}} + 1; - if((defined $opt_q) && ($num_videos <= 1)) { - if($video =~ /(.*?)\.(\d+)\.(\w+)$/) { - $dstfile = $1; - $dstnum = $2; - $new_dstvideo = "$1.$2.mp4"; - $videos{$ext}{$new_dstvideo} = $videos{$ext}{$video}; # make a new dst video entry with the src video being the same - delete $videos{$ext}{$video}; # delete the old destination video from the hash - } - } - } -} - # Check for duplicate filenames in the dstfiles being created for other exts foreach $ext (sort keys %videos) { foreach $video (sort keys %{$videos{$ext}}) { @@ -176,71 +159,6 @@ foreach $ext (sort keys %videos) { } } -# Only merge the videos if there is more than 1 video to merge on a given day for a given ext -# If there is only 1 video for a given day for a given ext, re-quantize it here if that option was given -foreach $ext (sort keys %videos) { - foreach $video (sort keys %{$videos{$ext}}) { - - # Get a count of the number of videos for this date - my $num_videos = $#{$videos{$ext}{$video}} + 1; - - # Process any single videos now - if($num_videos <= 1) { - - # Store the srcvideo name - my $srcvideo = $videos{$ext}{$video}[0]; - my $pwd = `pwd`; chomp($pwd); - - # Make a note if this video is interlaced or not - my $ffmpeg_cmd = ""; - if($use_compute_host) { $ffmpeg_cmd .= "ssh $compute_host 'cd \"$pwd\";"; } - $ffmpeg_cmd .= "$ffmpeg -i $srcvideo 2>&1 | grep -q \"frame rate differs\""; - if($use_compute_host) { $ffmpeg_cmd .= "'"; } - my $progressive = system('$ffmpeg_cmd'); - if(!$progressive) { print " Detected interlaced video content: $srcvideo\n"; } - - # Re-quantize the input video to reduce the resulting output filesize - # This also gives us a chance to deinterlace the video as well - # Only do this for .MTS videos - if((defined $opt_q) && ($ext =~ /mts/i)) { - - # Set our requantize factor accordingly - my $requantize_option = ""; - if(!$progressive) { $requantize_option = "-q $interlaced_requantize_quality"; } - else { $requantize_option = "-q $progressive_requantize_quality"; } - - # Set our de-interlace option accordingly - my $deinterlace_option = ""; - if(!$progressive) { $deinterlace_option = "-d"; } - - # Use HandBrake to requantize/deinterlace the input video - print " Re-quantizing input video content: $video\n"; - my $handbrake_cmd = ""; - if($use_compute_host) { $handbrake_cmd .= "ssh $compute_host 'cd \"$pwd\";"; } - $handbrake_cmd .= "$handbrake $deinterlace_option $requantize_option $handbrake_options -i $srcvideo -o \"$video\" > /dev/null 2>&1"; - if($use_compute_host) { $handbrake_cmd .= "'"; } - if(! defined $opt_t) { - my $errno = system("$handbrake_cmd"); - $errno = $errno >> 8; - if($errno > 1) { - unlink "$video"; - die "-E- handbrake encountered some errors with exit code $errno\n"; - } else { - # Remove the original srcvideo since we created a new version of it that we are going to keep instead - if(!defined $opt_k) { - system("rm -f $srcvideo\n"); - } - } - } - } - - # Remove the video from the array since we already processed it above - delete $videos{$ext}{$video}; - next; - } - } -} - # Tell the user which videos we are going to merge foreach $ext (sort keys %videos) { foreach $video (sort keys %{$videos{$ext}}) { @@ -268,8 +186,10 @@ foreach $ext (sort keys %videos) { if($use_compute_host) { $cmd .= "ssh $compute_host 'cd \"$pwd\";"; } $cmd .= "$make_mkv -t \"$video_title_prefix $year-$month-$day\" -o \"$video\" -i $videos"; if($requantize_input_video) { $cmd .= ' -q'; } + if($recompress_input_video) { $cmd .= ' -z'; } if($use_compute_host) { $cmd .= "'"; } if(defined $opt_t) { + # Print what will be done, but don't actually do it print "\n-> Creating \"$video\"\n"; print "$cmd\n"; if(!defined $opt_k) { diff --git a/organize_videos b/organize_videos index 782ee17..5727d57 100755 --- a/organize_videos +++ b/organize_videos @@ -142,7 +142,9 @@ my $errno = 0; my $merge_opts = ""; if(defined $opt_t) { $merge_opts .= "-t "; } if(defined $opt_k) { $merge_opts .= "-k "; } -$errno=system("$merge_videos_by_day -q -s \"$srcpathname\" $merge_opts"); +if($requantize_input_video) { $merge_opts .= ' -q'; } +if($recompress_input_video) { $merge_opts .= ' -z'; } +$errno=system("$merge_videos_by_day -s \"$srcpathname\" $merge_opts"); $errno = $errno >> 8; if($errno) { die "-E- $merge_videos_by_day encountered some errors with exit code $errno\n"; } diff --git a/organize_videos.conf b/organize_videos.conf index 09b4a5f..d6236be 100644 --- a/organize_videos.conf +++ b/organize_videos.conf @@ -56,7 +56,7 @@ $movie_file_ext = "-iregex \".*\.mov\" -o -iregex \".*\.3gp\" -o -iregex \".*\.m # Video file creation dates must not have changed in the last X minutes to process any of the video files # This is done to ensure that all videos from a given upload from a camera have completed prior to looking for videos to merge -$minage = "+30"; +$minage = "+15"; # What command should be used to find files that have changed (are at least $minage old) $find_changed_cmd = "find \"$srcpathname/\" -not -cmin $minage -a \\( $movie_file_ext \\)"; @@ -72,10 +72,11 @@ $tmpfile = `tempfile`; chomp($tmpfile); $timezone = `cat /etc/timezone`; chomp($timezone); # handbrake options used when re-encoding the videos -$handbrake_options='--strict-anamorphic --crop 0:0:0:0 -E ac3'; +$handbrake_requantize_options='--strict-anamorphic --crop 0:0:0:0 -E ac3'; +$handbrake_recompress_options='--strict-anamorphic --crop 0:0:0:0 --denoise="weak" -e x264 -q 18 -x b-adapt=2:rc-lookahead=50 -v 2 -a 1 -6 dpl2 --preset="High Profile"'; # tmp chapter file used by handbrake when creating mkv -$chapter_file = $tmpfile; +$chapter_file = `tempfile`; chomp($chapter_file); # handbrake input file options $input_file_options = "-S"; @@ -94,7 +95,8 @@ $compute_host = "pippin.pippins.net"; $use_compute_host = 1; # This will dramatically decrease the size of the video with minimal compute processing requirements. -$requantize_input_video=1; +$requantize_input_video=0; +$recompress_input_video=1; # What text to put on the front of the title for the merged video being created $video_title_prefix = "HomeVideos:";