Page 1 of 1

Archive Event Movie Generator Script

Posted: Mon Nov 22, 2010 8:13 pm
by MrEvoMan
Hello all,

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`;
    
    
}
Please test it and let me know how it works.