Archive Events to MPEG Video

If you've made a patch to quick fix a bug or to add a new feature not yet in the main tree then post it here so others can try it out.
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

The easiest (only?) way to do a batch conversion to mpeg or avi is to create a small script that just calls zmvideo.pl passing in the event id as a parameter. You can then use the custom script option on the filters to run your script which will be passed in the event id, which can then be passed to zmvideo.pl. You can probably just use the full path to zmvideo.pl instead of an additional script but I've not tried it and you might want to add logging etc to your script.

This assumes by the way that generation of videos via zmvideo.pl works for you (ie via the web interface). Otherwise you can always call ffmpeg directly from your script with whatever parameters work for you.

By the way, scripts are only ever called once per event from filters so you won't get videos created repeatedly for the same events.

Phil
skydiver
Posts: 86
Joined: Wed Jun 16, 2004 7:15 pm

Post by skydiver »

When you say that they will be called once per event, what exactly are the parameters which determine whether the filter has been called previously. My concern are that in the debugging process, I will not be changing the filter once set, only the script itself while debugging.

Any help in creating the script would be most usefel but I am using this as an occation to learn a little scripting via the O'Reilly's Classic Shell Scripting book :)

Trying like hell to lose the newbie moniker.
jameswilson
Posts: 5111
Joined: Wed Jun 08, 2005 8:07 pm
Location: Midlands UK

Post by jameswilson »

i assume the emailed record in the events table is modified when the script is run. I suppose you could just edit the table and put tis back to a 0 to make it show up again.
James Wilson

Disclaimer: The above is pure theory and may work on a good day with the wind behind it. etc etc.
http://www.securitywarehouse.co.uk
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

That is correct. There are fields for Emailed, Messaged, Uploaded etc in the Events table. To get a filter to rerun on an event just reset these fields to 0.

Phil
skydiver
Posts: 86
Joined: Wed Jun 16, 2004 7:15 pm

Post by skydiver »

How is the script executed? Is is passed an array of all matching events or is it called once for each event?
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

Once per event, with the event id passed in as a parameter.

Phil
skydiver
Posts: 86
Joined: Wed Jun 16, 2004 7:15 pm

Post by skydiver »

When the filter is submitted, does the processing occur in the background (ie. If the filter window is closed on the client, does processing continue to occur in thebackground)?

I have tried to set the script to execute to the following:
/usr/local/bin/zmvideo.pl -e
to no avail.


I have also tried to create a script like:

#!/bin/bash
echo Processed Event $1 >> /usr/local/bin/filter-zmvideo.log
/usr/local/bin/zmvideo.pl -e $1 -r 1 -s 1 -o

I am filtering for all Archived events. I have gone into the events table in phpMyAdmin and checked that the fields Uploaded, Emailed, Messaged, and Executed are all set to 0 on records with the Archived field set to 1.

I can't see any execution of the script occuring. Where does zm log filtered event processing? I cannot find it in the messages log.
skydiver
Posts: 86
Joined: Wed Jun 16, 2004 7:15 pm

Post by skydiver »

Selfishly bumping this tread back into activity. I am still having problems trying to get the filteres script to execute.
jameswilson
Posts: 5111
Joined: Wed Jun 08, 2005 8:07 pm
Location: Midlands UK

Post by jameswilson »

if you have saved the filter it will be run in the background at the freq set in options

Log wise if you look in you log folder there sould be another folder called zm and most of zm's logs are in there. I know the filter one is but i forget its name at the mo.

Script wise ill bow out now as i aint got a clue
James Wilson

Disclaimer: The above is pure theory and may work on a good day with the wind behind it. etc etc.
http://www.securitywarehouse.co.uk
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

I will take a proper look at this tomorrow and hopefully get back to you.

Phil
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

I have just set up a test filter to auto execute. I created a test script in /tmp, called zmtest.pl (see listing below) and set the following path /tmp/zmtest.pl in the filter.

I was slightly wrong above as what is passed in is not just the event id but <monitor_id>/<event_id>, e.g. 3/1654 which is effectively the path component to the event under the events directory. I can't remember even doing that change but I assume that wasn't your issue as you'd have seen your script running but with bogus parameters.

I made sure that /tmp/zmtest.pl had appriopriate execute permissions and it seems to be running ok. The script is as follows

Code: Select all

#!/usr/bin/perl -wT
use strict;
use bytes;

use constant ZM_CONFIG => "/usr/local/etc/zm.conf";	# Path to the ZoneMinder config file, autogenerated do not change (from zmconfig)
use constant ZM_PATH_BIN => "/usr/local/bin";	# Path to the ZoneMinder executables, autogenerated do not change (from zmconfig)
use constant ZM_PATH_WEB => "/var/www/html/zm";	# Path to the ZoneMinder web files, autogenerated do not change (from zmconfig)
use constant ZM_PATH_CGI => "/var/www/cgi-bin";	# Path to the ZoneMinder cgi files, autogenerated do not change (from zmconfig)

