Added support for ffmpeg.

git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@481 e3e1d417-86f3-4887-817a-d78f3d33393f
pull/27/merge
stan 2003-04-14 13:04:52 +00:00
parent 10ff484a90
commit d29ccdcde7
3 changed files with 98 additions and 44 deletions

View File

@ -61,6 +61,7 @@ use constant ZM_OPT_MESSAGE => <from zmconfig>;
use constant ZM_MESSAGE_ADDRESS => <from zmconfig>;
use constant ZM_URL => <from zmconfig>;
use constant ZM_FROM_EMAIL => <from zmconfig>;
use constant ZM_OPT_MPEG => <from zmconfig>;
use constant EVENT_PATH => ZM_PATH_WEB.'/'.ZM_DIR_EVENTS;
use constant LOG_FILE => ZM_PATH_LOGS.'/zmfilter-%d.log';
@ -655,7 +656,7 @@ sub substituteTags
{
push( @$attachments_ref, { type=>"image/jpeg", path=>sprintf( "%s/%d/capture-%03d.jpg", $filter->{MonitorName}, $event->{Id}, $max_alarm_frame->{FrameId} ) } );
}
if ( $attachments_ref && $text =~ s/%EV%/Event video attached/g )
if ( $attachments_ref && ZM_OPT_MPEG ne "no" && $text =~ s/%EV%/Event video attached/g )
{
my $command = ZM_PATH_BIN."/zmvideo.pl -e $event->{Id}";
my $output = qx($command);

View File

@ -36,12 +36,16 @@ use constant ZM_PATH_WEB => "<from zmconfig>";
use constant ZM_PATH_CGI => "<from zmconfig>";
use constant ZM_PATH_LOGS => "<from zmconfig>";
use constant ZM_PATH_NETPBM => "<from zmconfig>";
use constant ZM_OPT_MPEG => "<from zmconfig>";
use constant ZM_PATH_MPEG_ENCODE => "<from zmconfig>";
use constant ZM_PATH_FFMPEG => "<from zmconfig>";
use constant ZM_FFMPEG_OPTIONS => "<from zmconfig>";
use constant ZM_DB_SERVER => "<from zmconfig>";
use constant ZM_DB_NAME => "<from zmconfig>";
use constant ZM_DB_USERB => "<from zmconfig>";
use constant ZM_DB_PASSB => "<from zmconfig>";
use constant ZM_DIR_EVENTS => "<from zmconfig>";
use constant ZM_COLOUR_JPEG_FILES => "<from zmconfig>";
use constant LOG_FILE => ZM_PATH_LOGS.'/zmvideo.log';
use constant VERBOSE => 0; # Whether to output more verbose debug
@ -85,6 +89,12 @@ if ( !$event_id || $event_id < 0 )
Usage();
}
if ( ZM_OPT_MPEG eq "no" )
{
print( STDERR "Mpeg encoding is not currently enabled\n" );
exit(-1);
}
my $log_file = LOG_FILE;
open( LOG, ">>$log_file" ) or die( "Can't open log file: $!" );
#open( STDOUT, ">&LOG" ) || die( "Can't dup stdout: $!" );
@ -103,53 +113,68 @@ my $event = $sth->fetchrow_hashref();
$sth->finish();
chdir( ZM_PATH_WEB.'/'.ZM_DIR_EVENTS.'/'.$event->{MonitorName}.'/'.$event->{Id} );
( my $video_name = $event->{Name} ) =~ s/\s/_/g;
my $param_file = "$video_name.mpe";
my $video_file = "$video_name.mpg";
if ( !-s $video_file )
{
print( LOG "Creating video file $video_file for event $event->{Id}\n" );
open( PARAMS, ">$param_file" ) or die( "Can't open '$param_file': $!" );
print( PARAMS "PATTERN IBBPBBPBBPBBPBB\n" );
print( PARAMS "FORCE_ENCODE_LAST_FRAME\n" );
print( PARAMS "OUTPUT $video_file\n" );
print( PARAMS "BASE_FILE_FORMAT JPEG\n" );
print( PARAMS "GOP_SIZE 30\n" );
print( PARAMS "SLICES_PER_FRAME 1\n" );
print( PARAMS "PIXEL HALF\n" );
print( PARAMS "RANGE 10\n" );
print( PARAMS "PSEARCH_ALG LOGARITHMIC\n" );
print( PARAMS "BSEARCH_ALG CROSS2\n" );
print( PARAMS "IQSCALE 8\n" );
print( PARAMS "PQSCALE 10\n" );
print( PARAMS "BQSCALE 25\n" );
print( PARAMS "REFERENCE_FRAME ORIGINAL\n" );
print( PARAMS "FRAME_RATE 24\n" );
if ( $event->{Palette} == 1 )
if ( ZM_OPT_MPEG eq "mpeg_encode" )
{
print( PARAMS "INPUT_CONVERT ".ZM_PATH_NETPBM."/jpegtopnm * | ".ZM_PATH_NETPBM."/pgmtoppm white | ".ZM_PATH_NETPBM."/ppmtojpeg\n" );
my $param_file = "$video_name.mpe";
open( PARAMS, ">$param_file" ) or die( "Can't open '$param_file': $!" );
print( PARAMS "PATTERN IBBPBBPBBPBBPBB\n" );
print( PARAMS "FORCE_ENCODE_LAST_FRAME\n" );
print( PARAMS "OUTPUT $video_file\n" );
print( PARAMS "BASE_FILE_FORMAT JPEG\n" );
print( PARAMS "GOP_SIZE 30\n" );
print( PARAMS "SLICES_PER_FRAME 1\n" );
print( PARAMS "PIXEL HALF\n" );
print( PARAMS "RANGE 10\n" );
print( PARAMS "PSEARCH_ALG LOGARITHMIC\n" );
print( PARAMS "BSEARCH_ALG CROSS2\n" );
print( PARAMS "IQSCALE 8\n" );
print( PARAMS "PQSCALE 10\n" );
print( PARAMS "BQSCALE 25\n" );
print( PARAMS "REFERENCE_FRAME ORIGINAL\n" );
print( PARAMS "FRAME_RATE 24\n" );
if ( $event->{Palette} == 1 && !ZM_COLOUR_JPEG_FILES )
{
print( PARAMS "INPUT_CONVERT ".ZM_PATH_NETPBM."/jpegtopnm * | ".ZM_PATH_NETPBM."/pgmtoppm white | ".ZM_PATH_NETPBM."/ppmtojpeg\n" );
}
else
{
print( PARAMS "INPUT_CONVERT *\n" );
}
print( PARAMS "INPUT_DIR .\n" );
print( PARAMS "INPUT\n" );
for ( my $i = 1; $i <= $event->{Frames}; $i++ )
{
printf( PARAMS "capture-%03d.jpg\n", $i );
}
print( PARAMS "END_INPUT\n" );
close( PARAMS );
my $command = ZM_PATH_MPEG_ENCODE." $param_file >mpeg.log";
my $output = qx($command);
}
elsif ( ZM_OPT_MPEG eq "ffmpeg" )
{
my $frame_rate = sprintf( "%.2f", $event->{Frames}/$event->{Length} );
my $command = ZM_PATH_FFMPEG." -y ".ZM_FFMPEG_OPTIONS." -r $frame_rate -i capture-%03d.jpg $video_file > mpeg.log";
my $output = qx($command);
}
else
{
print( PARAMS "INPUT_CONVERT *\n" );
die( "Bogus mpeg option ".ZM_OPT_MPEG."\n" );
}
print( PARAMS "INPUT_DIR .\n" );
print( PARAMS "INPUT\n" );
for ( my $i = 1; $i <= $event->{Frames}; $i++ )
{
printf( PARAMS "capture-%03d.jpg\n", $i );
}
print( PARAMS "END_INPUT\n" );
close( PARAMS );
my $command = ZM_PATH_MPEG_ENCODE." $param_file >mpeg.log";
my $output = qx($command);
my $status = $? >> 8;
if ( $status )
{

View File

@ -219,6 +219,13 @@ my @options =
help => "Some cameras or video cards capture images in BGR (Blue-Green-Red) order even when the paletter says RGB. If you see strange colours casts on your images then it may be worth trying this option to see if that corrects the issue. Note this option will apply only to local cameras and not those over a network.",
type => $types{boolean},
},
{
name => "ZM_COLOUR_JPEG_FILES",
default => "yes",
description => "Colourise greyscale JPEG files",
help => "Cameras that capture in greyscale can write their captured images to jpeg files with a corresponding greyscale colour space. This saves a small amount of disk space over colour ones. However some tools such as ffmpeg and mpeg_encode either fail to work with this colour space or have to convert it beforehand. Setting this option to yes uses up a little more space but makes creation of MPGE files much faster.",
type => $types{boolean},
},
{
name => "ZM_JPEG_FILE_QUALITY",
default => "70",
@ -275,24 +282,41 @@ my @options =
default => "2500",
description => "How long ZoneMinder waits before giving up on images (millseconds)",
requires => [ { name => "ZM_OPT_REMOTE_CAMERAS", value => "yes" } ],
help => "When retrieving remote images ZoneMinder will wait for this length of time before deciding that an image is not going to arrive and taking steps to retry. This timeout is in millseconds (1000 per second) and will apply to each part of an image if it is not sent in one whole chunk.",
help => "When retrieving remote images ZoneMinder will wait for this length of time before deciding that an image is not going to arrive and taking steps to retry. This timeout is in milliseconds (1000 per second) and will apply to each part of an image if it is not sent in one whole chunk.",
type => $types{integer},
},
{
name => "ZM_OPT_MPEG",
default => "no",
description => "Is the (optional) mpeg video encoder installed",
help => "ZoneMinder can optionally encode a series of video images into an MPEG encoded file and this path should point to where the Berkeley mpeg_encode program has ben installed. This encoder is fairly slow and you don't lose much by not having it as events can still be reviewed as video stream without it.",
description => "Is there an (optional) mpeg video encoder installed",
help => "ZoneMinder can optionally encode a series of video images into an MPEG encoded file. This option allows you to specifiy whether you have an mpeg encoder installed and if so which one. The two that ZoneMinder supports are mpeg_encode and ffmpeg, of which the latter is by far the fastest. However creating MPEG files can be fairly CPU and disk intensive and is not required as events can still be reviewed as video stream without it.",
type => $types{boolean},
type => { hint => 'no|mpeg_encode|ffmpeg', parse => sub { return( int($_[0] =~ /^([nmf])/i ), $1 =~ /^n/ ? 'no' : ( $1 =~ /^m/ ? 'mpeg_encode' : 'ffmpeg') ) } },
},
{
name => "ZM_PATH_MPEG_ENCODE",
default => "/usr/local/bin/mpeg_encode",
description => "Path to (optional) mpeg video encoder",
help => "ZoneMinder can optionally encode a series of video images into an MPEG encoded file and this path should point to where the Berkeley mpeg_encode program has ben installed. This encoder is fairly slow and you don't lose much by not having it as events can still be reviewed as video stream without it.",
requires => [ { name=>"ZM_OPT_MPEG", value=>"yes" } ],
description => "Path to (optional) Berkeley mpeg encoder",
help => "This path should point to where the Berkeley mpeg_encode program has been installed.",
requires => [ { name=>"ZM_OPT_MPEG", value=>"mpeg_encode" } ],
type => $types{abs_path},
},
{
name => "ZM_PATH_FFMPEG",
default => "/usr/local/bin/ffmpeg",
description => "Path to (optional) ffmpeg mpeg encoder",
help => "This path should point to where the ffmpeg has been installed.",
requires => [ { name=>"ZM_OPT_MPEG", value=>"ffmpeg" } ],
type => $types{abs_path},
},
{
name => "ZM_FFMPEG_OPTIONS",
default => "-hq -intra",
description => "Additional options to ffmpeg",
help => "Ffmpeg can take many options on the command line to control the quality of video produced. This option allows you to specify your own set. Check the ffmpeg documentation for the meaning of these and other options.",
requires => [ { name=>"ZM_OPT_MPEG", value=>"ffmpeg" } ],
type => $types{string},
},
{
name => "ZM_OPT_NETPBM",
default => "no",
@ -976,6 +1000,10 @@ sub loadOptions
}
if ( defined($value) )
{
if ( $name eq "ZM_OPT_MPEG" && $value eq "yes" )
{
$value = "mpeg_encode";
}
$option->{value} = $value;
}
}
@ -991,7 +1019,7 @@ sub breaktext
if ( $reprocess )
{
my @config_files = qw( src/zm_config.h web/zm_config.php scripts/zmdc.pl scripts/zmwatch.pl scripts/zmaudit.pl scripts/zmfilter.pl scripts/zmx10.pl scripts/zmpkg.pl scripts/zm db/zmschema.sql );
my @config_files = qw( src/zm_config.h web/zm_config.php scripts/zmdc.pl scripts/zmwatch.pl scripts/zmaudit.pl scripts/zmfilter.pl scripts/zmx10.pl scripts/zmpkg.pl scripts/zmvideo.pl scripts/zm db/zmschema.sql );
foreach my $config_file ( @config_files )
{