If you have a ton of videos and you are running out of room on your hard drive. You can use this script to reduce the file size of every video file in a directory.
Required[]
Description[]
This script uses mencoder to re-encode each file using the XVID video codec, and the mp3lame audio codec. The default settings are video quality #5 and 96kbs audio bitrate. 96kbs audio bitrate is fine for most things. Video quality #5 is fine for most low-action videos, like Law and Order type, or if you don't mind it getting chunky during explosions.
- Features
- Ignores non-video files
- Copies instead of encodes files smaller than 100MB, so it won't compress already small files (size can be changed)
- Moves new files to a directory
- default small
- Creates a log: /tmp/video_dir_smallify.log
- Can set process priority
- Displays estimate of time left based on last encoding time.
- Displays final summary
- Statistic
- Average file size: 140MB for a 45min video
- Compression time: 20m to compress a 45m show, based on a 3 GHz computer
Example of output[]
Detected 3 video files. Roughly est. 1.5 h to completion, based on encoding time 30min/file. Creating 'small' directory To Exit before completion hit Ctrl-C twice. Smallifying: American.Dad.S05E01.In.Country.Club.PDTV.XviD-FQM.avi (1 of 3 files) Encoding video... Encoding finished. Original file size: 175MB Final file size: 84 MB Encoding took 0.2 h Smallifying: American.Dad.S05E02.Moon.Over.Isla.Island.PDTV.XviD-FQM.avi (2 of 3 files) Updated est. time left 0.4 h, based on last encoding Encoding video... Encoding finished. Original file size: 175MB Final file size: 69 MB Encoding took 0.2 h Smallifying: American.Dad.S05E03.PDTV.XviD-2HD.avi (3 of 3 files) Updated est. time left 0.2 h, based on last encoding Encoding video... Encoding finished. Original file size: 175MB Final file size: 65 MB Encoding took 0.2 h ========================================== Summary of encoding ------------------------------------------ American.Dad.S05E01.In.Country.Club.PDTV.XviD-FQM.avi Original Size: 175 MB Final: 84 MB American.Dad.S05E02.Moon.Over.Isla.Island.PDTV.XviD-FQM.avi Original Size: 175 MB Final: 69 MB American.Dad.S05E03.PDTV.XviD-2HD.avi Original Size: 175 MB Final: 65 MB ----------------------------------------------- Original dir: shrink/ Final dir: shrink//small Log file: /tmp/video_dir_smallify.log Total encoding time: 0.5 h All done. Before deleting old files: Check a few files Check log for errors Look at the file sizes for inconsistency
Script[]
#!/usr/bin/perl # use Time::HiRes qw ( time ); ################################## # Name: Video directory Smallifier # Version: 0.2 # Creator: Jeff Israel # Date: Oct 21, 2009 # License: GPL 3.0 # Description: This script reduces the file size of every video file # in a directory # Requirements: mencoder (part of mplayer), XVID library, mp3lame # Usage: video_dir_smallify.pl [video directory] # Example: video_dir_smallify.pl /pub/video/tv/castle/ ################################## # Configure $video_quality=5; # 5 is good for most low action # $video_bitrate=500; # not used, adjust $video_quality $audio_bitrate=96; $video_codec='xvid'; # currently only supports _xvid_ $audio_codec='libmp3lame'; # currently only supports _libmp3lame_ $video_output_dir = 'small'; # where the new videos go, relative dir, example input='videos/' output='videos/small/' $min_file_size =100; # skips encoding video if small than x in MB, recomended 150MB for 1h videos, 100MB for 30m videos $niceness = '19'; # 19 is lowest priority, 0 is highest $log_file = '/tmp/video_dir_smallify.log'; @video_file_extentions = ("avi","rm","mpg","mpeg","asf","ram","wmv","mp4","ogg",'ogm',"m4v","mkv",'rmvb','mov','divx'); #will only encode files with these extensions ##################################### # Code # $directory_name = $ARGV[0]; #commands # if ( $audio_codec eq 'vorbis' ) { # $audio_var = "-oac lavc -lavcopts acodec=vorbis:abitrate=$audio_bitrate"} # if ( $video_codec eq 'xvid') { # $video_var = "-ovc lavc -lavcopts vcodec=mpeg4:vbitrate=$video_bitrate:vhq -ffourcc XVID"; # } $encode_command = "nice -n $niceness mencoder -oac mp3lame -lameopts abr:br=$audio_bitrate -ovc xvid -xvidencopts fixed_quant=$video_quality "; ############################ # Some input error checking if($directory_name eq ""){ print "Error: no directory entered.\n the first arg is the directory\n"; exit; } if ( !( -d $directory_name) ){ #check if directory exists print "Error: $directory_name is not a directory\n"; exit; } if ( !( -w $directory_name) ){ #check if directory exists print "Error: $directory_name is not writeable\n"; exit; } opendir(DIR, "$directory_name"); #precheck if video files in dir $video_cnt=0; while (defined($dir = readdir(DIR))) { if ( isVideo($dir) ) { $video_cnt++; } } closedir(DIR); if ( $video_cnt == 0 ) { print "Error: not video files in $directory_name\n"; exit; } sub isVideo { # doo my $filename = $_[0]; foreach $ext (@video_file_extentions) { if ($filename =~ /$ext$/i) { # print "$ext: $filename: match\n"; return 1; } else { # print "$ext: $filename: no match\n"; } } 0; } $est_time = 0.5 * $video_cnt; print "Detected $video_cnt video files. \nRoughly est. $est_time h to completion, based on encoding time 30min/file.\n"; if ( -d "$directory_name/$video_output_dir" ) { #checks to see if new dir exists print "Warning: directory, $video_output_dir, exists. This is OK, but files within $video_output_dir may be overwritten\n"; } else { mkdir("$directory_name/$video_output_dir"); print "Creating \'$video_output_dir\' directory\n"; } if ( -e $log_file ) { my $log_file_old = $log_file . '.old'; system("mv $log_file $log_file_old"); } print "To Exit before completion hit Ctrl-C twice.\n\n"; $cnt=0; $summary="\n\n==========================================\nSummary of encoding\n------------------------------------------\n"; $total_start_time=time; opendir(DIR, "$directory_name"); $first=1; while (defined($dir = readdir(DIR))) { if ( ($dir ne '.') && ($dir ne '..') && !( -d "$directory_name/$dir" ) ) { if ( isVideo($dir) ) { $cnt++; $file_size = (-s "$directory_name/$dir")/1024/1024; $file_size =~ s/\..*//; if ( $file_size < $min_file_size ) { print "Copying instead of re-encoding: $dir < $min_file_size\MB\n"; system("cp \"$directory_name/$dir\" \"$directory_name/$video_output_dir/$dir\""); sleep(1); } else { system("rm -f divx2pass.log frameno.avi"); # deleting temp files the might be left over $file_name_full = "$directory_name/$dir"; $new_file_name = "$directory_name/$video_output_dir/$dir.avi"; print "Smallifying: $dir ($cnt of $video_cnt files)\n"; if ( $first == 0 ) { $time_elapst = sprintf("%.1f",($stop_time - $start_time) / 3600 ); # rounding time to one decimal print " Updated est. time left " . ( 1 + $video_cnt - $cnt)*$time_elapst . " h, based on last encoding \n"; } $first=0; $start_time = time; # print " Encoding audio...\n"; # print "$audio_enc_command \"$file_name_full\""; # system(); # print " Encoding video...\n"; # print "$video_enc_command \"$file_name_full\" -o \"$new_file_name\""; # system(); print " Encoding video... \n"; system("echo \"\n\n\n============================================================\" >> $log_file"); system("echo \"Encoding $dir\" >> $log_file"); system("echo \"============================================================\" >> $log_file"); system("$encode_command \"$file_name_full\" -o \"$new_file_name\" &>> $log_file "); # system("echo \"$mencoder_out\" >> $log_file"); sleep(1); print " Encoding finished.\n"; print " Original file size: $file_size\MB\n"; $org_file_size = $file_size; $file_size = (-s "$new_file_name")/1024/1024; $file_size =~ s/\..*//; print " Final file size: $file_size MB\n"; $summary .= "$dir\n Original Size: $org_file_size MB Final: $file_size MB\n"; $stop_time = time; $time_elapst1 = ($stop_time - $start_time) / 3600 ; $time_elapst = sprintf("%.1f", ($stop_time - $start_time) / 3600 ); # rounding time to one decimal # print " start=$start_time, $stop_time, $time_elapst, $time_elapst1\n"; print " Encoding took $time_elapst h\n"; } } else { print "Skipping: $dir is not a recognised video file\n"; } } } closedir(DIR); $total_stop_time=time; $total_time= sprintf("%.1f",($total_stop_time - $total_start_time) / 3600); $summary .= "\n-----------------------------------------------\nOriginal dir: $directory_name\nFinal dir: $directory_name/$video_output_dir\nLog file: $log_file\nTotal encoding time: $total_time h\n\n"; print $summary; system ("echo \"$summary\" >> $log_file"); #Post processing log file # system("cat $log_file |grep -v '^Pos' |grep -v '^1 duplicate frame(s)!'|grep -v '^Skipping frame!' "); $out_text = ''; open FILE, "<", "$log_file"; while (<FILE>) { my $line = $_; if ( $line !~ /^Pos/ && $line !~ /^Skipping frame!/ && $line !~ /^. duplicate frame\(s\)!/ ) { $out_text .= $line; } } close FILE; open FILE, ">$log_file" ; print FILE $out_text; close FILE; print "All done.\n"; print "Before deleting old files:\n"; print " Check a few files\n"; print " Check log for errors\n"; print " Look at the file sizes for inconsistency\n"; print "\n";
External links[]
- libmp3lame: http://lame.sourceforge.net/
- mplayer/mencoder: http://www.mplayerhq.hu/
- XVID: http://www.xvid.org/