Merge branch 'master' into dragndrop_monitor_sorting

This commit is contained in:
Isaac Connor 2017-06-06 20:39:58 -04:00
commit b4bdc1fd6b
56 changed files with 6109 additions and 5942 deletions

View File

@ -1,6 +1,8 @@
language: cpp
sudo: required
dist: trusty
git:
depth: 9999999
notifications:
irc: chat.freenode.net#zoneminder-dev
branches:
@ -20,6 +22,7 @@ addons:
- git
- curl
- sshfs
- sed
env:
matrix:
- OS=el DIST=6

View File

@ -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

View File

View File

@ -1,16 +0,0 @@
Last-Update: 2015-08-16
Forwarded: no
Author: Dmitry Smirnov <onlyjob@member.fsf.org>
Description: correct path to CGI app according to default web server configuration.
--- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in
+++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in
@@ -428,7 +428,7 @@ our @options =
},
{
name => "ZM_PATH_ZMS",
- default => "/cgi-bin/nph-zms",
+ default => "/zm/cgi-bin/nph-zms",
description => "Web path to zms streaming server",
help => qqq("
The ZoneMinder streaming server is required to send streamed

View File

@ -1,2 +0,0 @@
default_cgi-path.patch
use_libjs-mootools.patch

View File

@ -1,18 +0,0 @@
Last-Update: 2015-03-29
Forwarded: no
Bug-Debian: http://bugs.debian.org/585590
Reviewed-By: Dmitry Smirnov <onlyjob@member.fsf.org>
Description: use mootools shipped by debian, rather than the zoneminder included mootools.
--- a/web/skins/classic/includes/functions.php
+++ b/web/skins/classic/includes/functions.php
@@ -63,9 +63,8 @@
}
?>
<script type="text/javascript" src="tools/mootools/mootools-core.js"></script>
<script type="text/javascript" src="tools/mootools/mootools-more.js"></script>
- <script type="text/javascript" src="js/mootools.ext.js"></script>
<script type="text/javascript" src="js/logger.js"></script>
<script type="text/javascript" src="js/overlay.js"></script>
<?php
if ( $skinJsPhpFile )

View File

@ -1 +1 @@
3.0 (native)
3.0 (quilt)

View File

@ -5,6 +5,7 @@ Maintainer: Dmitry Smirnov <onlyjob@debian.org>
Uploaders: Vagrant Cascadian <vagrant@debian.org>
Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apache2-dev, dh-linktree
,cmake
,libx264-dev, libmp4v2-dev
,libboost-dev
,libavdevice-dev (>= 6:10~)
,libavcodec-dev (>= 6:10~)
@ -15,7 +16,7 @@ Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apa
,libgcrypt-dev
,libcurl4-gnutls-dev
,libgnutls-openssl-dev
,libjpeg-dev
,libjpeg8-dev | libjpeg9-dev | libjpeg62-turbo-dev
,libmysqlclient-dev
,libpcre3-dev
,libpolkit-gobject-1-dev
@ -27,12 +28,10 @@ Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apa
,libsys-mmap-perl [!hurd-any]
,libwww-perl
,libdata-uuid-perl
,libx264-dev
,libmp4v2-dev
# Unbundled (dh_linktree):
,libjs-jquery
,libjs-mootools
Standards-Version: 3.9.6
Standards-Version: 3.9.8
Homepage: http://www.zoneminder.com/
Vcs-Browser: http://anonscm.debian.org/cgit/collab-maint/zoneminder.git
Vcs-Git: git://anonscm.debian.org/collab-maint/zoneminder.git
@ -41,11 +40,10 @@ Package: zoneminder
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,javascript-common
,libmp4v2-2, libx264-142|libx264-148, libswscale-ffmpeg3|libswscale4|libswscale3
,ffmpeg | libav-tools
,libdate-manip-perl
,libdate-manip-perl, libmime-lite-perl, libmime-tools-perl
,libdbd-mysql-perl
,libmime-lite-perl
,libmime-tools-perl
,libphp-serialization-perl
,libmodule-load-conditional-perl
,libnet-sftp-foreign-perl
@ -66,10 +64,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,libdata-uuid-perl
,mysql-client | virtual-mysql-client
,perl-modules
,php5-mysql | php-mysql, php5-gd | php-gd, php-apcu, php-apcu-bc | php-gd
,php5-mysql | php-mysql, php5-gd | php-gd , php5-apcu | php-apcu , php-apc | php-apcu-bc
,policykit-1
,rsyslog | system-log-daemon
,zip
,libpcre3
Recommends: ${misc:Recommends}
,libapache2-mod-php5 | libapache2-mod-php | php5-fpm | php-fpm
,mysql-server | virtual-mysql-server

View File

@ -1,2 +0,0 @@
default_cgi-path.patch
use_libjs-mootools.patch

View File

@ -28,7 +28,7 @@ override_dh_auto_configure:
override_dh_clean:
dh_clean $(MANPAGES1)
$(RM) -r docs/_build docs/installationguide
$(RM) -r docs/_build
build-indep:
#$(MAKE) -C docs text

View File

@ -1 +1 @@
3.0 (native)
3.0 (quilt)

View File

@ -3,6 +3,7 @@ usr/bin
usr/lib/zoneminder
usr/share/polkit-1
usr/share/zoneminder/db
usr/share/zoneminder/icons
usr/share/zoneminder/www
# libzoneminder-perl files:

View File

@ -2,6 +2,8 @@
missingok
notifempty
sharedscripts
delaycompress
compress
postrotate
/usr/bin/zmpkg.pl logrot >>/dev/null 2>&1 || :
endscript

View File

@ -0,0 +1,2 @@
?package(zoneminder):needs="x11" section="Applications/Video" title="ZoneMinder" command="/usr/bin/x-www-browser http://localhost/zm" icon="/usr/share/zoneminder/icons/16x16/icon.xpm"

View File

@ -12,6 +12,10 @@ if [ "$1" = "configure" ]; then
if [ -z "$2" ]; then
chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/*
fi
if [ ! -e "/etc/apache2/mods-enabled/cgi.load" ]; then
echo "The cgi module is not enabled in apache2. I am enabling it using a2enmod cgi."
a2enmod cgi
fi
# Do this every time the package is installed or upgraded

File diff suppressed because it is too large Load Diff

View File

@ -45,265 +45,239 @@ use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
sub new
{
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
bless( $self, $class );
srand( time() );
return $self;
sub new {
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
bless( $self, $class );
srand( time() );
return $self;
}
our $AUTOLOAD;
sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
sub AUTOLOAD {
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
if ( exists($self->{$name}) ) {
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
sub open
{
my $self = shift;
sub open {
my $self = shift;
$self->loadMonitor();
$self->loadMonitor();
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open';
$self->{state} = 'open';
}
sub close
{
my $self = shift;
$self->{state} = 'closed';
sub close {
my $self = shift;
$self->{state} = 'closed';
}
sub printMsg
{
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
sub printMsg {
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
sub sendCmd {
my $self = shift;
my $cmd = shift;
my $result = undef;
my $result = undef;
printMsg( $cmd, "Tx" );
printMsg( $cmd, "Tx" );
my $url;
if ( $self->{Monitor}->{ControlAddress} =~ /^http/ ) {
$url = $self->{Monitor}->{ControlAddress}.$cmd;
} else {
$url = 'http://'.$self->{Monitor}->{ControlAddress}.$cmd;
} # en dif
my $req = HTTP::Request->new( GET=>$url );
my $url;
if ( $self->{Monitor}->{ControlAddress} =~ /^http/ ) {
$url = $self->{Monitor}->{ControlAddress}.$cmd;
} else {
$url = 'http://'.$self->{Monitor}->{ControlAddress}.$cmd;
} # en dif
my $req = HTTP::Request->new( GET=>$url );
my $res = $self->{ua}->request($req);
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
}
else
{
Error( "Error check failed: '".$res->status_line()."'" );
}
if ( $res->is_success ) {
$result = !undef;
} else {
Error( "Error check failed: '".$res->status_line()."'" );
}
return( $result );
return( $result );
}
sub reset
{
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "/admin/ptctl.cgi?move=reset";
$self->sendCmd( $cmd );
sub reset {
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "/admin/ptctl.cgi?move=reset";
$self->sendCmd( $cmd );
}
sub moveMap
{
my $self = shift;
my $params = shift;
my $xcoord = $self->getParam( $params, 'xcoord' );
my $ycoord = $self->getParam( $params, 'ycoord' );
sub moveMap {
my $self = shift;
my $params = shift;
my $xcoord = $self->getParam( $params, 'xcoord' );
my $ycoord = $self->getParam( $params, 'ycoord' );
my $hor = $xcoord * 100 / $self->{Monitor}->{Width};
my $ver = $ycoord * 100 / $self->{Monitor}->{Height};
my $hor = $xcoord * 100 / $self->{Monitor}->{Width};
my $ver = $ycoord * 100 / $self->{Monitor}->{Height};
my $maxver = 8;
my $maxhor = 30;
my $horDir = "right";
my $verDir = "up";
my $horSteps = 0;
my $verSteps = 0;
my $maxver = 8;
my $maxhor = 30;
# Horizontal movement
if ($hor < 50) {
# left
$horSteps = ((50 - $hor) / 50) * $maxhor;
$horDir = "left";
}
elsif ($hor > 50) {
# right
$horSteps = (($hor - 50) / 50) * $maxhor;
$horDir = "right";
}
# Vertical movement
if ($ver < 50) {
# up
$verSteps = ((50 - $ver) / 50) * $maxver;
$verDir = "up";
}
elsif ($ver > 50) {
# down
$verSteps = (($ver - 50) / 50) * $maxver;
$verDir = "down";
}
my $horDir = "right";
my $verDir = "up";
my $horSteps = 0;
my $verSteps = 0;
my $v = int($verSteps);
my $h = int($horSteps);
# Horizontal movement
if ( $hor < 50 ) {
# left
$horSteps = ((50 - $hor) / 50) * $maxhor;
$horDir = "left";
}
elsif ( $hor > 50 ) {
# right
$horSteps = (($hor - 50) / 50) * $maxhor;
$horDir = "right";
}
Debug( "Move Map to $xcoord,$ycoord, hor=$h $horDir, ver=$v $verDir");
my $cmd = "/cgi/admin/ptctrl.cgi?action=movedegree&Cmd=$horDir&Degree=$h";
$self->sendCmd( $cmd );
$cmd = "/cgi/admin/ptctrl.cgi?action=movedegree&Cmd=$verDir&Degree=$v";
$self->sendCmd( $cmd );
# Vertical movement
if ( $ver < 50 ) {
# up
$verSteps = ((50 - $ver) / 50) * $maxver;
$verDir = "up";
}
elsif ( $ver > 50 ) {
# down
$verSteps = (($ver - 50) / 50) * $maxver;
$verDir = "down";
}
my $v = int($verSteps);
my $h = int($horSteps);
Debug( "Move Map to $xcoord,$ycoord, hor=$h $horDir, ver=$v $verDir");
my $cmd = "/cgi/admin/ptctrl.cgi?action=movedegree&Cmd=$horDir&Degree=$h";
$self->sendCmd( $cmd );
$cmd = "/cgi/admin/ptctrl.cgi?action=movedegree&Cmd=$verDir&Degree=$v";
$self->sendCmd( $cmd );
}
sub moveRelUp
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'tiltstep' );
Debug( "Step Up $step" );
my $cmd = "/admin/ptctl.cgi?move=up";
$self->sendCmd( $cmd );
sub moveRelUp {
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'tiltstep' );
Debug( "Step Up $step" );
my $cmd = "/admin/ptctl.cgi?move=up";
$self->sendCmd( $cmd );
}
sub moveRelDown
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'tiltstep' );
Debug( "Step Down $step" );
my $cmd = "/admin/ptctl.cgi?move=down";
$self->sendCmd( $cmd );
sub moveRelDown {
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'tiltstep' );
Debug( "Step Down $step" );
my $cmd = "/admin/ptctl.cgi?move=down";
$self->sendCmd( $cmd );
}
sub moveRelLeft
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'panstep' );
Debug( "Step Left $step" );
my $cmd = "/admin/ptctl.cgi?move=left";
$self->sendCmd( $cmd );
sub moveRelLeft {
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'panstep' );
if ( $self->{Monitor}->{Orientation} eq "hori" ) {
Debug( "Stepping Right because flipped horizontally " );
$self->sendCmd( "/admin/ptctl.cgi?move=right" );
} else {
Debug( "Step Left" );
$self->sendCmd( "/admin/ptctl.cgi?move=left" );
}
}
sub moveRelRight
{
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'panstep' );
Debug( "Step Right $step" );
my $cmd = "/admin/ptctl.cgi?move=right";
$self->sendCmd( $cmd );
sub moveRelRight {
my $self = shift;
my $params = shift;
my $step = $self->getParam( $params, 'panstep' );
if ( $self->{Monitor}->{Orientation} eq "hori" ) {
Debug( "Stepping Left because flipped horizontally " );
$self->sendCmd( "/admin/ptctl.cgi?move=left" );
} else {
Debug( "Step Right" );
$self->sendCmd( "/admin/ptctl.cgi?move=right" );
}
}
sub presetClear
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Clear Preset $preset" );
#my $cmd = "/axis-cgi/com/ptz.cgi?removeserverpresetno=$preset";
#$self->sendCmd( $cmd );
sub presetClear {
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Clear Preset $preset" );
#my $cmd = "/axis-cgi/com/ptz.cgi?removeserverpresetno=$preset";
#$self->sendCmd( $cmd );
}
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
my $cmd = "/admin/ptctl.cgi?position=" . ($preset - 1) . "&positionname=zm$preset";
$self->sendCmd( $cmd );
sub presetSet {
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
my $cmd = "/admin/ptctl.cgi?position=" . ($preset - 1) . "&positionname=zm$preset";
$self->sendCmd( $cmd );
}
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
my $cmd = "/admin/ptctl.cgi?move=p" . ($preset - 1);
$self->sendCmd( $cmd );
sub presetGoto {
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
my $cmd = "/admin/ptctl.cgi?move=p" . ($preset - 1);
$self->sendCmd( $cmd );
}
sub presetHome
{
my $self = shift;
Debug( "Home Preset" );
my $cmd = "/admin/ptctl.cgi?move=h";
$self->sendCmd( $cmd );
sub presetHome {
my $self = shift;
Debug( "Home Preset" );
my $cmd = "/admin/ptctl.cgi?move=h";
$self->sendCmd( $cmd );
}
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
=head1 NAME
ZoneMinder::Database - Perl extension for blah blah blah
ZoneMinder::Control::SkyIPCam7xx.pm - Module for controlling AirLink101 SkyIPams
=head1 SYNOPSIS
use ZoneMinder::Database;
blah blah blah
use ZoneMinder::Control::SkyIPCam7xx;
=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.
Module for controlling AirLink101 Cameras.
=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.
ZoneMinder::Control
=head1 AUTHOR
@ -318,5 +292,4 @@ 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,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -28,30 +28,12 @@ use 5.006;
use strict;
use warnings;
require Exporter;
require ZoneMinder::Base;
require ZoneMinder::Object;
require Date::Manip;
our @ISA = qw(Exporter ZoneMinder::Base);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
# This allows declaration use ZoneMinder ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = (
'functions' => [ qw(
) ]
);
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
our $VERSION = $ZoneMinder::Base::VERSION;
#our @ISA = qw(ZoneMinder::Object);
use parent qw(ZoneMinder::Object);
# ==========================================================================
#
@ -62,39 +44,24 @@ our $VERSION = $ZoneMinder::Base::VERSION;
use ZoneMinder::Config qw(:all);
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Database qw(:all);
require Date::Parse;
use vars qw/ $table $primary_key /;
$table = 'Events';
$primary_key = 'Id';
use POSIX;
sub new {
my ( $parent, $id, $data ) = @_;
my $self = {};
bless $self, $parent;
$$self{dbh} = $ZoneMinder::Database::dbh;
#zmDbConnect();
if ( ( $$self{Id} = $id ) or $data ) {
#$log->debug("loading $parent $id") if $debug or DEBUG_ALL;
$self->load( $data );
sub Time {
if ( @_ > 1 ) {
$_[0]{Time} = $_[1];
}
return $self;
} # end sub new
if ( ! defined $_[0]{Time} ) {
sub load {
my ( $self, $data ) = @_;
my $type = ref $self;
if ( ! $data ) {
#$log->debug("Object::load Loading from db $type");
$data = $$self{dbh}->selectrow_hashref( 'SELECT * FROM Events WHERE Id=?', {}, $$self{Id} );
if ( ! $data ) {
Error( "Failure to load Event record for $$self{Id}: Reason: " . $$self{dbh}->errstr );
} else {
Debug( 3, "Loaded Event $$self{Id}" );
} # end if
} # end if ! $data
if ( $data and %$data ) {
@$self{keys %$data} = values %$data;
} # end if
} # end sub load
$_[0]{Time} = Date::Parse::str2time( $_[0]{StartTime} );
}
return $_[0]{Time};
}
sub Name {
if ( @_ > 1 ) {
@ -130,6 +97,7 @@ sub find {
my $filter = new ZoneMinder::Event( $$db_filter{Id}, $db_filter );
push @results, $filter;
} # end while
$sth->finish();
return @results;
}
@ -138,36 +106,51 @@ sub find_one {
return $results[0] if @results;
}
sub getEventPath {
sub getPath {
return Path( @_ );
}
sub Path {
my $event = shift;
my $event_path = "";
if ( $Config{ZM_USE_DEEP_STORAGE} ) {
$event_path = $Config{ZM_DIR_EVENTS}
.'/'.$event->{MonitorId}
.'/'.strftime( "%y/%m/%d/%H/%M/%S",
localtime($event->{Time})
)
;
} else {
$event_path = $Config{ZM_DIR_EVENTS}
.'/'.$event->{MonitorId}
.'/'.$event->{Id}
;
if ( @_ > 1 ) {
$$event{Path} = $_[1];
if ( ! -e $$event{Path} ) {
Error("Setting path for event $$event{Id} to $_[1] but does not exist!");
}
}
if ( index($Config{ZM_DIR_EVENTS},'/') != 0 ){
$event_path = $Config{ZM_PATH_WEB}
.'/'.$event_path
;
}
return( $event_path );
if ( ! $$event{Path} ) {
my $path = ($Config{ZM_DIR_EVENTS}=~/^\//) ? $Config{ZM_DIR_EVENTS} : $Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS};
if ( $Config{ZM_USE_DEEP_STORAGE} ) {
if ( $event->Time() ) {
$$event{Path} = join('/',
$path,
$event->{MonitorId},
strftime( "%y/%m/%d/%H/%M/%S",
localtime($event->Time())
),
);
} else {
Error("Event $$event{Id} has no value for Time(), unable to determine path");
$$event{Path} = '';
}
} else {
$$event{Path} = join('/',
$path,
$event->{MonitorId},
$event->{Id},
);
}
} # end if
return $$event{Path};
}
sub GenerateVideo {
my ( $self, $rate, $fps, $scale, $size, $overwrite, $format ) = @_;
my $event_path = getEventPath( $self );
my $event_path = $self->getPath( );
chdir( $event_path );
( my $video_name = $self->{Name} ) =~ s/\s/_/g;
@ -228,9 +211,7 @@ sub GenerateVideo {
my $command = $Config{ZM_PATH_FFMPEG}
." -y -r $frame_rate "
.$Config{ZM_FFMPEG_INPUT_OPTIONS}
." -i %0"
.$Config{ZM_EVENT_IMAGE_DIGITS}
."d-capture.jpg -s $video_size "
.' -i ' . ( $$self{DefaultVideo} ? $$self{DefaultVideo} : '%0'.$Config{ZM_EVENT_IMAGE_DIGITS} .'d-capture.jpg' )
#. " -f concat -i /tmp/event_files.txt"
." -s $video_size "
.$Config{ZM_FFMPEG_OUTPUT_OPTIONS}
@ -253,54 +234,143 @@ sub GenerateVideo {
Info( "Video file $video_file already exists for event $self->{Id}\n" );
return $event_path.'/'.$video_file;
}
return;
return;
} # end sub GenerateVideo
sub delete {
my $event = $_[0];
Info( "Deleting event $event->{Id} from Monitor $event->{MonitorId} $event->{StartTime}\n" );
$ZoneMinder::Database::dbh->ping();
# Do it individually to avoid locking up the table for new events
my $sql = 'delete from Events where Id = ?';
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( $event->{Id} )
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish();
if ( ! $Config{ZM_OPT_FAST_DELETE} ) {
my $sql = 'delete from Frames where EventId = ?';
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
my $res = $sth->execute( $event->{Id} )
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish();
$sql = 'delete from Stats where EventId = ?';
$sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
$res = $sth->execute( $event->{Id} )
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
$sth->finish();
$event->delete_files( );
} else {
Debug('Not deleting frames, stats and files for speed.');
}
} # end sub delete
sub delete_files {
my $storage_path = ($Config{ZM_DIR_EVENTS}=~/^\//) ? $Config{ZM_DIR_EVENTS} : $Config{ZM_PATH_WEB}.'/'.$Config{ZM_DIR_EVENTS};
if ( ! $storage_path ) {
Fatal("Empty path when deleting files for event $_[0]{Id} ");
return;
}
chdir ( $storage_path );
if ( $Config{ZM_USE_DEEP_STORAGE} ) {
if ( ! $_[0]{MonitorId} ) {
Error("No monitor id assigned to event $_[0]{Id}");
return;
}
Debug("Deleting files for Event $_[0]{Id} from $storage_path.");
my $link_path = $_[0]{MonitorId}.'/*/*/*/.'.$_[0]{Id};
#Debug( "LP1:$link_path" );
my @links = glob($link_path);
#Debug( "L:".$links[0].": $!" );
if ( @links ) {
( $link_path ) = ( $links[0] =~ /^(.*)$/ ); # De-taint
#Debug( "LP2:$link_path" );
( my $day_path = $link_path ) =~ s/\.\d+//;
#Debug( "DP:$day_path" );
my $event_path = $day_path.readlink( $link_path );
( $event_path ) = ( $event_path =~ /^(.*)$/ ); # De-taint
#Debug( "EP:$event_path" );
my $command = "/bin/rm -rf $event_path";
#Debug( "C:$command" );
ZoneMinder::General::executeShellCommand( $command );
unlink( $link_path ) or Error( "Unable to unlink '$link_path': $!" );
my @path_parts = split( /\//, $event_path );
for ( my $i = int(@path_parts)-2; $i >= 1; $i-- ) {
my $delete_path = join( '/', @path_parts[0..$i] );
#Debug( "DP$i:$delete_path" );
my @has_files = glob( join('/', $storage_path,$delete_path,'*' ) );
#Debug( "HF1:".$has_files[0] ) if ( @has_files );
last if ( @has_files );
@has_files = glob( join('/', $storage_path, $delete_path, '.[0-9]*' ) );
#Debug( "HF2:".$has_files[0] ) if ( @has_files );
last if ( @has_files );
my $command = "/bin/rm -rf $storage_path/$delete_path";
ZoneMinder::General::executeShellCommand( $command );
}
}
} else {
my $command = "/bin/rm -rf $storage_path/$_[0]{MonitorId}/$_[0]{Id}";
ZoneMinder::General::executeShellCommand( $command );
}
} # end sub delete_files
sub Storage {
return new ZoneMinder::Storage( $_[0]{StorageId} );
}
sub check_for_in_filesystem {
my $path = $_[0]->Path();
if ( $path ) {
my @files = glob( $path . '/*' );
Debug("Checking for files for event $_[0]{Id} at $path using glob $path/* found " . scalar @files . " files");
return 1 if @files;
}
Debug("Checking for files for event $_[0]{Id} at $path using glob $path/* found no files");
return 0;
}
sub age {
if ( ! $_[0]{age} ) {
$_[0]{age} = (time() - ($^T - ((-M $_[0]->Path() ) * 24*60*60)));
}
return $_[0]{age};
}
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
=head1 NAME
ZoneMinder::Database - Perl extension for blah blah blah
ZoneMinder::Event - Perl Class for events
=head1 SYNOPSIS
use ZoneMinder::Event;
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.
The Event class has everything you need to deal with events from Perl.
=head1 AUTHOR
Philip Coombes, E<lt>philip.coombes@zoneminder.comE<gt>
Isaac Connor, E<lt>isaac@zoneminder.comE<gt>
=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
it under the same terms as Perl itself, either Perl version 5.8.3 or,

View File

@ -32,10 +32,9 @@ require ZoneMinder::Base;
require Date::Manip;
use parent qw(ZoneMinder::Object);
#our @ISA = qw(ZoneMinder::Object);
use vars qw/ $table $primary_key /;
$table = 'Events';
$table = 'Filters';
$primary_key = 'Id';
# ==========================================================================
#
@ -99,7 +98,7 @@ sub Execute {
my $sql = $self->Sql();
if ( $self->{HasDiskPercent} ) {
my $disk_percent = getDiskPercent( $$self{Storage} ? $$self{Storage}->Path() : () );
my $disk_percent = getDiskPercent();
$sql =~ s/zmDiskPercent/$disk_percent/g;
}
if ( $self->{HasDiskBlocks} ) {
@ -195,9 +194,6 @@ sub Sql {
# This gets used later, I forget for what
$$self{Server} = new ZoneMinder::Server( $temp_value );
}
} elsif ( $term->{attr} eq 'StorageId' ) {
$value = "'$temp_value'";
$$self{Storage} = new ZoneMinder::Storage( $temp_value );
} elsif ( $term->{attr} eq 'Name'
|| $term->{attr} eq 'Cause'
|| $term->{attr} eq 'Notes'
@ -253,14 +249,14 @@ sub Sql {
} # end if terms
if ( $self->{Sql} ) {
#if ( $self->{AutoMessage} ) {
if ( $self->{AutoMessage} ) {
# Include all events, including events that are still ongoing
# and have no EndTime yet
$sql .= " and ( ".$self->{Sql}." )";
#} else {
} else {
# Only include closed events (events with valid EndTime)
#$sql .= " where not isnull(E.EndTime) and ( ".$self->{Sql}." )";
#}
$sql .= " where not isnull(E.EndTime) and ( ".$self->{Sql}." )";
}
}
my @auto_terms;
if ( $self->{AutoArchive} ) {
@ -268,9 +264,9 @@ sub Sql {
}
# Don't do this, it prevents re-generation and concatenation.
# If the file already exists, then the video won't be re-recreated
#if ( $self->{AutoVideo} ) {
#push @auto_terms, "E.Videoed = 0";
#}
if ( $self->{AutoVideo} ) {
push @auto_terms, "E.Videoed = 0";
}
if ( $self->{AutoUpload} ) {
push @auto_terms, "E.Uploaded = 0";
}

View File

@ -41,7 +41,7 @@ our @ISA = qw(Exporter ZoneMinder::Base);
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = (
'constants' => [ qw(
constants => [ qw(
STATE_IDLE
STATE_PREALARM
STATE_ALARM
@ -56,7 +56,7 @@ our %EXPORT_TAGS = (
TRIGGER_ON
TRIGGER_OFF
) ],
'functions' => [ qw(
functions => [ qw(
zmMemVerify
zmMemInvalidate
zmMemRead
@ -77,12 +77,12 @@ our %EXPORT_TAGS = (
zmTriggerEventOn
zmTriggerEventOff
zmTriggerEventCancel
zmTriggerShowtext
zmTriggerShowtext
) ],
);
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();
@ -115,7 +115,7 @@ use constant TRIGGER_OFF => 2;
use Storable qw( freeze thaw );
if ( "@ENABLE_MMAP@" eq 'yes' ) {
if ( '@ENABLE_MMAP@' eq 'yes' ) {
# 'yes' if memory is mmapped
require ZoneMinder::Memory::Mapped;
ZoneMinder::Memory::Mapped->import();
@ -141,42 +141,42 @@ our $native = $arch/8;
our $mem_seq = 0;
our $mem_data = {
"shared_data" => { "type"=>"SharedData", "seq"=>$mem_seq++, "contents"=> {
"size" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"last_write_index" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"last_read_index" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"state" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"last_event" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"action" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"brightness" => { "type"=>"int32", "seq"=>$mem_seq++ },
"hue" => { "type"=>"int32", "seq"=>$mem_seq++ },
"colour" => { "type"=>"int32", "seq"=>$mem_seq++ },
"contrast" => { "type"=>"int32", "seq"=>$mem_seq++ },
"alarm_x" => { "type"=>"int32", "seq"=>$mem_seq++ },
"alarm_y" => { "type"=>"int32", "seq"=>$mem_seq++ },
"valid" => { "type"=>"uint8", "seq"=>$mem_seq++ },
"active" => { "type"=>"uint8", "seq"=>$mem_seq++ },
"signal" => { "type"=>"uint8", "seq"=>$mem_seq++ },
"format" => { "type"=>"uint8", "seq"=>$mem_seq++ },
"imagesize" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"epadding1" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"epadding2" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"last_write_time" => { "type"=>"time_t64", "seq"=>$mem_seq++ },
"last_read_time" => { "type"=>"time_t64", "seq"=>$mem_seq++ },
"control_state" => { "type"=>"uint8[256]", "seq"=>$mem_seq++ },
shared_data => { type=>'SharedData', seq=>$mem_seq++, contents=> {
size => { type=>'uint32', seq=>$mem_seq++ },
last_write_index => { type=>'uint32', seq=>$mem_seq++ },
last_read_index => { type=>'uint32', seq=>$mem_seq++ },
state => { type=>'uint32', seq=>$mem_seq++ },
last_event => { type=>'uint32', seq=>$mem_seq++ },
action => { type=>'uint32', seq=>$mem_seq++ },
brightness => { type=>'int32', seq=>$mem_seq++ },
hue => { type=>'int32', seq=>$mem_seq++ },
colour => { type=>'int32', seq=>$mem_seq++ },
contrast => { type=>'int32', seq=>$mem_seq++ },
alarm_x => { type=>'int32', seq=>$mem_seq++ },
alarm_y => { type=>'int32', seq=>$mem_seq++ },
valid => { type=>'uint8', seq=>$mem_seq++ },
active => { type=>'uint8', seq=>$mem_seq++ },
signal => { type=>'uint8', seq=>$mem_seq++ },
format => { type=>'uint8', seq=>$mem_seq++ },
imagesize => { type=>'uint32', seq=>$mem_seq++ },
epadding1 => { type=>'uint32', seq=>$mem_seq++ },
epadding2 => { type=>'uint32', seq=>$mem_seq++ },
last_write_time => { type=>'time_t64', seq=>$mem_seq++ },
last_read_time => { type=>'time_t64', seq=>$mem_seq++ },
control_state => { type=>'uint8[256]', seq=>$mem_seq++ },
}
},
"trigger_data" => { "type"=>"TriggerData", "seq"=>$mem_seq++, "contents"=> {
"size" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"trigger_state" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"trigger_score" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"padding" => { "type"=>"uint32", "seq"=>$mem_seq++ },
"trigger_cause" => { "type"=>"int8[32]", "seq"=>$mem_seq++ },
"trigger_text" => { "type"=>"int8[256]", "seq"=>$mem_seq++ },
"trigger_showtext" => { "type"=>"int8[256]", "seq"=>$mem_seq++ },
trigger_data => { type=>'TriggerData', seq=>$mem_seq++, 'contents'=> {
size => { type=>'uint32', seq=>$mem_seq++ },
trigger_state => { type=>'uint32', seq=>$mem_seq++ },
trigger_score => { type=>'uint32', seq=>$mem_seq++ },
padding => { type=>'uint32', seq=>$mem_seq++ },
trigger_cause => { type=>'int8[32]', seq=>$mem_seq++ },
trigger_text => { 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;
@ -195,28 +195,28 @@ sub zmMemInit {
}
}
foreach my $member_data ( sort { $a->{seq} <=> $b->{seq} } values( %{$section_data->{contents}} ) ) {
if ( $member_data->{type} eq "long"
|| $member_data->{type} eq "ulong"
|| $member_data->{type} eq "size_t"
if ( $member_data->{type} eq 'long'
|| $member_data->{type} eq 'ulong'
|| $member_data->{type} eq 'size_t'
) {
$member_data->{size} = $member_data->{align} = $native;
} elsif ( $member_data->{type} eq "int64"
|| $member_data->{type} eq "uint64"
|| $member_data->{type} eq "time_t64"
} elsif ( $member_data->{type} eq 'int64'
|| $member_data->{type} eq 'uint64'
|| $member_data->{type} eq 'time_t64'
) {
$member_data->{size} = $member_data->{align} = 8;
} elsif ( $member_data->{type} eq "int32"
|| $member_data->{type} eq "uint32"
|| $member_data->{type} eq "bool4"
} elsif ( $member_data->{type} eq 'int32'
|| $member_data->{type} eq 'uint32'
|| $member_data->{type} eq 'bool4'
) {
$member_data->{size} = $member_data->{align} = 4;
} elsif ($member_data->{type} eq "int16"
|| $member_data->{type} eq "uint16"
} elsif ($member_data->{type} eq 'int16'
|| $member_data->{type} eq 'uint16'
) {
$member_data->{size} = $member_data->{align} = 2;
} elsif ( $member_data->{type} eq "int8"
|| $member_data->{type} eq "uint8"
|| $member_data->{type} eq "bool1"
} elsif ( $member_data->{type} eq 'int8'
|| $member_data->{type} eq 'uint8'
|| $member_data->{type} eq 'bool1'
) {
$member_data->{size} = $member_data->{align} = 1;
} elsif ( $member_data->{type} =~ /^u?int8\[(\d+)\]$/ ) {
@ -248,51 +248,51 @@ sub zmMemVerify {
return( undef );
}
my $sd_size = zmMemRead( $monitor, "shared_data:size", 1 );
if ( $sd_size != $mem_data->{shared_data}->{size} ) {
if ( $sd_size ) {
Error( "Shared data size conflict in shared_data for monitor "
.$monitor->{Name}
.", expected "
.$mem_data->{shared_data}->{size}
.", got "
.$sd_size
);
} else {
Debug( "Shared data size conflict in shared_data for monitor "
.$monitor->{Name}
.", expected "
.$mem_data->{shared_data}->{size}
.", got ".$sd_size
);
}
return( undef );
my $sd_size = zmMemRead( $monitor, 'shared_data:size', 1 );
if ( $sd_size != $mem_data->{shared_data}->{size} ) {
if ( $sd_size ) {
Error( "Shared data size conflict in shared_data for monitor "
.$monitor->{Name}
.", expected "
.$mem_data->{shared_data}->{size}
.", got "
.$sd_size
);
} else {
Debug( "Shared data size conflict in shared_data for monitor "
.$monitor->{Name}
.", expected "
.$mem_data->{shared_data}->{size}
.", got ".$sd_size
);
}
my $td_size = zmMemRead( $monitor, "trigger_data:size", 1 );
if ( $td_size != $mem_data->{trigger_data}->{size} ) {
if ( $td_size ) {
Error( "Shared data size conflict in trigger_data for monitor "
.$monitor->{Name}
.", expected "
.$mem_data->{triggger_data}->{size}
.", got "
.$td_size
);
} else {
Debug( "Shared data size conflict in trigger_data for monitor "
.$monitor->{Name}
.", expected "
.$mem_data->{triggger_data}->{size}
.", got "
.$td_size
);
}
return( undef );
}
if ( !zmMemRead($monitor, "shared_data:valid",1) ) {
Error( "Shared data not valid for monitor $$monitor{Id}" );
return( undef );
return( undef );
}
my $td_size = zmMemRead( $monitor, 'trigger_data:size', 1 );
if ( $td_size != $mem_data->{trigger_data}->{size} ) {
if ( $td_size ) {
Error( "Shared data size conflict in trigger_data for monitor "
.$monitor->{Name}
.", expected "
.$mem_data->{triggger_data}->{size}
.", got "
.$td_size
);
} else {
Debug( "Shared data size conflict in trigger_data for monitor "
.$monitor->{Name}
.", expected "
.$mem_data->{triggger_data}->{size}
.", got "
.$td_size
);
}
return( undef );
}
if ( !zmMemRead($monitor, 'shared_data:valid',1) ) {
Error( "Shared data not valid for monitor $$monitor{Id}" );
return( undef );
}
return( !undef );
}
@ -325,32 +325,32 @@ sub zmMemRead {
return( undef );
}
my $value;
if ( $type eq "long" ) {
( $value ) = unpack( "l!", $data );
} elsif ( $type eq "ulong" || $type eq "size_t" ) {
( $value ) = unpack( "L!", $data );
} elsif ( $type eq "int64" || $type eq "time_t64" ) {
# The "q" type is only available on 64bit platforms, so use native.
( $value ) = unpack( "l!", $data );
} elsif ( $type eq "uint64" ) {
# The "q" type is only available on 64bit platforms, so use native.
( $value ) = unpack( "L!", $data );
} elsif ( $type eq "int32" ) {
( $value ) = unpack( "l", $data );
} elsif ( $type eq "uint32" || $type eq "bool4" ) {
( $value ) = unpack( "L", $data );
} elsif ( $type eq "int16" ) {
( $value ) = unpack( "s", $data );
} elsif ( $type eq "uint16" ) {
( $value ) = unpack( "S", $data );
} elsif ( $type eq "int8" ) {
( $value ) = unpack( "c", $data );
} elsif ( $type eq "uint8" || $type eq "bool1" ) {
( $value ) = unpack( "C", $data );
if ( $type eq 'long' ) {
( $value ) = unpack( 'l!', $data );
} elsif ( $type eq 'ulong' || $type eq 'size_t' ) {
( $value ) = unpack( 'L!', $data );
} elsif ( $type eq 'int64' || $type eq 'time_t64' ) {
# The 'q' type is only available on 64bit platforms, so use native.
( $value ) = unpack( 'l!', $data );
} elsif ( $type eq 'uint64' ) {
# The 'q' type is only available on 64bit platforms, so use native.
( $value ) = unpack( 'L!', $data );
} elsif ( $type eq 'int32' ) {
( $value ) = unpack( 'l', $data );
} elsif ( $type eq 'uint32' || $type eq 'bool4' ) {
( $value ) = unpack( 'L', $data );
} elsif ( $type eq 'int16' ) {
( $value ) = unpack( 's', $data );
} elsif ( $type eq 'uint16' ) {
( $value ) = unpack( 'S', $data );
} elsif ( $type eq 'int8' ) {
( $value ) = unpack( 'c', $data );
} elsif ( $type eq 'uint8' || $type eq 'bool1' ) {
( $value ) = unpack( 'C', $data );
} elsif ( $type =~ /^int8\[\d+\]$/ ) {
( $value ) = unpack( "Z".$size, $data );
( $value ) = unpack( 'Z'.$size, $data );
} elsif ( $type =~ /^uint8\[\d+\]$/ ) {
( $value ) = unpack( "C".$size, $data );
( $value ) = unpack( 'C'.$size, $data );
} else {
Fatal( "Unexpected type '".$type."' found for '".$field."'" );
}
@ -394,34 +394,34 @@ sub zmMemWrite {
my $size = $mem_data->{$section}->{contents}->{$element}->{size};
my $data;
if ( $type eq "long" ) {
$data = pack( "l!", $value );
} elsif ( $type eq "ulong" || $type eq "size_t" ) {
$data = pack( "L!", $value );
} elsif ( $type eq "int64" || $type eq "time_t64" ) {
# The "q" type is only available on 64bit platforms, so use native.
$data = pack( "l!", $value );
} elsif ( $type eq "uint64" ) {
# The "q" type is only available on 64bit platforms, so use native.
$data = pack( "L!", $value );
} elsif ( $type eq "int32" ) {
$data = pack( "l", $value );
} elsif ( $type eq "uint32" || $type eq "bool4" ) {
$data = pack( "L", $value );
} elsif ( $type eq "int16" ) {
$data = pack( "s", $value );
} elsif ( $type eq "uint16" ) {
$data = pack( "S", $value );
} elsif ( $type eq "int8" ) {
$data = pack( "c", $value );
} elsif ( $type eq "uint8" || $type eq "bool1" ) {
$data = pack( "C", $value );
if ( $type eq 'long' ) {
$data = pack( 'l!', $value );
} elsif ( $type eq 'ulong' || $type eq 'size_t' ) {
$data = pack( 'L!', $value );
} elsif ( $type eq 'int64' || $type eq 'time_t64' ) {
# The 'q' type is only available on 64bit platforms, so use native.
$data = pack( 'l!', $value );
} elsif ( $type eq 'uint64' ) {
# The 'q' type is only available on 64bit platforms, so use native.
$data = pack( 'L!', $value );
} elsif ( $type eq 'int32' ) {
$data = pack( 'l', $value );
} elsif ( $type eq 'uint32' || $type eq 'bool4' ) {
$data = pack( 'L', $value );
} elsif ( $type eq 'int16' ) {
$data = pack( 's', $value );
} elsif ( $type eq 'uint16' ) {
$data = pack( 'S', $value );
} elsif ( $type eq 'int8' ) {
$data = pack( 'c', $value );
} elsif ( $type eq 'uint8' || $type eq 'bool1' ) {
$data = pack( 'C', $value );
} elsif ( $type =~ /^int8\[\d+\]$/ ) {
$data = pack( "Z".$size, $value );
$data = pack( 'Z'.$size, $value );
} elsif ( $type =~ /^uint8\[\d+\]$/ ) {
$data = pack( "C".$size, $value );
$data = pack( 'C'.$size, $value );
} else {
Fatal( "Unexpected type '".$type."' found for '".$field."'" );
Fatal( "Unexpected type \"$type\" found for \"$field\"" );
}
if ( !zmMemPut( $monitor, $offset, $size, $data ) ) {
@ -438,26 +438,26 @@ sub zmMemWrite {
sub zmGetMonitorState {
my $monitor = shift;
return( zmMemRead( $monitor, "shared_data:state" ) );
return( zmMemRead( $monitor, 'shared_data:state' ) );
}
sub zmGetAlarmLocation {
my $monitor = shift;
return( zmMemRead( $monitor, [ "shared_data:alarm_x", "shared_data:alarm_y" ] ) );
return( zmMemRead( $monitor, [ 'shared_data:alarm_x', 'shared_data:alarm_y' ] ) );
}
sub zmSetControlState {
my $monitor = shift;
my $control_state = shift;
zmMemWrite( $monitor, { "shared_data:control_state" => $control_state } );
zmMemWrite( $monitor, { 'shared_data:control_state' => $control_state } );
}
sub zmGetControlState {
my $monitor = shift;
return( zmMemRead( $monitor, "shared_data:control_state" ) );
return( zmMemRead( $monitor, 'shared_data:control_state' ) );
}
sub zmSaveControlState {
@ -493,8 +493,8 @@ sub zmHasAlarmed {
my $monitor = shift;
my $last_event_id = shift;
my ( $state, $last_event ) = zmMemRead( $monitor, [ "shared_data:state"
,"shared_data:last_event"
my ( $state, $last_event ) = zmMemRead( $monitor, [ 'shared_data:state'
,'shared_data:last_event'
]
);
@ -509,63 +509,63 @@ sub zmHasAlarmed {
sub zmGetLastEvent {
my $monitor = shift;
return( zmMemRead( $monitor, "shared_data:last_event" ) );
return( zmMemRead( $monitor, 'shared_data:last_event' ) );
}
sub zmGetLastWriteTime {
my $monitor = shift;
return( zmMemRead( $monitor, "shared_data:last_write_time" ) );
return( zmMemRead( $monitor, 'shared_data:last_write_time' ) );
}
sub zmGetLastReadTime {
my $monitor = shift;
return( zmMemRead( $monitor, "shared_data:last_read_time" ) );
return( zmMemRead( $monitor, 'shared_data:last_read_time' ) );
}
sub zmGetMonitorActions {
my $monitor = shift;
return( zmMemRead( $monitor, "shared_data:action" ) );
return( zmMemRead( $monitor, 'shared_data:action' ) );
}
sub zmMonitorEnable {
my $monitor = shift;
my $action = zmMemRead( $monitor, "shared_data:action" );
my $action = zmMemRead( $monitor, 'shared_data:action' );
$action |= ACTION_SUSPEND;
zmMemWrite( $monitor, { "shared_data:action" => $action } );
zmMemWrite( $monitor, { 'shared_data:action' => $action } );
}
sub zmMonitorDisable {
my $monitor = shift;
my $action = zmMemRead( $monitor, "shared_data:action" );
my $action = zmMemRead( $monitor, 'shared_data:action' );
$action |= ACTION_RESUME;
zmMemWrite( $monitor, { "shared_data:action" => $action } );
zmMemWrite( $monitor, { 'shared_data:action' => $action } );
}
sub zmMonitorSuspend {
my $monitor = shift;
my $action = zmMemRead( $monitor, "shared_data:action" );
my $action = zmMemRead( $monitor, 'shared_data:action' );
$action |= ACTION_SUSPEND;
zmMemWrite( $monitor, { "shared_data:action" => $action } );
zmMemWrite( $monitor, { 'shared_data:action' => $action } );
}
sub zmMonitorResume {
my $monitor = shift;
my $action = zmMemRead( $monitor, "shared_data:action" );
my $action = zmMemRead( $monitor, 'shared_data:action' );
$action |= ACTION_RESUME;
zmMemWrite( $monitor, { "shared_data:action" => $action } );
zmMemWrite( $monitor, { 'shared_data:action' => $action } );
}
sub zmGetTriggerState {
my $monitor = shift;
return( zmMemRead( $monitor, "trigger_data:trigger_state" ) );
return( zmMemRead( $monitor, 'trigger_data:trigger_state' ) );
}
sub zmTriggerEventOn {
@ -576,12 +576,12 @@ sub zmTriggerEventOn {
my $showtext = shift;
my $values = {
"trigger_data:trigger_score" => $score,
"trigger_data:trigger_cause" => $cause,
'trigger_data:trigger_score' => $score,
'trigger_data:trigger_cause' => $cause,
};
$values->{"trigger_data:trigger_text"} = $text if ( defined($text) );
$values->{"trigger_data:trigger_showtext"} = $showtext if ( defined($showtext) );
$values->{"trigger_data:trigger_state"} = TRIGGER_ON; # Write state last so event not read incomplete
$values->{'trigger_data:trigger_text'} = $text if ( defined($text) );
$values->{'trigger_data:trigger_showtext'} = $showtext if ( defined($showtext) );
$values->{'trigger_data:trigger_state'} = TRIGGER_ON; # Write state last so event not read incomplete
zmMemWrite( $monitor, $values );
}
@ -590,11 +590,11 @@ sub zmTriggerEventOff {
my $monitor = shift;
my $values = {
"trigger_data:trigger_state" => TRIGGER_OFF,
"trigger_data:trigger_score" => 0,
"trigger_data:trigger_cause" => "",
"trigger_data:trigger_text" => "",
"trigger_data:trigger_showtext" => "",
'trigger_data:trigger_state' => TRIGGER_OFF,
'trigger_data:trigger_score' => 0,
'trigger_data:trigger_cause' => '',
'trigger_data:trigger_text' => '',
'trigger_data:trigger_showtext' => '',
};
zmMemWrite( $monitor, $values );
@ -604,11 +604,11 @@ sub zmTriggerEventCancel {
my $monitor = shift;
my $values = {
"trigger_data:trigger_state" => TRIGGER_CANCEL,
"trigger_data:trigger_score" => 0,
"trigger_data:trigger_cause" => "",
"trigger_data:trigger_text" => "",
"trigger_data:trigger_showtext" => "",
'trigger_data:trigger_state' => TRIGGER_CANCEL,
'trigger_data:trigger_score' => 0,
'trigger_data:trigger_cause' => '',
'trigger_data:trigger_text' => '',
'trigger_data:trigger_showtext' => '',
};
zmMemWrite( $monitor, $values );
@ -619,7 +619,7 @@ sub zmTriggerShowtext {
my $showtext = shift;
my $values = {
"trigger_data:trigger_showtext" => $showtext,
'trigger_data:trigger_showtext' => $showtext,
};
zmMemWrite( $monitor, $values );
@ -648,7 +648,7 @@ if ( zmMemVerify( $monitor ) ) {
"shared_data:last_write_index"
]
);
zmMemWrite( $monitor, { "trigger_data:trigger_showtext" => "Some Text" } );
zmMemWrite( $monitor, { 'trigger_data:trigger_showtext' => "Some Text" } );
=head1 DESCRIPTION

View File

@ -40,15 +40,15 @@ our @ISA = qw(Exporter ZoneMinder::Base);
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = (
'functions' => [ qw(
zmMemKey
zmMemAttach
zmMemDetach
zmMemGet
zmMemPut
zmMemClean
) ],
);
functions => [ qw(
zmMemKey
zmMemAttach
zmMemDetach
zmMemGet
zmMemPut
zmMemClean
) ],
);
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
@ -68,134 +68,119 @@ use ZoneMinder::Logger qw(:all);
use Sys::Mmap;
sub zmMemKey
{
my $monitor = shift;
return( defined($monitor->{MMapAddr})?$monitor->{MMapAddr}:undef );
sub zmMemKey {
my $monitor = shift;
return( defined($monitor->{MMapAddr})?$monitor->{MMapAddr}:undef );
}
sub zmMemAttach
{
my ( $monitor, $size ) = @_;
if ( ! $size ) {
Error( "No size passed to zmMemAttach for monitor $$monitor{Id}\n" );
return( undef );
sub zmMemAttach {
my ( $monitor, $size ) = @_;
if ( ! $size ) {
Error( "No size passed to zmMemAttach for monitor $$monitor{Id}\n" );
return( undef );
}
if ( !defined($monitor->{MMapAddr}) ) {
my $mmap_file = $Config{ZM_PATH_MAP}."/zm.mmap.".$monitor->{Id};
if ( ! -e $mmap_file ) {
Error( sprintf( "Memory map file '%s' does not exist. zmc might not be running."
, $mmap_file
)
);
return ( undef );
}
if ( !defined($monitor->{MMapAddr}) )
{
my $mmap_file = $Config{ZM_PATH_MAP}."/zm.mmap.".$monitor->{Id};
if ( ! -e $mmap_file ) {
Error( sprintf( "Memory map file '%s' does not exist. zmc might not be running."
, $mmap_file
)
);
return ( undef );
}
my $mmap_file_size = -s $mmap_file;
my $mmap_file_size = -s $mmap_file;
if ( $mmap_file_size < $size ) {
Error( sprintf( "Memory map file '%s' should have been %d but was instead %d"
, $mmap_file
, $size
, $mmap_file_size
)
);
return ( undef );
}
my $MMAP;
if ( !open( $MMAP, "+<", $mmap_file ) )
{
Error( sprintf( "Can't open memory map file '%s': $!\n", $mmap_file ) );
return( undef );
}
my $mmap = undef;
my $mmap_addr = mmap( $mmap, $size, PROT_READ|PROT_WRITE, MAP_SHARED, $MMAP );
if ( !$mmap_addr || !$mmap )
{
Error( sprintf( "Can't mmap to file '%s': $!\n", $mmap_file ) );
close( $MMAP );
return( undef );
}
$monitor->{MMapHandle} = $MMAP;
$monitor->{MMapAddr} = $mmap_addr;
$monitor->{MMap} = \$mmap;
if ( $mmap_file_size < $size ) {
Error( sprintf( "Memory map file '%s' should have been %d but was instead %d"
, $mmap_file
, $size
, $mmap_file_size
)
);
return ( undef );
}
return( !undef );
my $MMAP;
if ( !open( $MMAP, '+<', $mmap_file ) ) {
Error( sprintf( "Can't open memory map file '%s': $!\n", $mmap_file ) );
return( undef );
}
my $mmap = undef;
my $mmap_addr = mmap( $mmap, $size, PROT_READ|PROT_WRITE, MAP_SHARED, $MMAP );
if ( !$mmap_addr || !$mmap ) {
Error( sprintf( "Can't mmap to file '%s': $!\n", $mmap_file ) );
close( $MMAP );
return( undef );
}
$monitor->{MMapHandle} = $MMAP;
$monitor->{MMapAddr} = $mmap_addr;
$monitor->{MMap} = \$mmap;
}
return( !undef );
}
sub zmMemDetach
{
my $monitor = shift;
sub zmMemDetach {
my $monitor = shift;
if ( $monitor->{MMap} )
{
if ( ! munmap( ${$monitor->{MMap}} ) ) {
Warn( "Unable to munmap for monitor $$monitor{Id}\n");
}
delete $monitor->{MMap};
}
if ( $monitor->{MMapAddr} )
{
delete $monitor->{MMapAddr};
}
if ( $monitor->{MMapHandle} )
{
close( $monitor->{MMapHandle} );
delete $monitor->{MMapHandle};
if ( $monitor->{MMap} ) {
if ( ! munmap( ${$monitor->{MMap}} ) ) {
Warn( "Unable to munmap for monitor $$monitor{Id}\n");
}
delete $monitor->{MMap};
}
if ( $monitor->{MMapAddr} ) {
delete $monitor->{MMapAddr};
}
if ( $monitor->{MMapHandle} ) {
close( $monitor->{MMapHandle} );
delete $monitor->{MMapHandle};
}
}
sub zmMemGet
{
my $monitor = shift;
my $offset = shift;
my $size = shift;
sub zmMemGet {
my $monitor = shift;
my $offset = shift;
my $size = shift;
my $mmap = $monitor->{MMap};
if ( !$mmap || !$$mmap )
{
Error( sprintf( "Can't read from mapped memory for monitor '%d', gone away?"
, $monitor->{Id}
)
my $mmap = $monitor->{MMap};
if ( !$mmap || !$$mmap ) {
Error( sprintf( "Can't read from mapped memory for monitor '%d', gone away?"
, $monitor->{Id}
)
);
return( undef );
}
my $data = substr( $$mmap, $offset, $size );
return( $data );
return( undef );
}
my $data = substr( $$mmap, $offset, $size );
return( $data );
}
sub zmMemPut
{
my $monitor = shift;
my $offset = shift;
my $size = shift;
my $data = shift;
sub zmMemPut {
my $monitor = shift;
my $offset = shift;
my $size = shift;
my $data = shift;
my $mmap = $monitor->{MMap};
if ( !$mmap || !$$mmap )
{
Error( sprintf( "Can't write mapped memory for monitor '%d', gone away?"
, $monitor->{Id}
)
my $mmap = $monitor->{MMap};
if ( !$mmap || !$$mmap ) {
Error( sprintf( "Can't write mapped memory for monitor '%d', gone away?"
, $monitor->{Id}
)
);
return( undef );
}
substr( $$mmap, $offset, $size ) = $data;
return( !undef );
return( undef );
}
substr( $$mmap, $offset, $size ) = $data;
return( !undef );
}
sub zmMemClean
{
Debug( "Removing memory map files\n" );
my $mapPath = $Config{ZM_PATH_MAP}."/zm.mmap.*";
foreach my $mapFile( glob( $mapPath ) )
{
( $mapFile ) = $mapFile =~ /^(.+)$/;
Debug( "Removing memory map file '$mapFile'\n" );
unlink( $mapFile );
}
sub zmMemClean {
Debug( "Removing memory map files\n" );
my $mapPath = $Config{ZM_PATH_MAP}.'/zm.mmap.*';
foreach my $mapFile( glob( $mapPath ) ) {
( $mapFile ) = $mapFile =~ /^(.+)$/;
Debug( "Removing memory map file '$mapFile'\n" );
unlink( $mapFile );
}
}
1;

View File

@ -0,0 +1,85 @@
# ==========================================================================
#
# ZoneMinder Monitor Module, $Date$, $Revision$
# Copyright (C) 2001-2008 Philip Coombes
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the common definitions and functions used by the rest
# of the ZoneMinder scripts
#
package ZoneMinder::Monitor;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
require ZoneMinder::Object;
require ZoneMinder::Server;
#our @ISA = qw(Exporter ZoneMinder::Base);
use parent qw(ZoneMinder::Object);
# ==========================================================================
#
# General Utility Functions
#
# ==========================================================================
use ZoneMinder::Config qw(:all);
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Database qw(:all);
use POSIX;
use vars qw/ $table $primary_key /;
$table = 'Monitors';
$primary_key = 'Id';
sub Server {
return new ZoneMinder::Server( $_[0]{ServerId} );
} # end sub Server
1;
__END__
=head1 NAME
ZoneMinder::Monitor - Perl Class for Monitors
=head1 SYNOPSIS
use ZoneMinder::Monitor;
=head1 DESCRIPTION
=head1 AUTHOR
Isaac Connor, E<lt>isaac@zoneminder.comE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2001-2017 ZoneMinder LLC
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,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -0,0 +1,150 @@
# ==========================================================================
#
# ZoneMinder Object Module, $Date$, $Revision$
# Copyright (C) 2001-2017 ZoneMinder LLC
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the common definitions and functions used by the rest
# of the ZoneMinder scripts
#
package ZoneMinder::Object;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
our @ISA = qw(ZoneMinder::Base);
# ==========================================================================
#
# General Utility Functions
#
# ==========================================================================
use ZoneMinder::Config qw(:all);
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Database qw(:all);
use vars qw/ $AUTOLOAD /;
sub new {
my ( $parent, $id, $data ) = @_;
my $self = {};
bless $self, $parent;
no strict 'refs';
my $primary_key = ${$parent.'::primary_key'};
if ( ! $primary_key ) {
Error( 'NO primary_key for type ' . $parent );
return;
} # end if
if ( ( $$self{$primary_key} = $id ) or $data ) {
#$log->debug("loading $parent $id") if $debug or DEBUG_ALL;
$self->load( $data );
}
return $self;
} # end sub new
sub load {
my ( $self, $data ) = @_;
my $type = ref $self;
if ( ! $data ) {
no strict 'refs';
my $table = ${$type.'::table'};
if ( ! $table ) {
Error( 'NO table for type ' . $type );
return;
} # end if
my $primary_key = ${$type.'::primary_key'};
if ( ! $primary_key ) {
Error( 'NO primary_key for type ' . $type );
return;
} # end if
if ( ! $$self{$primary_key} ) {
my ( $caller, undef, $line ) = caller;
Error( (ref $self) . "::load called without $primary_key from $caller:$line");
} else {
#$log->debug("Object::load Loading from db $type");
Debug("Loading $type from $table WHERE $primary_key = $$self{$primary_key}");
$data = $ZoneMinder::Database::dbh->selectrow_hashref( "SELECT * FROM $table WHERE $primary_key=?", {}, $$self{$primary_key} );
if ( ! $data ) {
if ( $ZoneMinder::Database::dbh->errstr ) {
Error( "Failure to load Object record for $$self{$primary_key}: Reason: " . $ZoneMinder::Database::dbh->errstr );
} else {
Debug("No Results Loading $type from $table WHERE $primary_key = $$self{$primary_key}");
} # end if
} # end if
} # end if
} # end if ! $data
if ( $data and %$data ) {
@$self{keys %$data} = values %$data;
} # end if
} # end sub load
sub AUTOLOAD {
my ( $self, $newvalue ) = @_;
my $type = ref($_[0]);
my $name = $AUTOLOAD;
$name =~ s/.*://;
if ( @_ > 1 ) {
return $_[0]{$name} = $_[1];
}
return $_[0]{$name};
}
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
=head1 NAME
ZoneMinder::Object
=head1 SYNOPSIS
use parent ZoneMinder::Object;
This package should likely not be used directly, as it is meant mainly to be a parent for all other ZoneMinder classes.
=head1 DESCRIPTION
A base Object to act as parent for other ZoneMinder Objects.
=head2 EXPORT
None by default.
=head1 AUTHOR
Isaac Connor, E<lt>isaac@zoneminder.comE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2001-2017 ZoneMinder LLC
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,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -41,9 +41,9 @@ yet.
=head1 OPTIONS
-r, --report - Just report don't actually do anything
-i, --interactive - Ask before applying any changes
-c, --continuous - Run continuously
-i, --interactive - Ask before applying any changes
-r, --report - Just report don't actually do anything
-v, --version - Print the installed version of ZoneMinder
=cut
@ -57,8 +57,8 @@ use bytes;
# ==========================================================================
use constant MAX_AGED_DIRS => 10; # Number of event dirs to check age on
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_TAG => '(r)'; # Tag to append to event name when recovered
use constant RECOVER_TEXT => 'Recovered.'; # Text to append to event notes when recovered
# ==========================================================================
#
@ -96,10 +96,10 @@ logInit();
logSetSignal();
GetOptions(
'report' =>\$report,
'interactive' =>\$interactive,
'continuous' =>\$continuous,
'version' =>\$version
continuous =>\$continuous,
interactive =>\$interactive,
report =>\$report,
version =>\$version
) or pod2usage(-exitstatus => -1);
if ( $version ) {
@ -111,6 +111,10 @@ if ( ($report + $interactive + $continuous) > 1 ) {
pod2usage(-exitstatus => -1);
}
if ( ! exists $Config{ZM_AUDIT_MIN_AGE} ) {
Fatal('ZM_AUDIT_MIN_AGE is not set in config.');
}
my $dbh = zmDbConnect();
chdir( EVENT_PATH );
@ -126,13 +130,13 @@ MAIN: while( $loop ) {
$dbh = zmDbConnect();
if ( $continuous ) {
Error("Unable to connect to database");
Error('Unable to connect to database');
# if we are running continuously, then just skip to the next
# interval, otherwise we are a one off run, so wait a second and
# retry until someone kills us.
sleep( $Config{ZM_AUDIT_CHECK_INTERVAL} );
} else {
Fatal("Unable to connect to database");
Fatal('Unable to connect to database');
} # end if
} # end while can't connect to the db
@ -145,16 +149,12 @@ MAIN: while( $loop ) {
sleep 1;
} # end if
if ( ! exists $Config{ZM_AUDIT_MIN_AGE} ) {
Fatal("ZM_AUDIT_MIN_AGE is not set in config.");
}
my $db_monitors;
my $monitorSelectSql = "select Id from Monitors order by Id";
my $monitorSelectSql = 'select Id from Monitors order by Id';
my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql )
or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() );
my $eventSelectSql = "SELECT Id, (unix_timestamp() - unix_timestamp(StartTime)) as Age
FROM Events WHERE MonitorId = ? ORDER BY Id";
my $eventSelectSql = 'SELECT Id, (unix_timestamp() - unix_timestamp(StartTime)) as Age
FROM Events WHERE MonitorId = ? ORDER BY Id';
my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql )
or Fatal( "Can't prepare '$eventSelectSql': ".$dbh->errstr() );
@ -169,11 +169,11 @@ MAIN: while( $loop ) {
while ( my $event = $eventSelectSth->fetchrow_hashref() ) {
$db_events->{$event->{Id}} = $event->{Age};
}
Debug( "Got ".int(keys(%$db_events))." events\n" );
Debug( 'Got '.int(keys(%$db_events))." events\n" );
}
my $fs_monitors;
foreach my $monitor ( glob("[0-9]*") ) {
foreach my $monitor ( glob('[0-9]*') ) {
# Thie glob above gives all files starting with a digit. So a monitor with a name starting with a digit will be in this list.
next if $monitor =~ /\D/;
Debug( "Found filesystem monitor '$monitor'" );
@ -182,11 +182,17 @@ MAIN: while( $loop ) {
if ( $Config{ZM_USE_DEEP_STORAGE} ) {
foreach my $day_dir ( glob("$monitor_dir/*/*/*") ) {
Debug( "Checking $day_dir" );
Debug( "Checking day dir $day_dir" );
( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint
chdir( $day_dir );
opendir( DIR, "." )
or Fatal( "Can't open directory '$day_dir': $!" );
if ( ! chdir( $day_dir ) ) {
Error( "Can't chdir to '$day_dir': $!" );
next;
}
if ( ! opendir( DIR, '.' ) ) {
Error( "Can't open directory '$day_dir': $!" );
next;
}
my @event_links = sort { $b <=> $a } grep { -l $_ } readdir( DIR );
closedir( DIR );
my $count = 0;
@ -226,7 +232,7 @@ MAIN: while( $loop ) {
}
chdir( EVENT_PATH );
}
Debug( "Got ".int(keys(%$fs_events))." events\n" );
Debug( 'Got '.int(keys(%$fs_events))." events\n" );
} # end foreach monitor Id
redo MAIN if ( $cleaned );
@ -255,7 +261,7 @@ MAIN: while( $loop ) {
}
my $monitor_links;
foreach my $link ( glob("*") ) {
foreach my $link ( glob('*') ) {
next if ( !-l $link );
next if ( -e $link );
@ -270,16 +276,16 @@ MAIN: while( $loop ) {
redo MAIN if ( $cleaned );
$cleaned = 0;
my $deleteMonitorSql = "delete low_priority from Monitors where Id = ?";
my $deleteMonitorSql = 'delete low_priority from Monitors where Id = ?';
my $deleteMonitorSth = $dbh->prepare_cached( $deleteMonitorSql )
or Fatal( "Can't prepare '$deleteMonitorSql': ".$dbh->errstr() );
my $deleteEventSql = "delete low_priority from Events where Id = ?";
my $deleteEventSql = 'delete low_priority from Events where Id = ?';
my $deleteEventSth = $dbh->prepare_cached( $deleteEventSql )
or Fatal( "Can't prepare '$deleteEventSql': ".$dbh->errstr() );
my $deleteFramesSql = "delete low_priority from Frames where EventId = ?";
my $deleteFramesSql = 'delete low_priority from Frames where EventId = ?';
my $deleteFramesSth = $dbh->prepare_cached( $deleteFramesSql )
or Fatal( "Can't prepare '$deleteFramesSql': ".$dbh->errstr() );
my $deleteStatsSql = "delete low_priority from Stats where EventId = ?";
my $deleteStatsSql = 'delete low_priority from Stats where EventId = ?';
my $deleteStatsSth = $dbh->prepare_cached( $deleteStatsSql )
or Fatal( "Can't prepare '$deleteStatsSql': ".$dbh->errstr() );
while ( my ( $db_monitor, $db_events ) = each(%$db_monitors) ) {
@ -319,9 +325,9 @@ MAIN: while( $loop ) {
# Remove orphaned events (with no monitor)
$cleaned = 0;
my $selectOrphanedEventsSql = "SELECT Events.Id, Events.Name
my $selectOrphanedEventsSql = 'SELECT Events.Id, Events.Name
FROM Events LEFT JOIN Monitors ON (Events.MonitorId = Monitors.Id)
WHERE isnull(Monitors.Id)";
WHERE isnull(Monitors.Id)';
my $selectOrphanedEventsSth = $dbh->prepare_cached( $selectOrphanedEventsSql )
or Fatal( "Can't prepare '$selectOrphanedEventsSql': ".$dbh->errstr() );
$res = $selectOrphanedEventsSth->execute()
@ -356,8 +362,8 @@ MAIN: while( $loop ) {
# Remove orphaned frame records
$cleaned = 0;
my $selectOrphanedFramesSql = "SELECT DISTINCT EventId FROM Frames
WHERE EventId NOT IN (SELECT Id FROM Events)";
my $selectOrphanedFramesSql = 'SELECT DISTINCT EventId FROM Frames
WHERE EventId NOT IN (SELECT Id FROM Events)';
my $selectOrphanedFramesSth = $dbh->prepare_cached( $selectOrphanedFramesSql )
or Fatal( "Can't prepare '$selectOrphanedFramesSql': ".$dbh->errstr() );
$res = $selectOrphanedFramesSth->execute()
@ -374,8 +380,8 @@ MAIN: while( $loop ) {
# Remove orphaned stats records
$cleaned = 0;
my $selectOrphanedStatsSql = "SELECT DISTINCT EventId FROM Stats
WHERE EventId NOT IN (SELECT Id FROM Events)";
my $selectOrphanedStatsSql = 'SELECT DISTINCT EventId FROM Stats
WHERE EventId NOT IN (SELECT Id FROM Events)';
my $selectOrphanedStatsSth = $dbh->prepare_cached( $selectOrphanedStatsSql )
or Fatal( "Can't prepare '$selectOrphanedStatsSql': ".$dbh->errstr() );
$res = $selectOrphanedStatsSth->execute()
@ -429,20 +435,13 @@ MAIN: while( $loop ) {
aud_print( "Found open event '$event->{Id}'" );
if ( confirm( 'close', 'closing' ) ) {
$res = $updateUnclosedEventsSth->execute(
sprintf("%s%d%s",
$event->{Prefix},
$event->{Id},
RECOVER_TAG
),
sprintf('%s%d%s', $event->{Prefix}, $event->{Id}, RECOVER_TAG),
$event->{EndTime},
$event->{Length},
$event->{Frames},
$event->{AlarmFrames},
$event->{TotScore},
$event->{AlarmFrames}
? int($event->{TotScore} / $event->{AlarmFrames})
: 0
,
$event->{AlarmFrames} ? int($event->{TotScore} / $event->{AlarmFrames}) : 0,
$event->{MaxScore},
RECOVER_TEXT,
$event->{Id}
@ -453,8 +452,8 @@ MAIN: while( $loop ) {
# Now delete any old image files
my @old_files = grep { -M > $max_image_age } <$image_path/*.{jpg,gif,wbmp}>;
if ( @old_files ) {
aud_print( "Deleting ".int(@old_files)." old images\n" );
my $untainted_old_files = join( ";", @old_files );
aud_print( 'Deleting '.( scalar @old_files )." old images\n" );
my $untainted_old_files = join( ';', @old_files );
( $untainted_old_files ) = ( $untainted_old_files =~ /^(.*)$/ );
unlink( split( /;/, $untainted_old_files ) );
}
@ -467,7 +466,7 @@ MAIN: while( $loop ) {
if ( $Config{ZM_LOG_DATABASE_LIMIT} ) {
if ( $Config{ZM_LOG_DATABASE_LIMIT} =~ /^\d+$/ ) {
# 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 )
or Fatal( "Can't prepare '$selectLogRowCountSql': ".$dbh->errstr() );
$res = $selectLogRowCountSth->execute()
@ -475,20 +474,20 @@ MAIN: while( $loop ) {
my $row = $selectLogRowCountSth->fetchrow_hashref();
my $logRows = $row->{Rows};
if ( $logRows > $Config{ZM_LOG_DATABASE_LIMIT} ) {
my $deleteLogByRowsSql = "DELETE low_priority FROM Logs ORDER BY TimeKey ASC LIMIT ?";
my $deleteLogByRowsSql = 'DELETE low_priority FROM Logs ORDER BY TimeKey ASC LIMIT ?';
my $deleteLogByRowsSth = $dbh->prepare_cached( $deleteLogByRowsSql )
or Fatal( "Can't prepare '$deleteLogByRowsSql': ".$dbh->errstr() );
$res = $deleteLogByRowsSth->execute( $logRows - $Config{ZM_LOG_DATABASE_LIMIT} )
or Fatal( "Can't execute: ".$deleteLogByRowsSth->errstr() );
if ( $deleteLogByRowsSth->rows() ) {
aud_print( "Deleted ".$deleteLogByRowsSth->rows() ." log table entries by count\n" );
aud_print( 'Deleted '.$deleteLogByRowsSth->rows() ." log table entries by count\n" );
}
}
} else {
# Time of record
my $deleteLogByTimeSql =
"DELETE low_priority FROM Logs
WHERE TimeKey < unix_timestamp(now() - interval ".$Config{ZM_LOG_DATABASE_LIMIT}.")";
'DELETE low_priority FROM Logs
WHERE TimeKey < unix_timestamp(now() - interval '.$Config{ZM_LOG_DATABASE_LIMIT}.')';
my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql )
or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() );
$res = $deleteLogByTimeSth->execute()
@ -515,8 +514,8 @@ sub aud_print {
}
sub confirm {
my $prompt = shift || "delete";
my $action = shift || "deleting";
my $prompt = shift || 'delete';
my $action = shift || 'deleting';
my $yesno = 0;
if ( $report ) {

File diff suppressed because it is too large Load Diff

View File

@ -643,7 +643,7 @@ bool EventStream::loadInitialEventData( int init_event_id, unsigned int init_fra
bool EventStream::loadEventData( int event_id ) {
static char sql[ZM_SQL_MED_BUFSIZ];
snprintf( sql, sizeof(sql), "select MonitorId, Frames, unix_timestamp( StartTime ) as StartTimestamp, (SELECT max(Delta)-min(Delta) FROM Frames WHERE EventId=Events.Id) as Duration, DefaultVideo from Events Id = %d", event_id );
snprintf( sql, sizeof(sql), "SELECT MonitorId, Frames, unix_timestamp( StartTime ) AS StartTimestamp, (SELECT max(Delta)-min(Delta) FROM Frames WHERE EventId=Events.Id) AS Duration, DefaultVideo FROM Events WHERE Id = %d", event_id );
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) );

View File

@ -23,7 +23,7 @@
#include "zm_ffmpeg_camera.h"
extern "C"{
extern "C" {
#include "libavutil/time.h"
}
#ifndef AV_ERROR_MAX_STRING_SIZE
@ -125,8 +125,7 @@ int FfmpegCamera::PreCapture()
return( 0 );
}
int FfmpegCamera::Capture( Image &image )
{
int FfmpegCamera::Capture( Image &image ) {
if (!mCanCapture){
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 );
// What about audio stream? Maybe someday we could do sound detection...
if ( packet.stream_index == mVideoStreamId ) {
#if LIBAVCODEC_VERSION_CHECK(52, 23, 0, 23, 0)
if (avcodec_decode_video2(mVideoCodecContext, mRawFrame, &frameComplete, &packet) < 0)
#else
if (avcodec_decode_video(mVideoCodecContext, mRawFrame, &frameComplete, packet.data, packet.size) < 0)
#endif
int ret = zm_avcodec_decode_video( mVideoCodecContext, mRawFrame, &frameComplete, &packet );
if ( ret < 0 )
Fatal( "Unable to decode frame 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() );
}
if (mAudioStreamId >= 0) {
if ( mAudioStreamId >= 0 ) {
mAudioCodecContext = mFormatContext->streams[mAudioStreamId]->codec;
if ((mAudioCodec = avcodec_find_decoder(mAudioCodecContext->codec_id)) == NULL) {
Debug(1, "Can't find codec for audio stream from %s", mPath.c_str());
@ -437,7 +433,7 @@ int FfmpegCamera::OpenFfmpeg() {
mCanCapture = true;
return 0;
}
} // int FfmpegCamera::OpenFfmpeg()
int FfmpegCamera::ReopenFfmpeg() {
@ -462,8 +458,7 @@ int FfmpegCamera::CloseFfmpeg(){
av_frame_free( &mRawFrame );
#if HAVE_LIBSWSCALE
if ( mConvertContext )
{
if ( mConvertContext ) {
sws_freeContext( mConvertContext );
mConvertContext = NULL;
}
@ -490,8 +485,7 @@ int FfmpegCamera::CloseFfmpeg(){
return 0;
}
int FfmpegCamera::FfmpegInterruptCallback(void *ctx)
{
int FfmpegCamera::FfmpegInterruptCallback(void *ctx) {
FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
if (camera->mIsOpening){
int now = time(NULL);
@ -529,14 +523,14 @@ void *FfmpegCamera::ReopenFfmpegThreadCallback(void *ctx){
//Function to handle capture and store
int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event_file ) {
if (!mCanCapture){
if ( ! mCanCapture ) {
return -1;
}
int ret;
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 (mReopenThread != 0) {
if ( mReopenThread != 0 ) {
void *retval = 0;
ret = pthread_join(mReopenThread, &retval);
@ -548,7 +542,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
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." );
}
@ -639,6 +633,7 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
unsigned int packet_count = 0;
ZMPacket *queued_packet;
// Clear all packets that predate the moment when the recording began
packetqueue.clear_unwanted_packets( &recording, mVideoStreamId );
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.
// 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 ) {
Debug(3, "Clearing queue");
packetqueue.clearQueue( monitor->GetPreEventCount(), mVideoStreamId );
@ -688,18 +683,22 @@ else if ( packet.pts && video_last_pts > packet.pts ) {
}
#endif
}
if (
( packet.stream_index != mAudioStreamId || record_audio )
&&
( key_frame || packetqueue.size() )
) {
packetqueue.queuePacket( &packet );
// The following lines should ensure that the queue always begins with a video keyframe
if ( packet.stream_index == mAudioStreamId ) {
//Debug(2, "Have audio packet, reocrd_audio is (%d) and packetqueue.size is (%d)", record_audio, 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 );
}
} 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
if ( packet.stream_index == mVideoStreamId ) {
if ( videoStore ) {
if ( videoStore ) {
//Write the packet to our video store
int ret = videoStore->writeVideoFramePacket( &packet );
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;
}
} 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 {
#if LIBAVUTIL_VERSION_CHECK(56, 23, 0, 23, 0)

View File

@ -60,14 +60,12 @@ ZMPacket* zm_packetqueue::popPacket( ) {
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;
if ( pktQueue.empty() ) {
Debug(3, "Queue is empty");
return 0;
} else {
Debug(3, "Queue has (%d)", pktQueue.size() );
}
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;
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
if ( ( av_packet->stream_index == stream_id) && ( av_packet->flags & AV_PKT_FLAG_KEY ) ) {
if (!frames_to_keep)
break;
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;
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();
pktQueue.pop_front();
@ -96,6 +95,7 @@ unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream
delete_count += 1;
}
Debug(3, "Deleted (%d) packets", delete_count );
return delete_count;
} // 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
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 ) {
ZMPacket *zm_packet = *it;
AVPacket *av_packet = &(zm_packet->packet);
Debug(1, "Looking for keyframe after start" );
if (
( av_packet->flags & AV_PKT_FLAG_KEY )
&&
@ -134,7 +134,7 @@ Debug(1, "Looking for keyframe after start" );
&&
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;
}
}
@ -143,10 +143,29 @@ Debug(1, "Found keyframe before start" );
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;
while ( pktQueue.rend() != it ) {
while ( distance( it, pktQueue.rend() ) > 1 ) {
//while ( pktQueue.rend() != it ) {
packet = pktQueue.front();
pktQueue.pop_front();
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() );
}
}

View File

@ -27,7 +27,7 @@
#include "zm.h"
#include "zm_videostore.h"
extern "C"{
extern "C" {
#include "libavutil/time.h"
}
@ -37,23 +37,23 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
int64_t nStartTime,
Monitor * monitor
) {
video_input_stream = p_video_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;
#endif
//store inputs in variables local to class
filename = filename_in;
format = format_in;
keyframeMessage = false;
keyframeSkipNumber = 0;
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);
if ( ret < 0 ) {
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()
);
} else {
Debug(2, "Success alocateing output context");
Debug(2, "Success allocating output context");
}
//Couldn't deduce format from filename, trying from format name
if (!oc) {
if ( ! oc ) {
avformat_alloc_output_context2(&oc, NULL, format, filename);
if (!oc) {
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__ );
oc->metadata = pmetadata;
output_format = oc->oformat;
video_output_stream = avformat_new_stream(oc, (AVCodec*)video_input_context->codec);
if (!video_output_stream) {
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
// 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");
} else {
Debug(2, "Success creating video out stream" );
}
video_output_context = video_output_stream->codec;
#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 );
// Now copy them to the output stream
ret = avcodec_parameters_from_context( video_output_stream->codecpar, video_output_context );
if ( ret < 0 ) {
Error( "Could not initialize stream parameteres");
return;
} else {
Debug(2, "Success getting parameters");
Debug(2, "Success setting parameters");
}
zm_dump_stream_format( oc, 0, 0, 1 );
#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) {
Fatal("Unable to copy input video context to output video context %s\n",
av_make_error_string(ret).c_str());
@ -130,7 +148,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
// WHY?
//video_output_context->codec_tag = 0;
if (!video_output_context->codec_tag) {
if ( ! video_output_context->codec_tag ) {
Debug(2, "No 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
@ -145,6 +163,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
}
Monitor::Orientation orientation = monitor->getOrientation();
Debug(3, "Have orientation" );
if ( orientation ) {
if ( orientation == Monitor::ROTATE_0 ) {
@ -169,13 +188,22 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
resample_context = NULL;
#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;
#endif
if ( audio_input_context->codec_id != AV_CODEC_ID_AAC ) {
static char error_buffer[256];
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() ) {
return;
}
@ -187,9 +215,16 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
Error("Unable to create audio out stream\n");
audio_output_stream = NULL;
} 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);
#endif
if (ret < 0) {
Error("Unable to copy audio context %s\n", av_make_error_string(ret).c_str());
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_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");
/* Write the stream header, if any. */
ret = avformat_write_header(oc, NULL);
@ -252,8 +288,10 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
video_last_dts = 0;
audio_last_pts = 0;
audio_last_dts = 0;
previous_pts = 0;
previous_dts = 0;
video_previous_pts = 0;
video_previous_dts = 0;
audio_previous_pts = 0;
audio_previous_dts = 0;
} // VideoStore::VideoStore
@ -262,14 +300,14 @@ VideoStore::~VideoStore(){
if ( audio_output_codec ) {
// Do we need to flush the outputs? I have no idea.
AVPacket pkt;
int got_packet;
int got_packet = 0;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
int64_t size;
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 );
#else
ret = avcodec_encode_audio2( audio_output_context, &pkt, NULL, &got_packet );
@ -341,6 +379,18 @@ bool VideoStore::setup_resampler() {
#ifdef HAVE_LIBAVRESAMPLE
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);
if ( ! audio_output_codec ) {
Error("Could not find codec for AAC");
@ -348,8 +398,8 @@ bool VideoStore::setup_resampler() {
}
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 ) {
Error( "could not allocate codec context for AAC\n");
@ -359,18 +409,15 @@ bool VideoStore::setup_resampler() {
Debug(2, "Have audio_output_context");
AVDictionary *opts = NULL;
av_dict_set(&opts, "strict", "experimental", 0);
/* put sample parameters */
audio_output_context->bit_rate = audio_input_context->bit_rate;
audio_output_context->sample_rate = audio_input_context->sample_rate;
audio_output_context->channels = audio_input_context->channels;
audio_output_context->channel_layout = audio_input_context->channel_layout;
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;
for ( unsigned int i = 0; audio_output_codec->supported_samplerates[i]; 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 */
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",
av_get_sample_fmt_name( audio_output_context->sample_fmt));
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 };
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)",
audio_output_context->bit_rate,
@ -427,7 +452,30 @@ bool VideoStore::setup_resampler() {
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 );
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
ret = avcodec_parameters_from_context( audio_output_stream->codecpar, audio_output_context );
if ( ret < 0 ) {
Error( "Could not initialize stream parameteres");
return false;
}
#endif
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. */
if (!(input_frame = zm_av_frame_alloc())) {
Error("Could not allocate input frame");
@ -562,9 +610,9 @@ int VideoStore::writeVideoFramePacket( AVPacket *ipkt ) {
if ( ipkt->pts < video_last_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?
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 {
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 );
@ -588,24 +636,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
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 );
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 {
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)",
opkt.dts, video_input_stream->cur_dts, video_last_dts
);
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 );
video_last_dts = video_input_stream->cur_dts;
} else {
if ( ipkt->dts < video_last_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 {
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)",
opkt.dts, ipkt->dts, video_last_dts
);
Debug(3, "opkt.dts = %d from ipkt.dts(%d) - previus_dts(%d)", opkt.dts, ipkt->dts, video_last_dts );
video_last_dts = ipkt->dts;
}
}
@ -642,15 +686,15 @@ Debug(1, "writing video packet pts(%d) dts(%d) duration(%d)", opkt.pts, opkt.dts
dumpPacket( ipkt);
dumpPacket(&opkt);
} else if ((previous_dts > 0) && (previous_dts > opkt.dts)) {
Warning("%s:%d: DTS out of order: %lld \u226E %lld; discarding frame", __FILE__, __LINE__, previous_dts, opkt.dts);
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__, video_previous_dts, opkt.dts);
video_previous_dts = opkt.dts;
dumpPacket(&opkt);
} else {
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_dts = opkt.dts; // Unsure if av_interleaved_write_frame() clobbers opkt.dts when out of order, so storing in advance
video_previous_pts = opkt.pts;
ret = av_interleaved_write_frame(oc, &opkt);
if(ret<0){
// There's nothing we can really do if the frame is rejected, just drop it and get on with the next
@ -663,21 +707,20 @@ Debug(1, "writing video packet pts(%d) dts(%d) duration(%d)", opkt.pts, opkt.dts
return 0;
}
} // end int VideoStore::writeVideoFramePacket( AVPacket *ipkt )
int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
Debug(4, "writeAudioFrame");
if(!audio_output_stream) {
if ( ! 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
}
if ( audio_output_codec ) {
#ifdef HAVE_LIBAVRESAMPLE
#if 0
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
ret = avcodec_send_packet( audio_input_context, ipkt );
if ( ret < 0 ) {
Error("avcodec_send_packet fail %s", av_make_error_string(ret).c_str());
@ -696,26 +739,7 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
input_frame->channel_layout,
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
/**
* Decode the audio frame stored in the packet.
* The input audio stream decoder is used to do this.
@ -728,15 +752,13 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
av_make_error_string(ret).c_str());
dumpPacket( ipkt );
av_frame_free( &input_frame );
zm_av_packet_unref( &opkt );
return 0;
}
if ( ! data_present ) {
Debug(2, "Not ready to transcode a frame yet.");
zm_av_packet_unref(&opkt);
return 0;
}
#endif
int frame_size = input_frame->nb_samples;
Debug(4, "Frame size: %d", frame_size );
@ -778,11 +800,22 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
* Encode the audio frame and store it in the temporary packet.
* 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 ) {
Error( "Could not recieve packet (error '%s')",
av_make_error_string(ret).c_str());
zm_av_packet_unref(&opkt);
return 0;
}
#else
if (( ret = avcodec_encode_audio2( audio_output_context, &opkt, output_frame, &data_present )) < 0) {
#endif
Error( "Could not encode frame (error '%s')",
av_make_error_string(ret).c_str());
zm_av_packet_unref(&opkt);
@ -793,8 +826,8 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
zm_av_packet_unref(&opkt);
return 0;
}
#endif
#endif
} else {
av_init_packet(&opkt);
@ -807,14 +840,17 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
//Scale the PTS of the outgoing packet to be the correct time base
if ( ipkt->pts != AV_NOPTS_VALUE ) {
if ( !audio_last_pts ) {
if ( ! audio_last_pts ) {
opkt.pts = 0;
Debug(1, "No audio_last_pts");
} else {
if ( 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, "opkt.pts = %d from ipkt->pts(%d) - last_pts(%d)", opkt.pts, ipkt->pts, audio_last_pts );
Debug(2, "audio opkt.pts = %d from ipkt->pts(%d) - last_pts(%d)", opkt.pts, ipkt->pts, audio_last_pts );
}
audio_last_pts = ipkt->pts;
} else {
@ -825,28 +861,30 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
//Scale the DTS of the outgoing packet to be the correct time base
if ( ! audio_last_dts ) {
opkt.dts = 0;
} else {
if( ipkt->dts == AV_NOPTS_VALUE ) {
// 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 ) {
Debug(1, "Resetting audio_last_pts 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);
Debug(1, "Resetting audio_last_dts from (%d) to cur_dts (%d)", audio_last_dts, audio_input_stream->cur_dts );
opkt.dts = audio_previous_dts + av_rescale_q( audio_input_stream->cur_dts, AV_TIME_BASE_Q, audio_output_stream->time_base);
} 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;
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 {
if ( 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 {
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 );
}
}
audio_last_dts = ipkt->dts;
if ( 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;
@ -854,15 +892,17 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
// 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);
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
opkt.pos = -1;
opkt.flags = ipkt->flags;
opkt.stream_index = ipkt->stream_index;
Debug(2, "Stream index is %d", opkt.stream_index );
AVPacket safepkt;
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);
if(ret!=0){
Error("Error writing audio frame packet: %s\n", av_make_error_string(ret).c_str());

View File

@ -61,8 +61,10 @@ AVAudioResampleContext* resample_context;
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.
int64_t previous_pts;
int64_t previous_dts;
int64_t video_previous_pts;
int64_t video_previous_dts;
int64_t audio_previous_pts;
int64_t audio_previous_dts;
int64_t filter_in_rescale_delta_last;

View File

@ -163,7 +163,7 @@ int main( int argc, char *argv[] )
if ( analysis_update_delay )
{
cur_time = time( 0 );
if ( ( cur_time - last_analysis_update_time ) > analysis_update_delay )
if ( (unsigned int)( cur_time - last_analysis_update_time ) > analysis_update_delay )
{
analysis_rate = monitor->GetAnalysisRate();
monitor->UpdateAdaptiveSkip();

View File

@ -95,8 +95,7 @@ Options for use with monitors:
#include "zm_monitor.h"
#include "zm_local_camera.h"
void Usage( int status=-1 )
{
void Usage( int status=-1 ) {
fprintf( stderr, "zmu <-d device_path> [-v] [function] [-U<username> -P<password>]\n" );
fprintf( stderr, "zmu <-m monitor_id> [-v] [function] [-U<username> -P<password>]\n" );
fprintf( stderr, "General options:\n" );
@ -167,48 +166,38 @@ typedef enum {
ZMU_LIST = 0x10000000,
} Function;
bool ValidateAccess( User *user, int mon_id, int function )
{
bool ValidateAccess( User *user, int mon_id, int function ) {
bool allowed = true;
if ( function & (ZMU_STATE|ZMU_IMAGE|ZMU_TIME|ZMU_READ_IDX|ZMU_WRITE_IDX|ZMU_FPS) )
{
if ( function & (ZMU_STATE|ZMU_IMAGE|ZMU_TIME|ZMU_READ_IDX|ZMU_WRITE_IDX|ZMU_FPS) ) {
if ( user->getStream() < User::PERM_VIEW )
allowed = false;
}
if ( function & ZMU_EVENT )
{
if ( function & ZMU_EVENT ) {
if ( user->getEvents() < User::PERM_VIEW )
allowed = false;
}
if ( function & (ZMU_ZONES|ZMU_QUERY|ZMU_LIST) )
{
if ( function & (ZMU_ZONES|ZMU_QUERY|ZMU_LIST) ) {
if ( user->getMonitors() < User::PERM_VIEW )
allowed = false;
}
if ( function & (ZMU_ALARM|ZMU_NOALARM|ZMU_CANCEL|ZMU_RELOAD|ZMU_ENABLE|ZMU_DISABLE|ZMU_SUSPEND|ZMU_RESUME|ZMU_BRIGHTNESS|ZMU_CONTRAST|ZMU_HUE|ZMU_COLOUR) )
{
if ( function & (ZMU_ALARM|ZMU_NOALARM|ZMU_CANCEL|ZMU_RELOAD|ZMU_ENABLE|ZMU_DISABLE|ZMU_SUSPEND|ZMU_RESUME|ZMU_BRIGHTNESS|ZMU_CONTRAST|ZMU_HUE|ZMU_COLOUR) ) {
if ( user->getMonitors() < User::PERM_EDIT )
allowed = false;
}
if ( mon_id > 0 )
{
if ( !user->canAccess( mon_id ) )
{
if ( mon_id > 0 ) {
if ( !user->canAccess( mon_id ) ) {
allowed = false;
}
}
if ( !allowed )
{
if ( !allowed ) {
fprintf( stderr, "Error, insufficient privileges for requested action\n" );
exit( -1 );
}
return( allowed );
}
int main( int argc, char *argv[] )
{
if ( access(ZM_CONFIG, R_OK) != 0 )
{
int main( int argc, char *argv[] ) {
if ( access(ZM_CONFIG, R_OK) != 0 ) {
fprintf( stderr, "Can't open %s: %s\n", ZM_CONFIG, strerror(errno) );
exit( -1 );
}
@ -274,18 +263,15 @@ int main( int argc, char *argv[] )
int v4lVersion = 1;
#endif // ZM_HAS_V4L2/1
#endif // ZM_HAS_V4L
while (1)
{
while (1) {
int option_index = 0;
int c = getopt_long (argc, argv, "d:m:vsEDLurwei::S:t::fz::ancqhlB::C::H::O::U:P:A:V:", long_options, &option_index);
if (c == -1)
{
if (c == -1) {
break;
}
switch (c)
{
switch (c) {
case 'd':
if ( optarg )
device = optarg;
@ -405,8 +391,7 @@ int main( int argc, char *argv[] )
}
}
if (optind < argc)
{
if (optind < argc) {
fprintf( stderr, "Extraneous options, " );
while (optind < argc)
fprintf( stderr, "%s ", argv[optind++]);
@ -414,13 +399,11 @@ int main( int argc, char *argv[] )
Usage();
}
if ( device && !(function&ZMU_QUERY) )
{
if ( device && !(function&ZMU_QUERY) ) {
fprintf( stderr, "Error, -d option cannot be used with this option\n" );
Usage();
}
if ( scale != -1 && !(function&ZMU_IMAGE) )
{
if ( scale != -1 && !(function&ZMU_IMAGE) ) {
fprintf( stderr, "Error, -S option cannot be used with this option\n" );
Usage();
}
@ -435,46 +418,36 @@ int main( int argc, char *argv[] )
User *user = 0;
if ( config.opt_use_auth )
{
if ( strcmp( config.auth_relay, "none" ) == 0 )
{
if ( !username )
{
if ( config.opt_use_auth ) {
if ( strcmp( config.auth_relay, "none" ) == 0 ) {
if ( !username ) {
fprintf( stderr, "Error, username must be supplied\n" );
exit( -1 );
}
if ( username )
{
if ( username ) {
user = zmLoadUser( username );
}
}
else
{
if ( !(username && password) && !auth )
{
} else {
if ( !(username && password) && !auth ) {
fprintf( stderr, "Error, username and password or auth string must be supplied\n" );
exit( -1 );
}
//if ( strcmp( config.auth_relay, "hashed" ) == 0 )
{
if ( auth )
{
if ( auth ) {
user = zmLoadAuthUser( auth, false );
}
}
//else if ( strcmp( config.auth_relay, "plain" ) == 0 )
{
if ( username && password )
{
if ( username && password ) {
user = zmLoadUser( username, password );
}
}
}
if ( !user )
{
if ( !user ) {
fprintf( stderr, "Error, unable to authenticate user\n" );
exit( -1 );
}
@ -482,13 +455,10 @@ int main( int argc, char *argv[] )
}
if ( mon_id > 0 )
{
if ( mon_id > 0 ) {
Monitor *monitor = Monitor::Load( mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY );
if ( monitor )
{
if ( verbose )
{
if ( monitor ) {
if ( verbose ) {
printf( "Monitor %d(%s)\n", monitor->Id(), monitor->Name() );
}
if ( ! monitor->connect() ) {
@ -498,23 +468,19 @@ int main( int argc, char *argv[] )
char separator = ' ';
bool have_output = false;
if ( function & ZMU_STATE )
{
if ( function & ZMU_STATE ) {
Monitor::State state = monitor->GetState();
if ( verbose )
printf( "Current state: %s\n", state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle") );
else
{
else {
if ( have_output ) printf( "%c", separator );
printf( "%d", state );
have_output = true;
}
}
if ( function & ZMU_TIME )
{
if ( function & ZMU_TIME ) {
struct timeval timestamp = monitor->GetTimestamp( image_idx );
if ( verbose )
{
if ( verbose ) {
char timestamp_str[64] = "None";
if ( timestamp.tv_sec )
strftime( timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", localtime( &timestamp.tv_sec ) );
@ -522,62 +488,50 @@ int main( int argc, char *argv[] )
printf( "Time of last image capture: %s.%02ld\n", timestamp_str, timestamp.tv_usec/10000 );
else
printf( "Time of image %d capture: %s.%02ld\n", image_idx, timestamp_str, timestamp.tv_usec/10000 );
}
else
{
} else {
if ( have_output ) printf( "%c", separator );
printf( "%ld.%02ld", timestamp.tv_sec, timestamp.tv_usec/10000 );
have_output = true;
}
}
if ( function & ZMU_READ_IDX )
{
if ( function & ZMU_READ_IDX ) {
if ( verbose )
printf( "Last read index: %d\n", monitor->GetLastReadIndex() );
else
{
else {
if ( have_output ) printf( "%c", separator );
printf( "%d", monitor->GetLastReadIndex() );
have_output = true;
}
}
if ( function & ZMU_WRITE_IDX )
{
if ( function & ZMU_WRITE_IDX ) {
if ( verbose )
printf( "Last write index: %d\n", monitor->GetLastWriteIndex() );
else
{
else {
if ( have_output ) printf( "%c", separator );
printf( "%d", monitor->GetLastWriteIndex() );
have_output = true;
}
}
if ( function & ZMU_EVENT )
{
if ( function & ZMU_EVENT ) {
if ( verbose )
printf( "Last event id: %d\n", monitor->GetLastEvent() );
else
{
else {
if ( have_output ) printf( "%c", separator );
printf( "%d", monitor->GetLastEvent() );
have_output = true;
}
}
if ( function & ZMU_FPS )
{
if ( function & ZMU_FPS ) {
if ( verbose )
printf( "Current capture rate: %.2f frames per second\n", monitor->GetFPS() );
else
{
else {
if ( have_output ) printf( "%c", separator );
printf( "%.2f", monitor->GetFPS() );
have_output = true;
}
}
if ( function & ZMU_IMAGE )
{
if ( verbose )
{
if ( function & ZMU_IMAGE ) {
if ( verbose ) {
if ( image_idx == -1 )
printf( "Dumping last image captured to Monitor%d.jpg", monitor->Id() );
else
@ -588,77 +542,63 @@ int main( int argc, char *argv[] )
}
monitor->GetImage( image_idx, scale>0?scale:100 );
}
if ( function & ZMU_ZONES )
{
if ( function & ZMU_ZONES ) {
if ( verbose )
printf( "Dumping zone image to Zones%d.jpg\n", monitor->Id() );
monitor->DumpZoneImage( zoneString );
}
if ( function & ZMU_ALARM )
{
if ( function & ZMU_ALARM ) {
if ( verbose )
printf( "Forcing alarm on\n" );
monitor->ForceAlarmOn( config.forced_alarm_score, "Forced Web" );
}
if ( function & ZMU_NOALARM )
{
if ( function & ZMU_NOALARM ) {
if ( verbose )
printf( "Forcing alarm off\n" );
monitor->ForceAlarmOff();
}
if ( function & ZMU_CANCEL )
{
if ( function & ZMU_CANCEL ) {
if ( verbose )
printf( "Cancelling forced alarm on/off\n" );
monitor->CancelForced();
}
if ( function & ZMU_RELOAD )
{
if ( function & ZMU_RELOAD ) {
if ( verbose )
printf( "Reloading monitor settings\n" );
monitor->actionReload();
}
if ( function & ZMU_ENABLE )
{
if ( function & ZMU_ENABLE ) {
if ( verbose )
printf( "Enabling event generation\n" );
monitor->actionEnable();
}
if ( function & ZMU_DISABLE )
{
if ( function & ZMU_DISABLE ) {
if ( verbose )
printf( "Disabling event generation\n" );
monitor->actionDisable();
}
if ( function & ZMU_SUSPEND )
{
if ( function & ZMU_SUSPEND ) {
if ( verbose )
printf( "Suspending event generation\n" );
monitor->actionSuspend();
}
if ( function & ZMU_RESUME )
{
if ( function & ZMU_RESUME ) {
if ( verbose )
printf( "Resuming event generation\n" );
monitor->actionResume();
}
if ( function & ZMU_QUERY )
{
if ( function & ZMU_QUERY ) {
char monString[16382] = "";
monitor->DumpSettings( monString, verbose );
printf( "%s\n", monString );
}
if ( function & ZMU_BRIGHTNESS )
{
if ( verbose )
{
if ( function & ZMU_BRIGHTNESS ) {
if ( verbose ) {
if ( brightness >= 0 )
printf( "New brightness: %d\n", monitor->actionBrightness( brightness ) );
else
printf( "Current brightness: %d\n", monitor->actionBrightness() );
}
else
{
} else {
if ( have_output ) printf( "%c", separator );
if ( brightness >= 0 )
printf( "%d", monitor->actionBrightness( brightness ) );
@ -667,17 +607,13 @@ int main( int argc, char *argv[] )
have_output = true;
}
}
if ( function & ZMU_CONTRAST )
{
if ( verbose )
{
if ( function & ZMU_CONTRAST ) {
if ( verbose ) {
if ( contrast >= 0 )
printf( "New brightness: %d\n", monitor->actionContrast( contrast ) );
else
printf( "Current contrast: %d\n", monitor->actionContrast() );
}
else
{
} else {
if ( have_output ) printf( "%c", separator );
if ( contrast >= 0 )
printf( "%d", monitor->actionContrast( contrast ) );
@ -686,17 +622,13 @@ int main( int argc, char *argv[] )
have_output = true;
}
}
if ( function & ZMU_HUE )
{
if ( verbose )
{
if ( function & ZMU_HUE ) {
if ( verbose ) {
if ( hue >= 0 )
printf( "New hue: %d\n", monitor->actionHue( hue ) );
else
printf( "Current hue: %d\n", monitor->actionHue() );
}
else
{
} else {
if ( have_output ) printf( "%c", separator );
if ( hue >= 0 )
printf( "%d", monitor->actionHue( hue ) );
@ -705,17 +637,13 @@ int main( int argc, char *argv[] )
have_output = true;
}
}
if ( function & ZMU_COLOUR )
{
if ( verbose )
{
if ( function & ZMU_COLOUR ) {
if ( verbose ) {
if ( colour >= 0 )
printf( "New colour: %d\n", monitor->actionColour( colour ) );
else
printf( "Current colour: %d\n", monitor->actionColour() );
}
else
{
} else {
if ( have_output ) printf( "%c", separator );
if ( colour >= 0 )
printf( "%d", monitor->actionColour( colour ) );
@ -724,26 +652,19 @@ int main( int argc, char *argv[] )
have_output = true;
}
}
if ( have_output )
{
if ( have_output ) {
printf( "\n" );
}
if ( !function )
{
if ( !function ) {
Usage();
}
delete monitor;
}
else
{
} else {
fprintf( stderr, "Error, invalid monitor id %d\n", mon_id );
exit( -1 );
}
}
else
{
if ( function & ZMU_QUERY )
{
} else {
if ( function & ZMU_QUERY ) {
#if ZM_HAS_V4L
char vidString[0x10000] = "";
bool ok = LocalCamera::GetCurrentSettings( device, vidString, v4lVersion, verbose );
@ -755,24 +676,20 @@ int main( int argc, char *argv[] )
#endif // ZM_HAS_V4L
}
if ( function & ZMU_LIST )
{
if ( function & ZMU_LIST ) {
std::string sql = "select Id, Function+0 from Monitors";
if ( !verbose )
{
if ( !verbose ) {
sql += "where Function != 'None'";
}
sql += " order by Id asc";
if ( mysql_query( &dbconn, sql.c_str() ) )
{
if ( mysql_query( &dbconn, sql.c_str() ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
MYSQL_RES *result = mysql_store_result( &dbconn );
if ( !result )
{
if ( !result ) {
Error( "Can't use query result: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
@ -780,17 +697,13 @@ int main( int argc, char *argv[] )
Debug( 1, "Got %d monitors", n_monitors );
printf( "%4s%5s%6s%9s%14s%6s%6s%8s%8s\n", "Id", "Func", "State", "TrgState", "LastImgTim", "RdIdx", "WrIdx", "LastEvt", "FrmRate" );
for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ )
{
for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) {
int mon_id = atoi(dbrow[0]);
int function = atoi(dbrow[1]);
if ( !user || user->canAccess( mon_id ) )
{
if ( function > 1 )
{
if ( !user || user->canAccess( mon_id ) ) {
if ( function > 1 ) {
Monitor *monitor = Monitor::Load( mon_id, false, Monitor::QUERY );
if ( monitor && monitor->connect() )
{
if ( monitor && monitor->connect() ) {
struct timeval tv = monitor->GetTimestamp();
printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8d%8.2f\n",
monitor->Id(),
@ -805,9 +718,7 @@ int main( int argc, char *argv[] )
);
delete monitor;
}
}
else
{
} else {
struct timeval tv = { 0, 0 };
printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8d%8.2f\n",
mon_id,

View File

@ -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
commonprep () {
mkdir -p build
@ -46,7 +63,7 @@ commonprep () {
echo "Checking packpack github repo for changes..."
git -C packpack pull origin master
else
echo "Cloning pakcpack github repo..."
echo "Cloning packpack github repo..."
git clone https://github.com/packpack/packpack.git packpack
fi
@ -116,7 +133,7 @@ installtrusty () {
# This sets the naming convention for the deb packages
setdebpkgver () {
# Set VERSION to x.xx.x+x e.g. 1.30.2+15
# the last x is number of commits since release
# Creates zoneminder packages in the format: zoneminder-{version}-{release}
@ -125,6 +142,8 @@ setdebpkgver () {
export VERSION="$zmver+$commitnum"
export RELEASE="${DIST}"
checkvars
echo
echo "Packpack VERSION has been set to: ${VERSION}"
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 #
################
@ -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 RELEASE=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p')
checkvars
echo
echo "Packpack VERSION has been set to: ${VERSION}"
echo "Packpack RELEASE has been set to: ${RELEASE}"
@ -199,7 +230,9 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
else
ln -sfT distros/ubuntu1604 debian
fi
setdebchangelog
echo "Starting packpack..."
packpack/packpack
@ -218,6 +251,8 @@ elif [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86
ln -sfT distros/ubuntu1204 debian
setdebchangelog
echo "Starting packpack..."
packpack/packpack

View File

@ -1 +1 @@
1.30.4
1.31.0

View File

@ -100,12 +100,12 @@ App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
'engine' => 'File',
'types' => array('notice', 'info', 'debug'),
'file' => 'cake_debug',
'file' => '@ZM_LOGDIR@/cake_debug',
));
CakeLog::config('error', array(
'engine' => 'File',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => 'cake_error',
'file' => '@ZM_LOGDIR@/cake_error',
));
CakeLog::config('custom_path', array(
'engine' => 'File',

View File

@ -29,12 +29,15 @@ class Event {
Error('No row for Event ' . $IdOrRow );
}
} // end function __construct
public function Storage() {
return new Storage( isset($this->{'StorageId'}) ? $this->{'StorageId'} : NULL );
}
public function Monitor() {
return new Monitor( isset($this->{'MonitorId'}) ? $this->{'MonitorId'} : NULL );
}
public function __call( $fn, array $args){
if ( array_key_exists( $fn, $this ) ) {
return $this->{$fn};
@ -54,6 +57,7 @@ class Event {
$Storage = $this->Storage();
return $Storage->Path().'/'.$this->Relative_Path();
}
public function Relative_Path() {
$event_path = '';
@ -197,20 +201,26 @@ class Event {
return( $thumbData );
} // end function createListThumbnail
// frame is an array representing the db row for a frame.
function getImageSrc( $frame, $scale=SCALE_BASE, $captureOnly=false, $overwrite=false ) {
$Storage = new Storage( isset($this->{'StorageId'}) ? $this->{'StorageId'} : NULL );
$Event = $this;
$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'=>'' );
}
if ( file_exists( $eventPath.'/snapshot.jpg' ) ) {
$captImage = "snapshot.jpg";
if ( ( ! $frame ) and file_exists( $eventPath.'/snapshot.jpg' ) ) {
# No frame specified, so look for a snapshot to use
$captImage = 'snapshot.jpg';
Debug("Frame not specified, using snapshot");
} else {
$captImage = sprintf( '%0'.ZM_EVENT_IMAGE_DIGITS.'d-capture.jpg', $frame['FrameId'] );
if ( ! file_exists( $eventPath.'/'.$captImage ) ) {
# Generate the frame JPG
# Generate the frame JPG
if ( $Event->DefaultVideo() ) {
$videoPath = $eventPath.'/'.$Event->DefaultVideo();
@ -275,8 +285,7 @@ class Event {
}
$thumbFile = $thumbPath;
if ( $overwrite || !file_exists( $thumbFile ) || !filesize( $thumbFile ) )
{
if ( $overwrite || ! file_exists( $thumbFile ) || ! filesize( $thumbFile ) ) {
// Get new dimensions
list( $imageWidth, $imageHeight ) = getimagesize( $imagePath );
$thumbWidth = $imageWidth * $fraction;
@ -290,7 +299,7 @@ class Event {
if ( !imagejpeg( $thumbImage, $thumbPath ) )
Error( "Can't create thumbnail '$thumbPath'" );
}
}
} # Create thumbnails
$imageData = array(
'eventPath' => $eventPath,
@ -298,7 +307,7 @@ class Event {
'thumbPath' => $thumbPath,
'imageFile' => $imagePath,
'thumbFile' => $thumbFile,
'imageClass' => $alarmFrame?"alarm":"normal",
'imageClass' => $alarmFrame?'alarm':'normal',
'isAnalImage' => $isAnalImage,
'hasAnalImage' => $hasAnalImage,
);

View File

@ -27,9 +27,11 @@ class Frame {
Error("No row for Frame " . $IdOrRow );
}
} // end function __construct
public function Storage() {
return $this->Event()->Storage();
}
public function Event() {
return new Event( $this->{'EventId'} );
}
@ -70,7 +72,9 @@ class Frame {
}
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
public static function find( $parameters = array(), $limit = NULL ) {

File diff suppressed because it is too large Load Diff

View File

@ -177,7 +177,7 @@ isset($view) || $view = NULL;
isset($request) || $request = NULL;
isset($action) || $action = NULL;
if ( ZM_ENABLE_CSRF_MAGIC ) {
if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' ) {
Logger::Debug("Calling csrf_check with the following values: \$request = \"$request\", \$view = \"$view\", \$action = \"$action\"");
csrf_check();
}

View File

@ -1,7 +1,3 @@
#header {
width: 99%;
}
#layout {
margin-right: 10px;
}

View File

@ -1,7 +1,3 @@
#header {
width: 99%;
}
#layout {
margin-right: 10px;
}

View File

@ -21,31 +21,29 @@
// Only load new js & css in these views
$new_views = array('login');
function xhtmlHeaders( $file, $title )
{
global $css;
global $skin;
$skinCssFile = getSkinFile( 'css/'.$css.'/skin.css' );
$skinCssPhpFile = getSkinFile( 'css/'.$css.'/skin.css.php' );
function xhtmlHeaders( $file, $title ) {
global $css;
global $skin;
$skinCssFile = getSkinFile( 'css/'.$css.'/skin.css' );
$skinCssPhpFile = getSkinFile( 'css/'.$css.'/skin.css.php' );
$skinJsFile = getSkinFile( 'js/skin.js' );
$skinJsPhpFile = getSkinFile( 'js/skin.js.php' );
$cssJsFile = getSkinFile( 'js/'.$css.'.js' );
$skinJsFile = getSkinFile( 'js/skin.js' );
$skinJsPhpFile = getSkinFile( 'js/skin.js.php' );
$cssJsFile = getSkinFile( 'js/'.$css.'.js' );
$basename = basename( $file, '.php' );
$viewCssFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css' );
$viewCssPhpFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css.php' );
$viewJsFile = getSkinFile( 'views/js/'.$basename.'.js' );
$viewJsPhpFile = getSkinFile( 'views/js/'.$basename.'.js.php' );
$basename = basename( $file, '.php' );
$viewCssFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css' );
$viewCssPhpFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css.php' );
$viewJsFile = getSkinFile( 'views/js/'.$basename.'.js' );
$viewJsPhpFile = getSkinFile( 'views/js/'.$basename.'.js.php' );
extract( $GLOBALS, EXTR_OVERWRITE );
extract( $GLOBALS, EXTR_OVERWRITE );
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<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>
<link rel="icon" type="image/ico" href="graphics/favicon.ico"/>
<link rel="shortcut icon" href="graphics/favicon.ico"/>
@ -54,19 +52,17 @@ function xhtmlHeaders( $file, $title )
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css"/>
<link rel="stylesheet" href="<?php echo $skinCssFile ?>" type="text/css" media="screen"/>
<?php
if ( $viewCssFile )
{
if ( $viewCssFile ) {
?>
<link rel="stylesheet" href="<?php echo $viewCssFile ?>" type="text/css" media="screen"/>
<?php
}
if ( $viewCssPhpFile )
{
}
if ( $viewCssPhpFile ) {
?>
<style type="text/css">
/*<![CDATA[*/
<?php
require_once( $viewCssPhpFile );
require_once( $viewCssPhpFile );
?>
/*]]>*/
</style>
@ -99,9 +95,9 @@ var $j = jQuery.noConflict();
<script src="skins/<?php echo $skin ?>/js/video.js"></script>
<script src="./js/videojs.zoomrotate.js"></script>
<script src="skins/<?php echo $skin ?>/js/moment.min.js"></script>
<?php }
if ( $skinJsPhpFile )
{
<?php
}
if ( $skinJsPhpFile ) {
?>
<script type="text/javascript">
//<![CDATA[
@ -113,33 +109,31 @@ var $j = jQuery.noConflict();
//]]>
</script>
<?php
}
if ( $viewJsPhpFile )
{
}
if ( $viewJsPhpFile ) {
?>
<script type="text/javascript">
//<![CDATA[
<!--
<?php
require_once( $viewJsPhpFile );
require_once( $viewJsPhpFile );
?>
//-->
//]]>
</script>
<?php
}
}
if ( $cssJsFile ) {
?>
<script type="text/javascript" src="<?php echo $cssJsFile ?>"></script>
<?php } ?>
<script type="text/javascript" src="<?php echo $skinJsFile ?>"></script>
<?php
if ( $viewJsFile )
{
if ( $viewJsFile ) {
?>
<script type="text/javascript" src="<?php echo $viewJsFile ?>"></script>
<?php
}
}
?>
</head>
<?php

View File

@ -23,49 +23,49 @@ $servers = Server::find_all();
$eventCounts = array(
array(
"title" => translate('Events'),
"filter" => array(
"terms" => array(
'title' => translate('Events'),
'filter' => array(
'terms' => array(
)
),
),
array(
"title" => translate('Hour'),
"filter" => array(
"terms" => array(
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 hour" ),
'title' => translate('Hour'),
'filter' => array(
'terms' => array(
array( 'attr' => 'DateTime', 'op' => '>=', 'val' => '-1 hour' ),
)
),
),
array(
"title" => translate('Day'),
"filter" => array(
"terms" => array(
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 day" ),
'title' => translate('Day'),
'filter' => array(
'terms' => array(
array( 'attr' => "DateTime", 'op' => '>=', 'val' => '-1 day' ),
)
),
),
array(
"title" => translate('Week'),
"filter" => array(
"terms" => array(
array( "attr" => "DateTime", "op" => ">=", "val" => "-7 day" ),
'title' => translate('Week'),
'filter' => array(
'terms' => array(
array( 'attr' => "DateTime", 'op' => '>=', 'val' => '-7 day' ),
)
),
),
array(
"title" => translate('Month'),
"filter" => array(
"terms" => array(
array( "attr" => "DateTime", "op" => ">=", "val" => "-1 month" ),
'title' => translate('Month'),
'filter' => array(
'terms' => array(
array( 'attr' => "DateTime", 'op' => '>=', 'val' => '-1 month' ),
)
),
),
array(
"title" => translate('Archived'),
"filter" => array(
"terms" => array(
array( "attr" => "Archived", "op" => "=", "val" => "1" ),
'title' => translate('Archived'),
'filter' => array(
'terms' => array(
array( 'attr' => "Archived", 'op' => '=', 'val' => '1' ),
)
),
),
@ -103,12 +103,12 @@ for ( $i = 0; $i < count($monitors); $i++ ) {
$monitors[$i]['ZoneCount'] = dbFetchOne( 'select count(Id) as ZoneCount from Zones where MonitorId = ?', 'ZoneCount', array($monitors[$i]['Id']) );
$counts = array();
for ( $j = 0; $j < count($eventCounts); $j++ ) {
$filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['terms']), array( "cnj" => "and", "attr" => "MonitorId", "op" => "=", "val" => $monitors[$i]['Id'] ) );
$filter = addFilterTerm( $eventCounts[$j]['filter'], count($eventCounts[$j]['filter']['terms']), array( 'cnj' => 'and', 'attr' => 'MonitorId', 'op' => '=', 'val' => $monitors[$i]['Id'] ) );
parseFilter( $filter );
$counts[] = "count(if(1".$filter['sql'].",1,NULL)) as EventCount$j";
$counts[] = 'count(if(1'.$filter['sql'].",1,NULL)) as EventCount$j";
$monitors[$i]['eventCounts'][$j]['filter'] = $filter;
}
$sql = "select ".join($counts,", ")." from Events as E where MonitorId = ?";
$sql = 'SELECT '.join($counts,', ').' FROM Events AS E WHERE MonitorId = ?';
$counts = dbFetchOne( $sql, NULL, array($monitors[$i]['Id']) );
if ( $monitors[$i]['Function'] != 'None' ) {
$cycleCount++;
@ -157,7 +157,7 @@ xhtmlHeaders( __FILE__, translate('Console') );
<h3 id="systemStats"><?php echo translate('Load') ?>: <?php echo getLoad() ?> - <?php echo translate('Disk') ?>: <?php echo getDiskPercent() ?>% - <?php echo ZM_PATH_MAP ?>: <?php echo getDiskPercent(ZM_PATH_MAP) ?>%</h3>
<h2 id="title"><a href="http://www.zoneminder.com" target="ZoneMinder">ZoneMinder</a> <?php echo translate('Console') ?> - <?php echo makePopupLink( '?view=state', 'zmState', 'state', $status, canEdit( 'System' ) ) ?> - <?php echo $run_state ?> <?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="'.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?></h2>
<div class="clear"></div>
<h3 id="development"><center><?php echo ZM_WEB_CONSOLE_BANNER ?></center></h3>
<?php if ( ZM_WEB_CONSOLE_BANNER ) { ?><h3 id="development"><?php echo ZM_WEB_CONSOLE_BANNER ?></h3><?php } ?>
<div id="monitorSummary"><?php echo makePopupLink( '?view=groups', 'zmGroups', 'groups', sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ).($group?' ('.$group['Name'].')':''), canView( 'Groups' ) ); ?></div>
<?php
if ( ZM_OPT_X10 && canView( 'Devices' ) ) {
@ -179,21 +179,18 @@ if ( canView( 'Stream' ) && $cycleCount > 1 ) {
<?php echo makePopupLink( '?view=montagereview&amp;group='.$cycleGroup, 'zmMontage'.$cycleGroup, 'montagereview', translate('Montage Review'), $running ) ?>
</div>
<?php
} else {
?>
<?php
}
?>
<h3 id="loginBandwidth"><?php
if ( ZM_OPT_USE_AUTH ) {
?><?php echo translate('LoggedInAs') ?> <?php echo makePopupLink( '?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == "builtin") ) ?>, <?php echo strtolower( translate('ConfiguredFor') ) ?><?php
?><?php echo translate('LoggedInAs') ?> <?php echo makePopupLink( '?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == 'builtin') ) ?>, <?php echo strtolower( translate('ConfiguredFor') ) ?><?php
} else {
?><?php echo translate('ConfiguredFor') ?><?php
}
?>&nbsp;<?php echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', $bwArray[$_COOKIE['zmBandwidth']], ($user && $user['MaxBandwidth'] != 'low' ) ) ?> <?php echo translate('BandwidthHead') ?></h3>
</div>
<div id="content">
<table id="consoleTable" cellspacing="0">
<table id="consoleTable">
<thead>
<tr>
<?php if ( ZM_WEB_ID_ON_CONSOLE ) { ?>
@ -206,38 +203,16 @@ if ( ZM_OPT_USE_AUTH ) {
<?php } ?>
<th class="colSource"><?php echo translate('Source') ?></th>
<?php
for ( $i = 0; $i < count($eventCounts); $i++ ) {
for ( $i = 0; $i < count($eventCounts); $i++ ) {
?>
<th class="colEvents"><?php echo $eventCounts[$i]['title'] ?></th>
<?php
}
}
?>
<th class="colZones"><?php echo translate('Zones') ?></th>
<th class="colMark"><?php echo translate('Mark') ?></th>
</tr>
</thead>
<tfoot>
<tr>
<td class="colLeftButtons" colspan="<?php echo $left_columns ?>">
<input type="button" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
<input type="button" 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&amp;filter[terms][0][attr]=DateTime&amp;filter[terms][0][op]=%3c&amp;filter[terms][0][val]=now', 'zmFilter', 'filter', translate('Filters'), canView( 'Events' ) ) ?>
<input type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/>
<input 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.'&amp;page=1'.$eventCounts[$i]['filter']['query'], $eventsWindow, $eventsView, $eventCounts[$i]['total'], canView( 'Events' ) ) ?></td>
<?php
}
?>
<td class="colZones"><?php echo $zoneCount ?></td>
<td class="colMark"></td>
</tr>
</tfoot>
<tbody id="consoleTableBody">
<?php
foreach( $displayMonitors as $monitor ) {
@ -245,22 +220,22 @@ foreach( $displayMonitors as $monitor ) {
<tr id="<?php echo 'monitor_id-'.$monitor['Id'] ?>">
<?php
if ( !$monitor['zmc'] ) {
$dclass = "errorText";
$dclass = 'errorText';
} else {
// https://github.com/ZoneMinder/ZoneMinder/issues/1082
if ( !$monitor['zma'] && $monitor['Function']!='Monitor' )
$dclass = "warnText";
$dclass = 'warnText';
else
$dclass = "infoText";
$dclass = 'infoText';
}
if ( $monitor['Function'] == 'None' )
$fclass = "errorText";
$fclass = 'errorText';
//elseif ( $monitor['Function'] == 'Monitor' )
// $fclass = "warnText";
// $fclass = 'warnText';
else
$fclass = "infoText";
$fclass = 'infoText';
if ( !$monitor['Enabled'] )
$fclass .= " disabledText";
$fclass .= ' disabledText';
$scale = max( reScale( SCALE_BASE, $monitor['DefaultScale'], ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
?>
<?php if ( ZM_WEB_ID_ON_CONSOLE ) { ?>
@ -310,6 +285,28 @@ echo $Server->Name();
}
?>
</tbody>
<tfoot>
<tr>
<td class="colLeftButtons" colspan="<?php echo $left_columns ?>">
<input type="button" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
<input type="button" 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 type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/>
<input 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.'&amp;page=1'.$eventCounts[$i]['filter']['query'], $eventsWindow, $eventsView, $eventCounts[$i]['total'], canView( 'Events' ) ) ?></td>
<?php
}
?>
<td class="colZones"><?php echo $zoneCount ?></td>
<td class="colMark"></td>
</tr>
</tfoot>
</table>
</div>
</form>

View File

@ -18,35 +18,32 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canView( 'Control' ) )
{
$view = "error";
return;
if ( !canView( 'Control' ) ) {
$view = 'error';
return;
}
$groupSql = "";
$groupSql = '';
if ( !empty($_REQUEST['group']) ) {
$row = dbFetchOne( 'SELECT * FROM Groups WHERE Id = ?', NULL, array($_REQUEST['group']) );
$groupSql = " and find_in_set( Id, '".$row['MonitorIds']."' )";
$row = dbFetchOne( 'SELECT * FROM Groups WHERE Id = ?', NULL, array($_REQUEST['group']) );
$groupSql = " and find_in_set( Id, '".$row['MonitorIds']."' )";
}
$mid = validInt($_REQUEST['mid']);
$mid = !empty($_REQUEST['mid']) ? validInt($_REQUEST['mid']) : 0;
$sql = "SELECT * FROM Monitors WHERE Function != 'None' AND Controllable = 1$groupSql ORDER BY Sequence";
$mids = array();
foreach( dbFetchAll( $sql ) as $row )
{
if ( !visibleMonitor( $row['Id'] ) )
{
continue;
}
if ( empty($mid) )
$mid = $row['Id'];
$mids[$row['Id']] = $row['Name'];
foreach( dbFetchAll( $sql ) as $row ) {
if ( !visibleMonitor( $row['Id'] ) ) {
continue;
}
if ( empty($mid) )
$mid = $row['Id'];
$mids[$row['Id']] = $row['Name'];
}
foreach ( getSkinIncludes( 'includes/control_functions.php' ) as $includeFile )
require_once $includeFile;
require_once $includeFile;
$monitor = new Monitor( $mid );
@ -70,7 +67,7 @@ xhtmlHeaders(__FILE__, translate('Control') );
</div>
<div id="content">
<div id="ptzControls" class="ptzControls">
<?php echo ptzControls( $monitor ) ?>
<?php echo ptzControls( $monitor ) ?>
</div>
</div>
</div>

View File

@ -18,71 +18,49 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canView( 'Stream' ) )
{
$view = "error";
return;
if ( !canView( 'Stream' ) ) {
$view = 'error';
return;
}
if ( empty($_REQUEST['mode']) )
{
if ( canStream() )
$mode = "stream";
else
$mode = "still";
}
else
{
$mode = validHtmlStr($_REQUEST['mode']);
if ( empty($_REQUEST['mode']) ) {
if ( canStream() )
$mode = 'stream';
else
$mode = 'still';
} else {
$mode = validHtmlStr($_REQUEST['mode']);
}
$group = '';
$groupSql = '';
if ( !empty($_REQUEST['group']) )
{
$group = validInt($_REQUEST['group']);
$row = dbFetchOne( 'SELECT * FROM Groups WHERE Id = ?', NULL, array($group) );
$groupSql = " and find_in_set( Id, '".$row['MonitorIds']."' )";
if ( !empty($_REQUEST['group']) ) {
$group = validInt($_REQUEST['group']);
$row = dbFetchOne( 'SELECT * FROM Groups WHERE Id = ?', NULL, array($group) );
$groupSql = " and find_in_set( Id, '".$row['MonitorIds']."' )";
}
$sql = "SELECT * FROM Monitors WHERE Function != 'None'$groupSql ORDER BY Sequence";
$monitors = array();
$monIdx = 0;
foreach( dbFetchAll( $sql ) as $row )
{
if ( !visibleMonitor( $row['Id'] ) )
continue;
if ( isset($_REQUEST['mid']) && $row['Id'] == $_REQUEST['mid'] )
$monIdx = count($monitors);
$row['ScaledWidth'] = reScale( $row['Width'], $row['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
$row['ScaledHeight'] = reScale( $row['Height'], $row['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
$monitors[] = $row;
foreach( dbFetchAll( $sql ) as $row ) {
if ( !visibleMonitor( $row['Id'] ) )
continue;
if ( isset($_REQUEST['mid']) && $row['Id'] == $_REQUEST['mid'] )
$monIdx = count($monitors);
$row['ScaledWidth'] = reScale( $row['Width'], $row['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
$row['ScaledHeight'] = reScale( $row['Height'], $row['DefaultScale'], ZM_WEB_DEFAULT_SCALE );
$monitors[] = new Monitor( $row );
}
$monitor = $monitors[$monIdx];
$nextMid = $monIdx==(count($monitors)-1)?$monitors[0]['Id']:$monitors[$monIdx+1]['Id'];
$montageWidth = $monitor['ScaledWidth'];
$montageHeight = $monitor['ScaledHeight'];
$widthScale = ($montageWidth*SCALE_BASE)/$monitor['Width'];
$heightScale = ($montageHeight*SCALE_BASE)/$monitor['Height'];
$nextMid = $monIdx==(count($monitors)-1)?$monitors[0]->Id():$monitors[$monIdx+1]->Id();
$montageWidth = $monitor->ScaledWidth();
$montageHeight = $monitor->ScaledHeight();
$widthScale = ($montageWidth*SCALE_BASE)/$monitor->Width();
$heightScale = ($montageHeight*SCALE_BASE)/$monitor->Height();
$scale = (int)(($widthScale<$heightScale)?$widthScale:$heightScale);
if ( false && (ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT) )
{
$streamMode = "mpeg";
$streamSrc = getStreamSrc( array( "mode=".$streamMode, "monitor=".$monitor['Id'], "scale=".$scale, "bitrate=".ZM_WEB_VIDEO_BITRATE, "maxfps=".ZM_WEB_VIDEO_MAXFPS, "format=".ZM_MPEG_LIVE_FORMAT ) );
}
elseif ( $mode == 'stream' && canStream() )
{
$streamMode = "jpeg";
$streamSrc = getStreamSrc( array( "mode=".$streamMode, "monitor=".$monitor['Id'], "scale=".$scale, "maxfps=".ZM_WEB_VIDEO_MAXFPS ) );
}
else
{
$streamMode = "single";
$streamSrc = getStreamSrc( array( "mode=".$streamMode, "monitor=".$monitor['Id'], "scale=".$scale ) );
}
noCacheHeaders();
$focusWindow = true;
@ -94,33 +72,17 @@ xhtmlHeaders(__FILE__, translate('CycleWatch') );
<div id="header">
<div id="headerButtons">
<?php if ( $mode == "stream" ) { ?>
<a href="?view=<?php echo $view ?>&amp;mode=still&amp;group=<?php echo $group ?>&amp;mid=<?php echo $monitor['Id'] ?>"><?php echo translate('Stills') ?></a>
<a href="?view=<?php echo $view ?>&amp;mode=still&amp;group=<?php echo $group ?>&amp;mid=<?php echo $monitor->Id() ?>"><?php echo translate('Stills') ?></a>
<?php } else { ?>
<a href="?view=<?php echo $view ?>&amp;mode=stream&amp;group=<?php echo $group ?>&amp;mid=<?php echo $monitor['Id'] ?>"><?php echo translate('Stream') ?></a>
<a href="?view=<?php echo $view ?>&amp;mode=stream&amp;group=<?php echo $group ?>&amp;mid=<?php echo $monitor->Id() ?>"><?php echo translate('Stream') ?></a>
<?php } ?>
<a href="#" onclick="closeWindow(); return( false );"><?php echo translate('Close') ?></a>
</div>
<h2><?php echo translate('Cycle') ?> - <?php echo validHtmlStr($monitor['Name']) ?></h2>
<h2><?php echo translate('Cycle') ?> - <?php echo validHtmlStr($monitor->Name()) ?></h2>
</div>
<div id="content">
<div id="imageFeed">
<?php
if ( $streamMode == "mpeg" )
{
outputVideoStream( "liveStream", $streamSrc, reScale( $monitor['Width'], $scale ), reScale( $monitor['Height'], $scale ), ZM_MPEG_LIVE_FORMAT, validHtmlStr($monitor['Name']) );
}
elseif ( $streamMode == "jpeg" )
{
if ( canStreamNative() )
outputImageStream( "liveStream", $streamSrc, reScale( $monitor['Width'], $scale ), reScale( $monitor['Height'], $scale ), validHtmlStr($monitor['Name']) );
elseif ( canStreamApplet() )
outputHelperStream( "liveStream", $streamSrc, reScale( $monitor['Width'], $scale ), reScale( $monitor['Height'], $scale ), validHtmlStr($monitor['Name']) );
}
else
{
outputImageStill( "liveStream", $streamSrc, reScale( $monitor['Width'], $scale ), reScale( $monitor['Height'], $scale ), validHtmlStr($monitor['Name']) );
}
?>
<?php echo getStreamHTML( $monitor, array( 'scale'=>$scale, 'mode'=>$mode ) ); ?>
</div>
</div>
</div>

View File

@ -18,76 +18,70 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canView( 'Events' ) || (!empty($_REQUEST['execute']) && !canEdit('Events')) )
{
$view = "error";
return;
if ( !canView( 'Events' ) || (!empty($_REQUEST['execute']) && !canEdit('Events')) ) {
$view = 'error';
return;
}
require_once( 'includes/Event.php' );
if ( !empty($_REQUEST['execute']) )
{
executeFilter( $tempFilterName );
if ( !empty($_REQUEST['execute']) ) {
executeFilter( $tempFilterName );
}
$countSql = 'SELECT count(E.Id) AS EventCount FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId) WHERE';
$eventsSql = 'SELECT E.*,M.Name AS MonitorName FROM Monitors AS M INNER JOIN Events AS E on (M.Id = E.MonitorId) WHERE';
$eventsSql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale FROM Monitors AS M INNER JOIN Events AS E on (M.Id = E.MonitorId) WHERE';
if ( $user['MonitorIds'] ) {
$user_monitor_ids = ' M.Id in ('.$user['MonitorIds'].')';
$countSql .= $user_monitor_ids;
$eventsSql .= $user_monitor_ids;
} else {
$countSql .= " 1";
$eventsSql .= " 1";
$countSql .= " 1";
$eventsSql .= " 1";
}
parseSort();
parseFilter( $_REQUEST['filter'] );
$filterQuery = $_REQUEST['filter']['query'];
if ( $_REQUEST['filter']['sql'] )
{
$countSql .= $_REQUEST['filter']['sql'];
$eventsSql .= $_REQUEST['filter']['sql'];
if ( $_REQUEST['filter']['sql'] ) {
$countSql .= $_REQUEST['filter']['sql'];
$eventsSql .= $_REQUEST['filter']['sql'];
}
$eventsSql .= " ORDER BY $sortColumn $sortOrder";
if ( isset($_REQUEST['page']) )
$page = validInt($_REQUEST['page']);
$page = validInt($_REQUEST['page']);
else
$page = 0;
$page = 0;
if ( isset($_REQUEST['limit']) )
$limit = validInt($_REQUEST['limit']);
$limit = validInt($_REQUEST['limit']);
else
$limit = 0;
$limit = 0;
$nEvents = dbFetchOne( $countSql, 'EventCount' );
if ( !empty($limit) && $nEvents > $limit )
{
$nEvents = $limit;
if ( !empty($limit) && $nEvents > $limit ) {
$nEvents = $limit;
}
$pages = (int)ceil($nEvents/ZM_WEB_EVENTS_PER_PAGE);
if ( !empty($page) ) {
if ( $page < 0 )
$page = 1;
if ( $page > $pages )
$page = $pages;
if ( $page < 0 )
$page = 1;
else if ( $page > $pages )
$page = $pages;
}
if ( !empty($page) ) {
$limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE);
if ( empty( $limit ) )
{
$limitAmount = ZM_WEB_EVENTS_PER_PAGE;
}
else
{
$limitLeft = $limit - $limitStart;
$limitAmount = ($limitLeft>ZM_WEB_EVENTS_PER_PAGE)?ZM_WEB_EVENTS_PER_PAGE:$limitLeft;
}
$eventsSql .= " limit $limitStart, $limitAmount";
$limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE);
if ( empty( $limit ) ) {
$limitAmount = ZM_WEB_EVENTS_PER_PAGE;
} else {
$limitLeft = $limit - $limitStart;
$limitAmount = ($limitLeft>ZM_WEB_EVENTS_PER_PAGE)?ZM_WEB_EVENTS_PER_PAGE:$limitLeft;
}
$eventsSql .= " limit $limitStart, $limitAmount";
} elseif ( !empty( $limit ) ) {
$eventsSql .= " limit 0, ".$limit;
$eventsSql .= ' limit 0, '.$limit;
}
$maxWidth = 0;
@ -95,20 +89,19 @@ $maxHeight = 0;
$archived = false;
$unarchived = false;
$events = array();
foreach ( dbFetchAll( $eventsSql ) as $event_row )
{
$events[] = $event = new Event( $event_row );
foreach ( dbFetchAll( $eventsSql ) as $event_row ) {
$events[] = $event = new Event( $event_row );
# Doesn this code do anything?
$scale = max( reScale( SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
$eventWidth = reScale( $event_row['Width'], $scale );
$eventHeight = reScale( $event_row['Height'], $scale );
if ( $maxWidth < $eventWidth ) $maxWidth = $eventWidth;
if ( $maxHeight < $eventHeight ) $maxHeight = $eventHeight;
if ( $event_row['Archived'] )
$archived = true;
else
$unarchived = true;
# Doesn this code do anything?
$scale = max( reScale( SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
$eventWidth = reScale( $event_row['Width'], $scale );
$eventHeight = reScale( $event_row['Height'], $scale );
if ( $maxWidth < $eventWidth ) $maxWidth = $eventWidth;
if ( $maxHeight < $eventHeight ) $maxHeight = $eventHeight;
if ( $event_row['Archived'] )
$archived = true;
else
$unarchived = true;
}
$maxShortcuts = 5;
@ -124,20 +117,16 @@ xhtmlHeaders(__FILE__, translate('Events') );
<div id="header">
<div id="headerButtons">
<?php
if ( $pages > 1 )
{
if ( !empty($page) )
{
if ( $pages > 1 ) {
if ( !empty($page) ) {
?>
<a href="?view=<?php echo $view ?>&amp;page=0<?php echo $filterQuery ?><?php echo $sortQuery ?>&amp;limit=<?php echo $limit ?>"><?php echo translate('ViewAll') ?></a>
<?php
}
else
{
} else {
?>
<a href="?view=<?php echo $view ?>&amp;page=1<?php echo $filterQuery ?><?php echo $sortQuery ?>&amp;limit=<?php echo $limit ?>"><?php echo translate('ViewPaged') ?></a>
<?php
}
}
}
?>
<a href="#" onclick="closeWindows();"><?php echo translate('Close') ?></a>
@ -154,8 +143,7 @@ if ( $pages > 1 )
<input type="hidden" name="sort_asc" value="<?php echo validHtmlStr($_REQUEST['sort_asc']) ?>"/>
<input type="hidden" name="limit" value="<?php echo $limit ?>"/>
<?php
if ( $pagination )
{
if ( $pagination ) {
?>
<h3 class="pagination"><?php echo $pagination ?></h3>
<?php
@ -170,10 +158,8 @@ if ( $pagination )
<tbody>
<?php
$count = 0;
foreach ( $events as $event )
{
if ( ($count++%ZM_WEB_EVENTS_PER_PAGE) == 0 )
{
foreach ( $events as $event ) {
if ( ($count++%ZM_WEB_EVENTS_PER_PAGE) == 0 ) {
?>
<tr>
<th class="colId"><a href="<?php echo sortHeader( 'Id' ) ?>"><?php echo translate('Id') ?><?php echo sortTag( 'Id' ) ?></a></th>
@ -187,22 +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="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>
<?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>
<?php
}
if ( ZM_WEB_LIST_THUMBS )
{
}
if ( ZM_WEB_LIST_THUMBS ) {
?>
<th class="colThumbnail"><?php echo translate('Thumbnail') ?></th>
<?php
}
}
?>
<th class="colMark"><input type="checkbox" name="toggleCheck" value="1" onclick="toggleCheckbox( this, 'markEids' );"<?php if ( !canEdit( 'Events' ) ) { ?> disabled="disabled"<?php } ?>/></th>
</tr>
<?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>
<td class="colId"><?php echo makePopupLink( '?view=event&amp;eid='.$event->Id().$filterQuery.$sortQuery.'&amp;page=1', 'zmEvent', array( 'event', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), $event->Id().($event->Archived()?'*':'') ) ?></td>
@ -216,25 +202,37 @@ foreach ( $events as $event )
<td class="colTotScore"><?php echo $event->TotScore() ?></td>
<td class="colAvgScore"><?php echo $event->AvgScore() ?></td>
<td class="colMaxScore"><?php echo makePopupLink( '?view=frame&amp;eid='.$event->Id().'&amp;fid=0', 'zmImage', array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), $event->MaxScore() ) ?></td>
<?php if ( ZM_WEB_EVENT_DISK_SPACE ) { ?>
<td class="colDiskSpace"><?php echo $event->DiskSpace() ?></td>
<?php
}
if ( ZM_WEB_LIST_THUMBS )
{
if ( $thumbData = $event->createListThumbnail() )
{
if ( ZM_WEB_EVENT_DISK_SPACE ) {
?>
<td class="colThumbnail"><?php echo makePopupLink( '?view=frame&amp;eid='.$event->Id().'&amp;fid='.$thumbData['FrameId'], 'zmImage', array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), '<img src="?view=image&amp;eid='.$event->Id().'&amp;fid='.$thumbData['FrameId'].'&amp;width='.$thumbData['Width'].'&amp;height='.$thumbData['Height'].'" width="'.$thumbData['Width'].'" height="'.$thumbData['Height'].'" alt="'.$thumbData['FrameId'].'/'.$event->MaxScore().'"/>' ) ?></td>
<td class="colDiskSpace"><?php echo human_filesize( $event->DiskSpace() ) ?></td>
<?php
}
else
{
}
if ( ZM_WEB_LIST_THUMBS ) {
if ( $thumbData = $event->createListThumbnail() ) {
?>
<td class="colThumbnail">
<?php
$imgSrc = '?view=image&amp;eid='.$event->Id().'&amp;fid='.$thumbData['FrameId'].'&amp;width='.$thumbData['Width'].'&amp;height='.$thumbData['Height'];
$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.'\';"/>';
echo makePopupLink(
'?view=frame&amp;eid='.$event->Id().'&amp;fid='.$thumbData['FrameId'],
'zmImage',
array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ),
$imgHtml
);
?>
</td>
<?php
} else {
?>
<td class="colThumbnail">&nbsp;</td>
<?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>
</tr>
@ -244,14 +242,12 @@ foreach ( $events as $event )
</tbody>
</table>
<?php
if ( $pagination )
{
if ( $pagination ) {
?>
<h3 class="pagination"><?php echo $pagination ?></h3>
<?php
}
if ( true || canEdit( 'Events' ) )
{
if ( true || canEdit( 'Events' ) ) {
?>
<div id="contentButtons">
<input type="button" name="viewBtn" value="<?php echo translate('View') ?>" onclick="viewEvents( this, 'markEids' );" disabled="disabled"/>

View File

@ -18,34 +18,31 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canView( 'Events' ) )
{
$view = "error";
return;
if ( !canView( 'Events' ) ) {
$view = 'error';
return;
}
$selectName = "filterName";
$selectName = 'filterName';
$filterNames = array( ''=>translate('ChooseFilter') );
foreach ( dbFetchAll( "select * from Filters order by Name" ) as $row )
{
$filterNames[$row['Name']] = $row['Name'];
if ( $row['Background'] )
$filterNames[$row['Name']] .= "*";
if ( !empty($_REQUEST['reload']) && isset($_REQUEST['filterName']) && $_REQUEST['filterName'] == $row['Name'] )
$dbFilter = $row;
foreach ( dbFetchAll( 'select * from Filters order by Name' ) as $row ) {
$filterNames[$row['Name']] = $row['Name'];
if ( $row['Background'] )
$filterNames[$row['Name']] .= '*';
if ( !empty($_REQUEST['reload']) && isset($_REQUEST['filterName']) && $_REQUEST['filterName'] == $row['Name'] )
$dbFilter = $row;
}
$backgroundStr = "";
if ( isset($dbFilter) )
{
if ( $dbFilter['Background'] )
$backgroundStr = '['.strtolower(translate('Background')).']';
$_REQUEST['filter'] = jsonDecode( $dbFilter['Query'] );
$_REQUEST['sort_field'] = isset($_REQUEST['filter']['sort_field'])?$_REQUEST['filter']['sort_field']:"DateTime";
$_REQUEST['sort_asc'] = isset($_REQUEST['filter']['sort_asc'])?$_REQUEST['filter']['sort_asc']:"1";
$_REQUEST['limit'] = isset($_REQUEST['filter']['limit'])?$_REQUEST['filter']['limit']:"";
unset( $_REQUEST['filter']['sort_field'] );
unset( $_REQUEST['filter']['sort_asc'] );
unset( $_REQUEST['filter']['limit'] );
$backgroundStr = '';
if ( isset($dbFilter) ) {
if ( $dbFilter['Background'] )
$backgroundStr = '['.strtolower(translate('Background')).']';
$_REQUEST['filter'] = jsonDecode( $dbFilter['Query'] );
$_REQUEST['sort_field'] = isset($_REQUEST['filter']['sort_field'])?$_REQUEST['filter']['sort_field']:"DateTime";
$_REQUEST['sort_asc'] = isset($_REQUEST['filter']['sort_asc'])?$_REQUEST['filter']['sort_asc']:"1";
$_REQUEST['limit'] = isset($_REQUEST['filter']['limit'])?$_REQUEST['filter']['limit']:"";
unset( $_REQUEST['filter']['sort_field'] );
unset( $_REQUEST['filter']['sort_asc'] );
unset( $_REQUEST['filter']['limit'] );
}
# reload is set when the dropdown is changed.
@ -64,16 +61,14 @@ if ( isset( $_REQUEST['reload'] ) and ! $_REQUEST['reload'] ) {
$conjunctionTypes = array(
'and' => translate('ConjAnd'),
'or' => translate('ConjOr')
);
);
$obracketTypes = array();
$cbracketTypes = array();
if ( isset($_REQUEST['filter']['terms']) )
{
for ( $i = 0; $i <= count($_REQUEST['filter']['terms'])-2; $i++ )
{
$obracketTypes[$i] = str_repeat( "(", $i );
$cbracketTypes[$i] = str_repeat( ")", $i );
}
if ( isset($_REQUEST['filter']['terms']) ) {
for ( $i = 0; $i <= count($_REQUEST['filter']['terms'])-2; $i++ ) {
$obracketTypes[$i] = str_repeat( "(", $i );
$cbracketTypes[$i] = str_repeat( ")", $i );
}
}
$attrTypes = array(
@ -98,7 +93,7 @@ $attrTypes = array(
'DiskBlocks' => translate('AttrDiskBlocks'),
'SystemLoad' => translate('AttrSystemLoad'),
'ServerId' => translate('AttrServer'),
);
);
$opTypes = array(
'=' => translate('OpEq'),
'!=' => translate('OpNe'),
@ -110,15 +105,14 @@ $opTypes = array(
'!~' => translate('OpNotMatches'),
'=[]' => translate('OpIn'),
'![]' => translate('OpNotIn'),
);
);
$archiveTypes = array(
'0' => translate('ArchUnarchived'),
'1' => translate('ArchArchived')
);
);
$weekdays = array();
for ( $i = 0; $i < 7; $i++ )
{
$weekdays[$i] = strftime( "%A", mktime( 12, 0, 0, 1, $i+1, 2001 ) );
for ( $i = 0; $i < 7; $i++ ) {
$weekdays[$i] = strftime( '%A', mktime( 12, 0, 0, 1, $i+1, 2001 ) );
}
$sort_fields = array(
'Id' => translate('AttrId'),
@ -133,13 +127,12 @@ $sort_fields = array(
'TotScore' => translate('AttrTotalScore'),
'AvgScore' => translate('AttrAvgScore'),
'MaxScore' => translate('AttrMaxScore'),
);
);
$sort_dirns = array(
'1' => translate('SortAsc'),
'0' => translate('SortDesc')
);
if ( empty($_REQUEST['sort_field']) )
{
);
if ( empty($_REQUEST['sort_field']) ) {
$_REQUEST['sort_field'] = ZM_WEB_EVENT_SORT_FIELD;
$_REQUEST['sort_asc'] = (ZM_WEB_EVENT_SORT_ORDER == "asc");
}
@ -174,105 +167,93 @@ xhtmlHeaders(__FILE__, translate('EventFilter') );
<table id="fieldsTable" class="filterTable" cellspacing="0">
<tbody>
<?php
for ( $i = 0; isset($_REQUEST['filter']) && $i < count($_REQUEST['filter']['terms']); $i++ )
{
for ( $i = 0; isset($_REQUEST['filter']) && $i < count($_REQUEST['filter']['terms']); $i++ ) {
?>
<tr>
<?php
if ( $i == 0 )
{
if ( $i == 0 ) {
?>
<td>&nbsp;</td>
<?php
}
else
{
} else {
?>
<td><?php echo buildSelect( "filter[terms][$i][cnj]", $conjunctionTypes ); ?></td>
<?php
}
}
?>
<td><?php if ( count($_REQUEST['filter']['terms']) > 2 ) { echo buildSelect( "filter[terms][$i][obr]", $obracketTypes ); } else { ?>&nbsp;<?php } ?></td>
<td><?php echo buildSelect( "filter[terms][$i][attr]", $attrTypes, "clearValue( this, $i ); submitToFilter( this, 0 );" ); ?></td>
<?php
if ( isset($_REQUEST['filter']['terms'][$i]['attr']) )
{
if ( $_REQUEST['filter']['terms'][$i]['attr'] == "Archived" )
{
if ( isset($_REQUEST['filter']['terms'][$i]['attr']) ) {
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 buildSelect( "filter[terms][$i][val]", $archiveTypes ); ?></td>
<?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><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
}
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><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
}
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][val]", $weekdays ); ?></td>
<?php
} elseif ( false && $_REQUEST['filter']['terms'][$i]['attr'] == 'MonitorName' ) {
$monitors = array();
foreach ( dbFetchAll( "select Id,Name from Monitors order by Sequence asc" ) as $monitor ) {
if ( visibleMonitor( $monitor['Id'] ) ) {
$monitors[$monitor['Name']] = $monitor['Name'];
}
elseif ( false && $_REQUEST['filter']['terms'][$i]['attr'] == "MonitorName" )
{
$monitors = array();
foreach ( dbFetchAll( "select Id,Name from Monitors order by Sequence asc" ) as $monitor )
{
if ( visibleMonitor( $monitor['Id'] ) )
{
$monitors[$monitor['Name']] = $monitor['Name'];
}
}
}
?>
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
<td><?php echo buildSelect( "filter[terms][$i][val]", $monitors ); ?></td>
<?php
}
elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == "ServerId" )
{
$servers = array();
$servers['ZM_SERVER_ID'] = 'Current Server';
foreach ( dbFetchAll( "SELECT Id,Name FROM Servers ORDER BY lower(Name) ASC" ) as $server ) {
$servers[$server['Id']] = $server['Name'];
}
} elseif ( $_REQUEST['filter']['terms'][$i]['attr'] == 'ServerId' ) {
$servers = array();
$servers['ZM_SERVER_ID'] = 'Current Server';
foreach ( dbFetchAll( 'SELECT Id,Name FROM Servers ORDER BY lower(Name) ASC' ) as $server ) {
$servers[$server['Id']] = $server['Name'];
}
?>
<td><?php echo buildSelect( "filter[terms][$i][op]", $opTypes ); ?></td>
<td><?php echo buildSelect( "filter[terms][$i][val]", $servers ); ?></td>
<?php
}
else
{
} else {
?>
<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>
<?php
}
}
else
{
} else {
?>
<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>
<?php
}
}
?>
<td><?php if ( count($_REQUEST['filter']['terms']) > 2 ) { echo buildSelect( "filter[terms][$i][cbr]", $cbracketTypes ); } else { ?>&nbsp;<?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>
<?php
}
} # end foreach filter
?>
</tbody>
</table>
@ -346,9 +327,9 @@ if ( ZM_OPT_MESSAGE )
<input type="button" name="executeButton" id="executeButton" value="<?php echo translate('Execute') ?>" onclick="executeFilter( this );"/>
<?php if ( canEdit( 'Events' ) ) { ?>
<input type="button" value="<?php echo translate('Save') ?>" onclick="saveFilter( this );"/>
<?php } ?>
<?php if ( canEdit( 'Events' ) && isset($dbFilter) && $dbFilter['Name'] ) { ?>
<?php if ( isset($dbFilter) && $dbFilter['Name'] ) { ?>
<input type="button" value="<?php echo translate('Delete') ?>" onclick="deleteFilter( this, '<?php echo $dbFilter['Name'] ?>' );"/>
<?php } ?>
<?php } ?>
<input type="button" value="<?php echo translate('Reset') ?>" onclick="submitToFilter( this, 1 );"/>
</div>

View File

@ -19,15 +19,15 @@
//
if ( !canView( 'Events' ) ) {
$view = "error";
return;
$view = 'error';
return;
}
require_once('includes/Frame.php');
$eid = validInt($_REQUEST['eid']);
if ( !empty($_REQUEST['fid']) )
$fid = validInt($_REQUEST['fid']);
$fid = validInt($_REQUEST['fid']);
$Event = new Event( $eid );
$Monitor = $Event->Monitor();
@ -37,7 +37,7 @@ if ( !empty($fid) ) {
if ( !($frame = dbFetchOne( $sql, NULL, array($eid, $fid) )) )
$frame = array( 'FrameId'=>$fid, 'Type'=>'Normal', 'Score'=>0 );
} 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 );
@ -60,16 +60,27 @@ if ( isset( $_REQUEST['scale'] ) ) {
$scale = max( reScale( SCALE_BASE, $Monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
}
$imageData = $Event->getImageSrc( $frame, $scale, (isset($_REQUEST['show']) && $_REQUEST['show']=="capt") );
$imageData = $Event->getImageSrc( $frame, $scale, 0 );
if ( ! $imageData ) {
Error("No data found for Event $eid frame $fid");
$imageData = array();
}
$show = 'capt';
if ( isset($_REQUEST['show']) ) {
$show = $_REQUEST['show'];
} else if ( $imageData['hasAnalImage'] ) {
$show = 'anal';
}
$imagePath = $imageData['thumbPath'];
$eventPath = $imageData['eventPath'];
$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() );
$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() );
$focusWindow = true;
xhtmlHeaders(__FILE__, translate('Frame')." - ".$Event->Id()." - ".$Frame->FrameId() );
xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id()." - ".$Frame->FrameId() );
?>
<body>
<div id="page">
@ -88,33 +99,29 @@ xhtmlHeaders(__FILE__, translate('Frame')." - ".$Event->Id()." - ".$Frame->Frame
</div>
<div id="content">
<p id="image">
<?php if ( in_array($event['VideoWriter'],array("1","2")) ) { ?>
<img src="?view=image-ffmpeg&eid=<?php echo $event['Id'] ?>&fid=<?php echo $frame['FrameId'] ?>&scale=<?php echo $event['DefaultScale'] ?>" class="<?php echo $imageData['imageClass'] ?>">
<?php } else {
if ( $imageData['hasAnalImage'] ) { ?>
<a href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $Frame->FrameId() ?>&amp;scale=<?php echo $scale ?>&amp;show=<?php echo $imageData['isAnalImage']?"capt":"anal" ?>">
<?php } ?>
<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'] ) {
echo sprintf('<a href="?view=frame&amp;eid=%d&amp;fid=%d&scale=%d&amp;show=%s">', $Event->Id(), $Frame->FrameId(), $scale, ( $show=='anal'?'capt':'anal' ) );
} ?>
<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'] ?>"/>
<?php if ( $imageData['hasAnalImage'] ) { ?></a><?php } ?>
<?php } ?>
</p>
</p>
<p id="controls">
<?php if ( $Frame->FrameId() > 1 ) { ?>
<a id="firstLink" href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $firstFid ?>&amp;scale=<?php echo $scale ?>"><?php echo translate('First') ?></a>
<?php } if ( $Frame->FrameId() > 1 ) { ?>
<a id="prevLink" href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $prevFid ?>&amp;scale=<?php echo $scale ?>"><?php echo translate('Prev') ?></a>
<a id="firstLink" href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $firstFid ?>&amp;scale=<?php echo $scale ?>&amp;show=<?php echo $show ?>"><?php echo translate('First') ?></a>
<a id="prevLink" href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $prevFid ?>&amp;scale=<?php echo $scale ?>&amp;show=<?php echo $show ?>"><?php echo translate('Prev') ?></a>
<?php } if ( $Frame->FrameId() < $maxFid ) { ?>
<a id="nextLink" href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $nextFid ?>&amp;scale=<?php echo $scale ?>"><?php echo translate('Next') ?></a>
<?php } if ( $Frame->FrameId() < $maxFid ) { ?>
<a id="lastLink" href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $lastFid ?>&amp;scale=<?php echo $scale ?>"><?php echo translate('Last') ?></a>
<a id="nextLink" href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $nextFid ?>&amp;scale=<?php echo $scale ?>&amp;show=<?php echo $show ?>"><?php echo translate('Next') ?></a>
<a id="lastLink" href="?view=frame&amp;eid=<?php echo $Event->Id() ?>&amp;fid=<?php echo $lastFid ?>&amp;scale=<?php echo $scale ?>&amp;show=<?php echo $show ?>"><?php echo translate('Last') ?></a>
<?php } ?>
</p>
<?php if (file_exists ($dImagePath)) { ?>
<p id="diagImagePath"><?php echo $dImagePath ?></p>
<p id="diagImage"><img src=?"<?php echo viewImagePath( $dImagePath ) ?>" width="<?php echo reScale( $Event->Width(), $Event->DefaultScale(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $Event->DefaultScale(), $scale ) ?>" class="<?php echo $imageData['imageClass'] ?>"/></p>
<p id="diagImage"><img src="<?php echo viewImagePath( $dImagePath ) ?>" width="<?php echo reScale( $Event->Width(), $Monitor->DefaultScale(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $Monitor->DefaultScale(), $scale ) ?>" class="<?php echo $imageData['imageClass'] ?>"/></p>
<?php } if (file_exists ($rImagePath)) { ?>
<p id="refImagePath"><?php echo $rImagePath ?></p>
<p id="refImage"><img src="<?php echo viewImagePath( $rImagePath ) ?>" width="<?php echo reScale( $Event->Width(), $Event->DefaultScale(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $Event->DefaultScale(), $scale ) ?>" class="<?php echo $imageData['imageClass'] ?>"/></p>
<p id="refImage"><img src="<?php echo viewImagePath( $rImagePath ) ?>" width="<?php echo reScale( $Event->Width(), $Monitor->DefaultScale(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $Monitor->DefaultScale(), $scale ) ?>" class="<?php echo $imageData['imageClass'] ?>"/></p>
<?php } ?>
</div>
</div>

View File

@ -7,13 +7,13 @@ function updateButtons( element ) {
var canExecute = false;
if ( form.elements['AutoArchive'].checked )
canExecute = true;
else if ( typeof ZM_OPT_FFMPEG !== "undefined" && form.elements['AutoVideo'].checked )
else if ( form.elements['AutoVideo'] && form.elements['AutoVideo'].checked )
canExecute = true;
else if ( typeof ZM_OPT_UPLOAD !== "undefined" && form.elements['AutoUpload'].checked )
else if ( form.elements['AutoUpload'] && form.elements['AutoUpload'].checked )
canExecute = true;
else if ( typeof ZM_OPT_EMAIL !== "undefined" && form.elements['AutoEmail'].checked )
else if ( form.elements['AutoEmail'] && form.elements['AutoEmail'].checked )
canExecute = true;
else if ( typeof ZM_OPT_MESSAGE !== "undefined" && form.elements['AutoMessage'].checked )
else if ( form.elements['AutoMessage'] && form.elements['AutoMessage'].checked )
canExecute = true;
else if ( form.elements['AutoExecute'].checked && form.elements['AutoExecuteCmd'].value != '' )
canExecute = true;

View File

@ -94,7 +94,7 @@ function previewEvent( eventId, frameId ) {
if ( event['frames'] ) {
if ( event['frames'][frameId] ) {
showEventDetail( event['frames'][frameId]['html'] );
var imagePath = event.frames[frameId].Image.imagePath;
var imagePath = '/index.php?view=image&eid='+eventId+'&fid='+frameId;
var videoName = event.DefaultVideo;
loadEventImage( imagePath, eventId, frameId, event.Width, event.Height, event.Frames/event.Length, videoName, event.Length, event.StartTime, monitors[event.MonitorId]);
return;
@ -107,13 +107,13 @@ function previewEvent( eventId, frameId ) {
function loadEventImage( imagePath, eid, fid, width, height, fps, videoName, duration, startTime, Monitor ) {
var vid= $('preview');
var imageSrc = $('imageSrc');
if(videoName) {
if ( videoName && vid ) {
vid.show();
imageSrc.hide();
var newsource=imagePrefix+imagePath.slice(0,imagePath.lastIndexOf('/'))+"/"+videoName;
var newsource=imagePath.slice(0,imagePath.lastIndexOf('/'))+"/"+videoName;
//console.log(newsource);
//console.log(sources[0].src.slice(-newsource.length));
if(newsource!=vid.currentSrc.slice(-newsource.length) || vid.readyState==0) {
if ( newsource != vid.currentSrc.slice(-newsource.length) || vid.readyState == 0 ) {
//console.log("loading new");
//it is possible to set a long source list here will that be unworkable?
var sources = vid.getElementsByTagName('source');
@ -126,13 +126,13 @@ function loadEventImage( imagePath, eid, fid, width, height, fps, videoName, dur
addVideoTimingTrack(vid, Monitor.LabelFormat, Monitor.Name, duration, startTime)
vid.currentTime = fid/fps;
} else {
if(!vid.seeking)
if ( ! vid.seeking )
vid.currentTime=fid/fps;
}
} else {
vid.hide();
if ( vid ) vid.hide();
imageSrc.show();
imageSrc.setProperty( 'src', imagePrefix+imagePath );
imageSrc.setProperty( 'src', imagePath );
imageSrc.removeEvent( 'click' );
imageSrc.addEvent( 'click', showEvent.pass( [ eid, fid, width, height ] ) );
}

View File

@ -31,7 +31,7 @@ function changeScale() {
Cookie.write( 'zmWatchScale'+monitorId, scale, { duration: 10*365 } );
/*Stream could be an applet so can't use moo tools*/
var streamImg = document.getElementById('liveStream');
var streamImg = document.getElementById('liveStream'+monitorId);
if ( streamImg ) {
streamImg.style.width = newWidth + "px";
streamImg.style.height = newHeight + "px";
@ -146,14 +146,14 @@ function getStreamCmdResponse( respObj, respText ) {
streamCmdSlowRev( false );
else
streamCmdFastRev( false );
}
} // rate
} else {
$('modeValue').set( 'text', "Live" );
$('rate').addClass( 'hidden' );
$('delay').addClass( 'hidden' );
$('level').addClass( 'hidden' );
streamCmdPlay( false );
}
} // end if paused or delayed
$('zoomValue').set( 'text', streamStatus.zoom );
if ( streamStatus.zoom == "1.0" )
setButtonState( $('zoomOutBtn'), 'unavail' );
@ -538,13 +538,8 @@ function controlCmdImage( x, y ) {
fetchImage.pass( $('imageFeed').getElement('img') ).delay( 1000 );
}
var tempImage = null;
function fetchImage( streamImage ) {
var now = new Date();
if ( !tempImage )
tempImage = new Element( 'img' );
tempImage.setProperty( 'src', streamSrc+'&'+now.getTime() );
$(streamImage).setProperty( 'src', tempImage.getProperty( 'src' ) );
streamImage.src = streamImage.src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
}
function handleClick( event ) {

View File

@ -52,8 +52,6 @@ var monitorUrl = '<?php echo ( $monitor->Server()->Url() ) ?>';
var scale = <?php echo $scale ?>;
var streamSrc = "<?php echo preg_replace( '/&amp;/', '&', $streamSrc ) ?>";
var statusRefreshTimeout = <?php echo 1000*ZM_WEB_REFRESH_STATUS ?>;
var eventsRefreshTimeout = <?php echo 1000*ZM_WEB_REFRESH_EVENTS ?>;
var imageRefreshTimeout = <?php echo 1000*ZM_WEB_REFRESH_IMAGE ?>;

File diff suppressed because it is too large Load Diff

View File

@ -18,9 +18,8 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canView( 'Monitors' ) )
{
$view = "error";
if ( !canView( 'Monitors' ) ) {
$view = 'error';
return;
}
@ -34,29 +33,25 @@ $hicolor = '0x00ff00'; // Green
$presets = array();
$presetNames = array();
$presetNames[0] = translate('ChoosePreset');
$sql = "select *, Units-1 as UnitsIndex, CheckMethod-1 as CheckMethodIndex from ZonePresets order by Id asc";
foreach( dbFetchAll( $sql ) as $preset )
{
$presetNames[$preset['Id']] = $preset['Name'];
$presets[] = $preset;
$sql = 'SELECT *, Units-1 AS UnitsIndex, CheckMethod-1 AS CheckMethodIndex FROM ZonePresets ORDER BY Id ASC';
foreach( dbFetchAll( $sql ) as $preset ) {
$presetNames[$preset['Id']] = $preset['Name'];
$presets[] = $preset;
}
$optTypes = array();
foreach ( getEnumValues( 'Zones', 'Type' ) as $optType )
{
$optTypes[$optType] = $optType;
foreach ( getEnumValues( 'Zones', 'Type' ) as $optType ) {
$optTypes[$optType] = $optType;
}
$optUnits = array();
foreach ( getEnumValues( 'Zones', 'Units' ) as $optUnit )
{
$optUnits[$optUnit] = $optUnit;
foreach ( getEnumValues( 'Zones', 'Units' ) as $optUnit ) {
$optUnits[$optUnit] = $optUnit;
}
$optCheckMethods = array();
foreach ( getEnumValues( 'Zones', 'CheckMethod' ) as $optCheckMethod )
{
$optCheckMethods[$optCheckMethod] = $optCheckMethod;
foreach ( getEnumValues( 'Zones', 'CheckMethod' ) as $optCheckMethod ) {
$optCheckMethods[$optCheckMethod] = $optCheckMethod;
}
$monitor = new Monitor( $mid );
@ -66,14 +61,10 @@ $maxX = $monitor->Width()-1;
$minY = 0;
$maxY = $monitor->Height()-1;
if ( !isset($newZone) )
{
if ( $zid > 0 )
{
if ( !isset($newZone) ) {
if ( $zid > 0 ) {
$zone = dbFetchOne( 'SELECT * FROM Zones WHERE MonitorId = ? AND Id=?', NULL, array( $monitor->Id(), $zid ) );
}
else
{
} else {
$zone = array(
'Id' => 0,
'Name' => translate('New'),
@ -104,17 +95,16 @@ if ( !isset($newZone) )
$zone['AreaCoords'] = preg_replace( '/\s+/', ',', $zone['Coords'] );
$newZone = $zone;
}
} # end if new Zone
//if ( !$points )
//{
//$points = $zone['Points'];
//}
# Ensure Zone fits within the limits of the Monitor
limitPoints( $newZone['Points'], $minX, $minY, $maxX, $maxY );
ksort( $newZone['Points'], SORT_NUMERIC );
$newZone['Coords'] = pointsToCoords( $newZone['Points'] );
$newZone['Area'] = getPolyArea( $newZone['Points'] );
$newZone['AreaCoords'] = preg_replace( '/\s+/', ',', $newZone['Coords'] );
$selfIntersecting = isSelfIntersecting( $newZone['Points'] );
$focusWindow = true;
@ -122,7 +112,7 @@ $connkey = generateConnKey();
$streamSrc = '';
$streamMode = '';
# Have to do this here, because the .js.php references somethings figured out when generating the streamHTML
$StreamHTML = getStreamHTML( $monitor, $scale );
$StreamHTML = getStreamHTML( $monitor, array('scale'=>$scale) );
xhtmlHeaders(__FILE__, translate('Zone') );
?>
@ -162,7 +152,13 @@ xhtmlHeaders(__FILE__, translate('Zone') );
</tr>
<tr>
<th scope="row"><?php echo translate('ZoneAlarmColour') ?></th>
<td colspan="2"><input type="text" name="newAlarmRgbR" value="<?php echo ($newZone['AlarmRGB']>>16)&0xff ?>" size="3" onchange="limitRange( this, 0, 255 )"/>&nbsp;/&nbsp;<input type="text" name="newAlarmRgbG" value="<?php echo ($newZone['AlarmRGB']>>8)&0xff ?>" size="3" onchange="limitRange( this, 0, 255 )"/>&nbsp;/&nbsp;<input type="text" name="newAlarmRgbB" value="<?php echo $newZone['AlarmRGB']&0xff ?>" size="3" onchange="limitRange( this, 0, 255 )"/></td>
<td colspan="2">
<input type="text" name="newAlarmRgbR" value="<?php echo ($newZone['AlarmRGB']>>16)&0xff ?>" size="3" onchange="limitRange( this, 0, 255 )"/>
/
<input type="text" name="newAlarmRgbG" value="<?php echo ($newZone['AlarmRGB']>>8)&0xff ?>" size="3" onchange="limitRange( this, 0, 255 )"/>
/
<input type="text" name="newAlarmRgbB" value="<?php echo $newZone['AlarmRGB']&0xff ?>" size="3" onchange="limitRange( this, 0, 255 )"/>
</td>
</tr>
<tr>
<th scope="row"><?php echo translate('CheckMethod') ?></th>

View File

@ -18,23 +18,27 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canView( 'Monitors' ) )
{
$view = "error";
return;
if ( !canView( 'Monitors' ) ) {
$view = 'error';
return;
}
$mid = validInt($_REQUEST['mid']);
$monitor = new Monitor( $mid );
# Width() and Height() are already rotated
$minX = 0;
$maxX = $monitor->Width()-1;
$minY = 0;
$maxY = $monitor->Height()-1;
$zones = array();
foreach( dbFetchAll( 'select * from Zones where MonitorId = ? order by Area desc', NULL, array($mid) ) as $row )
{
if ( $row['Points'] = coordsToPoints( $row['Coords'] ) )
{
$row['AreaCoords'] = preg_replace( '/\s+/', ',', $row['Coords'] );
$zones[] = $row;
}
foreach( dbFetchAll( 'SELECT * FROM Zones WHERE MonitorId=? ORDER BY Area DESC', NULL, array($mid) ) as $row ) {
$row['Points'] = coordsToPoints( $row['Coords'] );
limitPoints( $row['Points'], $minX, $minY, $maxX, $maxY );
$row['Coords'] = pointsToCoords( $row['Points'] );
$row['AreaCoords'] = preg_replace( '/\s+/', ',', $row['Coords'] );
$zones[] = $row;
}
$connkey = generateConnKey();
@ -48,21 +52,14 @@ xhtmlHeaders(__FILE__, translate('Zones') );
<h2><?php echo translate('Zones') ?></h2>
</div>
<div id="content" style="width:<?php echo $monitor->Width() ?>px; height:<?php echo $monitor->Height() ?>px; position:relative; margin: 0 auto;">
<?php echo getStreamHTML( $monitor ); ?>
<svg class="zones" width="<?php echo $monitor->Width() ?>" height="<?php echo $monitor->Height() ?>" style="position:absolute; top: 0; left: 0; background: none;">
<?php
foreach( array_reverse($zones) as $zone ) {
?>
<polygon points="<?php echo $zone['AreaCoords'] ?>" class="<?php echo $zone['Type']?>" onclick="streamCmdQuit( true ); createPopup( '?view=zone&amp;mid=<?php echo $mid ?>&amp;zid=<?php echo $zone['Id'] ?>', 'zmZone', 'zone', <?php echo $monitor->Width ?>, <?php echo $monitor->Height ?> ); return( false );"/>
<?php
} // end foreach zone
?>
Sorry, your browser does not support inline SVG
</svg>
<form name="contentForm" id="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="hidden" name="view" value="<?php echo $view ?>"/>
<input type="hidden" name="action" value="delete"/>
<input type="hidden" name="mid" value="<?php echo $mid ?>"/>
<div id="contentButtons">
<input type="button" value="<?php echo translate('AddNewZone') ?>" onclick="createPopup( '?view=zone&amp;mid=<?php echo $mid ?>&amp;zid=0', 'zmZone', 'zone', <?php echo $monitor->Width() ?>, <?php echo $monitor->Height() ?> );"<?php if ( !canEdit( 'Monitors' ) ) { ?> disabled="disabled"<?php } ?>/>
<input type="submit" name="deleteBtn" value="<?php echo translate('Delete') ?>" disabled="disabled"/>
</div>
<table id="contentTable" class="major" cellspacing="0">
<thead>
<tr>
@ -88,9 +85,18 @@ foreach( $zones as $zone )
?>
</tbody>
</table>
<div id="contentButtons">
<input type="button" value="<?php echo translate('AddNewZone') ?>" onclick="createPopup( '?view=zone&amp;mid=<?php echo $mid ?>&amp;zid=0', 'zmZone', 'zone', <?php echo $monitor->Width() ?>, <?php echo $monitor->Height() ?> );"<?php if ( !canEdit( 'Monitors' ) ) { ?> disabled="disabled"<?php } ?>/>
<input type="submit" name="deleteBtn" value="<?php echo translate('Delete') ?>" disabled="disabled"/>
<div class="ZonesImage" style="position:relative; clear:both;">
<?php echo getStreamHTML( $monitor ); ?>
<svg class="zones" width="<?php echo $monitor->Width() ?>" height="<?php echo $monitor->Height() ?>" style="position:absolute; top: 0; left: 0; background: none;">
<?php
foreach( array_reverse($zones) as $zone ) {
?>
<polygon points="<?php echo $zone['AreaCoords'] ?>" class="<?php echo $zone['Type']?>" onclick="streamCmdQuit( true ); createPopup( '?view=zone&amp;mid=<?php echo $mid ?>&amp;zid=<?php echo $zone['Id'] ?>', 'zmZone', 'zone', <?php echo $monitor->Width ?>, <?php echo $monitor->Height ?> ); return( false );"/>
<?php
} // end foreach zone
?>
Sorry, your browser does not support inline SVG
</svg>
</div>
</form>
</div>

View File

@ -32,136 +32,183 @@
// If both scale and either width or height are specified, scale is ignored
//
if ( !canView( 'Events' ) )
{
$view = "error";
return;
if ( !canView( 'Events' ) ) {
$view = 'error';
return;
}
require_once('includes/Event.php');
require_once('includes/Frame.php');
header( 'Content-type: image/jpeg' );
// Compatibility for PHP 5.4
if (!function_exists('imagescale'))
{
function imagescale($image, $new_width, $new_height = -1, $mode = 0)
{
$mode; // Not supported
if (!function_exists('imagescale')) {
function imagescale($image, $new_width, $new_height = -1, $mode = 0) {
$mode; // Not supported
$new_height = ($new_height == -1) ? imagesy($image) : $new_height;
$imageNew = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($imageNew, $image, 0, 0, 0, 0, (int)$new_width, (int)$new_height, imagesx($image), imagesy($image));
return $imageNew;
}
$new_height = ($new_height == -1) ? imagesy($image) : $new_height;
$imageNew = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($imageNew, $image, 0, 0, 0, 0, (int)$new_width, (int)$new_height, imagesx($image), imagesy($image));
return $imageNew;
}
}
$errorText = false;
if ( empty($_REQUEST['path']) )
{
$filename = '';
$Frame = null;
$Event = null;
$path = null;
if ( empty($_REQUEST['path']) ) {
if ( ! empty($_REQUEST['fid']) ) {
$show = empty($_REQUEST['show']) ? 'capture' : $_REQUEST['show'];
if ( ! empty($_REQUEST['eid'] ) ) {
$Event = new Event( $_REQUEST['eid'] );
$Frame = Frame::find_one( array( 'EventId' => $_REQUEST['eid'], 'FrameId' => $_REQUEST['fid'] ) );
if ( ! $Frame ) {
Fatal("No Frame found for event(".$_REQUEST['eid'].") and frame id(".$_REQUEST['fid'].")");
}
$path = $Event->Path().'/'.sprintf("%'.0".ZM_EVENT_IMAGE_DIGITS.'d',$_REQUEST['fid']).'-'.$show.'.jpg';
} else {
# If we are only specifying fid, then the fid must be the primary key into the frames table. But when the event is specified, then it is the frame #
$Frame = new Frame( $_REQUEST['fid'] );
$Event = new Event( $Frame->EventId() );
$path = $Event->Path().'/'.sprintf("%'.0".ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
}
$path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg';
} else {
Fatal("No Frame ID specified");
header("HTTP/1.0 404 Not Found");
return;
}
if ( ! file_exists( $path ) ) {
Logger::Debug( "$path does not exist");
# Generate the frame JPG
if ( $show == 'capture' and $Event->DefaultVideo() ) {
$command ='ffmpeg -ss '. $Frame->Delta() .' -i '.$Event->Path().'/'.$Event->DefaultVideo().' -frames:v 1 '.$path;
#$command ='ffmpeg -ss '. $Frame->Delta() .' -i '.$Event->Path().'/'.$Event->DefaultVideo().' -vf "select=gte(n\\,'.$Frame->FrameId().'),setpts=PTS-STARTPTS" '.$path;
#$command ='ffmpeg -v 0 -i '.$Storage->Path().'/'.$Event->Path().'/'.$Event->DefaultVideo().' -vf "select=gte(n\\,'.$Frame->FrameId().'),setpts=PTS-STARTPTS" '.$path;
Logger::Debug( "Running $command" );
$output = array();
$retval = 0;
exec( $command, $output, $retval );
Logger::Debug("Command: $command, retval: $retval, output: " . implode("\n", $output));
if ( ! file_exists( $path ) ) {
header('HTTP/1.0 404 Not Found');
Fatal("Can't create frame images from video for this event (".$Event->DefaultVideo() );
}
} else {
header('HTTP/1.0 404 Not Found');
Fatal("Can't create frame images from video becuase there is no video file for this event (".$Event->DefaultVideo() );
}
}
} else {
Warning('Loading images by path is deprecated');
$dir_events = realpath(ZM_DIR_EVENTS);
$path = realpath($dir_events . '/' . $_REQUEST['path']);
$pos = strpos($path, $dir_events);
if ( $pos == 0 && $pos !== false ) {
if ( ! empty( $user['MonitorIds'] ) ) {
$imageOk = false;
$pathMonId = substr( $path, 0, strspn( $path, '1234567890' ) );
foreach ( preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) as $monId ) {
if ( $pathMonId == $monId ) {
$imageOk = true;
break;
}
}
if ( !$imageOk )
$errorText = 'No image permissions';
}
} else {
$errorText = "No image path";
$errorText = 'Invalid image path';
}
if ( ! file_exists( $path ) ) {
header('HTTP/1.0 404 Not Found');
Fatal("Image not found at $path");
}
} else {
$dir_events = realpath(ZM_DIR_EVENTS);
$path = realpath($dir_events . '/' . $_REQUEST['path']);
$pos = strpos($path, $dir_events);
if($pos == 0 && $pos !== false) {
if ( !empty($user['MonitorIds']) ) {
$imageOk = false;
$pathMonId = substr( $path, 0, strspn( $path, "1234567890" ) );
foreach ( preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) as $monId ) {
if ( $pathMonId == $monId ) {
$imageOk = true;
break;
}
}
if ( !$imageOk )
$errorText = "No image permissions";
}
} else {
$errorText = "Invalid image path";
}
}
$scale=0;
if( !empty($_REQUEST['scale']) )
if (is_numeric($_REQUEST['scale']))
{
$x = $_REQUEST['scale'];
if($x >= 1 and $x <= 400)
$scale=$x;
}
if( !empty($_REQUEST['scale']) ) {
if (is_numeric($_REQUEST['scale'])) {
$x = $_REQUEST['scale'];
if($x >= 1 and $x <= 400)
$scale=$x;
}
}
$width=0;
if( !empty($_REQUEST['width']) )
if (is_numeric($_REQUEST['width']))
{
$x = $_REQUEST['width'];
if($x >= 10 and $x <= 8000)
$width=$x;
}
if ( !empty($_REQUEST['width']) ) {
if (is_numeric($_REQUEST['width'])) {
$x = $_REQUEST['width'];
if($x >= 10 and $x <= 8000)
$width=$x;
}
}
$height=0;
if( !empty($_REQUEST['height']) )
if (is_numeric($_REQUEST['height']))
{
$x = $_REQUEST['height'];
if($x >= 10 and $x <= 8000)
$height=$x;
}
if( !empty($_REQUEST['height']) ) {
if (is_numeric($_REQUEST['height'])) {
$x = $_REQUEST['height'];
if($x >= 10 and $x <= 8000)
$height=$x;
}
}
header( 'Content-type: image/jpeg' );
if ( $errorText )
Error( $errorText );
else
if( ($scale==0 || $scale==100) && $width==0 && $height==0 )
readfile( $path );
else
{
$i = imagecreatefromjpeg ( $path );
$oldWidth=imagesx($i);
$oldHeight=imagesy($i);
if($width==0 && $height==0) // scale has to be set to get here with both zero
{
$width = $oldWidth * $scale / 100.0;
$height= $oldHeight * $scale / 100.0;
}
elseif ($width==0 && $height!=0)
{
$width = ($height * $oldWidth) / $oldHeight;
}
elseif ($width!=0 && $height==0)
{
$height = ($width * $oldHeight) / $oldWidth;
}
if($width==$oldWidth && $height==$oldHeight) // See if we really need to scale
{
imagejpeg($i);
imagedestroy($i);
}
else // we do need to scale
{
$iScale = imagescale($i, $width, $height);
imagejpeg($iScale);
imagedestroy($i);
imagedestroy($iScale);
}
# This is so that Save Image As give a useful filename
if ( $Event ) {
$filename = $Event->MonitorId().'_'.$Event->Id().'_'.$Frame->FrameId().'.jpg';
header('Content-Disposition: inline; filename="' . $filename . '"');
}
ob_clean();
flush();
if ( $errorText ) {
Error( $errorText );
} else {
if ( ( $scale==0 || $scale==100 ) && $width==0 && $height==0 ) {
if ( ! readfile( $path ) ) {
Error("No bytes read from ". $path );
}
?>
} else {
Logger::Debug("Doing a scaled image: scale($scale) width($width) height($height)");
$i = 0;
if ( ! ( $width && $height ) ) {
$i = imagecreatefromjpeg( $path );
$oldWidth = imagesx( $i );
$oldHeight = imagesy( $i );
if ( $width == 0 && $height == 0 ) { // scale has to be set to get here with both zero
$width = $oldWidth * $scale / 100.0;
$height= $oldHeight * $scale / 100.0;
} elseif ( $width == 0 && $height != 0 ) {
$width = ($height * $oldWidth) / $oldHeight;
} elseif ( $width != 0 && $height == 0 ) {
$height = ($width * $oldHeight) / $oldWidth;
}
if ( $width == $oldWidth && $height == $oldHeight) {
Warning( 'No change to width despite scaling.' );
}
}
# Slight optimisation, thumbnails always specify width and height, so we can cache them.
$scaled_path = preg_replace('/\.jpg$/', "-${width}x${height}.jpg", $path );
if ( ! file_exists( $scaled_path ) or ! readfile( $scaled_path ) ) {
Logger::Debug( "Cached scaled image does not exist at $scaled_path or is no good.. Creating it");
ob_start();
if ( ! $i )
$i = imagecreatefromjpeg( $path );
$iScale = imagescale( $i, $width, $height );
imagejpeg( $iScale );
imagedestroy( $i );
imagedestroy( $iScale );
$scaled_jpeg_data = ob_get_contents();
file_put_contents( $scaled_path, $scaled_jpeg_data );
ob_end_clean();
echo $scaled_jpeg_data;
}
}
}