Added various comments and new options to add in flexibility in the configuration.
authorAlan J. Pippin <alan@pippins.net>
Fri, 18 Nov 2011 04:00:19 +0000 (21:00 -0700)
committerAlan J. Pippin <ajp@pippins.net>
Fri, 18 Nov 2011 04:00:19 +0000 (21:00 -0700)
Added playlist creation capability.

make_mkv
merge_videos_by_day
organize_videos

index ea3b50cda0238ed603ba06fe93acff191f76eed1..4c411529b887953d9e7a33df97ebedb4343cce14 100755 (executable)
--- a/make_mkv
+++ b/make_mkv
@@ -6,7 +6,7 @@
 # mkvtoolnix - http://www.bunkus.org/videotools/mkvtoolnix/
 # ffmpeg
 
-###########################
+####################################################################################################
 # Includes
 use File::Copy;
 use File::Basename;
@@ -16,17 +16,19 @@ use DateTime;
 use DateTime::Duration;
 use DateTime::Format::Duration;
 
-###########################
-# Configuration parameters
+####################################################################################################
+# Configuration parameters - CHANGE THESE TO SUITE YOUR NEEDS
 my $mkvmerge=`which mkvmerge`; chomp($mkvmerge);
 my $ffmpeg=`which ffmpeg`; chomp($ffmpeg);
 my $tmpfile = `tempfile`; chomp($tmpfile);
 my $chapter_file = $tmpfile;
 my $input_file_options = "-S";
 my $output_file_options = "--chapters $chapter_file";
+####################################################################################################
 
-###########################
-# Options
+
+####################################################################################################
+# Command Line Options
 getopts("st:o:i:h");
 
 if(! -x $mkvmerge) { die "-E- Unable to find required program: mkvmerge\n"; }
@@ -45,7 +47,7 @@ sub usage {
     return 1;
 }
 