# Load the config from the database into the symbol table
BEGIN
{
	no strict 'refs';

	open( CONFIG, "<".ZM_CONFIG ) or die( "Can't open config file: $!" );
	foreach my $str ( <CONFIG> )
	{
		next if ( $str =~ /^\s*$/ );
		next if ( $str =~ /^\s*#/ );
		my ( $name, $value ) = $str =~ /^\s*([^=\\s]+)\s*=\s*(\S+)\s*$/;
		$name =~ tr/a-z/A-Z/;
		if (( $name eq 'ZM_DB_SERVER' ) ||
			( $name eq 'ZM_DB_NAME' ) ||
			( $name eq 'ZM_DB_USER' ) ||
			( $name eq 'ZM_DB_PASS' ))
		{
			*{$name} = sub { $value };
		}
	}
	close( CONFIG );

	use DBI;
	my $dbh = DBI->connect( "DBI:mysql:database=".&ZM_DB_NAME.";host=".&ZM_DB_SERVER, &ZM_DB_USER, &ZM_DB_PASS );
	my $sql = "select * from Config";
	my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
	my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
	while( my $config = $sth->fetchrow_hashref() )
	{
		*{$config->{Name}} = sub { $config->{Value} };
	}
	$sth->finish();
	$dbh->disconnect();
}

use constant LOG_FILE => ZM_PATH_LOGS.'/zmtest.log';
use constant VERBOSE => 0; # Whether to output more verbose debug

use DBI;
use Data::Dumper;
use Getopt::Long qw(:config no_ignore_case );

$| = 1;

$ENV{PATH}  = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};

my $log_file = LOG_FILE;
open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
#open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
#select( STDOUT ); $| = 1;
open( STDERR, ">&LOG" ) || die( "Can't dup stderr: $!" );
select( STDERR ); $| = 1;
select( LOG ); $| = 1;

my $event_id;
my $monitor_id;

if ( $ARGV[0] )
{
	( $monitor_id, $event_id ) = $ARGV[0] =~ m|^(\d+)/(\d+)$|;

	if ( !$monitor_id || $monitor_id < 0 )
	{
		print( "No valid monitor id given\n" );
		exit( -1 );
	}
	if ( !$event_id || $event_id < 0 )
	{
		print( "No valid event id given\n" );
		exit( -1 );
	}
}
else
{
	print( "No vald monitor/event ids given\n" );
	exit( -1 );
}

my ( $detaint_event_id ) = $event_id =~ /^(\d+)$/;
my ( $detaint_monitor_id ) = $monitor_id =~ /^(\d+)$/;

$event_id = $detaint_event_id;
$monitor_id = $detaint_monitor_id;

# Change to event directory
chdir( ZM_PATH_WEB.'/'.ZM_DIR_EVENTS.'/'.$monitor_id.'/'.$event_id );

# Do your thing here
#
# For instance, get event details
my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_SERVER, ZM_DB_USER, ZM_DB_PASS );
my $sql = "select * from Events where Id = ?";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $event_id ) or die( "Can't execute: ".$sth->errstr() );

my $event = $sth->fetchrow_hashref();
$sth->finish();

print( Dumper( $event ) );

$dbh->disconnect();

exit( 0 );
This is probably more complicated than you need as it loads the ZM config and creates a log file (make sure you have permissions for this) before laoding the event from the DB. At it's simplest you could just change directory to <events_dir>/<script argument> to get to the event.

Either way, if you use this as an initial example you should see something in the zmtest.log and the zmfilter.log indicating whether it has run ok. If the script fails to run then zmfilter will not mark the event as having been executed, otherwise it will and the event will not be rerun.

Hopefully this is of some use and if you are going to use this example to test don't forget to change the paths at the top to those on your system.

Phil
skydiver
Posts: 86
Joined: Wed Jun 16, 2004 7:15 pm

Post by skydiver »

Thanks!! This gives me a jumping off point to finally start to get this task debugged. Once I get it working, I will post back with report of success or for
further help.
chsholl
Posts: 3
Joined: Mon Apr 10, 2006 7:05 pm
Location: Brasil

FFMPEG

Post by chsholl »

Someone know how to configure ffmpeg correctly? Because I installed it, but a grey screen show...Thank's. My hard Disk is crowded whit jpg images...help-me, please...
gola10
Posts: 150
Joined: Wed Nov 01, 2006 3:16 pm
Location: Panama

Post by gola10 »

I have a 250gb hard disk for zoneminder with 8 cameras running 7/24 and can only record no more than 3 days and also has had some database crash.

I has seen in this forum that AVI may use less disk space. I would like to be able to convert every event that is one day old to AVI and erase the event from the database.
There are many post about it but has not found one that say how can it be done by a newbie.

Is someone doing something like this?

This will also keep the database small and maybe the computer would has less load.
Post Reply