Merge branch 'master' into storageareas
This commit is contained in:
commit
451714a403
|
@ -1,6 +1,8 @@
|
||||||
language: cpp
|
language: cpp
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
git:
|
||||||
|
depth: 9999999
|
||||||
notifications:
|
notifications:
|
||||||
irc: chat.freenode.net#zoneminder-dev
|
irc: chat.freenode.net#zoneminder-dev
|
||||||
branches:
|
branches:
|
||||||
|
@ -20,6 +22,7 @@ addons:
|
||||||
- git
|
- git
|
||||||
- curl
|
- curl
|
||||||
- sshfs
|
- sshfs
|
||||||
|
- sed
|
||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
- OS=el DIST=6
|
- OS=el DIST=6
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
zoneminder (1.28.1-1) unstable; urgency=low
|
|
||||||
|
|
||||||
This version is no longer automatically initialize or upgrade database.
|
|
||||||
See README.Debian for details.
|
|
||||||
|
|
||||||
Changed installation paths (please correct your web server configuration):
|
|
||||||
/usr/share/zoneminder --> /usr/share/zoneminder/www
|
|
||||||
/usr/lib/cgi-bin --> /usr/lib/zoneminder/cgi-bin
|
|
||||||
|
|
||||||
-- Dmitry Smirnov <onlyjob@debian.org> Tue, 31 Mar 2015 15:12:17 +1100
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
zoneminder (1.31.0-trusty) trusty; urgency=medium
|
zoneminder (1.31.0-trusty) trusty; urgency=medium
|
||||||
|
|
||||||
* placeholder
|
* placeholder
|
||||||
|
|
||||||
-- Isaac Connor <iconnor@connortechnology.com> Fri, 13 May 2016 09:45:49 -0400
|
-- Isaac Connor <iconnor@connortechnology.com> Fri, 13 May 2016 09:45:49 -0400
|
||||||
|
=======
|
||||||
|
>>>>>>> master
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
3.0 (native)
|
3.0 (quilt)
|
||||||
|
|
|
@ -1600,7 +1600,7 @@ our @options = (
|
||||||
this overhead is fairly small but may be noticeable on IO-constrained
|
this overhead is fairly small but may be noticeable on IO-constrained
|
||||||
systems.
|
systems.
|
||||||
`,
|
`,
|
||||||
type => $types{string},
|
type => $types{boolean},
|
||||||
category => 'web',
|
category => 'web',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -223,9 +223,7 @@ sub GenerateVideo {
|
||||||
|
|
||||||
my $status = $? >> 8;
|
my $status = $? >> 8;
|
||||||
if ( $status ) {
|
if ( $status ) {
|
||||||
Error( "Unable to generate video, check "
|
Error( "Unable to generate video, check $event_path/ffmpeg.log for details");
|
||||||
.$event_path."/ffmpeg.log for details"
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +269,6 @@ sub delete {
|
||||||
}
|
}
|
||||||
} # end sub delete
|
} # end sub delete
|
||||||
|
|
||||||
|
|
||||||
sub delete_files {
|
sub delete_files {
|
||||||
|
|
||||||
my $Storage = new ZoneMinder::Storage( $_[0]{StorageId} );
|
my $Storage = new ZoneMinder::Storage( $_[0]{StorageId} );
|
||||||
|
@ -353,49 +350,26 @@ sub age {
|
||||||
|
|
||||||
1;
|
1;
|
||||||
__END__
|
__END__
|
||||||
# Below is stub documentation for your module. You'd better edit it!
|
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
ZoneMinder::Database - Perl extension for blah blah blah
|
ZoneMinder::Event - Perl Class for events
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
use ZoneMinder::Event;
|
use ZoneMinder::Event;
|
||||||
blah blah blah
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
Stub documentation for ZoneMinder, created by h2xs. It looks like the
|
The Event class has everything you need to deal with events from Perl.
|
||||||
author of the extension was negligent enough to leave the stub
|
|
||||||
unedited.
|
|
||||||
|
|
||||||
Blah blah blah.
|
|
||||||
|
|
||||||
=head2 EXPORT
|
|
||||||
|
|
||||||
None by default.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=head1 SEE ALSO
|
|
||||||
|
|
||||||
Mention other useful documentation such as the documentation of
|
|
||||||
related modules or operating system documentation (such as man pages
|
|
||||||
in UNIX), or any relevant external documentation such as RFCs or
|
|
||||||
standards.
|
|
||||||
|
|
||||||
If you have a mailing list set up for your module, mention it here.
|
|
||||||
|
|
||||||
If you have a web site set up for your module, mention it here.
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
Philip Coombes, E<lt>philip.coombes@zoneminder.comE<gt>
|
Isaac Connor, E<lt>isaac@zoneminder.comE<gt>
|
||||||
|
|
||||||
=head1 COPYRIGHT AND LICENSE
|
=head1 COPYRIGHT AND LICENSE
|
||||||
|
|
||||||
Copyright (C) 2001-2008 Philip Coombes
|
Copyright (C) 2001-2017 ZoneMinder LLC
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or modify
|
This library is free software; you can redistribute it and/or modify
|
||||||
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
||||||
|
|
|
@ -41,7 +41,7 @@ our @ISA = qw(Exporter ZoneMinder::Base);
|
||||||
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
||||||
# will save memory.
|
# will save memory.
|
||||||
our %EXPORT_TAGS = (
|
our %EXPORT_TAGS = (
|
||||||
'constants' => [ qw(
|
constants => [ qw(
|
||||||
STATE_IDLE
|
STATE_IDLE
|
||||||
STATE_PREALARM
|
STATE_PREALARM
|
||||||
STATE_ALARM
|
STATE_ALARM
|
||||||
|
@ -56,7 +56,7 @@ our %EXPORT_TAGS = (
|
||||||
TRIGGER_ON
|
TRIGGER_ON
|
||||||
TRIGGER_OFF
|
TRIGGER_OFF
|
||||||
) ],
|
) ],
|
||||||
'functions' => [ qw(
|
functions => [ qw(
|
||||||
zmMemVerify
|
zmMemVerify
|
||||||
zmMemInvalidate
|
zmMemInvalidate
|
||||||
zmMemRead
|
zmMemRead
|
||||||
|
@ -83,7 +83,7 @@ our %EXPORT_TAGS = (
|
||||||
);
|
);
|
||||||
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
||||||
|
|
||||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
|
||||||
|
|
||||||
our @EXPORT = qw();
|
our @EXPORT = qw();
|
||||||
|
|
||||||
|
@ -142,43 +142,43 @@ our $native = $arch/8;
|
||||||
our $mem_seq = 0;
|
our $mem_seq = 0;
|
||||||
|
|
||||||
our $mem_data = {
|
our $mem_data = {
|
||||||
'shared_data' => { 'type'=>'SharedData', 'seq'=>$mem_seq++, 'contents'=> {
|
shared_data => { type=>'SharedData', seq=>$mem_seq++, contents=> {
|
||||||
'size' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
size => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'last_write_index' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
last_write_index => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'last_read_index' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
last_read_index => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'state' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
state => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'last_event' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
last_event => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'action' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
action => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'brightness' => { 'type'=>'int32', 'seq'=>$mem_seq++ },
|
brightness => { type=>'int32', seq=>$mem_seq++ },
|
||||||
'hue' => { 'type'=>'int32', 'seq'=>$mem_seq++ },
|
hue => { type=>'int32', seq=>$mem_seq++ },
|
||||||
'colour' => { 'type'=>'int32', 'seq'=>$mem_seq++ },
|
colour => { type=>'int32', seq=>$mem_seq++ },
|
||||||
'contrast' => { 'type'=>'int32', 'seq'=>$mem_seq++ },
|
contrast => { type=>'int32', seq=>$mem_seq++ },
|
||||||
'alarm_x' => { 'type'=>'int32', 'seq'=>$mem_seq++ },
|
alarm_x => { type=>'int32', seq=>$mem_seq++ },
|
||||||
'alarm_y' => { 'type'=>'int32', 'seq'=>$mem_seq++ },
|
alarm_y => { type=>'int32', seq=>$mem_seq++ },
|
||||||
'valid' => { 'type'=>'uint8', 'seq'=>$mem_seq++ },
|
valid => { type=>'uint8', seq=>$mem_seq++ },
|
||||||
'active' => { 'type'=>'uint8', 'seq'=>$mem_seq++ },
|
active => { type=>'uint8', seq=>$mem_seq++ },
|
||||||
'signal' => { 'type'=>'uint8', 'seq'=>$mem_seq++ },
|
signal => { type=>'uint8', seq=>$mem_seq++ },
|
||||||
'format' => { 'type'=>'uint8', 'seq'=>$mem_seq++ },
|
format => { type=>'uint8', seq=>$mem_seq++ },
|
||||||
'imagesize' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
imagesize => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'epadding1' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
epadding1 => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'epadding2' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
epadding2 => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'startup_time' => { 'type'=>'time_t64', 'seq'=>$mem_seq++ },
|
startup_time => { type=>'time_t64', seq=>$mem_seq++ },
|
||||||
'last_write_time' => { 'type'=>'time_t64', 'seq'=>$mem_seq++ },
|
last_write_time => { type=>'time_t64', seq=>$mem_seq++ },
|
||||||
'last_read_time' => { 'type'=>'time_t64', 'seq'=>$mem_seq++ },
|
last_read_time => { type=>'time_t64', seq=>$mem_seq++ },
|
||||||
'control_state' => { 'type'=>'uint8[256]', 'seq'=>$mem_seq++ },
|
control_state => { type=>'uint8[256]', seq=>$mem_seq++ },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'trigger_data' => { 'type'=>'TriggerData', 'seq'=>$mem_seq++, 'contents'=> {
|
trigger_data => { type=>'TriggerData', seq=>$mem_seq++, 'contents'=> {
|
||||||
'size' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
size => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'trigger_state' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
trigger_state => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'trigger_score' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
trigger_score => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'padding' => { 'type'=>'uint32', 'seq'=>$mem_seq++ },
|
padding => { type=>'uint32', seq=>$mem_seq++ },
|
||||||
'trigger_cause' => { 'type'=>'int8[32]', 'seq'=>$mem_seq++ },
|
trigger_cause => { type=>'int8[32]', seq=>$mem_seq++ },
|
||||||
'trigger_text' => { 'type'=>'int8[256]', 'seq'=>$mem_seq++ },
|
trigger_text => { type=>'int8[256]', seq=>$mem_seq++ },
|
||||||
'trigger_showtext' => { 'type'=>'int8[256]', 'seq'=>$mem_seq++ },
|
trigger_showtext => { type=>'int8[256]', seq=>$mem_seq++ },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'end' => { 'seq'=>$mem_seq++, 'size'=> 0 }
|
end => { seq=>$mem_seq++, size=>0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
our $mem_size = 0;
|
our $mem_size = 0;
|
||||||
|
@ -420,7 +420,7 @@ sub zmMemWrite {
|
||||||
} elsif ( $type =~ /^uint8\[\d+\]$/ ) {
|
} elsif ( $type =~ /^uint8\[\d+\]$/ ) {
|
||||||
$data = pack( 'C'.$size, $value );
|
$data = pack( 'C'.$size, $value );
|
||||||
} else {
|
} else {
|
||||||
Fatal( "Unexpected type '".$type."' found for '".$field."'" );
|
Fatal( "Unexpected type \"$type\" found for \"$field\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !zmMemPut( $monitor, $offset, $size, $data ) ) {
|
if ( !zmMemPut( $monitor, $offset, $size, $data ) ) {
|
||||||
|
|
|
@ -40,15 +40,15 @@ our @ISA = qw(Exporter ZoneMinder::Base);
|
||||||
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
||||||
# will save memory.
|
# will save memory.
|
||||||
our %EXPORT_TAGS = (
|
our %EXPORT_TAGS = (
|
||||||
'functions' => [ qw(
|
functions => [ qw(
|
||||||
zmMemKey
|
zmMemKey
|
||||||
zmMemAttach
|
zmMemAttach
|
||||||
zmMemDetach
|
zmMemDetach
|
||||||
zmMemGet
|
zmMemGet
|
||||||
zmMemPut
|
zmMemPut
|
||||||
zmMemClean
|
zmMemClean
|
||||||
) ],
|
) ],
|
||||||
);
|
);
|
||||||
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
||||||
|
|
||||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||||
|
@ -102,7 +102,7 @@ sub zmMemAttach {
|
||||||
return ( undef );
|
return ( undef );
|
||||||
}
|
}
|
||||||
my $MMAP;
|
my $MMAP;
|
||||||
if ( !open( $MMAP, "+<", $mmap_file ) ) {
|
if ( !open( $MMAP, '+<', $mmap_file ) ) {
|
||||||
Error( sprintf( "Can't open memory map file '%s': $!\n", $mmap_file ) );
|
Error( sprintf( "Can't open memory map file '%s': $!\n", $mmap_file ) );
|
||||||
return( undef );
|
return( undef );
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,7 @@ sub zmMemAttach {
|
||||||
|
|
||||||
sub zmMemDetach {
|
sub zmMemDetach {
|
||||||
my $monitor = shift;
|
my $monitor = shift;
|
||||||
|
|
||||||
if ( $monitor->{MMap} ) {
|
if ( $monitor->{MMap} ) {
|
||||||
if ( ! munmap( ${$monitor->{MMap}} ) ) {
|
if ( ! munmap( ${$monitor->{MMap}} ) ) {
|
||||||
Warn( "Unable to munmap for monitor $$monitor{Id}\n");
|
Warn( "Unable to munmap for monitor $$monitor{Id}\n");
|
||||||
|
@ -174,7 +175,7 @@ sub zmMemPut {
|
||||||
|
|
||||||
sub zmMemClean {
|
sub zmMemClean {
|
||||||
Debug( "Removing memory map files\n" );
|
Debug( "Removing memory map files\n" );
|
||||||
my $mapPath = $Config{ZM_PATH_MAP}."/zm.mmap.*";
|
my $mapPath = $Config{ZM_PATH_MAP}.'/zm.mmap.*';
|
||||||
foreach my $mapFile( glob( $mapPath ) ) {
|
foreach my $mapFile( glob( $mapPath ) ) {
|
||||||
( $mapFile ) = $mapFile =~ /^(.+)$/;
|
( $mapFile ) = $mapFile =~ /^(.+)$/;
|
||||||
Debug( "Removing memory map file '$mapFile'\n" );
|
Debug( "Removing memory map file '$mapFile'\n" );
|
||||||
|
|
|
@ -61,49 +61,22 @@ sub Storage {
|
||||||
|
|
||||||
1;
|
1;
|
||||||
__END__
|
__END__
|
||||||
# Below is stub documentation for your module. You'd better edit it!
|
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
ZoneMinder::Database - Perl extension for blah blah blah
|
ZoneMinder::Monitor - Perl Class for Monitors
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
use ZoneMinder::Monitor;
|
use ZoneMinder::Monitor;
|
||||||
blah blah blah
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
Stub documentation for ZoneMinder, created by h2xs. It looks like the
|
|
||||||
author of the extension was negligent enough to leave the stub
|
|
||||||
unedited.
|
|
||||||
|
|
||||||
Blah blah blah.
|
|
||||||
|
|
||||||
=head2 EXPORT
|
|
||||||
|
|
||||||
None by default.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=head1 SEE ALSO
|
|
||||||
|
|
||||||
Mention other useful documentation such as the documentation of
|
|
||||||
related modules or operating system documentation (such as man pages
|
|
||||||
in UNIX), or any relevant external documentation such as RFCs or
|
|
||||||
standards.
|
|
||||||
|
|
||||||
If you have a mailing list set up for your module, mention it here.
|
|
||||||
|
|
||||||
If you have a web site set up for your module, mention it here.
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
Philip Coombes, E<lt>philip.coombes@zoneminder.comE<gt>
|
Isaac Connor, E<lt>isaac@zoneminder.comE<gt>
|
||||||
|
|
||||||
=head1 COPYRIGHT AND LICENSE
|
=head1 COPYRIGHT AND LICENSE
|
||||||
|
|
||||||
Copyright (C) 2001-2008 Philip Coombes
|
Copyright (C) 2001-2017 ZoneMinder LLC
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or modify
|
This library is free software; you can redistribute it and/or modify
|
||||||
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
||||||
|
|
|
@ -59,7 +59,7 @@ use bytes;
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
|
|
||||||
use constant RECOVER_TAG => '(r)'; # Tag to append to event name when recovered
|
use constant RECOVER_TAG => '(r)'; # Tag to append to event name when recovered
|
||||||
use constant RECOVER_TEXT => "Recovered."; # Text to append to event notes when recovered
|
use constant RECOVER_TEXT => 'Recovered.'; # Text to append to event notes when recovered
|
||||||
|
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
#
|
#
|
||||||
|
@ -98,11 +98,11 @@ logInit();
|
||||||
logSetSignal();
|
logSetSignal();
|
||||||
|
|
||||||
GetOptions(
|
GetOptions(
|
||||||
'interactive' =>\$interactive,
|
continuous =>\$continuous,
|
||||||
'continuous' =>\$continuous,
|
interactive =>\$interactive,
|
||||||
'monitor_id=s' =>\$monitor_id,
|
monitor_id =>\$monitor_id,
|
||||||
'report' =>\$report,
|
report =>\$report,
|
||||||
'version' =>\$version
|
version =>\$version
|
||||||
) or pod2usage(-exitstatus => -1);
|
) or pod2usage(-exitstatus => -1);
|
||||||
|
|
||||||
if ( $version ) {
|
if ( $version ) {
|
||||||
|
@ -114,6 +114,10 @@ if ( ($report + $interactive + $continuous) > 1 ) {
|
||||||
pod2usage(-exitstatus => -1);
|
pod2usage(-exitstatus => -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! exists $Config{ZM_AUDIT_MIN_AGE} ) {
|
||||||
|
Fatal('ZM_AUDIT_MIN_AGE is not set in config.');
|
||||||
|
}
|
||||||
|
|
||||||
my $dbh = zmDbConnect();
|
my $dbh = zmDbConnect();
|
||||||
|
|
||||||
require ZoneMinder::Monitor;
|
require ZoneMinder::Monitor;
|
||||||
|
@ -128,10 +132,6 @@ my $loop = 1;
|
||||||
my $cleaned = 0;
|
my $cleaned = 0;
|
||||||
MAIN: while( $loop ) {
|
MAIN: while( $loop ) {
|
||||||
|
|
||||||
if ( ! exists $Config{ZM_AUDIT_MIN_AGE} ) {
|
|
||||||
Fatal("ZM_AUDIT_MIN_AGE is not set in config.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $continuous ) {
|
if ( $continuous ) {
|
||||||
# if we are running continuously, then just skip to the next
|
# if we are running continuously, then just skip to the next
|
||||||
# interval, otherwise we are a one off run, so wait a second and
|
# interval, otherwise we are a one off run, so wait a second and
|
||||||
|
@ -158,11 +158,11 @@ MAIN: while( $loop ) {
|
||||||
|
|
||||||
my %Monitors;
|
my %Monitors;
|
||||||
my $db_monitors;
|
my $db_monitors;
|
||||||
my $monitorSelectSql = $monitor_id ? 'SELECT * FRO Monitors WHERE Id=?' : 'SELECT * FROM Monitors ORDER BY Id';
|
my $monitorSelectSql = $monitor_id ? 'SELECT * FROM Monitors WHERE Id=?' : 'SELECT * FROM Monitors ORDER BY Id';
|
||||||
my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql )
|
my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql )
|
||||||
or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() );
|
or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() );
|
||||||
|
|
||||||
my $eventSelectSql = 'SELECT Id, (unix_timestamp() - unix_timestamp(StartTime)) as Age
|
my $eventSelectSql = 'SELECT Id, (unix_timestamp() - unix_timestamp(StartTime)) AS Age
|
||||||
FROM Events WHERE MonitorId = ? ORDER BY Id';
|
FROM Events WHERE MonitorId = ? ORDER BY Id';
|
||||||
my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql )
|
my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql )
|
||||||
or Fatal( "Can't prepare '$eventSelectSql': ".$dbh->errstr() );
|
or Fatal( "Can't prepare '$eventSelectSql': ".$dbh->errstr() );
|
||||||
|
@ -555,7 +555,7 @@ Debug("Event $db_event is not in fs.");
|
||||||
if ( $Config{ZM_LOG_DATABASE_LIMIT} ) {
|
if ( $Config{ZM_LOG_DATABASE_LIMIT} ) {
|
||||||
if ( $Config{ZM_LOG_DATABASE_LIMIT} =~ /^\d+$/ ) {
|
if ( $Config{ZM_LOG_DATABASE_LIMIT} =~ /^\d+$/ ) {
|
||||||
# Number of rows
|
# Number of rows
|
||||||
my $selectLogRowCountSql = 'SELECT count(*) as Rows from Logs';
|
my $selectLogRowCountSql = 'SELECT count(*) AS Rows FROM Logs';
|
||||||
my $selectLogRowCountSth = $dbh->prepare_cached( $selectLogRowCountSql )
|
my $selectLogRowCountSth = $dbh->prepare_cached( $selectLogRowCountSql )
|
||||||
or Fatal( "Can't prepare '$selectLogRowCountSql': ".$dbh->errstr() );
|
or Fatal( "Can't prepare '$selectLogRowCountSql': ".$dbh->errstr() );
|
||||||
$res = $selectLogRowCountSth->execute()
|
$res = $selectLogRowCountSth->execute()
|
||||||
|
@ -569,15 +569,14 @@ Debug("Event $db_event is not in fs.");
|
||||||
$res = $deleteLogByRowsSth->execute( $logRows - $Config{ZM_LOG_DATABASE_LIMIT} )
|
$res = $deleteLogByRowsSth->execute( $logRows - $Config{ZM_LOG_DATABASE_LIMIT} )
|
||||||
or Fatal( "Can't execute: ".$deleteLogByRowsSth->errstr() );
|
or Fatal( "Can't execute: ".$deleteLogByRowsSth->errstr() );
|
||||||
if ( $deleteLogByRowsSth->rows() ) {
|
if ( $deleteLogByRowsSth->rows() ) {
|
||||||
aud_print( 'Deleted '.$deleteLogByRowsSth->rows()
|
aud_print( 'Deleted '.$deleteLogByRowsSth->rows() ." log table entries by count\n" );
|
||||||
." log table entries by count\n" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
# Time of record
|
# Time of record
|
||||||
my $deleteLogByTimeSql =
|
my $deleteLogByTimeSql =
|
||||||
"DELETE low_priority FROM Logs
|
'DELETE low_priority FROM Logs
|
||||||
WHERE TimeKey < unix_timestamp(now() - interval ".$Config{ZM_LOG_DATABASE_LIMIT}.')';
|
WHERE TimeKey < unix_timestamp(now() - interval '.$Config{ZM_LOG_DATABASE_LIMIT}.')';
|
||||||
my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql )
|
my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql )
|
||||||
or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() );
|
or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() );
|
||||||
$res = $deleteLogByTimeSth->execute()
|
$res = $deleteLogByTimeSth->execute()
|
||||||
|
|
|
@ -27,7 +27,11 @@ zmfilter.pl - ZoneMinder tool to filter events
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
zmfilter.pl [-f <filter name>,--filter=<filter name>] [--filter_id=<filter id>] | -v, --version
|
zmfilter.pl [-f <filter name>,--filter=<filter name>] [--filter_id=<filter id>] | -v, --version
|
||||||
|
=======
|
||||||
|
zmfilter.pl [-f <filter name>,--filter=<filter name>] | -v, --version
|
||||||
|
>>>>>>> master
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
@ -70,7 +74,7 @@ use Getopt::Long;
|
||||||
use autouse 'Pod::Usage'=>qw(pod2usage);
|
use autouse 'Pod::Usage'=>qw(pod2usage);
|
||||||
use autouse 'Data::Dumper'=>qw(Dumper);
|
use autouse 'Data::Dumper'=>qw(Dumper);
|
||||||
|
|
||||||
my $filter_name = "";
|
my $filter_name = '';
|
||||||
my $filter_id;
|
my $filter_id;
|
||||||
my $version = 0;
|
my $version = 0;
|
||||||
|
|
||||||
|
@ -93,19 +97,19 @@ use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)
|
||||||
: ($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS})
|
: ($Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS})
|
||||||
;
|
;
|
||||||
|
|
||||||
logInit();
|
logInit();
|
||||||
logSetSignal();
|
logSetSignal();
|
||||||
|
|
||||||
if ( $Config{ZM_OPT_UPLOAD} ) {
|
if ( $Config{ZM_OPT_UPLOAD} ) {
|
||||||
# Comment these out if you don't have them and don't want to upload
|
# Comment these out if you don't have them and don't want to upload
|
||||||
# or don't want to use that format
|
# or don't want to use that format
|
||||||
if ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "zip" ) {
|
if ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq 'zip' ) {
|
||||||
require Archive::Zip;
|
require Archive::Zip;
|
||||||
import Archive::Zip qw( :ERROR_CODES :CONSTANTS );
|
import Archive::Zip qw( :ERROR_CODES :CONSTANTS );
|
||||||
} else {
|
} else {
|
||||||
require Archive::Tar;
|
require Archive::Tar;
|
||||||
}
|
}
|
||||||
if ( $Config{ZM_UPLOAD_PROTOCOL} eq "ftp" ) {
|
if ( $Config{ZM_UPLOAD_PROTOCOL} eq 'ftp' ) {
|
||||||
require Net::FTP;
|
require Net::FTP;
|
||||||
} else {
|
} else {
|
||||||
require Net::SFTP::Foreign;
|
require Net::SFTP::Foreign;
|
||||||
|
@ -144,8 +148,10 @@ if ( ! EVENT_PATH ) {
|
||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# In future, should not be neccessary wrt StorageAreas
|
||||||
chdir( EVENT_PATH );
|
chdir( EVENT_PATH );
|
||||||
|
|
||||||
|
# SHould not be neccessary... but nice to get a local var. What if it fails?
|
||||||
my $dbh = zmDbConnect();
|
my $dbh = zmDbConnect();
|
||||||
|
|
||||||
if ( $filter_name ) {
|
if ( $filter_name ) {
|
||||||
|
@ -157,10 +163,11 @@ if ( $filter_name ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! ( $filter_name or $filter_id ) ) {
|
if ( ! ( $filter_name or $filter_id ) ) {
|
||||||
|
Debug("Sleeping due to start delay: " . START_DELAY . ' seconds...' );
|
||||||
sleep( START_DELAY );
|
sleep( START_DELAY );
|
||||||
}
|
}
|
||||||
|
|
||||||
my $filters;
|
my @filters;
|
||||||
my $last_action = 0;
|
my $last_action = 0;
|
||||||
|
|
||||||
while( 1 ) {
|
while( 1 ) {
|
||||||
|
@ -194,28 +201,34 @@ sub getFilters {
|
||||||
my @sql_values;
|
my @sql_values;
|
||||||
|
|
||||||
my @filters;
|
my @filters;
|
||||||
my $sql = "SELECT * FROM Filters WHERE";
|
my $sql = 'SELECT * FROM Filters WHERE';
|
||||||
if ( $$sql_filters{Name} ) {
|
if ( $$sql_filters{Name} ) {
|
||||||
$sql .= " Name = ? and";
|
$sql .= ' Name = ? AND';
|
||||||
push @sql_values, $$sql_filters{Name};
|
push @sql_values, $$sql_filters{Name};
|
||||||
} elsif ( $$sql_filters{Id} ) {
|
} elsif ( $$sql_filters{Id} ) {
|
||||||
$sql .= " Id = ? and";
|
$sql .= ' Id = ? AND';
|
||||||
push @sql_values, $$sql_filters{Id};
|
push @sql_values, $$sql_filters{Id};
|
||||||
} else {
|
} else {
|
||||||
$sql .= " Background = 1 and";
|
$sql .= ' Background = 1 AND';
|
||||||
}
|
}
|
||||||
$sql .= "( AutoArchive = 1
|
$sql .= '( AutoArchive = 1
|
||||||
or AutoVideo = 1
|
or AutoVideo = 1
|
||||||
or AutoUpload = 1
|
or AutoUpload = 1
|
||||||
or AutoEmail = 1
|
or AutoEmail = 1
|
||||||
or AutoMessage = 1
|
or AutoMessage = 1
|
||||||
or AutoExecute = 1
|
or AutoExecute = 1
|
||||||
or AutoDelete = 1
|
or AutoDelete = 1
|
||||||
) ORDER BY Name";
|
) ORDER BY Name';
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
my $res = $sth->execute( @sql_values )
|
my $res;
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
if ( $filter_name ) {
|
||||||
|
$res = $sth->execute( $filter_name )
|
||||||
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
|
} else {
|
||||||
|
$res = $sth->execute()
|
||||||
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
|
}
|
||||||
FILTER: while( my $db_filter = $sth->fetchrow_hashref() ) {
|
FILTER: while( my $db_filter = $sth->fetchrow_hashref() ) {
|
||||||
my $filter = new ZoneMinder::Filter( $$db_filter{Id}, $db_filter );
|
my $filter = new ZoneMinder::Filter( $$db_filter{Id}, $db_filter );
|
||||||
Debug( "Found filter '$db_filter->{Name}'\n" );
|
Debug( "Found filter '$db_filter->{Name}'\n" );
|
||||||
|
@ -242,14 +255,14 @@ sub checkFilter {
|
||||||
|
|
||||||
my @Events = $filter->Execute();
|
my @Events = $filter->Execute();
|
||||||
Info( join( "Checking filter '$filter->{Name}'",
|
Info( join( "Checking filter '$filter->{Name}'",
|
||||||
($filter->{AutoDelete}?", delete":""),
|
($filter->{AutoDelete}?', delete':''),
|
||||||
($filter->{AutoArchive}?", archive":""),
|
($filter->{AutoArchive}?', archive':''),
|
||||||
($filter->{AutoVideo}?", video":""),
|
($filter->{AutoVideo}?', video':''),
|
||||||
($filter->{AutoUpload}?", upload":""),
|
($filter->{AutoUpload}?', upload':''),
|
||||||
($filter->{AutoEmail}?", email":""),
|
($filter->{AutoEmail}?', email':''),
|
||||||
($filter->{AutoMessage}?", message":""),
|
($filter->{AutoMessage}?', message':''),
|
||||||
($filter->{AutoExecute}?", execute":""),
|
($filter->{AutoExecute}?', execute':''),
|
||||||
" returned " , scalar @Events , ' events',
|
' returned ' , scalar @Events , ' events',
|
||||||
"\n",
|
"\n",
|
||||||
) );
|
) );
|
||||||
|
|
||||||
|
@ -260,11 +273,11 @@ sub checkFilter {
|
||||||
if ( $filter->{AutoArchive} ) {
|
if ( $filter->{AutoArchive} ) {
|
||||||
Info( "Archiving event $event->{Id}\n" );
|
Info( "Archiving event $event->{Id}\n" );
|
||||||
# Do it individually to avoid locking up the table for new events
|
# Do it individually to avoid locking up the table for new events
|
||||||
my $sql = "update Events set Archived = 1 where Id = ?";
|
my $sql = 'UPDATE Events SET Archived = 1 WHERE Id = ?';
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
my $res = $sth->execute( $event->{Id} )
|
my $res = $sth->execute( $event->{Id} )
|
||||||
or Error( "Can't execute '$sql': ".$sth->errstr() );
|
or Error( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
}
|
}
|
||||||
if ( $Config{ZM_OPT_FFMPEG} && $filter->{AutoVideo} ) {
|
if ( $Config{ZM_OPT_FFMPEG} && $filter->{AutoVideo} ) {
|
||||||
if ( !$event->{Videoed} ) {
|
if ( !$event->{Videoed} ) {
|
||||||
|
@ -296,7 +309,7 @@ sub checkFilter {
|
||||||
my $Event = new ZoneMinder::Event( $$event{Id}, $event );
|
my $Event = new ZoneMinder::Event( $$event{Id}, $event );
|
||||||
$Event->delete();
|
$Event->delete();
|
||||||
} else {
|
} else {
|
||||||
Error( "Unable to delete event $event->{Id} as previous operations failed\n" );
|
Error( "Unable toto delete event $event->{Id} as previous operations failed\n" );
|
||||||
}
|
}
|
||||||
} # end if AutoDelete
|
} # end if AutoDelete
|
||||||
} # end foreach event
|
} # end foreach event
|
||||||
|
@ -330,8 +343,17 @@ sub generateVideo {
|
||||||
$format = $ffmpeg_formats[0];
|
$format = $ffmpeg_formats[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
my $command = $Config{ZM_PATH_BIN}."/zmvideo.pl -e "
|
my $command = join( '',
|
||||||
.$event->{Id}." -r ".$rate." -s ".$scale." -f ".$format;
|
$Config{ZM_PATH_BIN},
|
||||||
|
'/zmvideo.pl -e ',
|
||||||
|
$event->{Id},
|
||||||
|
' -r ',
|
||||||
|
$rate,
|
||||||
|
' -s ',
|
||||||
|
$scale,
|
||||||
|
' -f ',
|
||||||
|
$format,
|
||||||
|
);
|
||||||
my $output = qx($command);
|
my $output = qx($command);
|
||||||
chomp( $output );
|
chomp( $output );
|
||||||
my $status = $? >> 8;
|
my $status = $? >> 8;
|
||||||
|
@ -345,13 +367,12 @@ sub generateVideo {
|
||||||
}
|
}
|
||||||
return( 0 );
|
return( 0 );
|
||||||
} else {
|
} else {
|
||||||
my $sql = "update Events set Videoed = 1 where Id = ?";
|
my $sql = 'UPDATE Events SET Videoed = 1 WHERE Id = ?';
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
my $res = $sth->execute( $event->{Id} )
|
my $res = $sth->execute( $event->{Id} )
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
if ( wantarray() )
|
if ( wantarray() ) {
|
||||||
{
|
|
||||||
return( $format, $output );
|
return( $format, $output );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,52 +384,53 @@ sub generateVideo {
|
||||||
# If neither capture nor analyse image exists it will try to extract a frame from .mp4 file if exists
|
# If neither capture nor analyse image exists it will try to extract a frame from .mp4 file if exists
|
||||||
# An empty string is returned if no one from methods above works
|
# An empty string is returned if no one from methods above works
|
||||||
sub generateImage {
|
sub generateImage {
|
||||||
my $event = shift;
|
my $event = shift;
|
||||||
my $frame = shift;
|
my $frame = shift;
|
||||||
my $analyse = do { @_ ? shift : 0 }; # don't return analyse image by default
|
my $analyse = do { @_ ? shift : 0 }; # don't return analyse image by default
|
||||||
|
|
||||||
my $capture_image_path = sprintf("%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-capture.jpg", getEventPath($event), $frame->{FrameId});
|
my $capture_image_path = sprintf('%s/%0'.$Config{ZM_EVENT_IMAGE_DIGITS}.'d-capture.jpg', getEventPath($event), $frame->{FrameId});
|
||||||
my $analyse_image_path = sprintf("%s/%0".$Config{ZM_EVENT_IMAGE_DIGITS}."d-analyse.jpg", getEventPath($event), $frame->{FrameId}) if $analyse;
|
my $analyse_image_path = sprintf('%s/%0'.$Config{ZM_EVENT_IMAGE_DIGITS}.'d-analyse.jpg', getEventPath($event), $frame->{FrameId}) if $analyse;
|
||||||
my $video_path = sprintf("%s/%d-video.mp4", getEventPath($event), $event->{Id});
|
my $video_path = sprintf('%s/%d-video.mp4', getEventPath($event), $event->{Id});
|
||||||
my $image_path = "";
|
my $image_path = '';
|
||||||
|
|
||||||
# check if the image file exists. If the file doesn't exist and we use H264 try to extract it from .mp4 video
|
# check if the image file exists. If the file doesn't exist and we use H264 try to extract it from .mp4 video
|
||||||
if ( $analyse && -r $analyse_image_path ) {
|
if ( $analyse && -r $analyse_image_path ) {
|
||||||
$image_path = $analyse_image_path;
|
$image_path = $analyse_image_path;
|
||||||
} elsif ( -r $capture_image_path ) {
|
} elsif ( -r $capture_image_path ) {
|
||||||
$image_path = $capture_image_path;
|
$image_path = $capture_image_path;
|
||||||
} elsif ( -e $video_path ) {
|
} elsif ( -e $video_path ) {
|
||||||
if ( !system("ffmpeg -y -v 0 -i ".$video_path." -vf 'select=gte(n\\,".$frame->{FrameId}."),setpts=PTS-STARTPTS' -vframes 1 -f image2 ".$capture_image_path) ) {
|
if ( !system('ffmpeg -y -v 0 -i '.$video_path." -vf 'select=gte(n\\,".$frame->{FrameId}."),setpts=PTS-STARTPTS' -vframes 1 -f image2 ".$capture_image_path) ) {
|
||||||
$image_path = $capture_image_path;
|
$image_path = $capture_image_path;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return $image_path;
|
}
|
||||||
|
return $image_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub uploadArchFile {
|
sub uploadArchFile {
|
||||||
my $filter = shift;
|
my $filter = shift;
|
||||||
my $event = shift;
|
my $event = shift;
|
||||||
|
|
||||||
if ( ! $Config{ZM_UPLOAD_HOST} ) {
|
if ( ! $Config{ZM_UPLOAD_HOST} ) {
|
||||||
Error( "Cannot upload archive as no upload host defined" );
|
Error( 'Cannot upload archive as no upload host defined' );
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
my $archFile = $event->{MonitorName}.'-'.$event->{Id};
|
my $archFile = $event->{MonitorName}.'-'.$event->{Id};
|
||||||
my $archImagePath = getEventPath( $event )
|
my $archImagePath = getEventPath( $event )
|
||||||
."/"
|
.'/'
|
||||||
.(
|
.(
|
||||||
( $Config{ZM_UPLOAD_ARCH_ANALYSE} )
|
( $Config{ZM_UPLOAD_ARCH_ANALYSE} )
|
||||||
? '{*analyse,*capture}'
|
? '{*analyse,*capture}'
|
||||||
: '*capture'
|
: '*capture'
|
||||||
)
|
)
|
||||||
.".jpg"
|
.'.jpg'
|
||||||
;
|
;
|
||||||
my @archImageFiles = glob($archImagePath);
|
my @archImageFiles = glob($archImagePath);
|
||||||
my $archLocPath;
|
my $archLocPath;
|
||||||
|
|
||||||
my $archError = 0;
|
my $archError = 0;
|
||||||
if ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "zip" ) {
|
if ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq 'zip' ) {
|
||||||
$archFile .= '.zip';
|
$archFile .= '.zip';
|
||||||
$archLocPath = $Config{ZM_UPLOAD_LOC_DIR}.'/'.$archFile;
|
$archLocPath = $Config{ZM_UPLOAD_LOC_DIR}.'/'.$archFile;
|
||||||
my $zip = Archive::Zip->new();
|
my $zip = Archive::Zip->new();
|
||||||
|
@ -419,7 +441,7 @@ sub uploadArchFile {
|
||||||
Debug( "Adding $imageFile\n" );
|
Debug( "Adding $imageFile\n" );
|
||||||
my $member = $zip->addFile( $imageFile );
|
my $member = $zip->addFile( $imageFile );
|
||||||
if ( !$member ) {
|
if ( !$member ) {
|
||||||
Error( "Unable to add image file $imageFile to zip archive $archLocPath" );
|
Error( "Unable toto add image file $imageFile to zip archive $archLocPath" );
|
||||||
$archError = 1;
|
$archError = 1;
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
@ -437,7 +459,7 @@ sub uploadArchFile {
|
||||||
} else {
|
} else {
|
||||||
Error( "Error adding images to zip archive $archLocPath, not writing" );
|
Error( "Error adding images to zip archive $archLocPath, not writing" );
|
||||||
}
|
}
|
||||||
} elsif ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq "tar" ) {
|
} elsif ( $Config{ZM_UPLOAD_ARCH_FORMAT} eq 'tar' ) {
|
||||||
if ( $Config{ZM_UPLOAD_ARCH_COMPRESS} ) {
|
if ( $Config{ZM_UPLOAD_ARCH_COMPRESS} ) {
|
||||||
$archFile .= '.tar.gz';
|
$archFile .= '.tar.gz';
|
||||||
} else {
|
} else {
|
||||||
|
@ -452,73 +474,72 @@ sub uploadArchFile {
|
||||||
@archImageFiles
|
@archImageFiles
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Error( "Tar error: ".Archive::Tar->error()."\n " );
|
Error( 'Tar error: '.Archive::Tar->error()."\n " );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $archError ) {
|
if ( $archError ) {
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
|
||||||
|
|
||||||
if ( $Config{ZM_UPLOAD_PROTOCOL} eq "ftp" ) {
|
|
||||||
Info( "Uploading to ".$Config{ZM_UPLOAD_HOST}." using FTP\n" );
|
|
||||||
my $ftp = Net::FTP->new(
|
|
||||||
$Config{ZM_UPLOAD_HOST},
|
|
||||||
Timeout=>$Config{ZM_UPLOAD_TIMEOUT},
|
|
||||||
Passive=>$Config{ZM_UPLOAD_FTP_PASSIVE},
|
|
||||||
Debug=>$Config{ZM_UPLOAD_DEBUG}
|
|
||||||
);
|
|
||||||
if ( !$ftp ) {
|
|
||||||
Error( "Can't create FTP connection: $@" );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
$ftp->login( $Config{ZM_UPLOAD_USER}, $Config{ZM_UPLOAD_PASS} )
|
|
||||||
or Error( "FTP - Can't login" );
|
|
||||||
$ftp->binary()
|
|
||||||
or Error( "FTP - Can't go binary" );
|
|
||||||
$ftp->cwd( $Config{ZM_UPLOAD_REM_DIR} )
|
|
||||||
or Error( "FTP - Can't cwd" )
|
|
||||||
if ( $Config{ZM_UPLOAD_REM_DIR} );
|
|
||||||
$ftp->put( $archLocPath )
|
|
||||||
or Error( "FTP - Can't upload '$archLocPath'" );
|
|
||||||
$ftp->quit()
|
|
||||||
or Error( "FTP - Can't quit" );
|
|
||||||
} else {
|
} else {
|
||||||
my $host = $Config{ZM_UPLOAD_HOST};
|
if ( $Config{ZM_UPLOAD_PROTOCOL} eq 'ftp' ) {
|
||||||
$host .= ":".$Config{ZM_UPLOAD_PORT}
|
Info( 'Uploading to '.$Config{ZM_UPLOAD_HOST}." using FTP\n" );
|
||||||
if $Config{ZM_UPLOAD_PORT};
|
my $ftp = Net::FTP->new(
|
||||||
Info( "Uploading to ".$host." using SFTP\n" );
|
$Config{ZM_UPLOAD_HOST},
|
||||||
my %sftpOptions = ( host=>$Config{ZM_UPLOAD_HOST}, user=>$Config{ZM_UPLOAD_USER} );
|
Timeout=>$Config{ZM_UPLOAD_TIMEOUT},
|
||||||
$sftpOptions{password} = $Config{ZM_UPLOAD_PASS}
|
Passive=>$Config{ZM_UPLOAD_FTP_PASSIVE},
|
||||||
if $Config{ZM_UPLOAD_PASS};
|
Debug=>$Config{ZM_UPLOAD_DEBUG}
|
||||||
$sftpOptions{port} = $Config{ZM_UPLOAD_PORT}
|
);
|
||||||
if $Config{ZM_UPLOAD_PORT};
|
if ( !$ftp ) {
|
||||||
$sftpOptions{timeout} = $Config{ZM_UPLOAD_TIMEOUT}
|
Error( "Unable tocreate FTP connection: $@" );
|
||||||
if $Config{ZM_UPLOAD_TIMEOUT};
|
return( 0 );
|
||||||
my @more_ssh_args;
|
}
|
||||||
push @more_ssh_args, '-o'=>'StrictHostKeyChecking=no'
|
$ftp->login( $Config{ZM_UPLOAD_USER}, $Config{ZM_UPLOAD_PASS} )
|
||||||
if ! $Config{ZM_UPLOAD_STRICT};
|
or Error( "FTP - Unable tologin" );
|
||||||
push @more_ssh_args, '-v'
|
$ftp->binary()
|
||||||
if $Config{ZM_UPLOAD_DEBUG};
|
or Error( "FTP - Unable togo binary" );
|
||||||
$sftpOptions{more} = [@more_ssh_args];
|
$ftp->cwd( $Config{ZM_UPLOAD_REM_DIR} )
|
||||||
my $sftp = Net::SFTP::Foreign->new( $Config{ZM_UPLOAD_HOST}, %sftpOptions );
|
or Error( "FTP - Unable tocwd" )
|
||||||
if ( $sftp->error ) {
|
if ( $Config{ZM_UPLOAD_REM_DIR} );
|
||||||
Error( "Can't create SFTP connection: ".$sftp->error );
|
$ftp->put( $archLocPath )
|
||||||
return( 0 );
|
or Error( "FTP - Unable toupload '$archLocPath'" );
|
||||||
|
$ftp->quit()
|
||||||
|
or Error( "FTP - Unable toquit" );
|
||||||
|
} else {
|
||||||
|
my $host = $Config{ZM_UPLOAD_HOST};
|
||||||
|
$host .= ':'.$Config{ZM_UPLOAD_PORT}
|
||||||
|
if $Config{ZM_UPLOAD_PORT};
|
||||||
|
Info( 'Uploading to '.$host." using SFTP\n" );
|
||||||
|
my %sftpOptions = ( host=>$Config{ZM_UPLOAD_HOST}, user=>$Config{ZM_UPLOAD_USER} );
|
||||||
|
$sftpOptions{password} = $Config{ZM_UPLOAD_PASS}
|
||||||
|
if $Config{ZM_UPLOAD_PASS};
|
||||||
|
$sftpOptions{port} = $Config{ZM_UPLOAD_PORT}
|
||||||
|
if $Config{ZM_UPLOAD_PORT};
|
||||||
|
$sftpOptions{timeout} = $Config{ZM_UPLOAD_TIMEOUT}
|
||||||
|
if $Config{ZM_UPLOAD_TIMEOUT};
|
||||||
|
my @more_ssh_args;
|
||||||
|
push @more_ssh_args, '-o'=>'StrictHostKeyChecking=no'
|
||||||
|
if ! $Config{ZM_UPLOAD_STRICT};
|
||||||
|
push @more_ssh_args, '-v'
|
||||||
|
if $Config{ZM_UPLOAD_DEBUG};
|
||||||
|
$sftpOptions{more} = [@more_ssh_args];
|
||||||
|
my $sftp = Net::SFTP::Foreign->new( $Config{ZM_UPLOAD_HOST}, %sftpOptions );
|
||||||
|
if ( $sftp->error ) {
|
||||||
|
Error( "Unable tocreate SFTP connection: ".$sftp->error );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
$sftp->setcwd( $Config{ZM_UPLOAD_REM_DIR} )
|
||||||
|
or Error( "SFTP - Unable tosetcwd: ".$sftp->error )
|
||||||
|
if $Config{ZM_UPLOAD_REM_DIR};
|
||||||
|
$sftp->put( $archLocPath, $archFile )
|
||||||
|
or Error( "SFTP - Unable toupload '$archLocPath': ".$sftp->error );
|
||||||
}
|
}
|
||||||
$sftp->setcwd( $Config{ZM_UPLOAD_REM_DIR} )
|
unlink( $archLocPath );
|
||||||
or Error( "SFTP - Can't setcwd: ".$sftp->error )
|
my $sql = 'UPDATE Events SET Uploaded = 1 WHERE Id = ?';
|
||||||
if $Config{ZM_UPLOAD_REM_DIR};
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
$sftp->put( $archLocPath, $archFile )
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
or Error( "SFTP - Can't upload '$archLocPath': ".$sftp->error );
|
my $res = $sth->execute( $event->{Id} )
|
||||||
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink( $archLocPath );
|
|
||||||
my $sql = "update Events set Uploaded = 1 where Id = ?";
|
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
|
||||||
my $res = $sth->execute( $event->{Id} )
|
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
|
||||||
return( 1 );
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +556,7 @@ sub substituteTags {
|
||||||
|
|
||||||
my $monitor = {};
|
my $monitor = {};
|
||||||
if ( $need_monitor ) {
|
if ( $need_monitor ) {
|
||||||
my $db_now = strftime( "%Y-%m-%d %H:%M:%S", localtime() );
|
my $db_now = strftime( '%Y-%m-%d %H:%M:%S', localtime() );
|
||||||
my $sql = "SELECT
|
my $sql = "SELECT
|
||||||
M.Id,
|
M.Id,
|
||||||
count(E.Id) as EventCount,
|
count(E.Id) as EventCount,
|
||||||
|
@ -555,9 +576,9 @@ sub substituteTags {
|
||||||
ORDER BY Id"
|
ORDER BY Id"
|
||||||
;
|
;
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
my $res = $sth->execute( $event->{MonitorId} )
|
my $res = $sth->execute( $event->{MonitorId} )
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
$monitor = $sth->fetchrow_hashref();
|
$monitor = $sth->fetchrow_hashref();
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
return() if ( !$monitor );
|
return() if ( !$monitor );
|
||||||
|
@ -574,9 +595,9 @@ sub substituteTags {
|
||||||
ORDER BY FrameId"
|
ORDER BY FrameId"
|
||||||
;
|
;
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
my $res = $sth->execute( $event->{Id} )
|
my $res = $sth->execute( $event->{Id} )
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
while( my $frame = $sth->fetchrow_hashref() ) {
|
while( my $frame = $sth->fetchrow_hashref() ) {
|
||||||
if ( !$first_alarm_frame ) {
|
if ( !$first_alarm_frame ) {
|
||||||
$first_alarm_frame = $frame;
|
$first_alarm_frame = $frame;
|
||||||
|
@ -615,64 +636,47 @@ sub substituteTags {
|
||||||
$text =~ s/%EST%/$event->{TotScore}/g;
|
$text =~ s/%EST%/$event->{TotScore}/g;
|
||||||
$text =~ s/%ESA%/$event->{AvgScore}/g;
|
$text =~ s/%ESA%/$event->{AvgScore}/g;
|
||||||
$text =~ s/%ESM%/$event->{MaxScore}/g;
|
$text =~ s/%ESM%/$event->{MaxScore}/g;
|
||||||
|
|
||||||
if ( $first_alarm_frame ) {
|
if ( $first_alarm_frame ) {
|
||||||
$text =~ s/%EPI1%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$first_alarm_frame->{FrameId}/g;
|
$text =~ s/%EPI1%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$first_alarm_frame->{FrameId}/g;
|
||||||
$text =~ s/%EPIM%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$max_alarm_frame->{FrameId}/g;
|
$text =~ s/%EPIM%/$url?view=frame&mid=$event->{MonitorId}&eid=$event->{Id}&fid=$max_alarm_frame->{FrameId}/g;
|
||||||
if ( $attachments_ref && $text =~ s/%EI1%//g ) {
|
if ( $attachments_ref && $text =~ s/%EI1%//g ) {
|
||||||
my $path = generateImage( $event, $first_alarm_frame);
|
my $path = generateImage( $event, $first_alarm_frame );
|
||||||
if ( -e $path ) {
|
|
||||||
push( @$attachments_ref,
|
|
||||||
{
|
|
||||||
type=>"image/jpeg",
|
|
||||||
path=>$path
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( $attachments_ref && $text =~ s/%EIM%//g ) {
|
|
||||||
# Don't attach the same image twice
|
|
||||||
if ( !@$attachments_ref
|
|
||||||
|| ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} )
|
|
||||||
) {
|
|
||||||
my $path = generateImage( $event, $max_alarm_frame);
|
|
||||||
if ( -e $path ) {
|
if ( -e $path ) {
|
||||||
push( @$attachments_ref,
|
push( @$attachments_ref, { type=>'image/jpeg', path=>$path } );
|
||||||
{
|
|
||||||
type=>"image/jpeg",
|
|
||||||
path=>$path
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ( $attachments_ref && $text =~ s/%EI1A%//g ) {
|
if ( $attachments_ref && $text =~ s/%EIM%//g ) {
|
||||||
my $path = generateImage( $event, $first_alarm_frame, "analyse" );
|
# Don't attach the same image twice
|
||||||
if ( -e $path ) {
|
if ( !@$attachments_ref
|
||||||
push( @$attachments_ref,
|
|| ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} )
|
||||||
{
|
) {
|
||||||
type=>"image/jpeg",
|
my $path = generateImage( $event, $max_alarm_frame );
|
||||||
path=>$path
|
if ( -e $path ) {
|
||||||
|
push( @$attachments_ref, { type=>'image/jpeg', path=>$path } );
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( $attachments_ref && $text =~ s/%EIMA%//g ) {
|
|
||||||
# Don't attach the same image twice
|
|
||||||
if ( !@$attachments_ref
|
|
||||||
|| ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} )
|
|
||||||
) {
|
|
||||||
my $path = generateImage( $event, $max_alarm_frame, "analyse");
|
|
||||||
if ( -e $path ) {
|
|
||||||
push( @$attachments_ref,
|
|
||||||
{
|
|
||||||
type=>"image/jpeg",
|
|
||||||
path=>$path
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if ( $attachments_ref && $text =~ s/%EI1A%//g ) {
|
||||||
}
|
my $path = generateImage( $event, $first_alarm_frame, 'analyse' );
|
||||||
|
if ( -e $path ) {
|
||||||
|
push( @$attachments_ref, { type=>'image/jpeg', path=>$path } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( $attachments_ref && $text =~ s/%EIMA%//g ) {
|
||||||
|
# Don't attach the same image twice
|
||||||
|
if ( !@$attachments_ref
|
||||||
|
|| ($first_alarm_frame->{FrameId} != $max_alarm_frame->{FrameId} )
|
||||||
|
) {
|
||||||
|
my $path = generateImage( $event, $max_alarm_frame, 'analyse');
|
||||||
|
if ( -e $path ) {
|
||||||
|
push( @$attachments_ref, { type=>'image/jpeg', path=>$path } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} # end if $first_alarm_frame
|
||||||
|
|
||||||
if ( $attachments_ref && $Config{ZM_OPT_FFMPEG} ) {
|
if ( $attachments_ref && $Config{ZM_OPT_FFMPEG} ) {
|
||||||
if ( $text =~ s/%EV%//g ) {
|
if ( $text =~ s/%EV%//g ) {
|
||||||
my ( $format, $path ) = generateVideo( $filter, $event );
|
my ( $format, $path ) = generateVideo( $filter, $event );
|
||||||
|
@ -694,7 +698,7 @@ sub substituteTags {
|
||||||
$text =~ s/%FP%/$url?view=filter&mid=$event->{MonitorId}&filter_name=$filter_name/g;
|
$text =~ s/%FP%/$url?view=filter&mid=$event->{MonitorId}&filter_name=$filter_name/g;
|
||||||
|
|
||||||
return( $text );
|
return( $text );
|
||||||
}
|
} # end subsitituteTags
|
||||||
|
|
||||||
sub sendEmail {
|
sub sendEmail {
|
||||||
my $filter = shift;
|
my $filter = shift;
|
||||||
|
@ -705,7 +709,7 @@ sub sendEmail {
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
if ( ! $Config{ZM_EMAIL_ADDRESS} ) {
|
if ( ! $Config{ZM_EMAIL_ADDRESS} ) {
|
||||||
Error( "No email address defined, not sending email" );
|
Error( 'No email address defined, not sending email' );
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,11 +730,11 @@ sub sendEmail {
|
||||||
From => $Config{ZM_FROM_EMAIL},
|
From => $Config{ZM_FROM_EMAIL},
|
||||||
To => $Config{ZM_EMAIL_ADDRESS},
|
To => $Config{ZM_EMAIL_ADDRESS},
|
||||||
Subject => $subject,
|
Subject => $subject,
|
||||||
Type => "multipart/mixed"
|
Type => 'multipart/mixed'
|
||||||
);
|
);
|
||||||
### Add the text message part
|
### Add the text message part
|
||||||
$mail->attach (
|
$mail->attach (
|
||||||
Type => "TEXT",
|
Type => 'TEXT',
|
||||||
Data => $body
|
Data => $body
|
||||||
);
|
);
|
||||||
### Add the attachments
|
### Add the attachments
|
||||||
|
@ -739,7 +743,7 @@ sub sendEmail {
|
||||||
$mail->attach(
|
$mail->attach(
|
||||||
Path => $attachment->{path},
|
Path => $attachment->{path},
|
||||||
Type => $attachment->{type},
|
Type => $attachment->{type},
|
||||||
Disposition => "attachment"
|
Disposition => 'attachment'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
### Send the Message
|
### Send the Message
|
||||||
|
@ -752,15 +756,15 @@ sub sendEmail {
|
||||||
$ssmtp_location = qx('which ssmtp');
|
$ssmtp_location = qx('which ssmtp');
|
||||||
}
|
}
|
||||||
if ( !$ssmtp_location ) {
|
if ( !$ssmtp_location ) {
|
||||||
Debug( "Can't find ssmtp, trying MIME::Lite->send" );
|
Debug( "Unable tofind ssmtp, trying MIME::Lite->send" );
|
||||||
MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 );
|
MIME::Lite->send( 'smtp', $Config{ZM_EMAIL_HOST}, Timeout=>60 );
|
||||||
$mail->send();
|
$mail->send();
|
||||||
} else {
|
} else {
|
||||||
### Send using SSMTP
|
### Send using SSMTP
|
||||||
$mail->send( 'sendmail', $ssmtp_location, $Config{ZM_EMAIL_ADDRESS} );
|
$mail->send( 'sendmail', $ssmtp_location, $Config{ZM_EMAIL_ADDRESS} );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 );
|
MIME::Lite->send( 'smtp', $Config{ZM_EMAIL_HOST}, Timeout=>60 );
|
||||||
$mail->send();
|
$mail->send();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -777,23 +781,23 @@ sub sendEmail {
|
||||||
$mail->attach(
|
$mail->attach(
|
||||||
Path => $attachment->{path},
|
Path => $attachment->{path},
|
||||||
Type => $attachment->{type},
|
Type => $attachment->{type},
|
||||||
Encoding => "base64"
|
Encoding => 'base64'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$mail->smtpsend( Host => $Config{ZM_EMAIL_HOST}, MailFrom => $Config{ZM_FROM_EMAIL} );
|
$mail->smtpsend( Host => $Config{ZM_EMAIL_HOST}, MailFrom => $Config{ZM_FROM_EMAIL} );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if ( $@ ) {
|
if ( $@ ) {
|
||||||
Error( "Can't send email: $@" );
|
Error( "Unable tosend email: $@" );
|
||||||
return( 0 );
|
return( 0 );
|
||||||
} else {
|
} else {
|
||||||
Info( "Notification email sent\n" );
|
Info( "Notification email sent\n" );
|
||||||
}
|
}
|
||||||
my $sql = "update Events set Emailed = 1 where Id = ?";
|
my $sql = 'update Events set Emailed = 1 where Id = ?';
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
my $res = $sth->execute( $event->{Id} )
|
my $res = $sth->execute( $event->{Id} )
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
|
|
||||||
return( 1 );
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
@ -807,7 +811,7 @@ sub sendMessage {
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
if ( ! $Config{ZM_MESSAGE_ADDRESS} ) {
|
if ( ! $Config{ZM_MESSAGE_ADDRESS} ) {
|
||||||
Error( "No message address defined, not sending message" );
|
Error( 'No message address defined, not sending message' );
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,11 +832,11 @@ sub sendMessage {
|
||||||
From => $Config{ZM_FROM_EMAIL},
|
From => $Config{ZM_FROM_EMAIL},
|
||||||
To => $Config{ZM_MESSAGE_ADDRESS},
|
To => $Config{ZM_MESSAGE_ADDRESS},
|
||||||
Subject => $subject,
|
Subject => $subject,
|
||||||
Type => "multipart/mixed"
|
Type => 'multipart/mixed'
|
||||||
);
|
);
|
||||||
### Add the text message part
|
### Add the text message part
|
||||||
$mail->attach (
|
$mail->attach (
|
||||||
Type => "TEXT",
|
Type => 'TEXT',
|
||||||
Data => $body
|
Data => $body
|
||||||
);
|
);
|
||||||
### Add the attachments
|
### Add the attachments
|
||||||
|
@ -841,7 +845,7 @@ sub sendMessage {
|
||||||
$mail->attach(
|
$mail->attach(
|
||||||
Path => $attachment->{path},
|
Path => $attachment->{path},
|
||||||
Type => $attachment->{type},
|
Type => $attachment->{type},
|
||||||
Disposition => "attachment"
|
Disposition => 'attachment'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
### Send the Message
|
### Send the Message
|
||||||
|
@ -854,15 +858,15 @@ sub sendMessage {
|
||||||
$ssmtp_location = qx('which ssmtp');
|
$ssmtp_location = qx('which ssmtp');
|
||||||
}
|
}
|
||||||
if ( !$ssmtp_location ) {
|
if ( !$ssmtp_location ) {
|
||||||
Debug( "Can't find ssmtp, trying MIME::Lite->send" );
|
Debug( 'Unable tofind ssmtp, trying MIME::Lite->send' );
|
||||||
MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 );
|
MIME::Lite->send( 'smtp', $Config{ZM_EMAIL_HOST}, Timeout=>60 );
|
||||||
$mail->send();
|
$mail->send();
|
||||||
} else {
|
} else {
|
||||||
### Send using SSMTP
|
### Send using SSMTP
|
||||||
$mail->send( 'sendmail', $ssmtp_location, $Config{ZM_MESSAGE_ADDRESS} );
|
$mail->send( 'sendmail', $ssmtp_location, $Config{ZM_MESSAGE_ADDRESS} );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 );
|
MIME::Lite->send( 'smtp', $Config{ZM_EMAIL_HOST}, Timeout=>60 );
|
||||||
$mail->send();
|
$mail->send();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -879,7 +883,7 @@ sub sendMessage {
|
||||||
$mail->attach(
|
$mail->attach(
|
||||||
Path => $attachment->{path},
|
Path => $attachment->{path},
|
||||||
Type => $attachment->{type},
|
Type => $attachment->{type},
|
||||||
Encoding => "base64"
|
Encoding => 'base64'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$mail->smtpsend( Host => $Config{ZM_EMAIL_HOST},
|
$mail->smtpsend( Host => $Config{ZM_EMAIL_HOST},
|
||||||
|
@ -888,16 +892,16 @@ sub sendMessage {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if ( $@ ) {
|
if ( $@ ) {
|
||||||
Error( "Can't send email: $@" );
|
Error( "Unable tosend email: $@" );
|
||||||
return( 0 );
|
return( 0 );
|
||||||
} else {
|
} else {
|
||||||
Info( "Notification message sent\n" );
|
Info( "Notification message sent\n" );
|
||||||
}
|
}
|
||||||
my $sql = "update Events set Messaged = 1 where Id = ?";
|
my $sql = 'update Events set Messaged = 1 where Id = ?';
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
my $res = $sth->execute( $event->{Id} )
|
my $res = $sth->execute( $event->{Id} )
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
|
|
||||||
return( 1 );
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
@ -923,11 +927,11 @@ sub executeCommand {
|
||||||
Error( "Command '$command' exited with status: $status\n" );
|
Error( "Command '$command' exited with status: $status\n" );
|
||||||
return( 0 );
|
return( 0 );
|
||||||
} else {
|
} else {
|
||||||
my $sql = "update Events set Executed = 1 where Id = ?";
|
my $sql = 'update Events set Executed = 1 where Id = ?';
|
||||||
my $sth = $dbh->prepare_cached( $sql )
|
my $sth = $dbh->prepare_cached( $sql )
|
||||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
or Fatal( "Unable toprepare '$sql': ".$dbh->errstr() );
|
||||||
my $res = $sth->execute( $event->{Id} )
|
my $res = $sth->execute( $event->{Id} )
|
||||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
or Fatal( "Unable toexecute '$sql': ".$sth->errstr() );
|
||||||
}
|
}
|
||||||
return( 1 );
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "zm_ffmpeg_camera.h"
|
#include "zm_ffmpeg_camera.h"
|
||||||
|
|
||||||
extern "C"{
|
extern "C" {
|
||||||
#include "libavutil/time.h"
|
#include "libavutil/time.h"
|
||||||
}
|
}
|
||||||
#ifndef AV_ERROR_MAX_STRING_SIZE
|
#ifndef AV_ERROR_MAX_STRING_SIZE
|
||||||
|
@ -125,8 +125,7 @@ int FfmpegCamera::PreCapture()
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int FfmpegCamera::Capture( Image &image )
|
int FfmpegCamera::Capture( Image &image ) {
|
||||||
{
|
|
||||||
if (!mCanCapture){
|
if (!mCanCapture){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -167,11 +166,8 @@ int FfmpegCamera::Capture( Image &image )
|
||||||
Debug( 5, "Got packet from stream %d dts (%d) pts(%d)", packet.stream_index, packet.pts, packet.dts );
|
Debug( 5, "Got packet from stream %d dts (%d) pts(%d)", packet.stream_index, packet.pts, packet.dts );
|
||||||
// What about audio stream? Maybe someday we could do sound detection...
|
// What about audio stream? Maybe someday we could do sound detection...
|
||||||
if ( packet.stream_index == mVideoStreamId ) {
|
if ( packet.stream_index == mVideoStreamId ) {
|
||||||
#if LIBAVCODEC_VERSION_CHECK(52, 23, 0, 23, 0)
|
int ret = zm_avcodec_decode_video( mVideoCodecContext, mRawFrame, &frameComplete, &packet );
|
||||||
if (avcodec_decode_video2(mVideoCodecContext, mRawFrame, &frameComplete, &packet) < 0)
|
if ( ret < 0 )
|
||||||
#else
|
|
||||||
if (avcodec_decode_video(mVideoCodecContext, mRawFrame, &frameComplete, packet.data, packet.size) < 0)
|
|
||||||
#endif
|
|
||||||
Fatal( "Unable to decode frame at frame %d", frameCount );
|
Fatal( "Unable to decode frame at frame %d", frameCount );
|
||||||
|
|
||||||
Debug( 4, "Decoded video packet at frame %d", frameCount );
|
Debug( 4, "Decoded video packet at frame %d", frameCount );
|
||||||
|
@ -364,7 +360,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
Fatal( "Unable to open codec for video stream from %s", mPath.c_str() );
|
Fatal( "Unable to open codec for video stream from %s", mPath.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mAudioStreamId >= 0) {
|
if ( mAudioStreamId >= 0 ) {
|
||||||
mAudioCodecContext = mFormatContext->streams[mAudioStreamId]->codec;
|
mAudioCodecContext = mFormatContext->streams[mAudioStreamId]->codec;
|
||||||
if ((mAudioCodec = avcodec_find_decoder(mAudioCodecContext->codec_id)) == NULL) {
|
if ((mAudioCodec = avcodec_find_decoder(mAudioCodecContext->codec_id)) == NULL) {
|
||||||
Debug(1, "Can't find codec for audio stream from %s", mPath.c_str());
|
Debug(1, "Can't find codec for audio stream from %s", mPath.c_str());
|
||||||
|
@ -437,7 +433,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
mCanCapture = true;
|
mCanCapture = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} // int FfmpegCamera::OpenFfmpeg()
|
||||||
|
|
||||||
int FfmpegCamera::ReopenFfmpeg() {
|
int FfmpegCamera::ReopenFfmpeg() {
|
||||||
|
|
||||||
|
@ -462,8 +458,7 @@ int FfmpegCamera::CloseFfmpeg(){
|
||||||
av_frame_free( &mRawFrame );
|
av_frame_free( &mRawFrame );
|
||||||
|
|
||||||
#if HAVE_LIBSWSCALE
|
#if HAVE_LIBSWSCALE
|
||||||
if ( mConvertContext )
|
if ( mConvertContext ) {
|
||||||
{
|
|
||||||
sws_freeContext( mConvertContext );
|
sws_freeContext( mConvertContext );
|
||||||
mConvertContext = NULL;
|
mConvertContext = NULL;
|
||||||
}
|
}
|
||||||
|
@ -490,8 +485,7 @@ int FfmpegCamera::CloseFfmpeg(){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FfmpegCamera::FfmpegInterruptCallback(void *ctx)
|
int FfmpegCamera::FfmpegInterruptCallback(void *ctx) {
|
||||||
{
|
|
||||||
FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
|
FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
|
||||||
if (camera->mIsOpening){
|
if (camera->mIsOpening){
|
||||||
int now = time(NULL);
|
int now = time(NULL);
|
||||||
|
@ -529,14 +523,14 @@ void *FfmpegCamera::ReopenFfmpegThreadCallback(void *ctx){
|
||||||
|
|
||||||
//Function to handle capture and store
|
//Function to handle capture and store
|
||||||
int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event_file ) {
|
int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event_file ) {
|
||||||
if (!mCanCapture){
|
if ( ! mCanCapture ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int ret;
|
int ret;
|
||||||
static char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
static char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
||||||
|
|
||||||
// If the reopen thread has a value, but mCanCapture != 0, then we have just reopened the connection to the ffmpeg device, and we can clean up the thread.
|
// If the reopen thread has a value, but mCanCapture != 0, then we have just reopened the connection to the ffmpeg device, and we can clean up the thread.
|
||||||
if (mReopenThread != 0) {
|
if ( mReopenThread != 0 ) {
|
||||||
void *retval = 0;
|
void *retval = 0;
|
||||||
|
|
||||||
ret = pthread_join(mReopenThread, &retval);
|
ret = pthread_join(mReopenThread, &retval);
|
||||||
|
@ -548,7 +542,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
||||||
mReopenThread = 0;
|
mReopenThread = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mVideoCodecContext->codec_id != AV_CODEC_ID_H264) {
|
if ( mVideoCodecContext->codec_id != AV_CODEC_ID_H264 ) {
|
||||||
Error( "Input stream is not h264. The stored event file may not be viewable in browser." );
|
Error( "Input stream is not h264. The stored event file may not be viewable in browser." );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,6 +633,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
||||||
unsigned int packet_count = 0;
|
unsigned int packet_count = 0;
|
||||||
ZMPacket *queued_packet;
|
ZMPacket *queued_packet;
|
||||||
|
|
||||||
|
// Clear all packets that predate the moment when the recording began
|
||||||
packetqueue.clear_unwanted_packets( &recording, mVideoStreamId );
|
packetqueue.clear_unwanted_packets( &recording, mVideoStreamId );
|
||||||
|
|
||||||
while ( ( queued_packet = packetqueue.popPacket() ) ) {
|
while ( ( queued_packet = packetqueue.popPacket() ) ) {
|
||||||
|
@ -673,7 +668,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
||||||
|
|
||||||
// Buffer video packets, since we are not recording.
|
// Buffer video packets, since we are not recording.
|
||||||
// All audio packets are keyframes, so only if it's a video keyframe
|
// All audio packets are keyframes, so only if it's a video keyframe
|
||||||
if ( packet.stream_index == mVideoStreamId) {
|
if ( packet.stream_index == mVideoStreamId ) {
|
||||||
if ( key_frame ) {
|
if ( key_frame ) {
|
||||||
Debug(3, "Clearing queue");
|
Debug(3, "Clearing queue");
|
||||||
packetqueue.clearQueue( monitor->GetPreEventCount(), mVideoStreamId );
|
packetqueue.clearQueue( monitor->GetPreEventCount(), mVideoStreamId );
|
||||||
|
@ -688,18 +683,22 @@ else if ( packet.pts && video_last_pts > packet.pts ) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
// The following lines should ensure that the queue always begins with a video keyframe
|
||||||
( packet.stream_index != mAudioStreamId || record_audio )
|
if ( packet.stream_index == mAudioStreamId ) {
|
||||||
&&
|
//Debug(2, "Have audio packet, reocrd_audio is (%d) and packetqueue.size is (%d)", record_audio, packetqueue.size() );
|
||||||
( key_frame || packetqueue.size() )
|
if ( record_audio && packetqueue.size() ) {
|
||||||
) {
|
// if it's audio, and we are doing audio, and there is already something in the queue
|
||||||
packetqueue.queuePacket( &packet );
|
packetqueue.queuePacket( &packet );
|
||||||
|
}
|
||||||
|
} else if ( packet.stream_index == mVideoStreamId ) {
|
||||||
|
if ( key_frame || packetqueue.size() ) // it's a keyframe or we already have something in the queue
|
||||||
|
packetqueue.queuePacket( &packet );
|
||||||
}
|
}
|
||||||
} // end if recording or not
|
} // end if recording or not
|
||||||
|
|
||||||
if ( packet.stream_index == mVideoStreamId ) {
|
if ( packet.stream_index == mVideoStreamId ) {
|
||||||
if ( videoStore ) {
|
if ( videoStore ) {
|
||||||
//Write the packet to our video store
|
//Write the packet to our video store
|
||||||
int ret = videoStore->writeVideoFramePacket( &packet );
|
int ret = videoStore->writeVideoFramePacket( &packet );
|
||||||
if ( ret < 0 ) { //Less than zero and we skipped a frame
|
if ( ret < 0 ) { //Less than zero and we skipped a frame
|
||||||
|
@ -779,8 +778,10 @@ else if ( packet.pts && video_last_pts > packet.pts ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Debug(4, "Not recording audio packet" );
|
Debug(4, "Not doing recording of audio packet" );
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Debug(4, "Have audio packet, but not recording atm" );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if LIBAVUTIL_VERSION_CHECK(56, 23, 0, 23, 0)
|
#if LIBAVUTIL_VERSION_CHECK(56, 23, 0, 23, 0)
|
||||||
|
|
|
@ -60,14 +60,12 @@ ZMPacket* zm_packetqueue::popPacket( ) {
|
||||||
|
|
||||||
unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id ) {
|
unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id ) {
|
||||||
|
|
||||||
Debug(3, "Clearing all but %d frames", frames_to_keep );
|
Debug(3, "Clearing all but %d frames, queue has %d", frames_to_keep, pktQueue.size() );
|
||||||
frames_to_keep += 1;
|
frames_to_keep += 1;
|
||||||
|
|
||||||
if ( pktQueue.empty() ) {
|
if ( pktQueue.empty() ) {
|
||||||
Debug(3, "Queue is empty");
|
Debug(3, "Queue is empty");
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
|
||||||
Debug(3, "Queue has (%d)", pktQueue.size() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
list<ZMPacket *>::reverse_iterator it;
|
list<ZMPacket *>::reverse_iterator it;
|
||||||
|
@ -77,18 +75,19 @@ unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream
|
||||||
ZMPacket *zm_packet = *it;
|
ZMPacket *zm_packet = *it;
|
||||||
AVPacket *av_packet = &(zm_packet->packet);
|
AVPacket *av_packet = &(zm_packet->packet);
|
||||||
|
|
||||||
Debug(3, "Looking at packet with stream index (%d) with keyframe (%d), frames_to_keep is (%d)", av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), frames_to_keep );
|
Debug(4, "Looking at packet with stream index (%d) with keyframe (%d), frames_to_keep is (%d)", av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), frames_to_keep );
|
||||||
|
|
||||||
// Want frames_to_keep video keyframes. Otherwise, we may not have enough
|
// Want frames_to_keep video keyframes. Otherwise, we may not have enough
|
||||||
if ( ( av_packet->stream_index == stream_id) && ( av_packet->flags & AV_PKT_FLAG_KEY ) ) {
|
if ( ( av_packet->stream_index == stream_id) && ( av_packet->flags & AV_PKT_FLAG_KEY ) ) {
|
||||||
if (!frames_to_keep)
|
|
||||||
break;
|
|
||||||
frames_to_keep --;
|
frames_to_keep --;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( frames_to_keep ) {
|
||||||
|
Debug(3, "Hit end of queue, still need (%d) video keyframes", frames_to_keep );
|
||||||
|
}
|
||||||
unsigned int delete_count = 0;
|
unsigned int delete_count = 0;
|
||||||
while ( it != pktQueue.rend() ) {
|
while ( it != pktQueue.rend() ) {
|
||||||
Debug(3, "Deleting a packet from the front, count is (%d)", delete_count );
|
Debug(4, "Deleting a packet from the front, count is (%d)", delete_count );
|
||||||
|
|
||||||
packet = pktQueue.front();
|
packet = pktQueue.front();
|
||||||
pktQueue.pop_front();
|
pktQueue.pop_front();
|
||||||
|
@ -96,6 +95,7 @@ unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream
|
||||||
|
|
||||||
delete_count += 1;
|
delete_count += 1;
|
||||||
}
|
}
|
||||||
|
Debug(3, "Deleted (%d) packets", delete_count );
|
||||||
return delete_count;
|
return delete_count;
|
||||||
} // end unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id )
|
} // end unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id )
|
||||||
|
|
||||||
|
@ -123,10 +123,10 @@ void zm_packetqueue::clear_unwanted_packets( timeval *recording_started, int mVi
|
||||||
// Step 2 - pop packets until we get to the packet in step 2
|
// Step 2 - pop packets until we get to the packet in step 2
|
||||||
list<ZMPacket *>::reverse_iterator it;
|
list<ZMPacket *>::reverse_iterator it;
|
||||||
|
|
||||||
|
Debug(3, "Looking for keyframe after start recording stream id (%d)", mVideoStreamId );
|
||||||
for ( it = pktQueue.rbegin(); it != pktQueue.rend(); ++ it ) {
|
for ( it = pktQueue.rbegin(); it != pktQueue.rend(); ++ it ) {
|
||||||
ZMPacket *zm_packet = *it;
|
ZMPacket *zm_packet = *it;
|
||||||
AVPacket *av_packet = &(zm_packet->packet);
|
AVPacket *av_packet = &(zm_packet->packet);
|
||||||
Debug(1, "Looking for keyframe after start" );
|
|
||||||
if (
|
if (
|
||||||
( av_packet->flags & AV_PKT_FLAG_KEY )
|
( av_packet->flags & AV_PKT_FLAG_KEY )
|
||||||
&&
|
&&
|
||||||
|
@ -134,7 +134,7 @@ Debug(1, "Looking for keyframe after start" );
|
||||||
&&
|
&&
|
||||||
timercmp( &(zm_packet->timestamp), recording_started, < )
|
timercmp( &(zm_packet->timestamp), recording_started, < )
|
||||||
) {
|
) {
|
||||||
Debug(1, "Found keyframe before start" );
|
Debug(3, "Found keyframe before start with stream index (%d) with keyframe (%d)", av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,10 +143,29 @@ Debug(1, "Found keyframe before start" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZMPacket *zm_packet = *it;
|
||||||
|
AVPacket *av_packet = &(zm_packet->packet);
|
||||||
|
Debug(3, "Found packet before start with stream index (%d) with keyframe (%d), distance(%d), size(%d)",
|
||||||
|
av_packet->stream_index,
|
||||||
|
( av_packet->flags & AV_PKT_FLAG_KEY ),
|
||||||
|
distance( it, pktQueue.rend() ),
|
||||||
|
pktQueue.size() );
|
||||||
|
|
||||||
|
unsigned int deleted_frames = 0;
|
||||||
ZMPacket *packet = NULL;
|
ZMPacket *packet = NULL;
|
||||||
while ( pktQueue.rend() != it ) {
|
while ( distance( it, pktQueue.rend() ) > 1 ) {
|
||||||
|
//while ( pktQueue.rend() != it ) {
|
||||||
packet = pktQueue.front();
|
packet = pktQueue.front();
|
||||||
pktQueue.pop_front();
|
pktQueue.pop_front();
|
||||||
delete packet;
|
delete packet;
|
||||||
|
deleted_frames += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zm_packet = pktQueue.front();
|
||||||
|
av_packet = &(zm_packet->packet);
|
||||||
|
if ( ( ! ( av_packet->flags & AV_PKT_FLAG_KEY ) ) || ( av_packet->stream_index != mVideoStreamId ) ) {
|
||||||
|
Error( "Done looking for keyframe. Deleted %d frames. Remaining frames in queue: %d stream of head packet is (%d), keyframe (%d), distance(%d), packets(%d)", deleted_frames, pktQueue.size(), av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), distance( it, pktQueue.rend() ), pktQueue.size() );
|
||||||
|
} else {
|
||||||
|
Debug(1, "Done looking for keyframe. Deleted %d frames. Remaining frames in queue: %d stream of head packet is (%d), keyframe (%d), distance(%d), packets(%d)", deleted_frames, pktQueue.size(), av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), distance( it, pktQueue.rend() ), pktQueue.size() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "zm.h"
|
#include "zm.h"
|
||||||
#include "zm_videostore.h"
|
#include "zm_videostore.h"
|
||||||
|
|
||||||
extern "C"{
|
extern "C" {
|
||||||
#include "libavutil/time.h"
|
#include "libavutil/time.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,23 +37,23 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
int64_t nStartTime,
|
int64_t nStartTime,
|
||||||
Monitor * monitor
|
Monitor * monitor
|
||||||
) {
|
) {
|
||||||
|
|
||||||
video_input_stream = p_video_input_stream;
|
video_input_stream = p_video_input_stream;
|
||||||
audio_input_stream = p_audio_input_stream;
|
audio_input_stream = p_audio_input_stream;
|
||||||
|
|
||||||
|
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
|
video_input_context = avcodec_alloc_context3( NULL );
|
||||||
|
avcodec_parameters_to_context( video_input_context, video_input_stream->codecpar );
|
||||||
|
#else
|
||||||
video_input_context = video_input_stream->codec;
|
video_input_context = video_input_stream->codec;
|
||||||
|
#endif
|
||||||
|
|
||||||
//store inputs in variables local to class
|
//store inputs in variables local to class
|
||||||
filename = filename_in;
|
filename = filename_in;
|
||||||
format = format_in;
|
format = format_in;
|
||||||
|
|
||||||
keyframeMessage = false;
|
|
||||||
keyframeSkipNumber = 0;
|
|
||||||
|
|
||||||
Info("Opening video storage stream %s format: %s\n", filename, format);
|
Info("Opening video storage stream %s format: %s\n", filename, format);
|
||||||
|
|
||||||
//Init everything we need, shouldn't have to do this, ffmpeg_camera or something else will call it.
|
|
||||||
//av_register_all();
|
|
||||||
|
|
||||||
ret = avformat_alloc_output_context2(&oc, NULL, NULL, filename);
|
ret = avformat_alloc_output_context2(&oc, NULL, NULL, filename);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Warning("Could not create video storage stream %s as no output context"
|
Warning("Could not create video storage stream %s as no output context"
|
||||||
|
@ -62,11 +62,11 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
av_make_error_string(ret).c_str()
|
av_make_error_string(ret).c_str()
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Debug(2, "Success alocateing output context");
|
Debug(2, "Success allocating output context");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Couldn't deduce format from filename, trying from format name
|
//Couldn't deduce format from filename, trying from format name
|
||||||
if (!oc) {
|
if ( ! oc ) {
|
||||||
avformat_alloc_output_context2(&oc, NULL, format, filename);
|
avformat_alloc_output_context2(&oc, NULL, format, filename);
|
||||||
if (!oc) {
|
if (!oc) {
|
||||||
Fatal("Could not create video storage stream %s as no output context"
|
Fatal("Could not create video storage stream %s as no output context"
|
||||||
|
@ -82,29 +82,47 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__ );
|
if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__ );
|
||||||
|
|
||||||
oc->metadata = pmetadata;
|
oc->metadata = pmetadata;
|
||||||
|
|
||||||
output_format = oc->oformat;
|
output_format = oc->oformat;
|
||||||
|
|
||||||
video_output_stream = avformat_new_stream(oc, (AVCodec*)video_input_context->codec);
|
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
if (!video_output_stream) {
|
// Since we are not re-encoding, all we have to do is copy the parameters
|
||||||
|
video_output_context = avcodec_alloc_context3( NULL );
|
||||||
|
|
||||||
|
// Copy params from inputstream to context
|
||||||
|
ret = avcodec_parameters_to_context( video_output_context, video_input_stream->codecpar );
|
||||||
|
if ( ret < 0 ) {
|
||||||
|
Error( "Could not initialize context parameteres");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Debug( 2, "Success getting parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
video_output_stream = avformat_new_stream( oc, NULL );
|
||||||
|
if ( ! video_output_stream ) {
|
||||||
Fatal("Unable to create video out stream\n");
|
Fatal("Unable to create video out stream\n");
|
||||||
} else {
|
} else {
|
||||||
Debug(2, "Success creating video out stream" );
|
Debug(2, "Success creating video out stream" );
|
||||||
}
|
}
|
||||||
|
|
||||||
video_output_context = video_output_stream->codec;
|
// Now copy them to the output stream
|
||||||
|
ret = avcodec_parameters_from_context( video_output_stream->codecpar, video_output_context );
|
||||||
#if LIBAVCODEC_VERSION_CHECK(58, 0, 0, 0, 0)
|
|
||||||
Debug(2, "setting parameters");
|
|
||||||
ret = avcodec_parameters_to_context( video_output_context, video_input_stream->codecpar );
|
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error( "Could not initialize stream parameteres");
|
Error( "Could not initialize stream parameteres");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Debug(2, "Success getting parameters");
|
Debug(2, "Success setting parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zm_dump_stream_format( oc, 0, 0, 1 );
|
||||||
#else
|
#else
|
||||||
ret = avcodec_copy_context(video_output_context, video_input_context );
|
video_output_stream = avformat_new_stream(oc, (AVCodec*)video_input_context->codec );
|
||||||
|
if ( ! video_output_stream ) {
|
||||||
|
Fatal("Unable to create video out stream\n");
|
||||||
|
} else {
|
||||||
|
Debug(2, "Success creating video out stream" );
|
||||||
|
}
|
||||||
|
video_output_context = video_output_stream->codec;
|
||||||
|
ret = avcodec_copy_context( video_output_context, video_input_context );
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
Fatal("Unable to copy input video context to output video context %s\n",
|
Fatal("Unable to copy input video context to output video context %s\n",
|
||||||
av_make_error_string(ret).c_str());
|
av_make_error_string(ret).c_str());
|
||||||
|
@ -130,7 +148,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
|
|
||||||
// WHY?
|
// WHY?
|
||||||
//video_output_context->codec_tag = 0;
|
//video_output_context->codec_tag = 0;
|
||||||
if (!video_output_context->codec_tag) {
|
if ( ! video_output_context->codec_tag ) {
|
||||||
Debug(2, "No codec_tag");
|
Debug(2, "No codec_tag");
|
||||||
if (! oc->oformat->codec_tag
|
if (! oc->oformat->codec_tag
|
||||||
|| av_codec_get_id (oc->oformat->codec_tag, video_input_context->codec_tag) == video_output_context->codec_id
|
|| av_codec_get_id (oc->oformat->codec_tag, video_input_context->codec_tag) == video_output_context->codec_id
|
||||||
|
@ -145,6 +163,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
}
|
}
|
||||||
|
|
||||||
Monitor::Orientation orientation = monitor->getOrientation();
|
Monitor::Orientation orientation = monitor->getOrientation();
|
||||||
|
Debug(3, "Have orientation" );
|
||||||
if ( orientation ) {
|
if ( orientation ) {
|
||||||
if ( orientation == Monitor::ROTATE_0 ) {
|
if ( orientation == Monitor::ROTATE_0 ) {
|
||||||
|
|
||||||
|
@ -169,13 +188,22 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
resample_context = NULL;
|
resample_context = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (audio_input_stream) {
|
if ( audio_input_stream ) {
|
||||||
|
Debug(3, "Have audio stream" );
|
||||||
|
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
|
|
||||||
|
audio_input_context = avcodec_alloc_context3( NULL );
|
||||||
|
ret = avcodec_parameters_to_context( audio_input_context, audio_input_stream->codecpar );
|
||||||
|
#else
|
||||||
audio_input_context = audio_input_stream->codec;
|
audio_input_context = audio_input_stream->codec;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( audio_input_context->codec_id != AV_CODEC_ID_AAC ) {
|
if ( audio_input_context->codec_id != AV_CODEC_ID_AAC ) {
|
||||||
static char error_buffer[256];
|
static char error_buffer[256];
|
||||||
avcodec_string(error_buffer, sizeof(error_buffer), audio_input_context, 0 );
|
avcodec_string(error_buffer, sizeof(error_buffer), audio_input_context, 0 );
|
||||||
Debug(3, "Got something other than AAC (%s)", error_buffer );
|
Debug(2, "Got something other than AAC (%s)", error_buffer );
|
||||||
|
|
||||||
|
|
||||||
if ( ! setup_resampler() ) {
|
if ( ! setup_resampler() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -187,9 +215,16 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
Error("Unable to create audio out stream\n");
|
Error("Unable to create audio out stream\n");
|
||||||
audio_output_stream = NULL;
|
audio_output_stream = NULL;
|
||||||
} else {
|
} else {
|
||||||
audio_output_context = audio_output_stream->codec;
|
Debug(2, "setting parameters");
|
||||||
|
|
||||||
|
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
|
audio_output_context = avcodec_alloc_context3( NULL );
|
||||||
|
// Copy params from inputstream to context
|
||||||
|
ret = avcodec_parameters_to_context( audio_output_context, audio_input_stream->codecpar );
|
||||||
|
#else
|
||||||
|
audio_output_context = audio_output_stream->codec;
|
||||||
ret = avcodec_copy_context(audio_output_context, audio_input_context);
|
ret = avcodec_copy_context(audio_output_context, audio_input_context);
|
||||||
|
#endif
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
Error("Unable to copy audio context %s\n", av_make_error_string(ret).c_str());
|
Error("Unable to copy audio context %s\n", av_make_error_string(ret).c_str());
|
||||||
audio_output_stream = NULL;
|
audio_output_stream = NULL;
|
||||||
|
@ -233,7 +268,8 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
//av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
|
//av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
|
||||||
//av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
|
//av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
|
||||||
//av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
|
//av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
|
||||||
if ((ret = avformat_write_header(oc, &opts)) < 0) {
|
if ((ret = avformat_write_header(oc, NULL)) < 0) {
|
||||||
|
//if ((ret = avformat_write_header(oc, &opts)) < 0) {
|
||||||
Warning("Unable to set movflags to frag_custom+dash+delay_moov");
|
Warning("Unable to set movflags to frag_custom+dash+delay_moov");
|
||||||
/* Write the stream header, if any. */
|
/* Write the stream header, if any. */
|
||||||
ret = avformat_write_header(oc, NULL);
|
ret = avformat_write_header(oc, NULL);
|
||||||
|
@ -252,8 +288,10 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
video_last_dts = 0;
|
video_last_dts = 0;
|
||||||
audio_last_pts = 0;
|
audio_last_pts = 0;
|
||||||
audio_last_dts = 0;
|
audio_last_dts = 0;
|
||||||
previous_pts = 0;
|
video_previous_pts = 0;
|
||||||
previous_dts = 0;
|
video_previous_dts = 0;
|
||||||
|
audio_previous_pts = 0;
|
||||||
|
audio_previous_dts = 0;
|
||||||
|
|
||||||
} // VideoStore::VideoStore
|
} // VideoStore::VideoStore
|
||||||
|
|
||||||
|
@ -262,14 +300,14 @@ VideoStore::~VideoStore(){
|
||||||
if ( audio_output_codec ) {
|
if ( audio_output_codec ) {
|
||||||
// Do we need to flush the outputs? I have no idea.
|
// Do we need to flush the outputs? I have no idea.
|
||||||
AVPacket pkt;
|
AVPacket pkt;
|
||||||
int got_packet;
|
int got_packet = 0;
|
||||||
av_init_packet(&pkt);
|
av_init_packet(&pkt);
|
||||||
pkt.data = NULL;
|
pkt.data = NULL;
|
||||||
pkt.size = 0;
|
pkt.size = 0;
|
||||||
int64_t size;
|
int64_t size;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
#if LIBAVCODEC_VERSION_CHECK(58, 0, 0, 0, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
ret = avcodec_receive_packet( audio_output_context, &pkt );
|
ret = avcodec_receive_packet( audio_output_context, &pkt );
|
||||||
#else
|
#else
|
||||||
ret = avcodec_encode_audio2( audio_output_context, &pkt, NULL, &got_packet );
|
ret = avcodec_encode_audio2( audio_output_context, &pkt, NULL, &got_packet );
|
||||||
|
@ -341,6 +379,18 @@ bool VideoStore::setup_resampler() {
|
||||||
#ifdef HAVE_LIBAVRESAMPLE
|
#ifdef HAVE_LIBAVRESAMPLE
|
||||||
static char error_buffer[256];
|
static char error_buffer[256];
|
||||||
|
|
||||||
|
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
|
// Newer ffmpeg wants to keep everything separate... so have to lookup our own decoder, can't reuse the one from the camera.
|
||||||
|
AVCodec *audio_input_codec = avcodec_find_decoder(audio_input_stream->codecpar->codec_id);
|
||||||
|
#else
|
||||||
|
AVCodec *audio_input_codec = avcodec_find_decoder(audio_input_context->codec_id);
|
||||||
|
#endif
|
||||||
|
ret = avcodec_open2( audio_input_context, audio_input_codec, NULL );
|
||||||
|
if ( ret < 0 ) {
|
||||||
|
Error("Can't open input codec!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
audio_output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
|
audio_output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
|
||||||
if ( ! audio_output_codec ) {
|
if ( ! audio_output_codec ) {
|
||||||
Error("Could not find codec for AAC");
|
Error("Could not find codec for AAC");
|
||||||
|
@ -348,8 +398,8 @@ bool VideoStore::setup_resampler() {
|
||||||
}
|
}
|
||||||
Debug(2, "Have audio output codec");
|
Debug(2, "Have audio output codec");
|
||||||
|
|
||||||
audio_output_stream = avformat_new_stream( oc, audio_output_codec );
|
//audio_output_context = audio_output_stream->codec;
|
||||||
audio_output_context = audio_output_stream->codec;
|
audio_output_context = avcodec_alloc_context3( audio_output_codec );
|
||||||
|
|
||||||
if ( ! audio_output_context ) {
|
if ( ! audio_output_context ) {
|
||||||
Error( "could not allocate codec context for AAC\n");
|
Error( "could not allocate codec context for AAC\n");
|
||||||
|
@ -359,18 +409,15 @@ bool VideoStore::setup_resampler() {
|
||||||
|
|
||||||
Debug(2, "Have audio_output_context");
|
Debug(2, "Have audio_output_context");
|
||||||
|
|
||||||
AVDictionary *opts = NULL;
|
|
||||||
av_dict_set(&opts, "strict", "experimental", 0);
|
|
||||||
|
|
||||||
/* put sample parameters */
|
/* put sample parameters */
|
||||||
audio_output_context->bit_rate = audio_input_context->bit_rate;
|
audio_output_context->bit_rate = audio_input_context->bit_rate;
|
||||||
audio_output_context->sample_rate = audio_input_context->sample_rate;
|
audio_output_context->sample_rate = audio_input_context->sample_rate;
|
||||||
audio_output_context->channels = audio_input_context->channels;
|
audio_output_context->channels = audio_input_context->channels;
|
||||||
audio_output_context->channel_layout = audio_input_context->channel_layout;
|
audio_output_context->channel_layout = audio_input_context->channel_layout;
|
||||||
audio_output_context->sample_fmt = audio_input_context->sample_fmt;
|
audio_output_context->sample_fmt = audio_input_context->sample_fmt;
|
||||||
//audio_output_context->refcounted_frames = 1;
|
audio_output_context->refcounted_frames = 1;
|
||||||
|
|
||||||
if (audio_output_codec->supported_samplerates) {
|
if ( audio_output_codec->supported_samplerates ) {
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for ( unsigned int i = 0; audio_output_codec->supported_samplerates[i]; i++) {
|
for ( unsigned int i = 0; audio_output_codec->supported_samplerates[i]; i++) {
|
||||||
if ( audio_output_context->sample_rate == audio_output_codec->supported_samplerates[i] ) {
|
if ( audio_output_context->sample_rate == audio_output_codec->supported_samplerates[i] ) {
|
||||||
|
@ -387,36 +434,14 @@ bool VideoStore::setup_resampler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check that the encoder supports s16 pcm input */
|
/* check that the encoder supports s16 pcm input */
|
||||||
if (!check_sample_fmt( audio_output_codec, audio_output_context->sample_fmt)) {
|
if ( ! check_sample_fmt( audio_output_codec, audio_output_context->sample_fmt ) ) {
|
||||||
Debug( 3, "Encoder does not support sample format %s, setting to FLTP",
|
Debug( 3, "Encoder does not support sample format %s, setting to FLTP",
|
||||||
av_get_sample_fmt_name( audio_output_context->sample_fmt));
|
av_get_sample_fmt_name( audio_output_context->sample_fmt));
|
||||||
audio_output_context->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
audio_output_context->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
||||||
}
|
}
|
||||||
|
|
||||||
//audio_output_stream->time_base = audio_input_stream->time_base;
|
|
||||||
audio_output_context->time_base = (AVRational){ 1, audio_output_context->sample_rate };
|
audio_output_context->time_base = (AVRational){ 1, audio_output_context->sample_rate };
|
||||||
|
|
||||||
Debug(3, "Audio Time bases input stream (%d/%d) input codec: (%d/%d) output_stream (%d/%d) output codec (%d/%d)",
|
|
||||||
audio_input_stream->time_base.num,
|
|
||||||
audio_input_stream->time_base.den,
|
|
||||||
audio_input_context->time_base.num,
|
|
||||||
audio_input_context->time_base.den,
|
|
||||||
audio_output_stream->time_base.num,
|
|
||||||
audio_output_stream->time_base.den,
|
|
||||||
audio_output_context->time_base.num,
|
|
||||||
audio_output_context->time_base.den
|
|
||||||
);
|
|
||||||
|
|
||||||
ret = avcodec_open2(audio_output_context, audio_output_codec, &opts );
|
|
||||||
av_dict_free(&opts);
|
|
||||||
if ( ret < 0 ) {
|
|
||||||
av_strerror(ret, error_buffer, sizeof(error_buffer));
|
|
||||||
Fatal( "could not open codec (%d) (%s)\n", ret, error_buffer );
|
|
||||||
audio_output_codec = NULL;
|
|
||||||
audio_output_context = NULL;
|
|
||||||
audio_output_stream = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug(1, "Audio output bit_rate (%d) sample_rate(%d) channels(%d) fmt(%d) layout(%d) frame_size(%d)",
|
Debug(1, "Audio output bit_rate (%d) sample_rate(%d) channels(%d) fmt(%d) layout(%d) frame_size(%d)",
|
||||||
audio_output_context->bit_rate,
|
audio_output_context->bit_rate,
|
||||||
|
@ -427,7 +452,28 @@ bool VideoStore::setup_resampler() {
|
||||||
audio_output_context->frame_size
|
audio_output_context->frame_size
|
||||||
);
|
);
|
||||||
|
|
||||||
output_frame_size = audio_output_context->frame_size;
|
// Now copy them to the output stream
|
||||||
|
audio_output_stream = avformat_new_stream( oc, audio_output_codec );
|
||||||
|
|
||||||
|
ret = avcodec_parameters_from_context( audio_output_stream->codecpar, audio_output_context );
|
||||||
|
if ( ret < 0 ) {
|
||||||
|
Error( "Could not initialize stream parameteres");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVDictionary *opts = NULL;
|
||||||
|
av_dict_set( &opts, "strict", "experimental", 0);
|
||||||
|
ret = avcodec_open2( audio_output_context, audio_output_codec, &opts );
|
||||||
|
av_dict_free(&opts);
|
||||||
|
if ( ret < 0 ) {
|
||||||
|
av_strerror(ret, error_buffer, sizeof(error_buffer));
|
||||||
|
Fatal( "could not open codec (%d) (%s)\n", ret, error_buffer );
|
||||||
|
audio_output_codec = NULL;
|
||||||
|
audio_output_context = NULL;
|
||||||
|
audio_output_stream = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Create a new frame to store the audio samples. */
|
/** Create a new frame to store the audio samples. */
|
||||||
if (!(input_frame = zm_av_frame_alloc())) {
|
if (!(input_frame = zm_av_frame_alloc())) {
|
||||||
Error("Could not allocate input frame");
|
Error("Could not allocate input frame");
|
||||||
|
@ -562,9 +608,9 @@ int VideoStore::writeVideoFramePacket( AVPacket *ipkt ) {
|
||||||
if ( ipkt->pts < video_last_pts ) {
|
if ( ipkt->pts < video_last_pts ) {
|
||||||
Debug(1, "Resetting video_last_pts from (%d) to (%d)", video_last_pts, ipkt->pts );
|
Debug(1, "Resetting video_last_pts from (%d) to (%d)", video_last_pts, ipkt->pts );
|
||||||
// wrap around, need to figure out the distance FIXME having this wrong should cause a jump, but then play ok?
|
// wrap around, need to figure out the distance FIXME having this wrong should cause a jump, but then play ok?
|
||||||
opkt.pts = previous_pts + av_rescale_q( ipkt->pts, video_input_stream->time_base, video_output_stream->time_base);
|
opkt.pts = video_previous_pts + av_rescale_q( ipkt->pts, video_input_stream->time_base, video_output_stream->time_base);
|
||||||
} else {
|
} else {
|
||||||
opkt.pts = previous_pts + av_rescale_q( ipkt->pts - video_last_pts, video_input_stream->time_base, video_output_stream->time_base);
|
opkt.pts = video_previous_pts + av_rescale_q( ipkt->pts - video_last_pts, video_input_stream->time_base, video_output_stream->time_base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Debug(3, "opkt.pts = %d from ipkt->pts(%d) - last_pts(%d)", opkt.pts, ipkt->pts, video_last_pts );
|
Debug(3, "opkt.pts = %d from ipkt->pts(%d) - last_pts(%d)", opkt.pts, ipkt->pts, video_last_pts );
|
||||||
|
@ -588,24 +634,20 @@ int VideoStore::writeVideoFramePacket( AVPacket *ipkt ) {
|
||||||
// why are we using cur_dts instead of packet.dts? I think cur_dts is in AV_TIME_BASE_Q, but ipkt.dts is in video_input_stream->time_base
|
// why are we using cur_dts instead of packet.dts? I think cur_dts is in AV_TIME_BASE_Q, but ipkt.dts is in video_input_stream->time_base
|
||||||
if ( video_input_stream->cur_dts < video_last_dts ) {
|
if ( video_input_stream->cur_dts < video_last_dts ) {
|
||||||
Debug(1, "Resetting video_last_dts from (%d) to (%d) p.dts was (%d)", video_last_dts, video_input_stream->cur_dts, ipkt->dts );
|
Debug(1, "Resetting video_last_dts from (%d) to (%d) p.dts was (%d)", video_last_dts, video_input_stream->cur_dts, ipkt->dts );
|
||||||
opkt.dts = previous_dts + av_rescale_q(video_input_stream->cur_dts, AV_TIME_BASE_Q, video_output_stream->time_base);
|
opkt.dts = video_previous_dts + av_rescale_q(video_input_stream->cur_dts, AV_TIME_BASE_Q, video_output_stream->time_base);
|
||||||
} else {
|
} else {
|
||||||
opkt.dts = previous_dts + av_rescale_q(video_input_stream->cur_dts - video_last_dts, AV_TIME_BASE_Q, video_output_stream->time_base);
|
opkt.dts = video_previous_dts + av_rescale_q(video_input_stream->cur_dts - video_last_dts, AV_TIME_BASE_Q, video_output_stream->time_base);
|
||||||
}
|
}
|
||||||
Debug(3, "opkt.dts = %d from video_input_stream->cur_dts(%d) - previus_dts(%d)",
|
Debug(3, "opkt.dts = %d from video_input_stream->cur_dts(%d) - previus_dts(%d)", opkt.dts, video_input_stream->cur_dts, video_last_dts );
|
||||||
opkt.dts, video_input_stream->cur_dts, video_last_dts
|
|
||||||
);
|
|
||||||
video_last_dts = video_input_stream->cur_dts;
|
video_last_dts = video_input_stream->cur_dts;
|
||||||
} else {
|
} else {
|
||||||
if ( ipkt->dts < video_last_dts ) {
|
if ( ipkt->dts < video_last_dts ) {
|
||||||
Debug(1, "Resetting video_last_dts from (%d) to (%d)", video_last_dts, ipkt->dts );
|
Debug(1, "Resetting video_last_dts from (%d) to (%d)", video_last_dts, ipkt->dts );
|
||||||
opkt.dts = previous_dts + av_rescale_q( ipkt->dts, video_input_stream->time_base, video_output_stream->time_base);
|
opkt.dts = video_previous_dts + av_rescale_q( ipkt->dts, video_input_stream->time_base, video_output_stream->time_base);
|
||||||
} else {
|
} else {
|
||||||
opkt.dts = previous_dts + av_rescale_q( ipkt->dts - video_last_dts, video_input_stream->time_base, video_output_stream->time_base);
|
opkt.dts = video_previous_dts + av_rescale_q( ipkt->dts - video_last_dts, video_input_stream->time_base, video_output_stream->time_base);
|
||||||
}
|
}
|
||||||
Debug(3, "opkt.dts = %d from ipkt.dts(%d) - previus_dts(%d)",
|
Debug(3, "opkt.dts = %d from ipkt.dts(%d) - previus_dts(%d)", opkt.dts, ipkt->dts, video_last_dts );
|
||||||
opkt.dts, ipkt->dts, video_last_dts
|
|
||||||
);
|
|
||||||
video_last_dts = ipkt->dts;
|
video_last_dts = ipkt->dts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -642,15 +684,15 @@ Debug(1, "writing video packet pts(%d) dts(%d) duration(%d)", opkt.pts, opkt.dts
|
||||||
dumpPacket( ipkt);
|
dumpPacket( ipkt);
|
||||||
dumpPacket(&opkt);
|
dumpPacket(&opkt);
|
||||||
|
|
||||||
} else if ((previous_dts > 0) && (previous_dts > opkt.dts)) {
|
} else if ((video_previous_dts > 0) && (video_previous_dts > opkt.dts)) {
|
||||||
Warning("%s:%d: DTS out of order: %lld \u226E %lld; discarding frame", __FILE__, __LINE__, previous_dts, opkt.dts);
|
Warning("%s:%d: DTS out of order: %lld \u226E %lld; discarding frame", __FILE__, __LINE__, video_previous_dts, opkt.dts);
|
||||||
previous_dts = opkt.dts;
|
video_previous_dts = opkt.dts;
|
||||||
dumpPacket(&opkt);
|
dumpPacket(&opkt);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
previous_dts = opkt.dts; // Unsure if av_interleaved_write_frame() clobbers opkt.dts when out of order, so storing in advance
|
video_previous_dts = opkt.dts; // Unsure if av_interleaved_write_frame() clobbers opkt.dts when out of order, so storing in advance
|
||||||
previous_pts = opkt.pts;
|
video_previous_pts = opkt.pts;
|
||||||
ret = av_interleaved_write_frame(oc, &opkt);
|
ret = av_interleaved_write_frame(oc, &opkt);
|
||||||
if(ret<0){
|
if(ret<0){
|
||||||
// There's nothing we can really do if the frame is rejected, just drop it and get on with the next
|
// There's nothing we can really do if the frame is rejected, just drop it and get on with the next
|
||||||
|
@ -663,21 +705,20 @@ Debug(1, "writing video packet pts(%d) dts(%d) duration(%d)", opkt.pts, opkt.dts
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
} // end int VideoStore::writeVideoFramePacket( AVPacket *ipkt )
|
||||||
|
|
||||||
int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
||||||
Debug(4, "writeAudioFrame");
|
Debug(4, "writeAudioFrame");
|
||||||
|
|
||||||
if(!audio_output_stream) {
|
if ( ! audio_output_stream ) {
|
||||||
Debug(1, "Called writeAudioFramePacket when no audio_output_stream");
|
Debug(1, "Called writeAudioFramePacket when no audio_output_stream");
|
||||||
return 0;//FIXME -ve return codes do not free packet in ffmpeg_camera at the moment
|
return 0;//FIXME -ve return codes do not free packet in ffmpeg_camera at the moment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( audio_output_codec ) {
|
if ( audio_output_codec ) {
|
||||||
#ifdef HAVE_LIBAVRESAMPLE
|
#ifdef HAVE_LIBAVRESAMPLE
|
||||||
|
|
||||||
#if 0
|
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
ret = avcodec_send_packet( audio_input_context, ipkt );
|
ret = avcodec_send_packet( audio_input_context, ipkt );
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
Error("avcodec_send_packet fail %s", av_make_error_string(ret).c_str());
|
Error("avcodec_send_packet fail %s", av_make_error_string(ret).c_str());
|
||||||
|
@ -696,26 +737,7 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
||||||
input_frame->channel_layout,
|
input_frame->channel_layout,
|
||||||
audio_output_context->refcounted_frames
|
audio_output_context->refcounted_frames
|
||||||
);
|
);
|
||||||
|
|
||||||
ret = avcodec_send_frame( audio_output_context, input_frame );
|
|
||||||
if ( ret < 0 ) {
|
|
||||||
av_frame_unref( input_frame );
|
|
||||||
Error("avcodec_send_frame fail(%d), %s codec is open(%d) is_encoder(%d)", ret, av_make_error_string(ret).c_str(),
|
|
||||||
avcodec_is_open( audio_output_context ),
|
|
||||||
av_codec_is_encoder( audio_output_context->codec)
|
|
||||||
);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ret = avcodec_receive_packet( audio_output_context, &opkt );
|
|
||||||
if ( ret < 0 ) {
|
|
||||||
av_frame_unref( input_frame );
|
|
||||||
Error("avcodec_receive_packet fail %s", av_make_error_string(ret).c_str());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
av_frame_unref( input_frame );
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode the audio frame stored in the packet.
|
* Decode the audio frame stored in the packet.
|
||||||
* The input audio stream decoder is used to do this.
|
* The input audio stream decoder is used to do this.
|
||||||
|
@ -728,15 +750,13 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
||||||
av_make_error_string(ret).c_str());
|
av_make_error_string(ret).c_str());
|
||||||
dumpPacket( ipkt );
|
dumpPacket( ipkt );
|
||||||
av_frame_free( &input_frame );
|
av_frame_free( &input_frame );
|
||||||
zm_av_packet_unref( &opkt );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( ! data_present ) {
|
if ( ! data_present ) {
|
||||||
Debug(2, "Not ready to transcode a frame yet.");
|
Debug(2, "Not ready to transcode a frame yet.");
|
||||||
zm_av_packet_unref(&opkt);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
int frame_size = input_frame->nb_samples;
|
int frame_size = input_frame->nb_samples;
|
||||||
Debug(4, "Frame size: %d", frame_size );
|
Debug(4, "Frame size: %d", frame_size );
|
||||||
|
|
||||||
|
@ -778,11 +798,22 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
||||||
* Encode the audio frame and store it in the temporary packet.
|
* Encode the audio frame and store it in the temporary packet.
|
||||||
* The output audio stream encoder is used to do this.
|
* The output audio stream encoder is used to do this.
|
||||||
*/
|
*/
|
||||||
#if LIBAVCODEC_VERSION_CHECK(58, 0, 0, 0, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
|
if (( ret = avcodec_send_frame( audio_output_context, output_frame ) ) < 0 ) {
|
||||||
|
Error( "Could not send frame (error '%s')",
|
||||||
|
av_make_error_string(ret).c_str());
|
||||||
|
zm_av_packet_unref(&opkt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (( ret = avcodec_receive_packet( audio_output_context, &opkt )) < 0 ) {
|
if (( ret = avcodec_receive_packet( audio_output_context, &opkt )) < 0 ) {
|
||||||
|
Error( "Could not recieve packet (error '%s')",
|
||||||
|
av_make_error_string(ret).c_str());
|
||||||
|
zm_av_packet_unref(&opkt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if (( ret = avcodec_encode_audio2( audio_output_context, &opkt, output_frame, &data_present )) < 0) {
|
if (( ret = avcodec_encode_audio2( audio_output_context, &opkt, output_frame, &data_present )) < 0) {
|
||||||
#endif
|
|
||||||
Error( "Could not encode frame (error '%s')",
|
Error( "Could not encode frame (error '%s')",
|
||||||
av_make_error_string(ret).c_str());
|
av_make_error_string(ret).c_str());
|
||||||
zm_av_packet_unref(&opkt);
|
zm_av_packet_unref(&opkt);
|
||||||
|
@ -793,8 +824,8 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
||||||
zm_av_packet_unref(&opkt);
|
zm_av_packet_unref(&opkt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
av_init_packet(&opkt);
|
av_init_packet(&opkt);
|
||||||
|
@ -807,14 +838,17 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
||||||
|
|
||||||
//Scale the PTS of the outgoing packet to be the correct time base
|
//Scale the PTS of the outgoing packet to be the correct time base
|
||||||
if ( ipkt->pts != AV_NOPTS_VALUE ) {
|
if ( ipkt->pts != AV_NOPTS_VALUE ) {
|
||||||
if ( !audio_last_pts ) {
|
if ( ! audio_last_pts ) {
|
||||||
opkt.pts = 0;
|
opkt.pts = 0;
|
||||||
|
Debug(1, "No audio_last_pts");
|
||||||
} else {
|
} else {
|
||||||
if ( audio_last_pts > ipkt->pts ) {
|
if ( audio_last_pts > ipkt->pts ) {
|
||||||
Debug(1, "Resetting audeo_start_pts from (%d) to (%d)", audio_last_pts, ipkt->pts );
|
Debug(1, "Resetting audeo_start_pts from (%d) to (%d)", audio_last_pts, ipkt->pts );
|
||||||
|
opkt.pts = audio_previous_pts + av_rescale_q(ipkt->pts, audio_input_stream->time_base, audio_output_stream->time_base);
|
||||||
|
} else {
|
||||||
|
opkt.pts = audio_previous_pts + av_rescale_q(ipkt->pts - audio_last_pts, audio_input_stream->time_base, audio_output_stream->time_base);
|
||||||
}
|
}
|
||||||
opkt.pts = previous_pts + av_rescale_q(ipkt->pts - audio_last_pts, audio_input_stream->time_base, audio_output_stream->time_base);
|
Debug(2, "audio opkt.pts = %d from ipkt->pts(%d) - last_pts(%d)", opkt.pts, ipkt->pts, audio_last_pts );
|
||||||
Debug(2, "opkt.pts = %d from ipkt->pts(%d) - last_pts(%d)", opkt.pts, ipkt->pts, audio_last_pts );
|
|
||||||
}
|
}
|
||||||
audio_last_pts = ipkt->pts;
|
audio_last_pts = ipkt->pts;
|
||||||
} else {
|
} else {
|
||||||
|
@ -825,28 +859,30 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
||||||
//Scale the DTS of the outgoing packet to be the correct time base
|
//Scale the DTS of the outgoing packet to be the correct time base
|
||||||
if ( ! audio_last_dts ) {
|
if ( ! audio_last_dts ) {
|
||||||
opkt.dts = 0;
|
opkt.dts = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if( ipkt->dts == AV_NOPTS_VALUE ) {
|
if( ipkt->dts == AV_NOPTS_VALUE ) {
|
||||||
// So if the input has no dts assigned... still need an output dts... so we use cur_dts?
|
// So if the input has no dts assigned... still need an output dts... so we use cur_dts?
|
||||||
|
|
||||||
if ( audio_last_dts > audio_input_stream->cur_dts ) {
|
if ( audio_last_dts > audio_input_stream->cur_dts ) {
|
||||||
Debug(1, "Resetting audio_last_pts from (%d) to cur_dts (%d)", audio_last_dts, audio_input_stream->cur_dts );
|
Debug(1, "Resetting audio_last_dts from (%d) to cur_dts (%d)", audio_last_dts, audio_input_stream->cur_dts );
|
||||||
opkt.dts = previous_dts + av_rescale_q( audio_input_stream->cur_dts, AV_TIME_BASE_Q, audio_output_stream->time_base);
|
opkt.dts = audio_previous_dts + av_rescale_q( audio_input_stream->cur_dts, AV_TIME_BASE_Q, audio_output_stream->time_base);
|
||||||
} else {
|
} else {
|
||||||
opkt.dts = previous_dts + av_rescale_q( audio_input_stream->cur_dts - audio_last_dts, AV_TIME_BASE_Q, audio_output_stream->time_base);
|
opkt.dts = audio_previous_dts + av_rescale_q( audio_input_stream->cur_dts - audio_last_dts, AV_TIME_BASE_Q, audio_output_stream->time_base);
|
||||||
}
|
}
|
||||||
audio_last_dts = audio_input_stream->cur_dts;
|
audio_last_dts = audio_input_stream->cur_dts;
|
||||||
Debug(2, "opkt.dts = %d from video_input_stream->cur_dts(%d) - last_dts(%d)", opkt.dts, audio_input_stream->cur_dts, audio_last_dts );
|
Debug(2, "opkt.dts = %d from video_input_stream->cur_dts(%d) - last_dts(%d)", opkt.dts, audio_input_stream->cur_dts, audio_last_dts );
|
||||||
} else {
|
} else {
|
||||||
if ( audio_last_dts > ipkt->dts ) {
|
if ( audio_last_dts > ipkt->dts ) {
|
||||||
Debug(1, "Resetting audio_last_dts from (%d) to (%d)", audio_last_dts, ipkt->dts );
|
Debug(1, "Resetting audio_last_dts from (%d) to (%d)", audio_last_dts, ipkt->dts );
|
||||||
opkt.dts = previous_dts + av_rescale_q(ipkt->dts, audio_input_stream->time_base, audio_output_stream->time_base);
|
opkt.dts = audio_previous_dts + av_rescale_q(ipkt->dts, audio_input_stream->time_base, audio_output_stream->time_base);
|
||||||
} else {
|
} else {
|
||||||
opkt.dts = previous_dts + av_rescale_q(ipkt->dts - audio_last_dts, audio_input_stream->time_base, audio_output_stream->time_base);
|
opkt.dts = audio_previous_dts + av_rescale_q(ipkt->dts - audio_last_dts, audio_input_stream->time_base, audio_output_stream->time_base);
|
||||||
}
|
}
|
||||||
Debug(2, "opkt.dts = %d from ipkt->dts(%d) - last_dts(%d)", opkt.dts, ipkt->dts, audio_last_dts );
|
Debug(2, "opkt.dts = %d from ipkt->dts(%d) - last_dts(%d)", opkt.dts, ipkt->dts, audio_last_dts );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
audio_last_dts = ipkt->dts;
|
||||||
if ( opkt.dts > opkt.pts ) {
|
if ( opkt.dts > opkt.pts ) {
|
||||||
Debug(1,"opkt.dts(%d) must be <= opkt.pts(%d). Decompression must happen before presentation.", opkt.dts, opkt.pts );
|
Debug(1,"opkt.dts(%d) must be <= opkt.pts(%d). Decompression must happen before presentation.", opkt.dts, opkt.pts );
|
||||||
opkt.dts = opkt.pts;
|
opkt.dts = opkt.pts;
|
||||||
|
@ -854,15 +890,17 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
||||||
|
|
||||||
// I wonder if we could just use duration instead of all the hoop jumping above?
|
// I wonder if we could just use duration instead of all the hoop jumping above?
|
||||||
opkt.duration = av_rescale_q(ipkt->duration, audio_input_stream->time_base, audio_output_stream->time_base);
|
opkt.duration = av_rescale_q(ipkt->duration, audio_input_stream->time_base, audio_output_stream->time_base);
|
||||||
|
Debug( 2, "opkt.pts (%d), opkt.dts(%d) opkt.duration = (%d)", opkt.pts, opkt.dts, opkt.duration );
|
||||||
|
|
||||||
// pkt.pos: byte position in stream, -1 if unknown
|
// pkt.pos: byte position in stream, -1 if unknown
|
||||||
opkt.pos = -1;
|
opkt.pos = -1;
|
||||||
opkt.flags = ipkt->flags;
|
|
||||||
opkt.stream_index = ipkt->stream_index;
|
opkt.stream_index = ipkt->stream_index;
|
||||||
Debug(2, "Stream index is %d", opkt.stream_index );
|
Debug(2, "Stream index is %d", opkt.stream_index );
|
||||||
|
|
||||||
AVPacket safepkt;
|
AVPacket safepkt;
|
||||||
memcpy(&safepkt, &opkt, sizeof(AVPacket));
|
memcpy(&safepkt, &opkt, sizeof(AVPacket));
|
||||||
|
audio_previous_dts = opkt.dts; // Unsure if av_interleaved_write_frame() clobbers opkt.dts when out of order, so storing in advance
|
||||||
|
audio_previous_pts = opkt.pts;
|
||||||
ret = av_interleaved_write_frame(oc, &opkt);
|
ret = av_interleaved_write_frame(oc, &opkt);
|
||||||
if(ret!=0){
|
if(ret!=0){
|
||||||
Error("Error writing audio frame packet: %s\n", av_make_error_string(ret).c_str());
|
Error("Error writing audio frame packet: %s\n", av_make_error_string(ret).c_str());
|
||||||
|
|
|
@ -61,8 +61,10 @@ AVAudioResampleContext* resample_context;
|
||||||
int64_t audio_last_dts;
|
int64_t audio_last_dts;
|
||||||
|
|
||||||
// These are for output, should start at zero. We assume they do not wrap because we just aren't going to save files that big.
|
// These are for output, should start at zero. We assume they do not wrap because we just aren't going to save files that big.
|
||||||
int64_t previous_pts;
|
int64_t video_previous_pts;
|
||||||
int64_t previous_dts;
|
int64_t video_previous_dts;
|
||||||
|
int64_t audio_previous_pts;
|
||||||
|
int64_t audio_previous_dts;
|
||||||
|
|
||||||
int64_t filter_in_rescale_delta_last;
|
int64_t filter_in_rescale_delta_last;
|
||||||
|
|
||||||
|
|
1233
src/zmu.cpp
1233
src/zmu.cpp
File diff suppressed because it is too large
Load Diff
|
@ -39,6 +39,23 @@ checksanity () {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check key variables before calling packpack
|
||||||
|
checkvars () {
|
||||||
|
if [ -z ${VERSION} ]; then
|
||||||
|
echo
|
||||||
|
echo "FATAL: VERSION variable was null. Cannot continue."
|
||||||
|
echo
|
||||||
|
exit 98
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z ${RELEASE} ]; then
|
||||||
|
echo
|
||||||
|
echo "FATAL: RELEASE variable was null. Cannot Continue"
|
||||||
|
echo
|
||||||
|
exit 98
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Steps common to all builds
|
# Steps common to all builds
|
||||||
commonprep () {
|
commonprep () {
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
|
@ -46,7 +63,7 @@ commonprep () {
|
||||||
echo "Checking packpack github repo for changes..."
|
echo "Checking packpack github repo for changes..."
|
||||||
git -C packpack pull origin master
|
git -C packpack pull origin master
|
||||||
else
|
else
|
||||||
echo "Cloning pakcpack github repo..."
|
echo "Cloning packpack github repo..."
|
||||||
git clone https://github.com/packpack/packpack.git packpack
|
git clone https://github.com/packpack/packpack.git packpack
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -116,7 +133,7 @@ installtrusty () {
|
||||||
|
|
||||||
# This sets the naming convention for the deb packages
|
# This sets the naming convention for the deb packages
|
||||||
setdebpkgver () {
|
setdebpkgver () {
|
||||||
|
|
||||||
# Set VERSION to x.xx.x+x e.g. 1.30.2+15
|
# Set VERSION to x.xx.x+x e.g. 1.30.2+15
|
||||||
# the last x is number of commits since release
|
# the last x is number of commits since release
|
||||||
# Creates zoneminder packages in the format: zoneminder-{version}-{release}
|
# Creates zoneminder packages in the format: zoneminder-{version}-{release}
|
||||||
|
@ -125,6 +142,8 @@ setdebpkgver () {
|
||||||
export VERSION="$zmver+$commitnum"
|
export VERSION="$zmver+$commitnum"
|
||||||
export RELEASE="${DIST}"
|
export RELEASE="${DIST}"
|
||||||
|
|
||||||
|
checkvars
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Packpack VERSION has been set to: ${VERSION}"
|
echo "Packpack VERSION has been set to: ${VERSION}"
|
||||||
echo "Packpack RELEASE has been set to: ${RELEASE}"
|
echo "Packpack RELEASE has been set to: ${RELEASE}"
|
||||||
|
@ -132,6 +151,16 @@ setdebpkgver () {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# This adds an entry to the debian changelog
|
||||||
|
setdebchangelog () {
|
||||||
|
DATE=`date -R`
|
||||||
|
cat <<EOF > debian/changelog
|
||||||
|
zoneminder ($VERSION-${DIST}-1) unstable; urgency=low
|
||||||
|
*
|
||||||
|
-- Isaac Connor <iconnor@connortechnology.com> $DATE
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
################
|
################
|
||||||
# MAIN PROGRAM #
|
# MAIN PROGRAM #
|
||||||
################
|
################
|
||||||
|
@ -154,6 +183,8 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
|
||||||
export VERSION=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\1/p')
|
export VERSION=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\1/p')
|
||||||
export RELEASE=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p')
|
export RELEASE=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p')
|
||||||
|
|
||||||
|
checkvars
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Packpack VERSION has been set to: ${VERSION}"
|
echo "Packpack VERSION has been set to: ${VERSION}"
|
||||||
echo "Packpack RELEASE has been set to: ${RELEASE}"
|
echo "Packpack RELEASE has been set to: ${RELEASE}"
|
||||||
|
@ -199,7 +230,9 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
|
||||||
else
|
else
|
||||||
ln -sfT distros/ubuntu1604 debian
|
ln -sfT distros/ubuntu1604 debian
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
setdebchangelog
|
||||||
|
|
||||||
echo "Starting packpack..."
|
echo "Starting packpack..."
|
||||||
packpack/packpack
|
packpack/packpack
|
||||||
|
|
||||||
|
@ -218,6 +251,8 @@ elif [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86
|
||||||
|
|
||||||
ln -sfT distros/ubuntu1204 debian
|
ln -sfT distros/ubuntu1204 debian
|
||||||
|
|
||||||
|
setdebchangelog
|
||||||
|
|
||||||
echo "Starting packpack..."
|
echo "Starting packpack..."
|
||||||
packpack/packpack
|
packpack/packpack
|
||||||
|
|
||||||
|
|
|
@ -100,12 +100,12 @@ App::uses('CakeLog', 'Log');
|
||||||
CakeLog::config('debug', array(
|
CakeLog::config('debug', array(
|
||||||
'engine' => 'File',
|
'engine' => 'File',
|
||||||
'types' => array('notice', 'info', 'debug'),
|
'types' => array('notice', 'info', 'debug'),
|
||||||
'file' => 'cake_debug',
|
'file' => '@ZM_LOGDIR@/cake_debug',
|
||||||
));
|
));
|
||||||
CakeLog::config('error', array(
|
CakeLog::config('error', array(
|
||||||
'engine' => 'File',
|
'engine' => 'File',
|
||||||
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
|
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
|
||||||
'file' => 'cake_error',
|
'file' => '@ZM_LOGDIR@/cake_error',
|
||||||
));
|
));
|
||||||
CakeLog::config('custom_path', array(
|
CakeLog::config('custom_path', array(
|
||||||
'engine' => 'File',
|
'engine' => 'File',
|
||||||
|
|
|
@ -29,12 +29,15 @@ class Event {
|
||||||
Error('No row for Event ' . $IdOrRow );
|
Error('No row for Event ' . $IdOrRow );
|
||||||
}
|
}
|
||||||
} // end function __construct
|
} // end function __construct
|
||||||
|
|
||||||
public function Storage() {
|
public function Storage() {
|
||||||
return new Storage( isset($this->{'StorageId'}) ? $this->{'StorageId'} : NULL );
|
return new Storage( isset($this->{'StorageId'}) ? $this->{'StorageId'} : NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Monitor() {
|
public function Monitor() {
|
||||||
return new Monitor( isset($this->{'MonitorId'}) ? $this->{'MonitorId'} : NULL );
|
return new Monitor( isset($this->{'MonitorId'}) ? $this->{'MonitorId'} : NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __call( $fn, array $args){
|
public function __call( $fn, array $args){
|
||||||
if ( array_key_exists( $fn, $this ) ) {
|
if ( array_key_exists( $fn, $this ) ) {
|
||||||
return $this->{$fn};
|
return $this->{$fn};
|
||||||
|
@ -54,6 +57,7 @@ class Event {
|
||||||
$Storage = $this->Storage();
|
$Storage = $this->Storage();
|
||||||
return $Storage->Path().'/'.$this->Relative_Path();
|
return $Storage->Path().'/'.$this->Relative_Path();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Relative_Path() {
|
public function Relative_Path() {
|
||||||
$event_path = '';
|
$event_path = '';
|
||||||
|
|
||||||
|
@ -197,20 +201,26 @@ class Event {
|
||||||
return( $thumbData );
|
return( $thumbData );
|
||||||
} // end function createListThumbnail
|
} // end function createListThumbnail
|
||||||
|
|
||||||
|
// frame is an array representing the db row for a frame.
|
||||||
function getImageSrc( $frame, $scale=SCALE_BASE, $captureOnly=false, $overwrite=false ) {
|
function getImageSrc( $frame, $scale=SCALE_BASE, $captureOnly=false, $overwrite=false ) {
|
||||||
$Storage = new Storage( isset($this->{'StorageId'}) ? $this->{'StorageId'} : NULL );
|
$Storage = new Storage( isset($this->{'StorageId'}) ? $this->{'StorageId'} : NULL );
|
||||||
$Event = $this;
|
$Event = $this;
|
||||||
$eventPath = $Event->Path();
|
$eventPath = $Event->Path();
|
||||||
|
|
||||||
if ( !is_array($frame) )
|
if ( $frame and ! is_array($frame) ) {
|
||||||
|
# Must be an Id
|
||||||
|
Debug("Assuming that $frame is an Id");
|
||||||
$frame = array( 'FrameId'=>$frame, 'Type'=>'' );
|
$frame = array( 'FrameId'=>$frame, 'Type'=>'' );
|
||||||
|
}
|
||||||
|
|
||||||
if ( file_exists( $eventPath.'/snapshot.jpg' ) ) {
|
if ( ( ! $frame ) and file_exists( $eventPath.'/snapshot.jpg' ) ) {
|
||||||
$captImage = "snapshot.jpg";
|
# No frame specified, so look for a snapshot to use
|
||||||
|
$captImage = 'snapshot.jpg';
|
||||||
|
Debug("Frame not specified, using snapshot");
|
||||||
} else {
|
} else {
|
||||||
$captImage = sprintf( '%0'.ZM_EVENT_IMAGE_DIGITS.'d-capture.jpg', $frame['FrameId'] );
|
$captImage = sprintf( '%0'.ZM_EVENT_IMAGE_DIGITS.'d-capture.jpg', $frame['FrameId'] );
|
||||||
if ( ! file_exists( $eventPath.'/'.$captImage ) ) {
|
if ( ! file_exists( $eventPath.'/'.$captImage ) ) {
|
||||||
# Generate the frame JPG
|
# Generate the frame JPG
|
||||||
if ( $Event->DefaultVideo() ) {
|
if ( $Event->DefaultVideo() ) {
|
||||||
$videoPath = $eventPath.'/'.$Event->DefaultVideo();
|
$videoPath = $eventPath.'/'.$Event->DefaultVideo();
|
||||||
|
|
||||||
|
@ -275,8 +285,7 @@ class Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
$thumbFile = $thumbPath;
|
$thumbFile = $thumbPath;
|
||||||
if ( $overwrite || !file_exists( $thumbFile ) || !filesize( $thumbFile ) )
|
if ( $overwrite || ! file_exists( $thumbFile ) || ! filesize( $thumbFile ) ) {
|
||||||
{
|
|
||||||
// Get new dimensions
|
// Get new dimensions
|
||||||
list( $imageWidth, $imageHeight ) = getimagesize( $imagePath );
|
list( $imageWidth, $imageHeight ) = getimagesize( $imagePath );
|
||||||
$thumbWidth = $imageWidth * $fraction;
|
$thumbWidth = $imageWidth * $fraction;
|
||||||
|
@ -290,7 +299,7 @@ class Event {
|
||||||
if ( !imagejpeg( $thumbImage, $thumbPath ) )
|
if ( !imagejpeg( $thumbImage, $thumbPath ) )
|
||||||
Error( "Can't create thumbnail '$thumbPath'" );
|
Error( "Can't create thumbnail '$thumbPath'" );
|
||||||
}
|
}
|
||||||
}
|
} # Create thumbnails
|
||||||
|
|
||||||
$imageData = array(
|
$imageData = array(
|
||||||
'eventPath' => $eventPath,
|
'eventPath' => $eventPath,
|
||||||
|
@ -298,7 +307,7 @@ class Event {
|
||||||
'thumbPath' => $thumbPath,
|
'thumbPath' => $thumbPath,
|
||||||
'imageFile' => $imagePath,
|
'imageFile' => $imagePath,
|
||||||
'thumbFile' => $thumbFile,
|
'thumbFile' => $thumbFile,
|
||||||
'imageClass' => $alarmFrame?"alarm":"normal",
|
'imageClass' => $alarmFrame?'alarm':'normal',
|
||||||
'isAnalImage' => $isAnalImage,
|
'isAnalImage' => $isAnalImage,
|
||||||
'hasAnalImage' => $hasAnalImage,
|
'hasAnalImage' => $hasAnalImage,
|
||||||
);
|
);
|
||||||
|
|
|
@ -27,9 +27,11 @@ class Frame {
|
||||||
Error("No row for Frame " . $IdOrRow );
|
Error("No row for Frame " . $IdOrRow );
|
||||||
}
|
}
|
||||||
} // end function __construct
|
} // end function __construct
|
||||||
|
|
||||||
public function Storage() {
|
public function Storage() {
|
||||||
return $this->Event()->Storage();
|
return $this->Event()->Storage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Event() {
|
public function Event() {
|
||||||
return new Event( $this->{'EventId'} );
|
return new Event( $this->{'EventId'} );
|
||||||
}
|
}
|
||||||
|
@ -70,7 +72,9 @@ class Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getImageSrc( $show='capture' ) {
|
public function getImageSrc( $show='capture' ) {
|
||||||
return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'Id'}.'&show='.$show.'&filename='.$this->Event()->MonitorId().'_'.$this->{'EventId'}.'_'.$this->{'FrameId'}.'.jpg';
|
|
||||||
|
return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'FrameId'}.'&eid='.$this->{'EventId'}.'&show='.$show;
|
||||||
|
#return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'Id'}.'&show='.$show.'&filename='.$this->Event()->MonitorId().'_'.$this->{'EventId'}.'_'.$this->{'FrameId'}.'.jpg';
|
||||||
} // end function getImageSrc
|
} // end function getImageSrc
|
||||||
|
|
||||||
public static function find( $parameters = array(), $limit = NULL ) {
|
public static function find( $parameters = array(), $limit = NULL ) {
|
||||||
|
|
|
@ -1149,17 +1149,17 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
||||||
if ( isset($filter['terms']) && count($filter['terms']) ) {
|
if ( isset($filter['terms']) && count($filter['terms']) ) {
|
||||||
for ( $i = 0; $i < count($filter['terms']); $i++ ) {
|
for ( $i = 0; $i < count($filter['terms']); $i++ ) {
|
||||||
if ( isset($filter['terms'][$i]['cnj']) ) {
|
if ( isset($filter['terms'][$i]['cnj']) ) {
|
||||||
$filter['query'] .= $querySep."filter[terms][$i][cnj]=".urlencode($filter['terms'][$i]['cnj']);
|
$filter['query'] .= $querySep.urlencode("filter[terms][$i][cnj]").'='.urlencode($filter['terms'][$i]['cnj']);
|
||||||
$filter['sql'] .= " ".$filter['terms'][$i]['cnj']." ";
|
$filter['sql'] .= ' '.$filter['terms'][$i]['cnj'].' ';
|
||||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][cnj]\" value=\"".htmlspecialchars($filter['terms'][$i]['cnj'])."\"/>\n";
|
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][cnj]\" value=\"".htmlspecialchars($filter['terms'][$i]['cnj'])."\"/>\n";
|
||||||
}
|
}
|
||||||
if ( isset($filter['terms'][$i]['obr']) ) {
|
if ( isset($filter['terms'][$i]['obr']) ) {
|
||||||
$filter['query'] .= $querySep."filter[terms][$i][obr]=".urlencode($filter['terms'][$i]['obr']);
|
$filter['query'] .= $querySep.urlencode("filter[terms][$i][obr]").'='.urlencode($filter['terms'][$i]['obr']);
|
||||||
$filter['sql'] .= " ".str_repeat( "(", $filter['terms'][$i]['obr'] )." ";
|
$filter['sql'] .= ' '.str_repeat( '(', $filter['terms'][$i]['obr'] ).' ';
|
||||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][obr]\" value=\"".htmlspecialchars($filter['terms'][$i]['obr'])."\"/>\n";
|
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][obr]\" value=\"".htmlspecialchars($filter['terms'][$i]['obr'])."\"/>\n";
|
||||||
}
|
}
|
||||||
if ( isset($filter['terms'][$i]['attr']) ) {
|
if ( isset($filter['terms'][$i]['attr']) ) {
|
||||||
$filter['query'] .= $querySep."filter[terms][$i][attr]=".urlencode($filter['terms'][$i]['attr']);
|
$filter['query'] .= $querySep.urlencode("filter[terms][$i][attr]").'='.urlencode($filter['terms'][$i]['attr']);
|
||||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][attr]\" value=\"".htmlspecialchars($filter['terms'][$i]['attr'])."\"/>\n";
|
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][attr]\" value=\"".htmlspecialchars($filter['terms'][$i]['attr'])."\"/>\n";
|
||||||
switch ( $filter['terms'][$i]['attr'] ) {
|
switch ( $filter['terms'][$i]['attr'] ) {
|
||||||
case 'MonitorName':
|
case 'MonitorName':
|
||||||
|
@ -1267,7 +1267,7 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
||||||
case '>' :
|
case '>' :
|
||||||
case '<' :
|
case '<' :
|
||||||
case '<=' :
|
case '<=' :
|
||||||
$filter['sql'] .= ' '.$filter['terms'][$i]['op']." $value";
|
$filter['sql'] .= ' '.$filter['terms'][$i]['op'].' '. $value;
|
||||||
break;
|
break;
|
||||||
case '=~' :
|
case '=~' :
|
||||||
$filter['sql'] .= ' regexp '.$value;
|
$filter['sql'] .= ' regexp '.$value;
|
||||||
|
@ -1276,20 +1276,20 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
||||||
$filter['sql'] .= ' not regexp '.$value;
|
$filter['sql'] .= ' not regexp '.$value;
|
||||||
break;
|
break;
|
||||||
case '=[]' :
|
case '=[]' :
|
||||||
$filter['sql'] .= ' in ('.join( ",", $valueList ).')';
|
$filter['sql'] .= ' in ('.join( ',', $valueList ).')';
|
||||||
break;
|
break;
|
||||||
case '![]' :
|
case '![]' :
|
||||||
$filter['sql'] .= ' not in ('.join( ',', $valueList ).')';
|
$filter['sql'] .= ' not in ('.join( ',', $valueList ).')';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filter['query'] .= $querySep."filter[terms][$i][op]=".urlencode($filter['terms'][$i]['op']);
|
$filter['query'] .= $querySep.urlencode("filter[terms][$i][op]").'='.urlencode($filter['terms'][$i]['op']);
|
||||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][op]\" value=\"".htmlspecialchars($filter['terms'][$i]['op'])."\"/>\n";
|
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][op]\" value=\"".htmlspecialchars($filter['terms'][$i]['op'])."\"/>\n";
|
||||||
$filter['query'] .= $querySep."filter[terms][$i][val]=".urlencode($filter['terms'][$i]['val']);
|
$filter['query'] .= $querySep.urlencode("filter[terms][$i][val]").'='.urlencode($filter['terms'][$i]['val']);
|
||||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][val]\" value=\"".htmlspecialchars($filter['terms'][$i]['val'])."\"/>\n";
|
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][val]\" value=\"".htmlspecialchars($filter['terms'][$i]['val'])."\"/>\n";
|
||||||
}
|
}
|
||||||
if ( isset($filter['terms'][$i]['cbr']) ) {
|
if ( isset($filter['terms'][$i]['cbr']) ) {
|
||||||
$filter['query'] .= $querySep."filter[terms][$i][cbr]=".urlencode($filter['terms'][$i]['cbr']);
|
$filter['query'] .= $querySep.urlencode("filter[terms][$i][cbr]").'='.urlencode($filter['terms'][$i]['cbr']);
|
||||||
$filter['sql'] .= ' '.str_repeat( ')', $filter['terms'][$i]['cbr'] ).' ';
|
$filter['sql'] .= ' '.str_repeat( ')', $filter['terms'][$i]['cbr'] ).' ';
|
||||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][cbr]\" value=\"".htmlspecialchars($filter['terms'][$i]['cbr'])."\"/>\n";
|
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[terms][$i][cbr]\" value=\"".htmlspecialchars($filter['terms'][$i]['cbr'])."\"/>\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,29 +23,28 @@
|
||||||
$bad_views = array('monitor', 'log');
|
$bad_views = array('monitor', 'log');
|
||||||
|
|
||||||
function xhtmlHeaders( $file, $title ) {
|
function xhtmlHeaders( $file, $title ) {
|
||||||
global $css;
|
global $css;
|
||||||
global $skin;
|
global $skin;
|
||||||
$skinCssFile = getSkinFile( 'css/'.$css.'/skin.css' );
|
$skinCssFile = getSkinFile( 'css/'.$css.'/skin.css' );
|
||||||
$skinCssPhpFile = getSkinFile( 'css/'.$css.'/skin.css.php' );
|
$skinCssPhpFile = getSkinFile( 'css/'.$css.'/skin.css.php' );
|
||||||
|
|
||||||
$skinJsFile = getSkinFile( 'js/skin.js' );
|
$skinJsFile = getSkinFile( 'js/skin.js' );
|
||||||
$skinJsPhpFile = getSkinFile( 'js/skin.js.php' );
|
$skinJsPhpFile = getSkinFile( 'js/skin.js.php' );
|
||||||
$cssJsFile = getSkinFile( 'js/'.$css.'.js' );
|
$cssJsFile = getSkinFile( 'js/'.$css.'.js' );
|
||||||
|
|
||||||
$basename = basename( $file, '.php' );
|
$basename = basename( $file, '.php' );
|
||||||
$viewCssFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css' );
|
$viewCssFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css' );
|
||||||
$viewCssPhpFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css.php' );
|
$viewCssPhpFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css.php' );
|
||||||
$viewJsFile = getSkinFile( 'views/js/'.$basename.'.js' );
|
$viewJsFile = getSkinFile( 'views/js/'.$basename.'.js' );
|
||||||
$viewJsPhpFile = getSkinFile( 'views/js/'.$basename.'.js.php' );
|
$viewJsPhpFile = getSkinFile( 'views/js/'.$basename.'.js.php' );
|
||||||
|
|
||||||
extract( $GLOBALS, EXTR_OVERWRITE );
|
extract( $GLOBALS, EXTR_OVERWRITE );
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
|
||||||
<title><?php echo ZM_WEB_TITLE_PREFIX ?> - <?php echo validHtmlStr($title) ?></title>
|
<title><?php echo ZM_WEB_TITLE_PREFIX ?> - <?php echo validHtmlStr($title) ?></title>
|
||||||
<link rel="icon" type="image/ico" href="graphics/favicon.ico"/>
|
<link rel="icon" type="image/ico" href="graphics/favicon.ico"/>
|
||||||
<link rel="shortcut icon" href="graphics/favicon.ico"/>
|
<link rel="shortcut icon" href="graphics/favicon.ico"/>
|
||||||
|
@ -54,17 +53,17 @@ function xhtmlHeaders( $file, $title ) {
|
||||||
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css"/>
|
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css"/>
|
||||||
<link rel="stylesheet" href="<?php echo $skinCssFile ?>" type="text/css" media="screen"/>
|
<link rel="stylesheet" href="<?php echo $skinCssFile ?>" type="text/css" media="screen"/>
|
||||||
<?php
|
<?php
|
||||||
if ( $viewCssFile ) {
|
if ( $viewCssFile ) {
|
||||||
?>
|
?>
|
||||||
<link rel="stylesheet" href="<?php echo $viewCssFile ?>" type="text/css" media="screen"/>
|
<link rel="stylesheet" href="<?php echo $viewCssFile ?>" type="text/css" media="screen"/>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( $viewCssPhpFile ) {
|
if ( $viewCssPhpFile ) {
|
||||||
?>
|
?>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
/*<![CDATA[*/
|
/*<![CDATA[*/
|
||||||
<?php
|
<?php
|
||||||
require_once( $viewCssPhpFile );
|
require_once( $viewCssPhpFile );
|
||||||
?>
|
?>
|
||||||
/*]]>*/
|
/*]]>*/
|
||||||
</style>
|
</style>
|
||||||
|
@ -96,8 +95,9 @@ var $j = jQuery.noConflict();
|
||||||
<script src="skins/<?php echo $skin ?>/js/video.js"></script>
|
<script src="skins/<?php echo $skin ?>/js/video.js"></script>
|
||||||
<script src="./js/videojs.zoomrotate.js"></script>
|
<script src="./js/videojs.zoomrotate.js"></script>
|
||||||
<script src="skins/<?php echo $skin ?>/js/moment.min.js"></script>
|
<script src="skins/<?php echo $skin ?>/js/moment.min.js"></script>
|
||||||
<?php }
|
<?php
|
||||||
if ( $skinJsPhpFile ) {
|
}
|
||||||
|
if ( $skinJsPhpFile ) {
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
|
@ -109,20 +109,20 @@ var $j = jQuery.noConflict();
|
||||||
//]]>
|
//]]>
|
||||||
</script>
|
</script>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( $viewJsPhpFile ) {
|
if ( $viewJsPhpFile ) {
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
//<![CDATA[
|
//<![CDATA[
|
||||||
<!--
|
<!--
|
||||||
<?php
|
<?php
|
||||||
require_once( $viewJsPhpFile );
|
require_once( $viewJsPhpFile );
|
||||||
?>
|
?>
|
||||||
//-->
|
//-->
|
||||||
//]]>
|
//]]>
|
||||||
</script>
|
</script>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( $cssJsFile ) {
|
if ( $cssJsFile ) {
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" src="<?php echo $cssJsFile ?>"></script>
|
<script type="text/javascript" src="<?php echo $cssJsFile ?>"></script>
|
||||||
|
@ -130,11 +130,11 @@ var $j = jQuery.noConflict();
|
||||||
<script type="text/javascript" src="<?php echo $skinJsFile ?>"></script>
|
<script type="text/javascript" src="<?php echo $skinJsFile ?>"></script>
|
||||||
<script type="text/javascript" src="js/logger.js"></script>
|
<script type="text/javascript" src="js/logger.js"></script>
|
||||||
<?php
|
<?php
|
||||||
if ( $viewJsFile ) {
|
if ( $viewJsFile ) {
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" src="<?php echo $viewJsFile ?>"></script>
|
<script type="text/javascript" src="<?php echo $viewJsFile ?>"></script>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</head>
|
</head>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -152,30 +152,6 @@ xhtmlHeaders( __FILE__, translate('Console') );
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<td class="colLeftButtons" colspan="<?php echo $left_columns ?>">
|
|
||||||
<input type="button" class="btn btn-primary" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
|
|
||||||
<input type="button" class="btn btn-primary" name="addBtn" value="<?php echo translate('AddNewMonitor') ?>" onclick="addMonitor( this )"/>
|
|
||||||
<!-- <?php echo makePopupButton( '?view=monitor', 'zmMonitor0', 'monitor', translate('AddNewMonitor'), (canEdit( 'Monitors' ) && !$user['MonitorIds']) ) ?> -->
|
|
||||||
<?php echo makePopupButton( '?view=filter&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3c&filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?>
|
|
||||||
<input class="btn btn-primary" type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/>
|
|
||||||
<input class="btn btn-danger" type="button" name="deleteBtn" value="<?php echo translate('Delete') ?>" onclick="deleteMonitor( this )" disabled="disabled"/>
|
|
||||||
</td>
|
|
||||||
<?php
|
|
||||||
for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
|
||||||
parseFilter( $eventCounts[$i]['filter'] );
|
|
||||||
?>
|
|
||||||
<td class="colEvents"><?php echo makePopupLink( '?view='.$eventsView.'&page=1'.$eventCounts[$i]['filter']['query'], $eventsWindow, $eventsView, $eventCounts[$i]['total'], canView( 'Events' ) ) ?></td>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<td class="colZones"><?php echo $zoneCount ?></td>
|
|
||||||
<?php if ( canEdit('Monitors') ) { ?>
|
|
||||||
<td class="colMark"></td>
|
|
||||||
<?php } ?>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
<tbody id="consoleTableBody">
|
<tbody id="consoleTableBody">
|
||||||
<?php
|
<?php
|
||||||
for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
|
@ -195,7 +171,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
if ( $monitor['Function'] == 'None' )
|
if ( $monitor['Function'] == 'None' )
|
||||||
$fclass = 'errorText';
|
$fclass = 'errorText';
|
||||||
//elseif ( $monitor['Function'] == 'Monitor' )
|
//elseif ( $monitor['Function'] == 'Monitor' )
|
||||||
// $fclass = "warnText";
|
// $fclass = 'warnText';
|
||||||
else
|
else
|
||||||
$fclass = 'infoText';
|
$fclass = 'infoText';
|
||||||
if ( !$monitor['Enabled'] )
|
if ( !$monitor['Enabled'] )
|
||||||
|
@ -251,6 +227,30 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
} # end for each monitor
|
} # end for each monitor
|
||||||
?>
|
?>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td class="colLeftButtons" colspan="<?php echo $left_columns ?>">
|
||||||
|
<input type="button" class="btn btn-primary" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
|
||||||
|
<input type="button" class="btn btn-primary" name="addBtn" value="<?php echo translate('AddNewMonitor') ?>" onclick="addMonitor( this )"/>
|
||||||
|
<!-- <?php echo makePopupButton( '?view=monitor', 'zmMonitor0', 'monitor', translate('AddNewMonitor'), (canEdit( 'Monitors' ) && !$user['MonitorIds']) ) ?> -->
|
||||||
|
<?php echo makePopupButton( '?view=filter&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3c&filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?>
|
||||||
|
<input class="btn btn-primary" type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/>
|
||||||
|
<input class="btn btn-danger" type="button" name="deleteBtn" value="<?php echo translate('Delete') ?>" onclick="deleteMonitor( this )" disabled="disabled"/>
|
||||||
|
</td>
|
||||||
|
<?php
|
||||||
|
for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
||||||
|
parseFilter( $eventCounts[$i]['filter'] );
|
||||||
|
?>
|
||||||
|
<td class="colEvents"><?php echo makePopupLink( '?view='.$eventsView.'&page=1'.$eventCounts[$i]['filter']['query'], $eventsWindow, $eventsView, $eventCounts[$i]['total'], canView( 'Events' ) ) ?></td>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<td class="colZones"><?php echo $zoneCount ?></td>
|
||||||
|
<?php if ( canEdit('Monitors') ) { ?>
|
||||||
|
<td class="colMark"></td>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -81,7 +81,7 @@ if ( !empty($page) ) {
|
||||||
}
|
}
|
||||||
$eventsSql .= " limit $limitStart, $limitAmount";
|
$eventsSql .= " limit $limitStart, $limitAmount";
|
||||||
} elseif ( !empty( $limit ) ) {
|
} elseif ( !empty( $limit ) ) {
|
||||||
$eventsSql .= " limit 0, ".$limit;
|
$eventsSql .= ' limit 0, '.$limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$maxWidth = 0;
|
$maxWidth = 0;
|
||||||
|
@ -118,15 +118,15 @@ xhtmlHeaders(__FILE__, translate('Events') );
|
||||||
<div id="headerButtons">
|
<div id="headerButtons">
|
||||||
<?php
|
<?php
|
||||||
if ( $pages > 1 ) {
|
if ( $pages > 1 ) {
|
||||||
if ( !empty($page) ) {
|
if ( !empty($page) ) {
|
||||||
?>
|
?>
|
||||||
<a href="?view=<?php echo $view ?>&page=0<?php echo $filterQuery ?><?php echo $sortQuery ?>&limit=<?php echo $limit ?>"><?php echo translate('ViewAll') ?></a>
|
<a href="?view=<?php echo $view ?>&page=0<?php echo $filterQuery ?><?php echo $sortQuery ?>&limit=<?php echo $limit ?>"><?php echo translate('ViewAll') ?></a>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<a href="?view=<?php echo $view ?>&page=1<?php echo $filterQuery ?><?php echo $sortQuery ?>&limit=<?php echo $limit ?>"><?php echo translate('ViewPaged') ?></a>
|
<a href="?view=<?php echo $view ?>&page=1<?php echo $filterQuery ?><?php echo $sortQuery ?>&limit=<?php echo $limit ?>"><?php echo translate('ViewPaged') ?></a>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<a href="#" onclick="closeWindows();"><?php echo translate('Close') ?></a>
|
<a href="#" onclick="closeWindows();"><?php echo translate('Close') ?></a>
|
||||||
|
@ -173,21 +173,22 @@ foreach ( $events as $event ) {
|
||||||
<th class="colTotScore"><a href="<?php echo sortHeader( 'TotScore' ) ?>"><?php echo translate('TotalBrScore') ?><?php echo sortTag( 'TotScore' ) ?></a></th>
|
<th class="colTotScore"><a href="<?php echo sortHeader( 'TotScore' ) ?>"><?php echo translate('TotalBrScore') ?><?php echo sortTag( 'TotScore' ) ?></a></th>
|
||||||
<th class="colAvgScore"><a href="<?php echo sortHeader( 'AvgScore' ) ?>"><?php echo translate('AvgBrScore') ?><?php echo sortTag( 'AvgScore' ) ?></a></th>
|
<th class="colAvgScore"><a href="<?php echo sortHeader( 'AvgScore' ) ?>"><?php echo translate('AvgBrScore') ?><?php echo sortTag( 'AvgScore' ) ?></a></th>
|
||||||
<th class="colMaxScore"><a href="<?php echo sortHeader( 'MaxScore' ) ?>"><?php echo translate('MaxBrScore') ?><?php echo sortTag( 'MaxScore' ) ?></a></th>
|
<th class="colMaxScore"><a href="<?php echo sortHeader( 'MaxScore' ) ?>"><?php echo translate('MaxBrScore') ?><?php echo sortTag( 'MaxScore' ) ?></a></th>
|
||||||
<?php if ( ZM_WEB_EVENT_DISK_SPACE ) { ?>
|
<?php
|
||||||
|
if ( ZM_WEB_EVENT_DISK_SPACE ) { ?>
|
||||||
<th class="colDiskSpace"><a href="<?php echo sortHeader( 'DiskSpace' ) ?>"><?php echo translate('DiskSpace') ?><?php echo sortTag( 'DiskSpace' ) ?></a></th>
|
<th class="colDiskSpace"><a href="<?php echo sortHeader( 'DiskSpace' ) ?>"><?php echo translate('DiskSpace') ?><?php echo sortTag( 'DiskSpace' ) ?></a></th>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( ZM_WEB_LIST_THUMBS ) {
|
if ( ZM_WEB_LIST_THUMBS ) {
|
||||||
?>
|
?>
|
||||||
<th class="colThumbnail"><?php echo translate('Thumbnail') ?></th>
|
<th class="colThumbnail"><?php echo translate('Thumbnail') ?></th>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<th class="colMark"><input type="checkbox" name="toggleCheck" value="1" onclick="toggleCheckbox( this, 'markEids' );"<?php if ( !canEdit( 'Events' ) ) { ?> disabled="disabled"<?php } ?>/></th>
|
<th class="colMark"><input type="checkbox" name="toggleCheck" value="1" onclick="toggleCheckbox( this, 'markEids' );"<?php if ( !canEdit( 'Events' ) ) { ?> disabled="disabled"<?php } ?>/></th>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
$scale = max( reScale( SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
|
$scale = max( reScale( SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="colId"><?php echo makePopupLink( '?view=event&eid='.$event->Id().$filterQuery.$sortQuery.'&page=1', 'zmEvent', array( 'event', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), $event->Id().($event->Archived()?'*':'') ) ?></td>
|
<td class="colId"><?php echo makePopupLink( '?view=event&eid='.$event->Id().$filterQuery.$sortQuery.'&page=1', 'zmEvent', array( 'event', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), $event->Id().($event->Archived()?'*':'') ) ?></td>
|
||||||
|
@ -201,35 +202,37 @@ foreach ( $events as $event ) {
|
||||||
<td class="colTotScore"><?php echo $event->TotScore() ?></td>
|
<td class="colTotScore"><?php echo $event->TotScore() ?></td>
|
||||||
<td class="colAvgScore"><?php echo $event->AvgScore() ?></td>
|
<td class="colAvgScore"><?php echo $event->AvgScore() ?></td>
|
||||||
<td class="colMaxScore"><?php echo makePopupLink( '?view=frame&eid='.$event->Id().'&fid=0', 'zmImage', array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), $event->MaxScore() ) ?></td>
|
<td class="colMaxScore"><?php echo makePopupLink( '?view=frame&eid='.$event->Id().'&fid=0', 'zmImage', array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), $event->MaxScore() ) ?></td>
|
||||||
<?php if ( ZM_WEB_EVENT_DISK_SPACE ) { ?>
|
<?php
|
||||||
|
if ( ZM_WEB_EVENT_DISK_SPACE ) {
|
||||||
|
?>
|
||||||
<td class="colDiskSpace"><?php echo human_filesize( $event->DiskSpace() ) ?></td>
|
<td class="colDiskSpace"><?php echo human_filesize( $event->DiskSpace() ) ?></td>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( ZM_WEB_LIST_THUMBS ) {
|
if ( ZM_WEB_LIST_THUMBS ) {
|
||||||
if ( $thumbData = $event->createListThumbnail() ) {
|
if ( $thumbData = $event->createListThumbnail() ) {
|
||||||
?>
|
?>
|
||||||
<td class="colThumbnail">
|
<td class="colThumbnail">
|
||||||
<?php
|
<?php
|
||||||
|
$imgSrc = '?view=image&eid='.$event->Id().'&fid='.$thumbData['FrameId'].'&width='.$thumbData['Width'].'&height='.$thumbData['Height'];
|
||||||
$imgSrc = '?view=image&eid='.$event->Id().'&fid='.$thumbData['FrameId'].'&width='.$thumbData['Width'].'&height='.$thumbData['Height'];
|
$streamSrc = getStreamSrc( array( "source=event", "mode=jpeg", "event=".$event->Id(), "scale=".$scale, "maxfps=".ZM_WEB_VIDEO_MAXFPS, "replay=single") );
|
||||||
$streamSrc = getStreamSrc( array( "source=event", "mode=jpeg", "event=".$event->Id(), "scale=".$scale, "maxfps=".ZM_WEB_VIDEO_MAXFPS, "replay=single") );
|
|
||||||
|
|
||||||
$imgHtml = '<img id="thumbnail'.$event->id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($thumbData['Width']) .'px;height:'. validInt( $thumbData['Height'] ).'px;" onmouseover="this.src=\''.$streamSrc.'\';" onmouseout="this.src=\''.$imgSrc.'\';"/>';
|
$imgHtml = '<img id="thumbnail'.$event->id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($thumbData['Width']) .'px;height:'. validInt( $thumbData['Height'] ).'px;" onmouseover="this.src=\''.$streamSrc.'\';" onmouseout="this.src=\''.$imgSrc.'\';"/>';
|
||||||
|
|
||||||
echo makePopupLink(
|
echo makePopupLink(
|
||||||
'?view=frame&eid='.$event->Id().'&fid='.$thumbData['FrameId'],
|
'?view=frame&eid='.$event->Id().'&fid='.$thumbData['FrameId'],
|
||||||
'zmImage',
|
'zmImage',
|
||||||
array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ),
|
array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ),
|
||||||
$imgHtml
|
$imgHtml
|
||||||
);
|
);
|
||||||
?></td>
|
?>
|
||||||
|
</td>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<td class="colThumbnail"> </td>
|
<td class="colThumbnail"> </td>
|
||||||
<?php
|
<?php
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // end if ZM_WEB_LIST_THUMBS
|
||||||
?>
|
?>
|
||||||
<td class="colMark"><input type="checkbox" name="markEids[]" value="<?php echo $event->Id() ?>" onclick="configureButton( this, 'markEids' );"<?php if ( !canEdit( 'Events' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
<td class="colMark"><input type="checkbox" name="markEids[]" value="<?php echo $event->Id() ?>" onclick="configureButton( this, 'markEids' );"<?php if ( !canEdit( 'Events' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -239,14 +242,12 @@ foreach ( $events as $event ) {
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<?php
|
<?php
|
||||||
if ( $pagination )
|
if ( $pagination ) {
|
||||||
{
|
|
||||||
?>
|
?>
|
||||||
<h3 class="pagination"><?php echo $pagination ?></h3>
|
<h3 class="pagination"><?php echo $pagination ?></h3>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( true || canEdit( 'Events' ) )
|
if ( true || canEdit( 'Events' ) ) {
|
||||||
{
|
|
||||||
?>
|
?>
|
||||||
<div id="contentButtons">
|
<div id="contentButtons">
|
||||||
<input type="button" name="viewBtn" value="<?php echo translate('View') ?>" onclick="viewEvents( this, 'markEids' );" disabled="disabled"/>
|
<input type="button" name="viewBtn" value="<?php echo translate('View') ?>" onclick="viewEvents( this, 'markEids' );" disabled="disabled"/>
|
||||||
|
|
|
@ -68,7 +68,7 @@ if ( isset( $_REQUEST['reload'] ) and ! $_REQUEST['reload'] ) {
|
||||||
$conjunctionTypes = array(
|
$conjunctionTypes = array(
|
||||||
'and' => translate('ConjAnd'),
|
'and' => translate('ConjAnd'),
|
||||||
'or' => translate('ConjOr')
|
'or' => translate('ConjOr')
|
||||||
);
|
);
|
||||||
$obracketTypes = array();
|
$obracketTypes = array();
|
||||||
$cbracketTypes = array();
|
$cbracketTypes = array();
|
||||||
if ( isset($_REQUEST['filter']['terms']) ) {
|
if ( isset($_REQUEST['filter']['terms']) ) {
|
||||||
|
@ -102,7 +102,8 @@ $attrTypes = array(
|
||||||
'StorageId' => translate('AttrStorageArea'),
|
'StorageId' => translate('AttrStorageArea'),
|
||||||
'ServerId' => translate('AttrServer'),
|
'ServerId' => translate('AttrServer'),
|
||||||
'StateId' => translate('AttrStateId'),
|
'StateId' => translate('AttrStateId'),
|
||||||
);
|
);
|
||||||
|
|
||||||
$opTypes = array(
|
$opTypes = array(
|
||||||
'=' => translate('OpEq'),
|
'=' => translate('OpEq'),
|
||||||
'!=' => translate('OpNe'),
|
'!=' => translate('OpNe'),
|
||||||
|
@ -114,15 +115,18 @@ $opTypes = array(
|
||||||
'!~' => translate('OpNotMatches'),
|
'!~' => translate('OpNotMatches'),
|
||||||
'=[]' => translate('OpIn'),
|
'=[]' => translate('OpIn'),
|
||||||
'![]' => translate('OpNotIn'),
|
'![]' => translate('OpNotIn'),
|
||||||
);
|
);
|
||||||
|
|
||||||
$archiveTypes = array(
|
$archiveTypes = array(
|
||||||
'0' => translate('ArchUnarchived'),
|
'0' => translate('ArchUnarchived'),
|
||||||
'1' => translate('ArchArchived')
|
'1' => translate('ArchArchived')
|
||||||
);
|
);
|
||||||
|
|
||||||
$weekdays = array();
|
$weekdays = array();
|
||||||
for ( $i = 0; $i < 7; $i++ ) {
|
for ( $i = 0; $i < 7; $i++ ) {
|
||||||
$weekdays[$i] = strftime( "%A", mktime( 12, 0, 0, 1, $i+1, 2001 ) );
|
$weekdays[$i] = strftime( '%A', mktime( 12, 0, 0, 1, $i+1, 2001 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$sort_fields = array(
|
$sort_fields = array(
|
||||||
'Id' => translate('AttrId'),
|
'Id' => translate('AttrId'),
|
||||||
'Name' => translate('AttrName'),
|
'Name' => translate('AttrName'),
|
||||||
|
@ -136,14 +140,16 @@ $sort_fields = array(
|
||||||
'TotScore' => translate('AttrTotalScore'),
|
'TotScore' => translate('AttrTotalScore'),
|
||||||
'AvgScore' => translate('AttrAvgScore'),
|
'AvgScore' => translate('AttrAvgScore'),
|
||||||
'MaxScore' => translate('AttrMaxScore'),
|
'MaxScore' => translate('AttrMaxScore'),
|
||||||
);
|
);
|
||||||
|
|
||||||
$sort_dirns = array(
|
$sort_dirns = array(
|
||||||
'1' => translate('SortAsc'),
|
'1' => translate('SortAsc'),
|
||||||
'0' => translate('SortDesc')
|
'0' => translate('SortDesc')
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( empty($_REQUEST['sort_field']) ) {
|
if ( empty($_REQUEST['sort_field']) ) {
|
||||||
$_REQUEST['sort_field'] = ZM_WEB_EVENT_SORT_FIELD;
|
$_REQUEST['sort_field'] = ZM_WEB_EVENT_SORT_FIELD;
|
||||||
$_REQUEST['sort_asc'] = (ZM_WEB_EVENT_SORT_ORDER == "asc");
|
$_REQUEST['sort_asc'] = (ZM_WEB_EVENT_SORT_ORDER == 'asc');
|
||||||
}
|
}
|
||||||
|
|
||||||
$hasCal = file_exists( 'tools/jscalendar/calendar.js' );
|
$hasCal = file_exists( 'tools/jscalendar/calendar.js' );
|
||||||
|
@ -180,98 +186,108 @@ for ( $i = 0; isset($_REQUEST['filter']) && $i < count($_REQUEST['filter']['term
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<?php
|
<?php
|
||||||
if ( $i == 0 ) {
|
if ( $i == 0 ) {
|
||||||
?>
|
?>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][cnj]", $conjunctionTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][cnj]", $conjunctionTypes ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php if ( count($_REQUEST['filter']['terms']) > 2 ) { echo buildSelect( "filter[terms][$i][obr]", $obracketTypes ); } else { ?> <?php } ?></td>
|
<td><?php if ( count($_REQUEST['filter']['terms']) > 2 ) { echo buildSelect( "filter[terms][$i][obr]", $obracketTypes ); } else { ?> <?php } ?></td>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][attr]", $attrTypes, "clearValue( this, $i ); submitToFilter( this, 0 );" ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][attr]", $attrTypes, "clearValue( this, $i ); submitToFilter( this, 0 );" ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
if ( isset($_REQUEST['filter']['terms'][$i]['attr']) ) {
|
if ( isset($_REQUEST['filter']['terms'][$i]['attr']) ) {
|
||||||
if ( $_REQUEST['filter']['terms'][$i]['attr'] == "Archived" ) {
|
if ( $_REQUEST['filter']['terms'][$i]['attr'] == 'Archived' ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo translate('OpEq') ?><input type="hidden" name="filter[terms][<?php echo $i ?>][op]" value="="/></td>
|
<td><?php echo translate('OpEq') ?><input type="hidden" name="filter[terms][<?php echo $i ?>][op]" value="="/></td>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][val]", $archiveTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][val]", $archiveTypes ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == "DateTime" ) {
|
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == 'DateTime' ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><input name="filter[terms][<?php echo $i ?>][val]" id="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($_REQUEST['filter']['terms'][$i]['val'])?validHtmlStr($_REQUEST['filter']['terms'][$i]['val']):'' ?>"/><?php if ( $hasCal ) { ?><script type="text/javascript">Calendar.setup( { inputField: "filter[terms][<?php echo $i ?>][val]", ifFormat: "%Y-%m-%d %H:%M", showsTime: true, timeFormat: "24", showOthers: true, weekNumbers: false });</script><?php } ?></td>
|
<td>
|
||||||
|
<input name="filter[terms][<?php echo $i ?>][val]" id="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($_REQUEST['filter']['terms'][$i]['val'])?validHtmlStr($_REQUEST['filter']['terms'][$i]['val']):'' ?>"/>
|
||||||
|
<?php if ( $hasCal ) { ?>
|
||||||
|
<script type="text/javascript">Calendar.setup( { inputField: "filter[terms][<?php echo $i ?>][val]", ifFormat: "%Y-%m-%d %H:%M", showsTime: true, timeFormat: "24", showOthers: true, weekNumbers: false });</script>
|
||||||
|
<?php } ?>
|
||||||
|
</td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == "Date" ) {
|
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == 'Date' ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><input name="filter[terms][<?php echo $i ?>][val]" id="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($_REQUEST['filter']['terms'][$i]['val'])?validHtmlStr($_REQUEST['filter']['terms'][$i]['val']):'' ?>"/><?php if ( $hasCal ) { ?><script type="text/javascript">Calendar.setup( { inputField: "filter[terms][<?php echo $i ?>][val]", ifFormat: "%Y-%m-%d", showOthers: true, weekNumbers: false });</script><?php } ?></td>
|
<td>
|
||||||
|
<input name="filter[terms][<?php echo $i ?>][val]" id="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($_REQUEST['filter']['terms'][$i]['val'])?validHtmlStr($_REQUEST['filter']['terms'][$i]['val']):'' ?>"/>
|
||||||
|
<?php if ( $hasCal ) { ?>
|
||||||
|
<script type="text/javascript">Calendar.setup( { inputField: "filter[terms][<?php echo $i ?>][val]", ifFormat: "%Y-%m-%d", showOthers: true, weekNumbers: false });</script>
|
||||||
|
<?php } ?>
|
||||||
|
</td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == "StateId" ) {
|
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == "StateId" ) {
|
||||||
$states = array();
|
$states = array();
|
||||||
foreach ( dbFetchAll( 'SELECT Id,Name FROM States ORDER BY lower(Name) ASC' ) as $state_row ) {
|
foreach ( dbFetchAll( 'SELECT Id,Name FROM States ORDER BY lower(Name) ASC' ) as $state_row ) {
|
||||||
$states[$state_row['Id']] = $state_row['Name'];
|
$states[$state_row['Id']] = $state_row['Name'];
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][val]", $states ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][val]", $states ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == "Weekday" ) {
|
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == 'Weekday' ) {
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][val]", $weekdays ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][val]", $weekdays ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( false && $_REQUEST['filter']['terms'][$i]['attr'] == "MonitorName" ) {
|
} elseif ( false && $_REQUEST['filter']['terms'][$i]['attr'] == 'MonitorName' ) {
|
||||||
$monitors = array();
|
$monitors = array();
|
||||||
foreach ( dbFetchAll( "select Id,Name from Monitors order by Sequence asc" ) as $monitor ) {
|
foreach ( dbFetchAll( "select Id,Name from Monitors order by Sequence asc" ) as $monitor ) {
|
||||||
if ( visibleMonitor( $monitor['Id'] ) ) {
|
if ( visibleMonitor( $monitor['Id'] ) ) {
|
||||||
$monitors[$monitor['Name']] = $monitor['Name'];
|
$monitors[$monitor['Name']] = $monitor['Name'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][val]", $monitors ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][val]", $monitors ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == "ServerId" ) {
|
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == 'ServerId' ) {
|
||||||
$servers = array();
|
$servers = array();
|
||||||
$servers['ZM_SERVER_ID'] = 'Current Server';
|
$servers['ZM_SERVER_ID'] = 'Current Server';
|
||||||
foreach ( dbFetchAll( "SELECT Id,Name FROM Servers ORDER BY lower(Name) ASC" ) as $server ) {
|
foreach ( dbFetchAll( "SELECT Id,Name FROM Servers ORDER BY lower(Name) ASC" ) as $server ) {
|
||||||
$servers[$server['Id']] = $server['Name'];
|
$servers[$server['Id']] = $server['Name'];
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][val]", $servers ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][val]", $servers ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == "StorageId" ) {
|
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == 'StorageId' ) {
|
||||||
$storageareas = array();
|
$storageareas = array();
|
||||||
$storageareas[0] = 'Default ' . ZM_DIR_EVENTS;
|
$storageareas[0] = 'Default ' . ZM_DIR_EVENTS;
|
||||||
foreach ( dbFetchAll( "SELECT Id,Name FROM Storage ORDER BY lower(Name) ASC" ) as $storage ) {
|
foreach ( dbFetchAll( "SELECT Id,Name FROM Storage ORDER BY lower(Name) ASC" ) as $storage ) {
|
||||||
$storageareas[$storage['Id']] = $storage['Name'];
|
$storageareas[$storage['Id']] = $storage['Name'];
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][val]", $storageareas ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][val]", $storageareas ); ?></td>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><input name="filter[terms][<?php echo $i ?>][val]" value="<?php echo $_REQUEST['filter']['terms'][$i]['val'] ?>"/></td>
|
<td><input name="filter[terms][<?php echo $i ?>][val]" value="<?php echo $_REQUEST['filter']['terms'][$i]['val'] ?>"/></td>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
|
||||||
<td><input name="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($_REQUEST['filter']['terms'][$i]['val'])?$_REQUEST['filter']['terms'][$i]['val']:'' ?>"/></td>
|
<td><input name="filter[terms][<?php echo $i ?>][val]" value="<?php echo isset($_REQUEST['filter']['terms'][$i]['val'])?$_REQUEST['filter']['terms'][$i]['val']:'' ?>"/></td>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<td><?php if ( count($_REQUEST['filter']['terms']) > 2 ) { echo buildSelect( "filter[terms][$i][cbr]", $cbracketTypes ); } else { ?> <?php } ?></td>
|
<td><?php if ( count($_REQUEST['filter']['terms']) > 2 ) { echo buildSelect( "filter[terms][$i][cbr]", $cbracketTypes ); } else { ?> <?php } ?></td>
|
||||||
<td><input type="button" onclick="addTerm( this, <?php echo $i+1 ?> )" value="+"/><?php if ( $_REQUEST['filter']['terms'] > 1 ) { ?><input type="button" onclick="delTerm( this, <?php echo $i ?> )" value="-"/><?php } ?></td>
|
<td><input type="button" onclick="addTerm( this, <?php echo $i+1 ?> )" value="+"/><?php if ( $_REQUEST['filter']['terms'] > 1 ) { ?><input type="button" onclick="delTerm( this, <?php echo $i ?> )" value="-"/><?php } ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
}
|
} # end foreach filter
|
||||||
?>
|
?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -279,7 +295,7 @@ for ( $i = 0; isset($_REQUEST['filter']) && $i < count($_REQUEST['filter']['term
|
||||||
<table id="sortTable" class="filterTable" cellspacing="0">
|
<table id="sortTable" class="filterTable" cellspacing="0">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for="sort_field"><?php echo translate('SortBy') ?></label><?php echo buildSelect( "sort_field", $sort_fields ); ?><?php echo buildSelect( "sort_asc", $sort_dirns ); ?></td>
|
<td><label for="sort_field"><?php echo translate('SortBy') ?></label><?php echo buildSelect( 'sort_field', $sort_fields ); ?><?php echo buildSelect( 'sort_asc', $sort_dirns ); ?></td>
|
||||||
<td><label for="limit"><?php echo translate('LimitResultsPre') ?></label><input type="text" size="6" id="limit" name="limit" value="<?php echo isset($_REQUEST['limit'])?validInt($_REQUEST['limit']):"" ?>"/><?php echo translate('LimitResultsPost') ?></td>
|
<td><label for="limit"><?php echo translate('LimitResultsPre') ?></label><input type="text" size="6" id="limit" name="limit" value="<?php echo isset($_REQUEST['limit'])?validInt($_REQUEST['limit']):"" ?>"/><?php echo translate('LimitResultsPost') ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -339,12 +355,18 @@ if ( ZM_OPT_MESSAGE ) {
|
||||||
<div id="contentButtons">
|
<div id="contentButtons">
|
||||||
<input type="submit" value="<?php echo translate('Submit') ?>" onclick="submitToEvents( this );"/>
|
<input type="submit" value="<?php echo translate('Submit') ?>" onclick="submitToEvents( this );"/>
|
||||||
<input type="button" name="executeButton" id="executeButton" value="<?php echo translate('Execute') ?>" onclick="executeFilter( this );"/>
|
<input type="button" name="executeButton" id="executeButton" value="<?php echo translate('Execute') ?>" onclick="executeFilter( this );"/>
|
||||||
<?php if ( canEdit( 'Events' ) ) { ?>
|
<?php
|
||||||
|
if ( canEdit( 'Events' ) ) {
|
||||||
|
?>
|
||||||
<input type="button" value="<?php echo translate('Save') ?>" onclick="saveFilter( this );"/>
|
<input type="button" value="<?php echo translate('Save') ?>" onclick="saveFilter( this );"/>
|
||||||
<?php } ?>
|
<?php
|
||||||
<?php if ( canEdit( 'Events' ) && isset($dbFilter) && $dbFilter['Name'] ) { ?>
|
if ( isset($dbFilter) && $dbFilter['Name'] ) {
|
||||||
<input type="button" value="<?php echo translate('Delete') ?>" onclick="deleteFilter( this, <?php echo $dbFilter['Id'] ?>, '<?php echo $dbFilter['Name'] ?>' );"/>
|
?>
|
||||||
<?php } ?>
|
<input type="button" value="<?php echo translate('Delete') ?>" onclick="deleteFilter( this, '<?php echo $dbFilter['Name'] ?>' );"/>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
<input type="button" value="<?php echo translate('Reset') ?>" onclick="submitToFilter( this, 1 );"/>
|
<input type="button" value="<?php echo translate('Reset') ?>" onclick="submitToFilter( this, 1 );"/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -37,7 +37,7 @@ if ( !empty($fid) ) {
|
||||||
if ( !($frame = dbFetchOne( $sql, NULL, array($eid, $fid) )) )
|
if ( !($frame = dbFetchOne( $sql, NULL, array($eid, $fid) )) )
|
||||||
$frame = array( 'FrameId'=>$fid, 'Type'=>'Normal', 'Score'=>0 );
|
$frame = array( 'FrameId'=>$fid, 'Type'=>'Normal', 'Score'=>0 );
|
||||||
} else {
|
} else {
|
||||||
$frame = dbFetchOne( 'SELECT * FROM Frames WHERE EventId = ? AND Score = ?', NULL, array( $eid, $Event->MaxScore() ) );
|
$frame = dbFetchOne( 'SELECT * FROM Frames WHERE EventId = ? AND Score = ?', NULL, array( $eid, $Event->MaxScore() ) );
|
||||||
}
|
}
|
||||||
$Frame = new Frame( $frame );
|
$Frame = new Frame( $frame );
|
||||||
|
|
||||||
|
@ -60,22 +60,27 @@ if ( isset( $_REQUEST['scale'] ) ) {
|
||||||
$scale = max( reScale( SCALE_BASE, $Monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
|
$scale = max( reScale( SCALE_BASE, $Monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$imageData = $Event->getImageSrc( $frame, $scale, 0 );
|
||||||
|
if ( ! $imageData ) {
|
||||||
|
Error("No data found for Event $eid frame $fid");
|
||||||
|
$imageData = array();
|
||||||
|
}
|
||||||
|
|
||||||
$show = 'capt';
|
$show = 'capt';
|
||||||
if ( isset($_REQUEST['show']) ) {
|
if ( isset($_REQUEST['show']) ) {
|
||||||
$show = $_REQUEST['show'];
|
$show = $_REQUEST['show'];
|
||||||
#} else if ( $imageData['hasAnalImage'] ) {
|
} else if ( $imageData['hasAnalImage'] ) {
|
||||||
#$show = 'anal';
|
$show = 'anal';
|
||||||
}
|
}
|
||||||
$imageData = $Event->getImageSrc( $frame, $scale, ($show=="capt") );
|
|
||||||
|
|
||||||
$imagePath = $imageData['thumbPath'];
|
$imagePath = $imageData['thumbPath'];
|
||||||
$eventPath = $imageData['eventPath'];
|
$eventPath = $imageData['eventPath'];
|
||||||
$dImagePath = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-diag-d.jpg", $eventPath, $Frame->FrameId() );
|
$dImagePath = sprintf( '%s/%0'.ZM_EVENT_IMAGE_DIGITS.'d-diag-d.jpg', $eventPath, $Frame->FrameId() );
|
||||||
$rImagePath = sprintf( "%s/%0".ZM_EVENT_IMAGE_DIGITS."d-diag-r.jpg", $eventPath, $Frame->FrameId() );
|
$rImagePath = sprintf( '%s/%0'.ZM_EVENT_IMAGE_DIGITS.'d-diag-r.jpg', $eventPath, $Frame->FrameId() );
|
||||||
|
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
|
||||||
xhtmlHeaders(__FILE__, translate('Frame')." - ".$Event->Id()." - ".$Frame->FrameId() );
|
xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id()." - ".$Frame->FrameId() );
|
||||||
?>
|
?>
|
||||||
<body>
|
<body>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
|
@ -94,13 +99,13 @@ xhtmlHeaders(__FILE__, translate('Frame')." - ".$Event->Id()." - ".$Frame->Frame
|
||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<p id="image">
|
<p id="image">
|
||||||
<?php if ( $imageData['hasAnalImage'] ) { ?>
|
|
||||||
<a href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $Frame->FrameId() ?>&scale=<?php echo $scale ?>&show=<?php echo $imageData['isAnalImage']?"capt":"anal" ?>">
|
<?php if ( $imageData['hasAnalImage'] ) {
|
||||||
<?php } ?>
|
echo sprintf('<a href="?view=frame&eid=%d&fid=%d&scale=%d&show=%s">', $Event->Id(), $Frame->FrameId(), $scale, ( $show=='anal'?'capt':'anal' ) );
|
||||||
<img id="frameImg" src="<?php echo $Frame->getImageSrc($imageData['isAnalImage']?'analyse':'capture') ?>" width="<?php echo reScale( $Event->Width(), $Event->DefaultScale(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $Event->DefaultScale(), $scale ) ?>" alt="<?php echo $Frame->EventId()."-".$Frame->FrameId() ?>" class="<?php echo $imageData['imageClass'] ?>"/>
|
} ?>
|
||||||
<?php if ( $imageData['hasAnalImage'] ) { ?>
|
<img id="frameImg" src="<?php echo $Frame->getImageSrc($show=='anal'?'analyse':'capture') ?>" width="<?php echo reScale( $Event->Width(), $Event->DefaultScale(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $Event->DefaultScale(), $scale ) ?>" alt="<?php echo $Frame->EventId()."-".$Frame->FrameId() ?>" class="<?php echo $imageData['imageClass'] ?>"/>
|
||||||
</a>
|
<?php if ( $imageData['hasAnalImage'] ) { ?></a><?php } ?>
|
||||||
<?php } ?>
|
|
||||||
</p>
|
</p>
|
||||||
<p id="controls">
|
<p id="controls">
|
||||||
<?php if ( $Frame->FrameId() > 1 ) { ?>
|
<?php if ( $Frame->FrameId() > 1 ) { ?>
|
||||||
|
|
|
@ -7,13 +7,13 @@ function updateButtons( element ) {
|
||||||
var canExecute = false;
|
var canExecute = false;
|
||||||
if ( form.elements['AutoArchive'].checked )
|
if ( form.elements['AutoArchive'].checked )
|
||||||
canExecute = true;
|
canExecute = true;
|
||||||
else if ( typeof ZM_OPT_FFMPEG !== "undefined" && form.elements['AutoVideo'].checked )
|
else if ( form.elements['AutoVideo'] && form.elements['AutoVideo'].checked )
|
||||||
canExecute = true;
|
canExecute = true;
|
||||||
else if ( typeof ZM_OPT_UPLOAD !== "undefined" && form.elements['AutoUpload'].checked )
|
else if ( form.elements['AutoUpload'] && form.elements['AutoUpload'].checked )
|
||||||
canExecute = true;
|
canExecute = true;
|
||||||
else if ( typeof ZM_OPT_EMAIL !== "undefined" && form.elements['AutoEmail'].checked )
|
else if ( form.elements['AutoEmail'] && form.elements['AutoEmail'].checked )
|
||||||
canExecute = true;
|
canExecute = true;
|
||||||
else if ( typeof ZM_OPT_MESSAGE !== "undefined" && form.elements['AutoMessage'].checked )
|
else if ( form.elements['AutoMessage'] && form.elements['AutoMessage'].checked )
|
||||||
canExecute = true;
|
canExecute = true;
|
||||||
else if ( form.elements['AutoExecute'].checked && form.elements['AutoExecuteCmd'].value != '' )
|
else if ( form.elements['AutoExecute'].checked && form.elements['AutoExecuteCmd'].value != '' )
|
||||||
canExecute = true;
|
canExecute = true;
|
||||||
|
|
|
@ -52,7 +52,7 @@ if ( ! $Server ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty($_REQUEST['mid']) ) {
|
if ( ! empty($_REQUEST['mid']) ) {
|
||||||
$monitor = new Monitor( $_REQUEST['mid'] );
|
$monitor = dbFetchMonitor( $_REQUEST['mid'] );
|
||||||
if ( ZM_OPT_X10 )
|
if ( ZM_OPT_X10 )
|
||||||
$x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid']) );
|
$x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid']) );
|
||||||
} else {
|
} else {
|
||||||
|
@ -155,13 +155,12 @@ function fourcc( $a, $b, $c, $d ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset( $_REQUEST['newMonitor'] ) ) {
|
if ( isset( $_REQUEST['newMonitor'] ) ) {
|
||||||
# Update the monitor object with whatever has been set so far.
|
$newMonitor = $_REQUEST['newMonitor'];
|
||||||
$monitor->set( $_REQUEST['newMonitor'] );
|
|
||||||
if ( ZM_OPT_X10 )
|
if ( ZM_OPT_X10 )
|
||||||
$newX10Monitor = $_REQUEST['newX10Monitor'];
|
$newX10Monitor = $_REQUEST['newX10Monitor'];
|
||||||
# FIXME: Triggers in the db is a comma separated string. Needs to be an array.
|
|
||||||
#$monitor->Triggers = explode( ',', isset($monitor->Triggers)?$monitor->Triggers:"" );
|
|
||||||
} else {
|
} else {
|
||||||
|
$newMonitor = $monitor;
|
||||||
|
$newMonitor['Triggers'] = explode( ',', isset($monitor['Triggers'])?$monitor['Triggers']:"" );
|
||||||
if ( ZM_OPT_X10 )
|
if ( ZM_OPT_X10 )
|
||||||
$newX10Monitor = $x10Monitor;
|
$newX10Monitor = $x10Monitor;
|
||||||
}
|
}
|
||||||
|
@ -176,28 +175,25 @@ if ( $monitor->AlarmMaxFPS == '0.00' )
|
||||||
|
|
||||||
if ( !empty($_REQUEST['preset']) ) {
|
if ( !empty($_REQUEST['preset']) ) {
|
||||||
$preset = dbFetchOne( 'SELECT Type, Device, Channel, Format, Protocol, Method, Host, Port, Path, Width, Height, Palette, MaxFPS, Controllable, ControlId, ControlDevice, ControlAddress, DefaultRate, DefaultScale FROM MonitorPresets WHERE Id = ?', NULL, array($_REQUEST['preset']) );
|
$preset = dbFetchOne( 'SELECT Type, Device, Channel, Format, Protocol, Method, Host, Port, Path, Width, Height, Palette, MaxFPS, Controllable, ControlId, ControlDevice, ControlAddress, DefaultRate, DefaultScale FROM MonitorPresets WHERE Id = ?', NULL, array($_REQUEST['preset']) );
|
||||||
#$monitor->set( $preset );
|
|
||||||
foreach ( $preset as $name=>$value ) {
|
foreach ( $preset as $name=>$value ) {
|
||||||
# Does isset handle NULL's? I don't think this code is correct.
|
|
||||||
if ( isset($value) ) {
|
if ( isset($value) ) {
|
||||||
$monitor->$name = $value;
|
$newMonitor[$name] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !empty($_REQUEST['probe']) ) {
|
if ( !empty($_REQUEST['probe']) ) {
|
||||||
$probe = unserialize(base64_decode($_REQUEST['probe']));
|
$probe = unserialize(base64_decode($_REQUEST['probe']));
|
||||||
foreach ( $probe as $name=>$value ) {
|
foreach ( $probe as $name=>$value ) {
|
||||||
# Again I don't think isset is useful here.
|
|
||||||
if ( isset($value) ) {
|
if ( isset($value) ) {
|
||||||
$monitor->$name = $value;
|
$newMonitor[$name] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( ZM_HAS_V4L && $monitor->Type == 'Local' ) {
|
if ( ZM_HAS_V4L && $newMonitor['Type'] == 'Local' ) {
|
||||||
$monitor->Palette = fourCC( substr($monitor->Palette,0,1), substr($monitor->Palette,1,1), substr($monitor->Palette,2,1), substr($monitor->Palette,3,1) );
|
$newMonitor['Palette'] = fourCC( substr($newMonitor['Palette'],0,1), substr($newMonitor['Palette'],1,1), substr($newMonitor['Palette'],2,1), substr($newMonitor['Palette'],3,1) );
|
||||||
if ( $monitor->Format == 'PAL' )
|
if ( $newMonitor['Format'] == 'PAL' )
|
||||||
$monitor->Format = 0x000000ff;
|
$newMonitor['Format'] = 0x000000ff;
|
||||||
elseif ( $monitor->Format == 'NTSC' )
|
elseif ( $newMonitor['Format'] == 'NTSC' )
|
||||||
$monitor->Format = 0x0000b000;
|
$newMonitor['Format'] = 0x0000b000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +465,7 @@ $videowriteropts = array(
|
||||||
'H264 Camera Passthrough' => 2
|
'H264 Camera Passthrough' => 2
|
||||||
);
|
);
|
||||||
|
|
||||||
xhtmlHeaders(__FILE__, translate('Monitor')." - ".validHtmlStr($monitor->Name) );
|
xhtmlHeaders(__FILE__, translate('Monitor')." - ".validHtmlStr($monitor['Name']) );
|
||||||
?>
|
?>
|
||||||
<body>
|
<body>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
|
@ -513,6 +509,10 @@ foreach ( $tabs as $name=>$value ) {
|
||||||
<li><a href="#" onclick="submitTab( '<?php echo $name ?>' ); return( false );"><?php echo $value ?></a></li>
|
<li><a href="#" onclick="submitTab( '<?php echo $name ?>' ); return( false );"><?php echo $value ?></a></li>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
|
<a href="#" onclick="createPopup( '?view=monitorpreset&mid=<?php echo $monitor['Id'] ?>', 'zmMonitorPreset<?php echo $monitor['Id'] ?>', 'monitorpreset' ); return( false );"><?php echo translate('Presets') ?></a>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -661,6 +661,7 @@ if ( ZM_HAS_V4L && ($tab != 'misc' || $monitor->Type != 'Local') ) {
|
||||||
<input type="hidden" name="newMonitor[SignalCheckColour]" value="<?php echo validHtmlStr($monitor->SignalCheckColour) ?>"/>
|
<input type="hidden" name="newMonitor[SignalCheckColour]" value="<?php echo validHtmlStr($monitor->SignalCheckColour) ?>"/>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
if ( ZM_HAS_V4L && ($tab != 'source' || $newMonitor['Type'] != 'Local') ) {
|
||||||
?>
|
?>
|
||||||
<table id="contentTable" class="major" cellspacing="0">
|
<table id="contentTable" class="major" cellspacing="0">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -754,28 +755,26 @@ switch ( $tab ) {
|
||||||
</select></td></tr>
|
</select></td></tr>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('RefImageBlendPct') ?></td><td><input type="text" name="newMonitor[RefBlendPerc]" value="<?php echo validHtmlStr($monitor->RefBlendPerc) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('RefImageBlendPct') ?></td><td><input type="text" name="newMonitor[RefBlendPerc]" value="<?php echo validHtmlStr($newMonitor['RefBlendPerc']) ?>" size="4"/></td></tr>
|
||||||
<tr><td><?php echo translate('AlarmRefImageBlendPct') ?></td><td><input type="text" name="newMonitor[AlarmRefBlendPerc]" value="<?php echo validHtmlStr($monitor->AlarmRefBlendPerc) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('AlarmRefImageBlendPct') ?></td><td><input type="text" name="newMonitor[AlarmRefBlendPerc]" value="<?php echo validHtmlStr($newMonitor['AlarmRefBlendPerc']) ?>" size="4"/></td></tr>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('Triggers') ?></td><td>
|
<tr><td><?php echo translate('Triggers') ?></td><td>
|
||||||
<?php
|
<?php
|
||||||
$optTriggers = getSetValues( 'Monitors', 'Triggers' );
|
$optTriggers = getSetValues( 'Monitors', 'Triggers' );
|
||||||
$breakCount = (int)(ceil(count($optTriggers)));
|
$breakCount = (int)(ceil(count($optTriggers)));
|
||||||
$breakCount = min( 3, $breakCount );
|
$breakCount = min( 3, $breakCount );
|
||||||
$optCount = 0;
|
$optCount = 0;
|
||||||
foreach( $optTriggers as $optTrigger ) {
|
foreach( $optTriggers as $optTrigger ) {
|
||||||
if ( ( ! ZM_OPT_X10 ) && ( $optTrigger == 'X10' ) )
|
if ( !ZM_OPT_X10 && $optTrigger == 'X10' )
|
||||||
continue;
|
continue;
|
||||||
if ( $optCount && ($optCount%$breakCount == 0) )
|
if ( $optCount && ($optCount%$breakCount == 0) )
|
||||||
echo '</br>';
|
echo '</br>';
|
||||||
echo '<input type="checkbox" name="newMonitor[Triggers][]" value="'. $optTrigger .'"';
|
?>
|
||||||
if ( isset($monitor->Triggers) && is_array( $monitor->Triggers ) and in_array( $optTrigger, $monitor->Triggers ) ) {
|
<input type="checkbox" name="newMonitor[Triggers][]" value="<?php echo $optTrigger ?>"<?php if ( isset($newMonitor['Triggers']) && in_array( $optTrigger, $newMonitor['Triggers'] ) ) { ?> checked="checked"<?php } ?>/> <?php echo $optTrigger ?>
|
||||||
echo ' checked="checked"';
|
<?php
|
||||||
}
|
|
||||||
echo '/> '. $optTrigger ;
|
|
||||||
$optCount ++;
|
$optCount ++;
|
||||||
}
|
}
|
||||||
if ( !$optCount ) {
|
if ( !$optCount ) {
|
||||||
|
@ -844,9 +843,11 @@ switch ( $tab ) {
|
||||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Deinterlacing ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Deinterlacing ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Deinterlacing ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
<tr><td><?php echo translate('DeviceChannel') ?></td><td><select name="newMonitor[Channel]"><?php foreach ( $v4l2DeviceChannels as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['Channel'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
<?php
|
<tr><td><?php echo translate('DeviceFormat') ?></td><td><select name="newMonitor[Format]"><?php foreach ( $v4l2DeviceFormats as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['Format'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
|
<tr><td><?php echo translate('CapturePalette') ?></td><td><select name="newMonitor[Palette]"><?php foreach ( $v4l2LocalPalettes as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['Palette'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<?php
|
<?php
|
||||||
|
@ -855,70 +856,111 @@ switch ( $tab ) {
|
||||||
<tr id="RTSPDescribe"<?php if ( $monitor->Protocol != 'rtsp' ) { echo ' style="display:none;"'; } ?>><td><?php echo translate('RTSPDescribe') ?> (<?php echo makePopupLink( '?view=optionhelp&option=OPTIONS_RTSPDESCRIBE', 'zmOptionHelp', 'optionhelp', '?' ) ?>) </td><td><input type="checkbox" name="newMonitor[RTSPDescribe]" value="1"<?php if ( !empty($monitor->RTSPDescribe) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
<tr id="RTSPDescribe"<?php if ( $monitor->Protocol != 'rtsp' ) { echo ' style="display:none;"'; } ?>><td><?php echo translate('RTSPDescribe') ?> (<?php echo makePopupLink( '?view=optionhelp&option=OPTIONS_RTSPDESCRIBE', 'zmOptionHelp', 'optionhelp', '?' ) ?>) </td><td><input type="checkbox" name="newMonitor[RTSPDescribe]" value="1"<?php if ( !empty($monitor->RTSPDescribe) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<?php
|
<tr><td><?php echo translate('RemoteHostName') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($newMonitor['Host']) ?>" size="36"/></td></tr>
|
||||||
break;
|
<tr><td><?php echo translate('RemoteHostPort') ?></td><td><input type="text" name="newMonitor[Port]" value="<?php echo validHtmlStr($newMonitor['Port']) ?>" size="6"/></td></tr>
|
||||||
|
<tr><td><?php echo translate('RemoteHostPath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr>
|
||||||
|
<?php
|
||||||
|
} elseif ( $newMonitor['Type'] == 'File' ) {
|
||||||
|
?>
|
||||||
|
<tr><td><?php echo translate('SourcePath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr>
|
||||||
|
<?php
|
||||||
|
} elseif ( $newMonitor['Type'] == 'cURL' ) {
|
||||||
|
?>
|
||||||
|
<tr><td><?php echo 'URL' ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr>
|
||||||
|
<tr><td><?php echo 'Username' ?></td><td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($newMonitor['User']) ?>" size="12"/></td></tr>
|
||||||
|
<tr><td><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($newMonitor['Pass']) ?>" size="12"/></td></tr>
|
||||||
|
<?php
|
||||||
|
} elseif ( $newMonitor['Type'] == 'Ffmpeg' || $newMonitor['Type'] == 'Libvlc' ) {
|
||||||
|
?>
|
||||||
|
<tr><td><?php echo translate('SourcePath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($newMonitor['Path']) ?>" size="36"/></td></tr>
|
||||||
|
<tr><td><?php echo translate('RemoteMethod') ?> (<?php echo makePopupLink('?view=optionhelp&option=OPTIONS_RTSPTrans', 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td><td><?php echo buildSelect( "newMonitor[Method]", $rtspFFMpegMethods ); ?></td></tr>
|
||||||
|
<tr><td><?php echo translate('Options') ?> (<?php echo makePopupLink( '?view=optionhelp&option=OPTIONS_'.strtoupper($newMonitor['Type']), 'zmOptionHelp', 'optionhelp', '?' ) ?>)</td><td><input type="text" name="newMonitor[Options]" value="<?php echo validHtmlStr($newMonitor['Options']) ?>" size="36"/></td></tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<tr><td><?php echo translate('TargetColorspace') ?></td><td><select name="newMonitor[Colours]"><?php foreach ( $Colours as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['Colours'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
|
<tr><td><?php echo translate('CaptureWidth') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Width]" value="<?php echo validHtmlStr($newMonitor['Width']) ?>" size="4" onkeyup="updateMonitorDimensions(this);"/></td></tr>
|
||||||
|
<tr><td><?php echo translate('CaptureHeight') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Height]" value="<?php echo validHtmlStr($newMonitor['Height']) ?>" size="4" onkeyup="updateMonitorDimensions(this);"/></td></tr>
|
||||||
|
<tr><td><?php echo translate('PreserveAspect') ?></td><td><input type="checkbox" name="preserveAspectRatio" value="1"/></td></tr>
|
||||||
|
<tr><td><?php echo translate('Orientation') ?></td><td><select name="newMonitor[Orientation]"><?php foreach ( $orientations as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['Orientation'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
|
<?php
|
||||||
|
if ( $newMonitor['Type'] == 'Local' ) {
|
||||||
|
?>
|
||||||
|
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['Deinterlacing'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
|
<?php
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['Deinterlacing'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if ( $newMonitor['Type'] == 'Remote' ) {
|
||||||
|
?>
|
||||||
|
<tr id="RTSPDescribe"<?php if ( $newMonitor['Protocol'] != 'rtsp' ) { echo ' style="display:none;"'; } ?>><td><?php echo translate('RTSPDescribe') ?> (<?php echo makePopupLink( '?view=optionhelp&option=OPTIONS_RTSPDESCRIBE', 'zmOptionHelp', 'optionhelp', '?' ) ?>) </td><td><input type="checkbox" name="newMonitor[RTSPDescribe]" value="1"<?php if ( !empty($newMonitor['RTSPDescribe']) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case 'storage' :
|
case 'storage' :
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('SaveJPEGs') ?></td><td><select name="newMonitor[SaveJPEGs]"><?php foreach ( $savejpegopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->SaveJPEGs ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
<tr><td><?php echo translate('SaveJPEGs') ?></td><td><select name="newMonitor[SaveJPEGs]"><?php foreach ( $savejpegopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['SaveJPEGs'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
<tr><td><?php echo translate('VideoWriter') ?></td><td><select name="newMonitor[VideoWriter]"><?php foreach ( $videowriteropts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->VideoWriter ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
<tr><td><?php echo translate('VideoWriter') ?></td><td><select name="newMonitor[VideoWriter]"><?php foreach ( $videowriteropts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['VideoWriter'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
<tr><td><?php echo translate('OptionalEncoderParam') ?></td><td><textarea name="newMonitor[EncoderParameters]" rows="4" cols="36"><?php echo validHtmlStr($monitor->EncoderParameters) ?></textarea></td></tr>
|
<tr><td><?php echo translate('OptionalEncoderParam') ?></td><td><textarea name="newMonitor[EncoderParameters]" rows="4" cols="36"><?php echo validHtmlStr($newMonitor['EncoderParameters']) ?></textarea></td></tr>
|
||||||
<tr><td><?php echo translate('RecordAudio') ?></td><td><input type="checkbox" name="newMonitor[RecordAudio]" value="1"<?php if ($monitor->RecordAudio) { ?> checked="checked"<?php } ?>/></td></tr>
|
<tr><td><?php echo translate('RecordAudio') ?></td><td><input type="checkbox" name="newMonitor[RecordAudio]" value="1"<?php if ( !empty($newMonitor['RecordAudio']) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||||
<?php
|
<?php
|
||||||
break;
|
break;
|
||||||
case 'timestamp' :
|
case 'timestamp' :
|
||||||
{
|
{
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('TimestampLabelFormat') ?></td><td><input type="text" name="newMonitor[LabelFormat]" value="<?php echo validHtmlStr($monitor->LabelFormat) ?>" size="32"/></td></tr>
|
<tr><td><?php echo translate('TimestampLabelFormat') ?></td><td><input type="text" name="newMonitor[LabelFormat]" value="<?php echo validHtmlStr($newMonitor['LabelFormat']) ?>" size="32"/></td></tr>
|
||||||
<tr><td><?php echo translate('TimestampLabelX') ?></td><td><input type="text" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('TimestampLabelX') ?></td><td><input type="text" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($newMonitor['LabelX']) ?>" size="4"/></td></tr>
|
||||||
<tr><td><?php echo translate('TimestampLabelY') ?></td><td><input type="text" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('TimestampLabelY') ?></td><td><input type="text" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($newMonitor['LabelY']) ?>" size="4"/></td></tr>
|
||||||
<tr><td><?php echo translate('TimestampLabelSize') ?></td><td><select name="newMonitor[LabelSize]"><?php foreach ( $label_size as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->LabelSize ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
<tr><td><?php echo translate('TimestampLabelSize') ?></td><td><select name="newMonitor[LabelSize]"><?php foreach ( $label_size as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $newMonitor['LabelSize'] ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||||
<?php
|
<?php
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'buffers' :
|
case 'buffers' :
|
||||||
{
|
{
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('ImageBufferSize') ?></td><td><input type="text" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($monitor->ImageBufferCount) ?>" size="6"/></td></tr>
|
<tr><td><?php echo translate('ImageBufferSize') ?></td><td><input type="text" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($newMonitor['ImageBufferCount']) ?>" size="6"/></td></tr>
|
||||||
<tr><td><?php echo translate('WarmupFrames') ?></td><td><input type="text" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($monitor->WarmupCount) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('WarmupFrames') ?></td><td><input type="text" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($newMonitor['WarmupCount']) ?>" size="4"/></td></tr>
|
||||||
<tr><td><?php echo translate('PreEventImageBuffer') ?></td><td><input type="text" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($monitor->PreEventCount) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('PreEventImageBuffer') ?></td><td><input type="text" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($newMonitor['PreEventCount']) ?>" size="4"/></td></tr>
|
||||||
<tr><td><?php echo translate('PostEventImageBuffer') ?></td><td><input type="text" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($monitor->PostEventCount) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('PostEventImageBuffer') ?></td><td><input type="text" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($newMonitor['PostEventCount']) ?>" size="4"/></td></tr>
|
||||||
<tr><td><?php echo translate('StreamReplayBuffer') ?></td><td><input type="text" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($monitor->StreamReplayBuffer) ?>" size="6"/></td></tr>
|
<tr><td><?php echo translate('StreamReplayBuffer') ?></td><td><input type="text" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($newMonitor['StreamReplayBuffer']) ?>" size="6"/></td></tr>
|
||||||
<tr><td><?php echo translate('AlarmFrameCount') ?></td><td><input type="text" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($monitor->AlarmFrameCount) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('AlarmFrameCount') ?></td><td><input type="text" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($newMonitor['AlarmFrameCount']) ?>" size="4"/></td></tr>
|
||||||
<?php
|
<?php
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'control' :
|
case 'control' :
|
||||||
{
|
{
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('Controllable') ?></td><td><input type="checkbox" name="newMonitor[Controllable]" value="1"<?php if ( !empty($monitor->Controllable) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
<tr><td><?php echo translate('Controllable') ?></td><td><input type="checkbox" name="newMonitor[Controllable]" value="1"<?php if ( !empty($newMonitor['Controllable']) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||||
<tr><td><?php echo translate('ControlType') ?></td><td><?php echo htmlSelect( "newMonitor[ControlId]", $controlTypes, $monitor->ControlId(), 'loadLocations( this )' ); ?><?php if ( canEdit( 'Control' ) ) { ?> <a href="#" onclick="createPopup( '?view=controlcaps', 'zmControlCaps', 'controlcaps' );"><?php echo translate('Edit') ?></a><?php } ?></td></tr>
|
<tr><td><?php echo translate('ControlType') ?></td><td><?php echo buildSelect( "newMonitor[ControlId]", $controlTypes, 'loadLocations( this )' ); ?><?php if ( canEdit( 'Control' ) ) { ?> <a href="#" onclick="createPopup( '?view=controlcaps', 'zmControlCaps', 'controlcaps' );"><?php echo translate('Edit') ?></a><?php } ?></td></tr>
|
||||||
<tr><td><?php echo translate('ControlDevice') ?></td><td><input type="text" name="newMonitor[ControlDevice]" value="<?php echo validHtmlStr($monitor->ControlDevice) ?>" size="32"/></td></tr>
|
<tr><td><?php echo translate('ControlDevice') ?></td><td><input type="text" name="newMonitor[ControlDevice]" value="<?php echo validHtmlStr($newMonitor['ControlDevice']) ?>" size="32"/></td></tr>
|
||||||
<tr><td><?php echo translate('ControlAddress') ?></td><td><input type="text" name="newMonitor[ControlAddress]" value="<?php echo validHtmlStr($monitor->ControlAddress) ?>" size="32"/></td></tr>
|
<tr><td><?php echo translate('ControlAddress') ?></td><td><input type="text" name="newMonitor[ControlAddress]" value="<?php echo validHtmlStr($newMonitor['ControlAddress']) ?>" size="32"/></td></tr>
|
||||||
<tr><td><?php echo translate('AutoStopTimeout') ?></td><td><input type="text" name="newMonitor[AutoStopTimeout]" value="<?php echo validHtmlStr($monitor->AutoStopTimeout) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('AutoStopTimeout') ?></td><td><input type="text" name="newMonitor[AutoStopTimeout]" value="<?php echo validHtmlStr($newMonitor['AutoStopTimeout']) ?>" size="4"/></td></tr>
|
||||||
<tr><td><?php echo translate('TrackMotion') ?></td><td><input type="checkbox" name="newMonitor[TrackMotion]" value="1"<?php if ( !empty($monitor->TrackMotion) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
<tr><td><?php echo translate('TrackMotion') ?></td><td><input type="checkbox" name="newMonitor[TrackMotion]" value="1"<?php if ( !empty($newMonitor['TrackMotion']) ) { ?> checked="checked"<?php } ?>/></td></tr>
|
||||||
<?php
|
<?php
|
||||||
$return_options = array(
|
$return_options = array(
|
||||||
'-1' => translate('None'),
|
'-1' => translate('None'),
|
||||||
'0' => translate('Home'),
|
'0' => translate('Home'),
|
||||||
'1' => translate('Preset')." 1",
|
'1' => translate('Preset')." 1",
|
||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('TrackDelay') ?></td><td><input type="text" name="newMonitor[TrackDelay]" value="<?php echo validHtmlStr($monitor->TrackDelay) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('TrackDelay') ?></td><td><input type="text" name="newMonitor[TrackDelay]" value="<?php echo validHtmlStr($newMonitor['TrackDelay']) ?>" size="4"/></td></tr>
|
||||||
<tr><td><?php echo translate('ReturnLocation') ?></td><td><?php echo htmlSelect( "newMonitor[ReturnLocation]", $return_options, $monitor->ReturnLocation() ); ?></td></tr>
|
<tr><td><?php echo translate('ReturnLocation') ?></td><td><?php echo buildSelect( "newMonitor[ReturnLocation]", $return_options ); ?></td></tr>
|
||||||
<tr><td><?php echo translate('ReturnDelay') ?></td><td><input type="text" name="newMonitor[ReturnDelay]" value="<?php echo validHtmlStr($monitor->ReturnDelay) ?>" size="4"/></td></tr>
|
<tr><td><?php echo translate('ReturnDelay') ?></td><td><input type="text" name="newMonitor[ReturnDelay]" value="<?php echo validHtmlStr($newMonitor['ReturnDelay']) ?>" size="4"/></td></tr>
|
||||||
<?php
|
<?php
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'x10' :
|
case 'x10' :
|
||||||
{
|
{
|
||||||
?>
|
?>
|
||||||
<tr><td><?php echo translate('X10ActivationString') ?></td><td><input type="text" name="newX10Monitor[Activation]" value="<?php echo validHtmlStr($newX10Monitor['Activation']) ?>" size="20"/></td></tr>
|
<tr><td><?php echo translate('X10ActivationString') ?></td><td><input type="text" name="newX10Monitor[Activation]" value="<?php echo validHtmlStr($newX10Monitor['Activation']) ?>" size="20"/></td></tr>
|
||||||
<tr><td><?php echo translate('X10InputAlarmString') ?></td><td><input type="text" name="newX10Monitor[AlarmInput]" value="<?php echo validHtmlStr($newX10Monitor['AlarmInput']) ?>" size="20"/></td></tr>
|
<tr><td><?php echo translate('X10InputAlarmString') ?></td><td><input type="text" name="newX10Monitor[AlarmInput]" value="<?php echo validHtmlStr($newX10Monitor['AlarmInput']) ?>" size="20"/></td></tr>
|
||||||
<tr><td><?php echo translate('X10OutputAlarmString') ?></td><td><input type="text" name="newX10Monitor[AlarmOutput]" value="<?php echo validHtmlStr($newX10Monitor['AlarmOutput']) ?>" size="20"/></td></tr>
|
<tr><td><?php echo translate('X10OutputAlarmString') ?></td><td><input type="text" name="newX10Monitor[AlarmOutput]" value="<?php echo validHtmlStr($newX10Monitor['AlarmOutput']) ?>" size="20"/></td></tr>
|
||||||
<?php
|
<?php
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'misc' :
|
case 'misc' :
|
||||||
{
|
{
|
||||||
|
@ -954,12 +996,13 @@ switch ( $tab ) {
|
||||||
<?php
|
<?php
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} // end switch tab
|
||||||
?>
|
?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div id="contentButtons">
|
<div id="contentButtons">
|
||||||
<input type="submit" value="<?php echo translate('Save') ?>"<?php if ( !canEdit( 'Monitors' ) ) { ?> disabled="disabled"<?php } ?>/><input type="button" value="<?php echo translate('Cancel') ?>" onclick="closeWindow()"/>
|
<input type="submit" value="<?php echo translate('Save') ?>"<?php if ( !canEdit( 'Monitors' ) ) { ?> disabled="disabled"<?php } ?>/>
|
||||||
|
<input type="button" value="<?php echo translate('Cancel') ?>" onclick="closeWindow()"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
Loading…
Reference in New Issue