#!/usr/local/bin/perl use Image::Magick; use File::Basename; use Date::Manip; ### set file locations. ### $dirtoget is picture capture dir ### $video_dir is output dir $dirtoget="/home/webcam/picture/"; $video_dir="/home/webcam/video/"; ### Remove larger time scales to keep disk space managable system("rm " . $video_dir . "week-*"); system("rm " . $video_dir . "month-*"); system("rm " . $video_dir . "project-*"); ### symlinks should have been deleted already, but delete temp symlinks if they're still there system("rm " . $dirtoget . "A*.jpg"); system("rm " . $dirtoget . "B*.jpg"); system("rm " . $dirtoget . "C*.jpg"); system("rm " . $dirtoget . "D*.jpg"); ### get file listing of capture directory opendir(IMGD, $dirtoget) || die("Cannot open directory"); @thefiles= readdir(IMGD); closedir(IMGD); @thefiles = sort(@thefiles); ### calculate starting and ending dates $ddates=&DateCalc("today 00:00:00","-1 day",\$err); $ddate=&UnixDate($ddates,"%Y%m%d%H%M"); $wdates=&DateCalc("today 00:00:00","-7 days",\$err); $wdate=&UnixDate($wdates,"%Y%m%d%H%M"); $mdates=&DateCalc("today 00:00:00","-1 month",\$err); $mdate=&UnixDate($mdates,"%Y%m%d%H%M"); $edate=&UnixDate("today 00:00:00","%Y%m%d%H%M"); ### Parse file listing, get date of first file, create symlink series for ffmpeg ### A00000.jpg series is for yesterday video ### yesterday video uses all 12 frames per hour from the previous day ### B00000.jpg series is for past week video ### past week uses only 6 frames per hour ### watchable after 2 days ### C00000.jpg series is for past month video ### past month uses only 1 frame per hour ### watchable after a week ### D00000.jpg series is for entire project video ### entire project only uses 3 frames per day 09:00AM 12:00PM 03:00PM ### Maybe disable for first month? ### Maybe switch to 1 frame per day near end of project? ### this section is inefficient and might take quite a while ### to process with more than 3 or 4 months of data ### but it only runs once a day on a computer that does nothing else. ### Hopefully it is not an issue $iday = 0; $iweek = 0; $imonth = 0; $iproject = 0; foreach $f (@thefiles) { ### ($f =~ /(0[7-9]|1[0-9])[0-9]{2}.jpg$/) - used to limit input to 7:00 to 19:00 ### ($f !~ /^(A|B|C|D)/) - used to prevent symlinks from being linked again if ( ($f !~ /^(A|B|C|D)/) && ($f =~ /(0[7-9]|1[0-9])[0-9]{2}.jpg$/) ) { $f = basename($f,".jpg"); if ( ($f >= $ddate) && ($f <= $edate) ) { if ( $iday == 0 ) { $dstart = $f; } $iday = sprintf( "%05d", $iday); symlink($dirtoget . $f . ".jpg",$dirtoget . "A" . $iday . ".jpg"); $iday++; } if ( ($f =~ /0$/) && ($f >= $wdate) && ($f <= $edate) ) { if ( $iweek == 0 ) { $wstart = $f; } $iweek = sprintf( "%05d", $iweek); symlink($dirtoget . $f . ".jpg",$dirtoget . "B" . $iweek . ".jpg"); $iweek++; } if ( ($f =~ /00$/) && ($f >= $mdate) && ($f <= $edate) ) { if ( $imonth == 0 ) { $mstart = $f; } $imonth = sprintf( "%05d", $imonth); symlink($dirtoget . $f . ".jpg",$dirtoget . "C" . $imonth . ".jpg"); $imonth++; } if ( ($f =~ /0900$/) || ($f =~ /1200$/) || ($f =~ /1500$/)) { if ( $iproject == 0 ) { $pstart = $f; } $iproject = sprintf( "%05d", $iproject); symlink($dirtoget . $f . ".jpg",$dirtoget . "D" . $iproject . ".jpg"); $iproject++; } } } ### Change first file date into something usable $dfirst = substr($dstart, 4, 2) . "/" . substr($dstart, 6, 2) . "/" . substr($dstart, 0, 4); $wfirst = substr($wstart, 4, 2) . "/" . substr($wstart, 6, 2) . "/" . substr($wstart, 0, 4); $mfirst = substr($mstart, 4, 2) . "/" . substr($mstart, 6, 2) . "/" . substr($mstart, 0, 4); $pfirst = substr($pstart, 4, 2) . "/" . substr($pstart, 6, 2) . "/" . substr($pstart, 0, 4); ### And make sure it's in the correct format $dfirst=&UnixDate($dfirst,"%m/%d/%Y"); $wfirst=&UnixDate($wfirst,"%m/%d/%Y"); $mfirst=&UnixDate($mfirst,"%m/%d/%Y"); $pfirst=&UnixDate($pfirst,"%m/%d/%Y"); ### Yesterday's date used for all file output $odate=&UnixDate("yesterday 00:00:00","%Y%m%d"); $podate=&UnixDate("yesterday 00:00:00","%m/%d/%Y"); ### Generate FLV fideos from temporary symlinks ### Month and entire project are disabled until more pictures are captured system("/usr/bin/nice -n 19 /usr/bin/ffmpeg -y -r 6 -i \"" . $dirtoget . "A%05d.jpg\" -aspect 4:3 -f flv -s 320x240 " . $video_dir . "daily-" . $odate . ".flv"); system("/usr/bin/nice -n 19 /usr/bin/ffmpeg -y -r 9 -i \"" . $dirtoget . "B%05d.jpg\" -aspect 4:3 -f flv -s 320x240 " . $video_dir . "week-" . $odate . ".flv"); system("/usr/bin/nice -n 19 /usr/bin/ffmpeg -y -r 12 -i \"" . $dirtoget . "C%05d.jpg\" -aspect 4:3 -f flv -s 320x240 " . $video_dir . "month-" . $odate . ".flv"); #system("/usr/bin/nice -n 19 /usr/bin/ffmpeg -y -r 12 -i \"" . $dirtoget . "D%05d.jpg\" -aspect 4:3 -f flv -s 320x240 " . $video_dir . "project-" . $odate . ".flv"); ### Generate Thumbnails ### I hope the lighting at 10:00 AM is good ### check to see if there is a picture captured at 10:00 am ### resize to 320x240 ### Daily $somedate = substr($dstart, 0, 8); if (-e $dirtoget . $somedate . "1000.jpg") { $image = Image::Magick->new; $image->Read($dirtoget . $somedate . "1000.jpg"); $image->Resize(width=>320,height=>240); $image->Write($video_dir . "daily-" . $odate . ".jpg"); } $somedate = substr($wstart, 0, 8); ### Week if (-e $dirtoget . $somedate . "1000.jpg") { $image2 = Image::Magick->new; $image2->Read($dirtoget . $somedate . "1000.jpg"); $image2->Resize(width=>320,height=>240); $image2->Write($video_dir . "week-" . $odate . ".jpg"); } ### Month $somedate = substr($mstart, 0, 8); if (-e $dirtoget . $somedate . "1000.jpg") { $image3 = Image::Magick->new; $image3->Read($dirtoget . $somedate . "1000.jpg"); $image3->Resize(width=>320,height=>240); $image3->Write($video_dir . "month-" . $odate . ".jpg"); } ### Project $somedate = substr($pstart, 0, 8); if (-e $dirtoget . $somedate . "1000.jpg") { $image4 = Image::Magick->new; $image4->Read($dirtoget . $somedate . "1000.jpg"); $image4->Resize(width=>320,height=>240); $image4->Write($video_dir . "project-" . $odate . ".jpg"); } ### Remove symlinks used to build video system("rm " . $dirtoget . "A*.jpg"); system("rm " . $dirtoget . "B*.jpg"); system("rm " . $dirtoget . "C*.jpg"); system("rm " . $dirtoget . "D*.jpg"); ### Generate XML Playlist for flash player ### Open playlist.xml for output and start XML file open (XMLFILE, ">$video_dir" . "playlist.xml"); print XMLFILE ''; print XMLFILE "\n \n"; print XMLFILE " TIME-LAPSE Playlist\n"; print XMLFILE " http://www.EXAMPLE.com\n"; ### @outfiles contains valid files to copy to webserver @outfiles = ('playlist.xml'); ### Daily if ((-e $video_dir . "daily-" . $odate . ".flv") && (-e $video_dir . "daily-" . $odate . ".jpg")) { push(@outfiles, "daily-" . $odate . ".flv"); push(@outfiles, "daily-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " " . $dfirst . "\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/daily-" . $odate . ".jpg\n"; print XMLFILE " Daily video from " . $dfirst . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Week if ((-e $video_dir . "week-" . $odate . ".flv") && (-e $video_dir . "week-" . $odate . ".jpg")) { push(@outfiles, "week-" . $odate . ".flv"); push(@outfiles, "week-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " Previous Week\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/week-" . $odate . ".jpg\n"; print XMLFILE " Video from " . $wfirst . " to " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Month if ((-e $video_dir . "month-" . $odate . ".flv") && (-e $video_dir . "month-" . $odate . ".jpg")) { push(@outfiles, "month-" . $odate . ".flv"); push(@outfiles, "month-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " Previous Month\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/month-" . $odate . ".jpg\n"; print XMLFILE " Video from " . $mfirst . " to " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Project if ((-e $video_dir . "project-" . $odate . ".flv") && (-e $video_dir . "project-" . $odate . ".jpg")) { push(@outfiles, "project-" . $odate . ".flv"); push(@outfiles, "project-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " Entire Project\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/project-" . $odate . ".jpg\n"; print XMLFILE " Video from " . $pfirst . " to " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Daily 2 days ago $odate=&UnixDate(&DateCalc("today 00:00:00","-2 days",\$err),"%Y%m%d"); $podate=&UnixDate(&DateCalc("today 00:00:00","-2 days",\$err),"%m/%d/%Y"); if ((-e $video_dir . "daily-" . $odate . ".flv") && (-e $video_dir . "daily-" . $odate . ".jpg")) { push(@outfiles, "daily-" . $odate . ".flv"); push(@outfiles, "daily-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " " . $podate . "\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/daily-" . $odate . ".jpg\n"; print XMLFILE " Daily video from " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Daily 3 days ago $odate=&UnixDate(&DateCalc("today 00:00:00","-3 days",\$err),"%Y%m%d"); $podate=&UnixDate(&DateCalc("today 00:00:00","-3 days",\$err),"%m/%d/%Y"); if ((-e $video_dir . "daily-" . $odate . ".flv") && (-e $video_dir . "daily-" . $odate . ".jpg")) { push(@outfiles, "daily-" . $odate . ".flv"); push(@outfiles, "daily-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " " . $podate . "\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/daily-" . $odate . ".jpg\n"; print XMLFILE " Daily video from " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Daily 4 days ago $odate=&UnixDate(&DateCalc("today 00:00:00","-4 days",\$err),"%Y%m%d"); $podate=&UnixDate(&DateCalc("today 00:00:00","-4 days",\$err),"%m/%d/%Y"); if ((-e $video_dir . "daily-" . $odate . ".flv") && (-e $video_dir . "daily-" . $odate . ".jpg")) { push(@outfiles, "daily-" . $odate . ".flv"); push(@outfiles, "daily-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " " . $podate . "\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/daily-" . $odate . ".jpg\n"; print XMLFILE " Daily video from " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Daily 5 days ago $odate=&UnixDate(&DateCalc("today 00:00:00","-5 days",\$err),"%Y%m%d"); $podate=&UnixDate(&DateCalc("today 00:00:00","-5 days",\$err),"%m/%d/%Y"); if ((-e $video_dir . "daily-" . $odate . ".flv") && (-e $video_dir . "daily-" . $odate . ".jpg")) { push(@outfiles, "daily-" . $odate . ".flv"); push(@outfiles, "daily-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " " . $podate . "\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/daily-" . $odate . ".jpg\n"; print XMLFILE " Daily video from " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Daily 6 days ago $odate=&UnixDate(&DateCalc("today 00:00:00","-6 days",\$err),"%Y%m%d"); $podate=&UnixDate(&DateCalc("today 00:00:00","-6 days",\$err),"%m/%d/%Y"); if ((-e $video_dir . "daily-" . $odate . ".flv") && (-e $video_dir . "daily-" . $odate . ".jpg")) { push(@outfiles, "daily-" . $odate . ".flv"); push(@outfiles, "daily-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " " . $podate . "\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/daily-" . $odate . ".jpg\n"; print XMLFILE " Daily video from " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Daily 7 days ago $odate=&UnixDate(&DateCalc("today 00:00:00","-7 days",\$err),"%Y%m%d"); $podate=&UnixDate(&DateCalc("today 00:00:00","-7 days",\$err),"%m/%d/%Y"); if ((-e $video_dir . "daily-" . $odate . ".flv") && (-e $video_dir . "daily-" . $odate . ".jpg")) { push(@outfiles, "daily-" . $odate . ".flv"); push(@outfiles, "daily-" . $odate . ".jpg"); print XMLFILE " \n"; print XMLFILE " " . $podate . "\n"; print XMLFILE " http://www.EXAMPLE.com/WEBSERVERPATH/daily-" . $odate . ".jpg\n"; print XMLFILE " Daily video from " . $podate . "\n"; print XMLFILE " \n"; print XMLFILE " \n"; print XMLFILE " \n"; } ### Finish XML and close print XMLFILE " \n"; print XMLFILE ""; close (XMLFILE); ### Delete existing files and copy created files to webserver ### single quotes are easier than escaping system('/sbin/mount.cifs //SERVER/SHARE /home/webcam/wwwroot -o rw,user=USERNAME,password=PASSWORD'); system('/bin/rm /home/webcam/wwwroot/*'); foreach $fout (@outfiles) { system("/bin/cp " . $video_dir . $fout . " /home/webcam/wwwroot/"); } system('/sbin/umount.cifs /home/webcam/wwwroot/'); ### Backup the pictures system('/sbin/mount.cifs //BACKUPSERVER/SHARE /home/webcam/wwwroot -o rw,user=USERNAME,password=PASSWORD'); system('/bin/rm /home/webcam/wwwroot/*.gz'); system('/bin/rm /home/webcam/backup.tar.gz'); system("/bin/tar czf /home/webcam/backup.tar.gz " . $dirtoget); system('/bin/cp /home/webcam/backup.tar.gz /home/webcam/wwwroot/'); system('/sbin/umount.cifs /home/webcam/wwwroot/');