I am not exactly a perl expert, but I wrote this script so that my ZM backup script can call it and besides doing a SQL dump, I want to save all my "Archived" events.
So, this script goes into the ZM database, grabs all events marked with an Archive flag, calculates the necessary FPS/Size/etc and generates the files and logs it all.
I have my system set with "Deep Storage" and the script automatically checks for that, however, I haven't been able to test this script on a non-deep storage configed system. So until someone can do that for me, make sure you test it.
Anyways, here it is... I'm sure there are bugs:
Code: Select all
#!/usr/bin/perl
####
# Zoneminder Event Archived Movie Generator
#
# Questions/Comments: fireball@the-shadows.net
####
use ZoneMinder;
use DBI;
# Define constant variables
$dbuser = "zmuser";
$dbpass = "zmpass";
$eventpath = "/var/www/events";
$tmpdir = "/tmp";
$outputdir = "/tmp/archivedmovies"; # Location of output movies.
$ffmpeg = "/usr/bin/ffmpeg";
$vidext = "avi"; # File extension
$time = time;
$hostname = `hostname -s`;
chomp $hostname;
# Connect to Database
my $dbh = DBI->connect('DBI:mysql:zm', $dbuser, $dbpass)
or die "Couldn't connect to database: " . DBI->errstr;
# Queries
# Use Deep Storage?
$isdeep = $dbh->prepare('SELECT Value from Config WHERE Name="ZM_USE_DEEP_STORAGE"')
or die "Couldn't prepare statement: " . $dbh->errstr;
$getevents = $dbh->prepare('SELECT * FROM Events WHERE Archived=1')
or die "Couldn't prepare statement: " . $dbh->errstr;
$isdeep->execute;
$deepvalue = $isdeep->fetchrow();
$getevents->execute;
while (@data = $getevents->fetchrow()) {
$starttime = $data[4]; $monid = $data[1]; $id = $data[0]; $frames = $data[9]; $duration = $data[8];
$width = $data[6]; $height = $data[7];
$size = $width . "x" . $height;
# Calculate FPS
$rawfps = $frames / $duration;
my $fps = sprintf( "%.2f", $rawfps);
if ($starttime =~ m/20(\d\d)\-(\d\d)\-(\d\d)\s(\d\d)\:(\d\d)\:(\d\d)/) {
$yr = $1;
$mon = $2;
$day = $3;
$hr = $4;
$min = $5;
$sec = $6;
}
if ($deepvalue eq "1") {
system("/bin/ls $eventpath/$monid/$yr/$mon/$day/$hr/$min/$sec/*capture.jpg > $tmpdir/eventfiles.$id");
}
else {
# This may need to be changed for non-deep storage filesystems
system("/bin/ls $eventpath/$monid/$id/*capture.jpg > $tmpdir/eventfiles.$id");
}
open(IMAGES, "$tmpdir/eventfiles.$id");
@eventimages = <IMAGES>;
chomp @eventimages;
$num = 1;
$num = sprintf("%9d", $num);
$num =~ tr/ /0/;
`mkdir $tmpdir/eventlinks.$id`;
foreach $image (@eventimages) {
`ln -s $image $tmpdir/eventlinks.$id/$num.jpg`;
$num++;
}
# Run the Command
`$ffmpeg -y -r $fps -i $tmpdir/eventlinks.$id/%09d.jpg -s $size -r 25 $outputdir/Event-$id\_20$yr$mon$day_$hr$min$sec.$vidext 2>> $outputdir/ffmpeg_$time.log`;
# Remove Files
`rm -r $tmpdir/eventlinks.$id $tmpdir/eventfiles.$id`;
}