-###########################
+####################################################################################################
 # Helper Subroutines
 sub epoch_to_date {
     my ($epoch) = @_;
@@ -53,7 +55,7 @@ sub epoch_to_date {
     return sprintf("%4d",$mtime->year)."-".sprintf("%02d",$mtime->month)."-".sprintf("%02d",$mtime->day)." ".$mtime->hms;
 }
 
-###########################
+####################################################################################################
 # MAIN
 
 # Turn the list of input videos into a hash with a value equal to the modification time in epoch seconds
@@ -123,8 +125,8 @@ if(! defined $opt_s) {
     if($errno > 1) { die "-E- mkvmerge encountered some errors with exit code $errno\n"; }
 }
 
-# Remove the temporary file
+# Remove the temporary file used for the chapter generation
 if(-e "$tmpfile") { unlink "$tmpfile"; }
 
-###########################
+####################################################################################################
 
index dec78b2355b21f55754a2301fca7da4b58e78ff2..6d48bfc5dc6dc36ac43dfdd8abaa6c549cf63cb5 100755 (executable)
@@ -1,4 +1,6 @@
 #!/usr/bin/perl
+# Author: Alan J. Pippin
+# Description: For the given srcpath, merge all the videos that were taken on the same day into a single mkv file
 
 use File::Copy;
 use File::Basename;
@@ -6,30 +8,36 @@ use Getopt::Std;
 use File::stat;
 use Time::localtime;
 
+####################################################################################################
+# Configuration parameters - CHANGE THESE TO SUITE YOUR NEEDS
+my $compute_host = "pippin.pippins.net"; # I need this since this script is run from a virtual machine 
+my $use_compute_host = 1; # Set to 1 to use a remote compute host to run the mkvmerge command. Set to 0 to use the local host to run it.
+my $make_mkv = "/naspool/videos/bin/make_mkv"; # Update this to be the path to the make_mkv script
+my $minage = "+10"; # Files must be older than X minutes to move
+my $owner = "ajp"; # The owner of the files after they are moved
+my $group = "pip"; # The group of the files after they are moved
+my $mode = "664"; # The mode to set on each file after they are moved
+my $video_suffix = "000"; # What number to start with when adding an incrementing suffix to the end of the video clip to avoid name collisons
+my $video_title_prefix = "HomeVideos:"; # What text to put on the front of the title for the merged video being created
+my $find_cmd = "find \"$srcpathname/\" -cmin $minage -iregex \".*\.mov\" -o -iregex \".*\.3gp\" -o -iregex \".*\.mp4\" -o -iregex \".*\.mts\"";
+####################################################################################################
+
 # Command line options
-getopts("h:tvs:");
+getopts("rh:tvs:");
 
 sub usage {
-    print "usage: $0 [-t] -s <srcpath>\n";
+    print "usage: $0 [-tvrh] -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 "   -r                    remove merged video clips; after a merge, remove the individual video files that were merged\n";
     return 1;
 }
-if(defined $opt_h) { usage(); exit 1; }
-
-# Configuration parameters
-my $compute_host = "pippin.pippins.net";
 my $srcpathname = $opt_s;
-my $minage = "+10"; # Files must be older than X minutes to move
-my $owner = "ajp"; # The owner of the files after they are moved
-my $group = "pip"; # The group of the files after they are moved
-my $mode = "664"; # The mode to set on each file after they are moved
-my $make_mkv = "/naspool/videos/bin/make_mkv"; chomp($make_mkv);
-my $find_cmd = "find \"$srcpathname/\" -cmin $minage -iregex \".*\.mov\" -o -iregex \".*\.3gp\" -o -iregex \".*\.mp4\" -o -iregex \".*\.mts\"";
+if(defined $opt_h) { usage(); exit 1; }
 
-# Sanity check
+# Sanity checks
 if(! -x $make_mkv) { die "-E- Unable to find required script: make_mkv\n"; }
 if(! -d $srcpathname) { &usage; print "-E- Can't find srcpath: $srcpathname\n"; exit 1; }
 if(defined $opt_h) { $compute_host = $opt_h; }
@@ -110,9 +118,9 @@ foreach $file (sort `$find_cmd`) {
     $dstfile = $dstdir . "/" . $year . "-" . $monthnum . "-" . $day;
 
     # Check for duplicate filenames at the destination
-    $newfile = $dstfile . "." . "000";
+    $newfile = $dstfile . "." . $video_suffix;
     if(-e "$newfile.$ext") {
-       foreach $i ('001' .. '999') {
+       foreach $i ($video_suffix+1 .. '999') {
            $newfile = $dstfile . "." . $i;
            if(! -e "$newfile.$ext") { last; }
        }
@@ -139,12 +147,17 @@ foreach $video (sort keys %videos) {
     }
     
     my $pwd = `pwd`; chomp($pwd);
-    my $cmd = "ssh $compute_host 'cd \"$pwd\"; $make_mkv -t \"HomeVideos: $year-$month-$day\" -o \"$video\" -i $videos'\n"; 
+    my $cmd = "";
+    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($use_compute_host) { $cmd .= "'"; }
     if(defined $opt_t) {
        print "\n-> Creating \"$video\"\n";
        print "$cmd\n";
-       foreach $video (@{$videos{$video}}) {
-           print("rm -f $video\n");
+       if(defined $opt_r) { 
+           foreach $video (@{$videos{$video}}) {
+               print("rm -f $video\n");
+           }
        }
     } else {
        # Create the merged video
@@ -156,8 +169,10 @@ foreach $video (sort keys %videos) {
        system("chgrp $group \"$video\"");
        system("chmod $mode \"$video\"");
        # Remove the individual video files
-       foreach $video (@{$videos{$video}}) {
-           system("rm -f $video");
+       if(defined $opt_r) { 
+           foreach $video (@{$videos{$video}}) {
+               system("rm -f $video");
+           }
        }
     }
 }
index c606da3fb266a971f5fa0aedd51d0794ccc0b2a5..754ac28124e8c17079678527a77a204d28c295e9 100755 (executable)
@@ -1,20 +1,27 @@
 #!/usr/bin/perl
+# Author: Alan J. Pippin
+# Description: Find videos from a temporary dropbox location and merge and move them into their final destination.
 
 use File::Copy;
 use File::Basename;
 use Getopt::Std;
 use File::stat;
 use Time::localtime;
+use File::Pid;
 
-# Configuration parameters
-my $srcpathname = "/naspool/pictures/New Photos"; # Path to look for photos to move from
-my $dstpathname = "/naspool/videos/HomeVideos"; # Path to move the photos to
+####################################################################################################
+# Configuration parameters - CHANGE THESE TO SUITE YOUR NEEDS
+my $srcpathname = "/naspool/pictures/New Photos"; # Path to look for videos to move from
+my $dstpathname = "/naspool/videos/HomeVideos"; # Path to move the videos to
 my $merge_videos_by_day = "/naspool/videos/bin/merge_videos_by_day";
-my $minage = "+10"; # Files must be older than X minutes to move
+my $minage = "+10"; # File creation dates must be older than X minutes to move
 my $owner = "ajp"; # The owner of the files after they are moved
 my $group = "pip"; # The group of the files after they are moved
 my $mode = "664"; # The mode to set on each file after they are moved
+my $playlist_extension = "pls"; # The extension to use when creating playlist files
+my $video_suffix = "000"; # What number to start with when adding an incrementing suffix to the end of the final video clip to avoid name collisions
 my $find_cmd = "find \"$srcpathname/\" -cmin $minage -a \\( -iregex \".*\.mov\" -o -iregex \".*\.3gp\" -o -iregex \".*\.mp4\" -o -iregex \".*\.mts\" -o -iregex \".*\.mkv\" \\)";
+####################################################################################################
 
 # Sanity check
 if(! -d $srcpathname) { print "-E- Can't find srcpath: $srcpathname\n"; exit 1; }
@@ -51,12 +58,15 @@ my %month2monthname = (
                       "12" => "Dec"
                       );
 
-getopts("htv");
+getopts("htvrpd:");
 
 sub usage {
-    print "usage: $0 [-v] [-t]\n";
-    print "   -v = verbose; print file being moved (to)\n";
+    print "usage: $0 [-v] [-t] [-r] [-p] [-d <dir>]\n";
+    print "   -v = verbose; print file being moved (to).\n";
     print "   -t = test; print what will happen, but don't do anything\n";
+    print "   -r = remove merged video clips; after a merge, remove the individual video files that were merged\n";
+    print "   -p = Only recreate video playlists. Do this for each year & month of video clips in the directory specified by -d <dir>.\n";
+    print "   -d <dir> = Directory to recreate the playlists in. Only needed if -p option is given\n";
     return 1;
 }
 
@@ -66,14 +76,54 @@ sub is_folder_empty {
     return scalar(grep { $_ ne "." && $_ ne ".." } readdir($dh)) == 0;
 }
 
+sub create_playlists {
+    my ($dstdirs) = @_;
+    
+    foreach $dstdir (@{$dstdirs}) {
+       print "-> Recreating playlists in: $dstdir\n";
+       print "-> Creating playlists for each month & year of clips from this directory: $video_directory\n";
+       opendir(VIDEODIR, "$dstdir") or die "-E- could not open: $dstdir\n";
+       chdir "$dstdir" || die "-E- Unable to change directory to the dstdir: $dstdir\n";
+       
+       my @all_files = readdir VIDEODIR;
+       closedir(VIDEODIR);
+       @all_files = sort @all_files;
+
+       print "   Removing all existing playlists from the directory\n";
+       if(! defined $opt_t) { system("rm *.$playlist_extension > /dev/null 2>&1"); }
+    
+       foreach $file (@all_files) {
+           next if -d $file;
+           next if ($file !~ /\.avi$/i && $file !~ /\.mpg$/i && $file !~ /\.mkv$/i && $file !~ /\.3gp$/i && $file !~ /\.mov$/i && $file !~ /\.mts$/i);
+           if($file =~ /(\d\d\d\d)-(\d\d)-(\d\d)/) {
+               $year = $1; $month = $2;
+               print "   Adding $file to $year.$playlist_extension & $year-$month.$playlist_extension\n";
+               if(! defined $opt_t) { system("echo \"$file\" >> $year.$playlist_extension"); }
+               if(! defined $opt_t) { system("echo \"$file\" >> $year-$month.$playlist_extension"); }
+           } else {
+               print "   Skipping $file since we can't extract the year and month from it\n"; 
+           }
+       }
+    }
+}
+
+# Sanity checks / Option processing
 if(defined $opt_h) { usage(); exit 1; }
+if(defined $opt_p) {
+    if(defined $opt_d) {
+       my @dstdirs = ("$opt_d"); 
+       create_playlists(\@dstdirs);
+    } else {
+       die "-E- You must specify the -d <dir> option when using the -p option\n"; 
+    }
+    exit 0;
+}
 
 # Only proceed if there are video files to organize
 $video_files_found=`$find_cmd`;
 if(!$video_files_found) { exit 0; }
 
 # Only one instance of this script running at a time
-use File::Pid;
 my $pidfile = File::Pid->new({file => "/tmp/organize_videos.pid"});
 exit if $pidfile->running();
 $pidfile->write();
@@ -83,15 +133,15 @@ system("date");
 
 # Merge videos prior to copying them over to the destination path
 my $errno = 0;
-if(defined $opt_t) { 
-    $errno=system("$merge_videos_by_day -s \"$srcpathname\" -t");
-} else {
-    $errno=system("$merge_videos_by_day -s \"$srcpathname\"");
-}
+my $merge_opts = "";
+if(defined $opt_t) { $merge_opts .= "-t "; }
+if(defined $opt_r) { $merge_opts .= "-r "; }
+$errno=system("$merge_videos_by_day -s \"$srcpathname\" $merge_opts");
 if($errno > 0) { $errno = $errno - 255; }
 if($errno) { die "-E- $merge_videos_by_day encountered some errors with exit code $errno\n"; }
 
 # Copy the videos over to the destination path
+my @dstdirs;
 chdir "$srcpathname";
 print "$find_cmd\n" if($opt_v);
 foreach $file (`$find_cmd`) {
@@ -106,9 +156,6 @@ foreach $file (`$find_cmd`) {
 
     # Throw out files not in the current srcpath
     if((! -f "$srcfile") && (! -f "$srcdir/$srcfile")) { next; }
-    
-    # Change all spaces to underscores in the filename
-    #$srcfile =~ s/ /_/g;
         
     # Make a note of the month, year, and day this video was taken (from the modification time of the file)
     $date_taken = ctime(stat("$srcdir/$srcfile")->mtime);
@@ -135,12 +182,13 @@ foreach $file (`$find_cmd`) {
 
     # We are ready to pick a destination folder to put the picture in
     $dstdir = $dstpathname . "/" . $year;
+    push(@dstdirs,$dstdir);
     $dstfile = $dstdir . "/" . $year . "-" . $monthnum . "-" . $day;
 
     # Check for duplicate filenames at the destination
-    $newfile = $dstfile . "." . "000";
+    $newfile = $dstfile . "." . $video_suffix;
     if(-e "$newfile.$ext") {
-       foreach $i ('001' .. '999') {
+       foreach $i ($video_suffix+1 .. '999') {
            $newfile = $dstfile . "." . $i;
            if(! -e "$newfile.$ext") { last; }
        }
@@ -155,13 +203,13 @@ foreach $file (`$find_cmd`) {
        $errno=system("mkdir -p \"$dstdir\"");
        if($errno) { print "-E- Error creating dstdir: $dstdir\n"; next; }
        # Perform the move operation from $srcdir/$srcfile -> $dstfile
-       if($opt_v) { print "-> Moving \"$srcdir/$srcfile\" to \"$dstfile\"\n"; }
+       print "-> Moving \"$srcdir/$srcfile\" to \"$dstfile\"\n";
        # Make sure the dstfile doesn't exist, if it does, don't do the move
        if(! -f "$dstfile") {
            $errno=system("mv \"$srcdir/$srcfile\" \"$dstfile\" 2>/dev/null");
            if($errno) { print "-E- Error moving srcfile to dstfile: $srcdir/$srcfile -> $dstfile\n"; next; }
        } else {
-           if($opt_v) { print "-> Skipping \"$srcdir/$srcfile\". Destfile \"$dstfile\" already exists.\n"; }
+           print "-> Skipping \"$srcdir/$srcfile\". Destfile \"$dstfile\" already exists.\n";
        }
        # Fix the permissions
        system("chown $owner \"$dstfile\"");
@@ -183,6 +231,9 @@ foreach $file (`$find_cmd`) {
     }
 }
 
+# For each destination dir we copied new content into, recreate the playlists
+create_playlists(\@dstdirs);
+
 $pidfile->remove();
 
 print "\n\n";