Creating a "movie" from a bunch of stills is pretty simple when you have ffmpeg handy. As before, code below is in chunks and the
full script can be found here.
Since we're storing all a day's images in a particular directory, all we need to do is glob them up and pipe a concatenate to ffmpeg.
#!/usr/bin/perl -w
use strict; use File::Glob ':glob'; use Date::Calc qw{ Today Add_Delta_Days }; use Data::Dumper;
use constant DEBUG => 1; use constant BASE_DIR => '/home/fliptop/tv-ip551wi/';
We'll use File::Glob to gather all the image filenames into a list. We'll also need the Add_Delta_Days method to figure out yesterday's date so we know which files to glob (this code gets run sometime after midnight and operates on the previous day's pictures).
Please note that this script is designed to work on images from just one camera. It could easily be modified to handle multiple directories for more than one camera by setting the BASE_DIR constant to an array of directories then looping over them with the ffmpeg code
below.
open LOG, '>>/tmp/ffmpeg_tv-ip551wi.log' or die "can't open log file: $!";
my @Yesterday = Add_Delta_Days(Today, -1);
# does the dir exist? my ($year, $month, $day) = @Yesterday; my $dir = sprintf "%s%s/%02d/%02d", BASE_DIR, @Yesterday; my $movie_dir = sprintf "%s%s/%02d", BASE_DIR, $year, $month;
unless (-e $dir) { printf LOG "base directory %s does not exist!\n", $dir if DEBUG; die; }
As always, open a log file for debugging purposes. After we figure out yesterday's date, make sure it exists and die if it doesn't.
my $files = sprintf "%s/*.jpg", $dir; my @list = bsd_glob($files);
printf LOG "found %s images in directory %s\n", scalar(@list), $dir if DEBUG; my $mpg = sprintf "%s/%s%02d%02d.mpg", $movie_dir, @Yesterday;
If the directory exists, we use the bsd_glob method to put all the filenames into the @list array. We'll give the final movie a name that corresponds to yesterday's date as well.
print LOG "creating mpg from images...\n" if DEBUG; my $resp = qx{ /bin/cat $files | /usr/bin/ffmpeg -f image2pipe -sameq -vcodec mjpeg -i - -y $mpg }; print LOG "finished creating mpg\n" if DEBUG;
if ($resp) { printf LOG "unable to create mpeg: $resp\n" if DEBUG; }
close LOG;
exit();
Here we use the cat command and pipe the output to ffmpeg, which will create a mjpeg movie. If you take one picture every 10 seconds over a 24-hour period, the final movie will be about 5 minutes long. See the ffmpeg man page for more information.
Cheap surveillance w/ perl and IP cameras, part 5
Creating a "movie" from a bunch of stills is pretty simple when you have ffmpeg handy. As before, code below is in chunks and the full script can be found here.
Since we're storing all a day's images in a particular directory, all we need to do is glob them up and pipe a concatenate to ffmpeg.
We'll use File::Glob to gather all the image filenames into a list. We'll also need the Add_Delta_Days method to figure out yesterday's date so we know which files to glob (this code gets run sometime after midnight and operates on the previous day's pictures).
Please note that this script is designed to work on images from just one camera. It could easily be modified to handle multiple directories for more than one camera by setting the BASE_DIR constant to an array of directories then looping over them with the ffmpeg code below.
As always, open a log file for debugging purposes. After we figure out yesterday's date, make sure it exists and die if it doesn't.
If the directory exists, we use the bsd_glob method to put all the filenames into the @list array. We'll give the final movie a name that corresponds to yesterday's date as well.
Here we use the cat command and pipe the output to ffmpeg, which will create a mjpeg movie. If you take one picture every 10 seconds over a 24-hour period, the final movie will be about 5 minutes long. See the ffmpeg man page for more information.
Coming next, invoking it all with cron.
Post Comment