Merge branch 'master' into dragndrop_monitor_sorting
This commit is contained in:
commit
b4bdc1fd6b
|
@ -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
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
zoneminder (1.28.1-1) unstable; urgency=low
|
||||
|
||||
This version is no longer automatically initialize or upgrade database.
|
||||
See README.Debian for details.
|
||||
|
||||
Changed installation paths (please correct your web server configuration):
|
||||
/usr/share/zoneminder --> /usr/share/zoneminder/www
|
||||
/usr/lib/cgi-bin --> /usr/lib/zoneminder/cgi-bin
|
||||
|
||||
-- Dmitry Smirnov <onlyjob@debian.org> Tue, 31 Mar 2015 15:12:17 +1100
|
|
@ -1,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
|
|
@ -1,2 +0,0 @@
|
|||
default_cgi-path.patch
|
||||
use_libjs-mootools.patch
|
|
@ -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 )
|
|
@ -1 +1 @@
|
|||
3.0 (native)
|
||||
3.0 (quilt)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
default_cgi-path.patch
|
||||
use_libjs-mootools.patch
|
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
3.0 (native)
|
||||
3.0 (quilt)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
missingok
|
||||
notifempty
|
||||
sharedscripts
|
||||
delaycompress
|
||||
compress
|
||||
postrotate
|
||||
/usr/bin/zmpkg.pl logrot >>/dev/null 2>&1 || :
|
||||
endscript
|
||||
|
|
|
@ -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"
|
||||
|
|
@ -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
|
@ -45,8 +45,7 @@ use ZoneMinder::Config qw(:all);
|
|||
|
||||
use Time::HiRes qw( usleep );
|
||||
|
||||
sub new
|
||||
{
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $id = shift;
|
||||
my $self = ZoneMinder::Control->new( $id );
|
||||
|
@ -57,21 +56,18 @@ sub new
|
|||
|
||||
our $AUTOLOAD;
|
||||
|
||||
sub AUTOLOAD
|
||||
{
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $class = ref($self) || croak( "$self not object" );
|
||||
my $name = $AUTOLOAD;
|
||||
$name =~ s/.*://;
|
||||
if ( exists($self->{$name}) )
|
||||
{
|
||||
if ( exists($self->{$name}) ) {
|
||||
return( $self->{$name} );
|
||||
}
|
||||
Fatal( "Can't access $name member of object of class $class" );
|
||||
}
|
||||
|
||||
sub open
|
||||
{
|
||||
sub open {
|
||||
my $self = shift;
|
||||
|
||||
$self->loadMonitor();
|
||||
|
@ -83,14 +79,12 @@ sub open
|
|||
$self->{state} = 'open';
|
||||
}
|
||||
|
||||
sub close
|
||||
{
|
||||
sub close {
|
||||
my $self = shift;
|
||||
$self->{state} = 'closed';
|
||||
}
|
||||
|
||||
sub printMsg
|
||||
{
|
||||
sub printMsg {
|
||||
my $self = shift;
|
||||
my $msg = shift;
|
||||
my $msg_len = length($msg);
|
||||
|
@ -98,8 +92,7 @@ sub printMsg
|
|||
Debug( $msg."[".$msg_len."]" );
|
||||
}
|
||||
|
||||
sub sendCmd
|
||||
{
|
||||
sub sendCmd {
|
||||
my $self = shift;
|
||||
my $cmd = shift;
|
||||
|
||||
|
@ -117,28 +110,23 @@ sub sendCmd
|
|||
|
||||
my $res = $self->{ua}->request($req);
|
||||
|
||||
if ( $res->is_success )
|
||||
{
|
||||
if ( $res->is_success ) {
|
||||
$result = !undef;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Error( "Error check failed: '".$res->status_line()."'" );
|
||||
}
|
||||
|
||||
return( $result );
|
||||
}
|
||||
|
||||
sub reset
|
||||
{
|
||||
sub reset {
|
||||
my $self = shift;
|
||||
Debug( "Camera Reset" );
|
||||
my $cmd = "/admin/ptctl.cgi?move=reset";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveMap
|
||||
{
|
||||
sub moveMap {
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $xcoord = $self->getParam( $params, 'xcoord' );
|
||||
|
@ -189,8 +177,7 @@ sub moveMap
|
|||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelUp
|
||||
{
|
||||
sub moveRelUp {
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'tiltstep' );
|
||||
|
@ -199,8 +186,7 @@ sub moveRelUp
|
|||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelDown
|
||||
{
|
||||
sub moveRelDown {
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'tiltstep' );
|
||||
|
@ -209,28 +195,34 @@ sub moveRelDown
|
|||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelLeft
|
||||
{
|
||||
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 );
|
||||
|
||||
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
|
||||
{
|
||||
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 );
|
||||
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
|
||||
{
|
||||
sub presetClear {
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset = $self->getParam( $params, 'preset' );
|
||||
|
@ -239,8 +231,7 @@ sub presetClear
|
|||
#$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub presetSet
|
||||
{
|
||||
sub presetSet {
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset = $self->getParam( $params, 'preset' );
|
||||
|
@ -249,8 +240,7 @@ sub presetSet
|
|||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub presetGoto
|
||||
{
|
||||
sub presetGoto {
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset = $self->getParam( $params, 'preset' );
|
||||
|
@ -259,8 +249,7 @@ sub presetGoto
|
|||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub presetHome
|
||||
{
|
||||
sub presetHome {
|
||||
my $self = shift;
|
||||
Debug( "Home Preset" );
|
||||
my $cmd = "/admin/ptctl.cgi?move=h";
|
||||
|
@ -269,41 +258,26 @@ sub presetHome
|
|||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
;
|
||||
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} = '';
|
||||
}
|
||||
return( $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}
|
||||
|
@ -256,51 +237,140 @@ sub GenerateVideo {
|
|||
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,
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -82,7 +82,7 @@ our %EXPORT_TAGS = (
|
|||
);
|
||||
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
||||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
|
||||
|
||||
our @EXPORT = qw();
|
||||
|
||||
|
@ -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,7 +248,7 @@ sub zmMemVerify {
|
|||
return( undef );
|
||||
}
|
||||
|
||||
my $sd_size = zmMemRead( $monitor, "shared_data:size", 1 );
|
||||
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 "
|
||||
|
@ -268,7 +268,7 @@ sub zmMemVerify {
|
|||
}
|
||||
return( undef );
|
||||
}
|
||||
my $td_size = zmMemRead( $monitor, "trigger_data:size", 1 );
|
||||
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 "
|
||||
|
@ -289,7 +289,7 @@ sub zmMemVerify {
|
|||
}
|
||||
return( undef );
|
||||
}
|
||||
if ( !zmMemRead($monitor, "shared_data:valid",1) ) {
|
||||
if ( !zmMemRead($monitor, 'shared_data:valid',1) ) {
|
||||
Error( "Shared data not valid for monitor $$monitor{Id}" );
|
||||
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
|
||||
|
||||
|
|
|
@ -40,7 +40,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 = (
|
||||
'functions' => [ qw(
|
||||
functions => [ qw(
|
||||
zmMemKey
|
||||
zmMemAttach
|
||||
zmMemDetach
|
||||
|
@ -68,21 +68,18 @@ use ZoneMinder::Logger qw(:all);
|
|||
|
||||
use Sys::Mmap;
|
||||
|
||||
sub zmMemKey
|
||||
{
|
||||
sub zmMemKey {
|
||||
my $monitor = shift;
|
||||
return( defined($monitor->{MMapAddr})?$monitor->{MMapAddr}:undef );
|
||||
}
|
||||
|
||||
sub zmMemAttach
|
||||
{
|
||||
sub zmMemAttach {
|
||||
my ( $monitor, $size ) = @_;
|
||||
if ( ! $size ) {
|
||||
Error( "No size passed to zmMemAttach for monitor $$monitor{Id}\n" );
|
||||
return( undef );
|
||||
}
|
||||
if ( !defined($monitor->{MMapAddr}) )
|
||||
{
|
||||
if ( !defined($monitor->{MMapAddr}) ) {
|
||||
|
||||
my $mmap_file = $Config{ZM_PATH_MAP}."/zm.mmap.".$monitor->{Id};
|
||||
if ( ! -e $mmap_file ) {
|
||||
|
@ -105,15 +102,13 @@ sub zmMemAttach
|
|||
return ( undef );
|
||||
}
|
||||
my $MMAP;
|
||||
if ( !open( $MMAP, "+<", $mmap_file ) )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
if ( !$mmap_addr || !$mmap ) {
|
||||
Error( sprintf( "Can't mmap to file '%s': $!\n", $mmap_file ) );
|
||||
close( $MMAP );
|
||||
return( undef );
|
||||
|
@ -125,37 +120,31 @@ sub zmMemAttach
|
|||
return( !undef );
|
||||
}
|
||||
|
||||
sub zmMemDetach
|
||||
{
|
||||
sub zmMemDetach {
|
||||
my $monitor = shift;
|
||||
|
||||
if ( $monitor->{MMap} )
|
||||
{
|
||||
if ( $monitor->{MMap} ) {
|
||||
if ( ! munmap( ${$monitor->{MMap}} ) ) {
|
||||
Warn( "Unable to munmap for monitor $$monitor{Id}\n");
|
||||
}
|
||||
delete $monitor->{MMap};
|
||||
}
|
||||
if ( $monitor->{MMapAddr} )
|
||||
{
|
||||
if ( $monitor->{MMapAddr} ) {
|
||||
delete $monitor->{MMapAddr};
|
||||
}
|
||||
if ( $monitor->{MMapHandle} )
|
||||
{
|
||||
if ( $monitor->{MMapHandle} ) {
|
||||
close( $monitor->{MMapHandle} );
|
||||
delete $monitor->{MMapHandle};
|
||||
}
|
||||
}
|
||||
|
||||
sub zmMemGet
|
||||
{
|
||||
sub zmMemGet {
|
||||
my $monitor = shift;
|
||||
my $offset = shift;
|
||||
my $size = shift;
|
||||
|
||||
my $mmap = $monitor->{MMap};
|
||||
if ( !$mmap || !$$mmap )
|
||||
{
|
||||
if ( !$mmap || !$$mmap ) {
|
||||
Error( sprintf( "Can't read from mapped memory for monitor '%d', gone away?"
|
||||
, $monitor->{Id}
|
||||
)
|
||||
|
@ -166,16 +155,14 @@ sub zmMemGet
|
|||
return( $data );
|
||||
}
|
||||
|
||||
sub zmMemPut
|
||||
{
|
||||
sub zmMemPut {
|
||||
my $monitor = shift;
|
||||
my $offset = shift;
|
||||
my $size = shift;
|
||||
my $data = shift;
|
||||
|
||||
my $mmap = $monitor->{MMap};
|
||||
if ( !$mmap || !$$mmap )
|
||||
{
|
||||
if ( !$mmap || !$$mmap ) {
|
||||
Error( sprintf( "Can't write mapped memory for monitor '%d', gone away?"
|
||||
, $monitor->{Id}
|
||||
)
|
||||
|
@ -186,12 +173,10 @@ sub zmMemPut
|
|||
return( !undef );
|
||||
}
|
||||
|
||||
sub zmMemClean
|
||||
{
|
||||
sub zmMemClean {
|
||||
Debug( "Removing memory map files\n" );
|
||||
my $mapPath = $Config{ZM_PATH_MAP}."/zm.mmap.*";
|
||||
foreach my $mapFile( glob( $mapPath ) )
|
||||
{
|
||||
my $mapPath = $Config{ZM_PATH_MAP}.'/zm.mmap.*';
|
||||
foreach my $mapFile( glob( $mapPath ) ) {
|
||||
( $mapFile ) = $mapFile =~ /^(.+)$/;
|
||||
Debug( "Removing memory map file '$mapFile'\n" );
|
||||
unlink( $mapFile );
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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 ) );
|
||||
|
|
|
@ -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 );
|
||||
|
@ -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);
|
||||
|
@ -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() ) ) {
|
||||
|
@ -689,11 +684,15 @@ else if ( packet.pts && video_last_pts > packet.pts ) {
|
|||
#endif
|
||||
}
|
||||
|
||||
if (
|
||||
( packet.stream_index != mAudioStreamId || record_audio )
|
||||
&&
|
||||
( key_frame || packetqueue.size() )
|
||||
) {
|
||||
// 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
|
||||
|
@ -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)
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,7 +62,7 @@ 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
|
||||
|
@ -82,28 +82,46 @@ 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 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
|
||||
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",
|
||||
|
@ -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 ) {
|
||||
|
||||
|
@ -170,12 +189,21 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
|||
#endif
|
||||
|
||||
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,16 +409,13 @@ 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 ) {
|
||||
int found = 0;
|
||||
|
@ -393,20 +440,31 @@ bool VideoStore::setup_resampler() {
|
|||
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
|
||||
|
||||
Debug(1, "Audio output bit_rate (%d) sample_rate(%d) channels(%d) fmt(%d) layout(%d) frame_size(%d)",
|
||||
audio_output_context->bit_rate,
|
||||
audio_output_context->sample_rate,
|
||||
audio_output_context->channels,
|
||||
audio_output_context->sample_fmt,
|
||||
audio_output_context->channel_layout,
|
||||
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 ) {
|
||||
|
@ -418,16 +476,6 @@ bool VideoStore::setup_resampler() {
|
|||
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,
|
||||
audio_output_context->sample_rate,
|
||||
audio_output_context->channels,
|
||||
audio_output_context->sample_fmt,
|
||||
audio_output_context->channel_layout,
|
||||
audio_output_context->frame_size
|
||||
);
|
||||
|
||||
output_frame_size = audio_output_context->frame_size;
|
||||
/** 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,7 +707,7 @@ 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");
|
||||
|
@ -673,11 +717,10 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
|||
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);
|
||||
|
@ -809,12 +842,15 @@ int VideoStore::writeAudioFramePacket( AVPacket *ipkt ) {
|
|||
if ( ipkt->pts != AV_NOPTS_VALUE ) {
|
||||
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());
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
249
src/zmu.cpp
249
src/zmu.cpp
|
@ -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( ×tamp.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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -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}"
|
||||
|
@ -200,6 +231,8 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
|
|||
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
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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,16 +201,22 @@ 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 ) ) {
|
||||
|
@ -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,
|
||||
);
|
||||
|
|
|
@ -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
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
#header {
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
#layout {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
#header {
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
#layout {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
// Only load new js & css in these views
|
||||
$new_views = array('login');
|
||||
|
||||
function xhtmlHeaders( $file, $title )
|
||||
{
|
||||
function xhtmlHeaders( $file, $title ) {
|
||||
global $css;
|
||||
global $skin;
|
||||
$skinCssFile = getSkinFile( 'css/'.$css.'/skin.css' );
|
||||
|
@ -45,7 +44,6 @@ function xhtmlHeaders( $file, $title )
|
|||
<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,14 +52,12 @@ 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[*/
|
||||
|
@ -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[
|
||||
|
@ -114,8 +110,7 @@ var $j = jQuery.noConflict();
|
|||
</script>
|
||||
<?php
|
||||
}
|
||||
if ( $viewJsPhpFile )
|
||||
{
|
||||
if ( $viewJsPhpFile ) {
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
|
@ -134,8 +129,7 @@ var $j = jQuery.noConflict();
|
|||
<?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
|
||||
|
|
|
@ -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&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
|
||||
}
|
||||
?> <?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 ) { ?>
|
||||
|
@ -216,28 +213,6 @@ for ( $i = 0; $i < count($eventCounts); $i++ ) {
|
|||
<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&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.'&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.'&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>
|
||||
|
|
|
@ -18,26 +18,23 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Control' ) )
|
||||
{
|
||||
$view = "error";
|
||||
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']."' )";
|
||||
}
|
||||
|
||||
$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'] ) )
|
||||
{
|
||||
foreach( dbFetchAll( $sql ) as $row ) {
|
||||
if ( !visibleMonitor( $row['Id'] ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( empty($mid) )
|
||||
|
|
|
@ -18,28 +18,23 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Stream' ) )
|
||||
{
|
||||
$view = "error";
|
||||
if ( !canView( 'Stream' ) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty($_REQUEST['mode']) )
|
||||
{
|
||||
if ( empty($_REQUEST['mode']) ) {
|
||||
if ( canStream() )
|
||||
$mode = "stream";
|
||||
$mode = 'stream';
|
||||
else
|
||||
$mode = "still";
|
||||
}
|
||||
else
|
||||
{
|
||||
$mode = 'still';
|
||||
} else {
|
||||
$mode = validHtmlStr($_REQUEST['mode']);
|
||||
}
|
||||
|
||||
$group = '';
|
||||
$groupSql = '';
|
||||
if ( !empty($_REQUEST['group']) )
|
||||
{
|
||||
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']."' )";
|
||||
|
@ -48,41 +43,24 @@ if ( !empty($_REQUEST['group']) )
|
|||
$sql = "SELECT * FROM Monitors WHERE Function != 'None'$groupSql ORDER BY Sequence";
|
||||
$monitors = array();
|
||||
$monIdx = 0;
|
||||
foreach( dbFetchAll( $sql ) as $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[] = $row;
|
||||
$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 ?>&mode=still&group=<?php echo $group ?>&mid=<?php echo $monitor['Id'] ?>"><?php echo translate('Stills') ?></a>
|
||||
<a href="?view=<?php echo $view ?>&mode=still&group=<?php echo $group ?>&mid=<?php echo $monitor->Id() ?>"><?php echo translate('Stills') ?></a>
|
||||
<?php } else { ?>
|
||||
<a href="?view=<?php echo $view ?>&mode=stream&group=<?php echo $group ?>&mid=<?php echo $monitor['Id'] ?>"><?php echo translate('Stream') ?></a>
|
||||
<a href="?view=<?php echo $view ?>&mode=stream&group=<?php echo $group ?>&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>
|
||||
|
|
|
@ -18,21 +18,19 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Events' ) || (!empty($_REQUEST['execute']) && !canEdit('Events')) )
|
||||
{
|
||||
$view = "error";
|
||||
if ( !canView( 'Events' ) || (!empty($_REQUEST['execute']) && !canEdit('Events')) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
require_once( 'includes/Event.php' );
|
||||
|
||||
if ( !empty($_REQUEST['execute']) )
|
||||
{
|
||||
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;
|
||||
|
@ -46,8 +44,7 @@ parseSort();
|
|||
parseFilter( $_REQUEST['filter'] );
|
||||
$filterQuery = $_REQUEST['filter']['query'];
|
||||
|
||||
if ( $_REQUEST['filter']['sql'] )
|
||||
{
|
||||
if ( $_REQUEST['filter']['sql'] ) {
|
||||
$countSql .= $_REQUEST['filter']['sql'];
|
||||
$eventsSql .= $_REQUEST['filter']['sql'];
|
||||
}
|
||||
|
@ -63,31 +60,28 @@ else
|
|||
$limit = 0;
|
||||
|
||||
$nEvents = dbFetchOne( $countSql, 'EventCount' );
|
||||
if ( !empty($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 )
|
||||
else if ( $page > $pages )
|
||||
$page = $pages;
|
||||
}
|
||||
|
||||
if ( !empty($page) ) {
|
||||
$limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE);
|
||||
if ( empty( $limit ) )
|
||||
{
|
||||
if ( empty( $limit ) ) {
|
||||
$limitAmount = ZM_WEB_EVENTS_PER_PAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
} 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,8 +89,7 @@ $maxHeight = 0;
|
|||
$archived = false;
|
||||
$unarchived = false;
|
||||
$events = array();
|
||||
foreach ( dbFetchAll( $eventsSql ) as $event_row )
|
||||
{
|
||||
foreach ( dbFetchAll( $eventsSql ) as $event_row ) {
|
||||
$events[] = $event = new Event( $event_row );
|
||||
|
||||
# Doesn this code do anything?
|
||||
|
@ -124,16 +117,12 @@ 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 ?>&page=0<?php echo $filterQuery ?><?php echo $sortQuery ?>&limit=<?php echo $limit ?>"><?php echo translate('ViewAll') ?></a>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
?>
|
||||
<a href="?view=<?php echo $view ?>&page=1<?php echo $filterQuery ?><?php echo $sortQuery ?>&limit=<?php echo $limit ?>"><?php echo translate('ViewPaged') ?></a>
|
||||
<?php
|
||||
|
@ -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,12 +173,12 @@ 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
|
||||
|
@ -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&eid='.$event->Id().'&fid=0', 'zmImage', array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), $event->MaxScore() ) ?></td>
|
||||
<?php if ( ZM_WEB_EVENT_DISK_SPACE ) { ?>
|
||||
<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&eid='.$event->Id().'&fid='.$thumbData['FrameId'], 'zmImage', array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ), '<img src="?view=image&eid='.$event->Id().'&fid='.$thumbData['FrameId'].'&width='.$thumbData['Width'].'&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&eid='.$event->Id().'&fid='.$thumbData['FrameId'].'&width='.$thumbData['Width'].'&height='.$thumbData['Height'];
|
||||
$streamSrc = getStreamSrc( array( "source=event", "mode=jpeg", "event=".$event->Id(), "scale=".$scale, "maxfps=".ZM_WEB_VIDEO_MAXFPS, "replay=single") );
|
||||
|
||||
$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&eid='.$event->Id().'&fid='.$thumbData['FrameId'],
|
||||
'zmImage',
|
||||
array( 'image', reScale( $event->Width(), $scale ), reScale( $event->Height(), $scale ) ),
|
||||
$imgHtml
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<td class="colThumbnail"> </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"/>
|
||||
|
|
|
@ -18,25 +18,22 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Events' ) )
|
||||
{
|
||||
$view = "error";
|
||||
if ( !canView( 'Events' ) ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
$selectName = "filterName";
|
||||
$selectName = 'filterName';
|
||||
$filterNames = array( ''=>translate('ChooseFilter') );
|
||||
foreach ( dbFetchAll( "select * from Filters order by Name" ) as $row )
|
||||
{
|
||||
foreach ( dbFetchAll( 'select * from Filters order by Name' ) as $row ) {
|
||||
$filterNames[$row['Name']] = $row['Name'];
|
||||
if ( $row['Background'] )
|
||||
$filterNames[$row['Name']] .= "*";
|
||||
$filterNames[$row['Name']] .= '*';
|
||||
if ( !empty($_REQUEST['reload']) && isset($_REQUEST['filterName']) && $_REQUEST['filterName'] == $row['Name'] )
|
||||
$dbFilter = $row;
|
||||
}
|
||||
|
||||
$backgroundStr = "";
|
||||
if ( isset($dbFilter) )
|
||||
{
|
||||
$backgroundStr = '';
|
||||
if ( isset($dbFilter) ) {
|
||||
if ( $dbFilter['Background'] )
|
||||
$backgroundStr = '['.strtolower(translate('Background')).']';
|
||||
$_REQUEST['filter'] = jsonDecode( $dbFilter['Query'] );
|
||||
|
@ -67,10 +64,8 @@ $conjunctionTypes = array(
|
|||
);
|
||||
$obracketTypes = array();
|
||||
$cbracketTypes = array();
|
||||
if ( isset($_REQUEST['filter']['terms']) )
|
||||
{
|
||||
for ( $i = 0; $i <= count($_REQUEST['filter']['terms'])-2; $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 );
|
||||
}
|
||||
|
@ -116,9 +111,8 @@ $archiveTypes = array(
|
|||
'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'),
|
||||
|
@ -138,8 +132,7 @@ $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,19 +167,15 @@ 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> </td>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
?>
|
||||
<td><?php echo buildSelect( "filter[terms][$i][cnj]", $conjunctionTypes ); ?></td>
|
||||
<?php
|
||||
|
@ -195,43 +184,41 @@ for ( $i = 0; isset($_REQUEST['filter']) && $i < count($_REQUEST['filter']['term
|
|||
<td><?php if ( count($_REQUEST['filter']['terms']) > 2 ) { echo buildSelect( "filter[terms][$i][obr]", $obracketTypes ); } else { ?> <?php } ?></td>
|
||||
<td><?php echo buildSelect( "filter[terms][$i][attr]", $attrTypes, "clearValue( this, $i ); submitToFilter( this, 0 );" ); ?></td>
|
||||
<?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" )
|
||||
{
|
||||
} 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'] ) )
|
||||
{
|
||||
foreach ( dbFetchAll( "select Id,Name from Monitors order by Sequence asc" ) as $monitor ) {
|
||||
if ( visibleMonitor( $monitor['Id'] ) ) {
|
||||
$monitors[$monitor['Name']] = $monitor['Name'];
|
||||
}
|
||||
}
|
||||
|
@ -239,29 +226,23 @@ for ( $i = 0; isset($_REQUEST['filter']) && $i < count($_REQUEST['filter']['term
|
|||
<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" )
|
||||
{
|
||||
} 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 ) {
|
||||
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>
|
||||
|
@ -272,7 +253,7 @@ for ( $i = 0; isset($_REQUEST['filter']) && $i < count($_REQUEST['filter']['term
|
|||
<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>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
//
|
||||
|
||||
if ( !canView( 'Events' ) ) {
|
||||
$view = "error";
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -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&eid=<?php echo $Event->Id() ?>&fid=<?php echo $Frame->FrameId() ?>&scale=<?php echo $scale ?>&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&eid=%d&fid=%d&scale=%d&show=%s">', $Event->Id(), $Frame->FrameId(), $scale, ( $show=='anal'?'capt':'anal' ) );
|
||||
} ?>
|
||||
<img id="frameImg" src="<?php echo $Frame->getImageSrc($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 id="controls">
|
||||
<?php if ( $Frame->FrameId() > 1 ) { ?>
|
||||
<a id="firstLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $firstFid ?>&scale=<?php echo $scale ?>"><?php echo translate('First') ?></a>
|
||||
<?php } if ( $Frame->FrameId() > 1 ) { ?>
|
||||
<a id="prevLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $prevFid ?>&scale=<?php echo $scale ?>"><?php echo translate('Prev') ?></a>
|
||||
<a id="firstLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $firstFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>"><?php echo translate('First') ?></a>
|
||||
<a id="prevLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $prevFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>"><?php echo translate('Prev') ?></a>
|
||||
<?php } if ( $Frame->FrameId() < $maxFid ) { ?>
|
||||
<a id="nextLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $nextFid ?>&scale=<?php echo $scale ?>"><?php echo translate('Next') ?></a>
|
||||
<?php } if ( $Frame->FrameId() < $maxFid ) { ?>
|
||||
<a id="lastLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $lastFid ?>&scale=<?php echo $scale ?>"><?php echo translate('Last') ?></a>
|
||||
<a id="nextLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $nextFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>"><?php echo translate('Next') ?></a>
|
||||
<a id="lastLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $lastFid ?>&scale=<?php echo $scale ?>&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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,10 +107,10 @@ 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 ) {
|
||||
|
@ -130,9 +130,9 @@ function loadEventImage( imagePath, eid, fid, width, height, fps, videoName, dur
|
|||
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 ] ) );
|
||||
}
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -52,8 +52,6 @@ var monitorUrl = '<?php echo ( $monitor->Server()->Url() ) ?>';
|
|||
|
||||
var scale = <?php echo $scale ?>;
|
||||
|
||||
var streamSrc = "<?php echo preg_replace( '/&/', '&', $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
|
@ -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,28 +33,24 @@ $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 )
|
||||
{
|
||||
$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 )
|
||||
{
|
||||
foreach ( getEnumValues( 'Zones', 'Type' ) as $optType ) {
|
||||
$optTypes[$optType] = $optType;
|
||||
}
|
||||
|
||||
$optUnits = array();
|
||||
foreach ( getEnumValues( 'Zones', 'Units' ) as $optUnit )
|
||||
{
|
||||
foreach ( getEnumValues( 'Zones', 'Units' ) as $optUnit ) {
|
||||
$optUnits[$optUnit] = $optUnit;
|
||||
}
|
||||
|
||||
$optCheckMethods = array();
|
||||
foreach ( getEnumValues( 'Zones', 'CheckMethod' ) as $optCheckMethod )
|
||||
{
|
||||
foreach ( getEnumValues( 'Zones', 'CheckMethod' ) as $optCheckMethod ) {
|
||||
$optCheckMethods[$optCheckMethod] = $optCheckMethod;
|
||||
}
|
||||
|
||||
|
@ -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 )"/> / <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>
|
||||
<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>
|
||||
|
|
|
@ -18,24 +18,28 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Monitors' ) )
|
||||
{
|
||||
$view = "error";
|
||||
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'] ) )
|
||||
{
|
||||
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&mid=<?php echo $mid ?>&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&mid=<?php echo $mid ?>&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&mid=<?php echo $mid ?>&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&mid=<?php echo $mid ?>&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>
|
||||
|
|
|
@ -32,21 +32,16 @@
|
|||
// If both scale and either width or height are specified, scale is ignored
|
||||
//
|
||||
|
||||
if ( !canView( 'Events' ) )
|
||||
{
|
||||
$view = "error";
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
@ -58,27 +53,58 @@ if (!function_exists('imagescale'))
|
|||
}
|
||||
|
||||
$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 {
|
||||
$errorText = "No image path";
|
||||
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);
|
||||
|
@ -86,7 +112,7 @@ if ( empty($_REQUEST['path']) )
|
|||
if ( $pos == 0 && $pos !== false ) {
|
||||
if ( ! empty( $user['MonitorIds'] ) ) {
|
||||
$imageOk = false;
|
||||
$pathMonId = substr( $path, 0, strspn( $path, "1234567890" ) );
|
||||
$pathMonId = substr( $path, 0, strspn( $path, '1234567890' ) );
|
||||
foreach ( preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) as $monId ) {
|
||||
if ( $pathMonId == $monId ) {
|
||||
$imageOk = true;
|
||||
|
@ -94,74 +120,95 @@ if ( empty($_REQUEST['path']) )
|
|||
}
|
||||
}
|
||||
if ( !$imageOk )
|
||||
$errorText = "No image permissions";
|
||||
$errorText = 'No image permissions';
|
||||
}
|
||||
} else {
|
||||
$errorText = "Invalid image path";
|
||||
$errorText = 'Invalid image path';
|
||||
}
|
||||
if ( ! file_exists( $path ) ) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
Fatal("Image not found at $path");
|
||||
}
|
||||
}
|
||||
|
||||
$scale=0;
|
||||
if( !empty($_REQUEST['scale']) )
|
||||
if (is_numeric($_REQUEST['scale']))
|
||||
{
|
||||
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']))
|
||||
{
|
||||
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']))
|
||||
{
|
||||
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 )
|
||||
# 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 )
|
||||
readfile( $path );
|
||||
else
|
||||
{
|
||||
} 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
|
||||
{
|
||||
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)
|
||||
{
|
||||
} elseif ( $width == 0 && $height != 0 ) {
|
||||
$width = ($height * $oldWidth) / $oldHeight;
|
||||
}
|
||||
elseif ($width!=0 && $height==0)
|
||||
{
|
||||
} 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);
|
||||
if ( $width == $oldWidth && $height == $oldHeight) {
|
||||
Warning( 'No change to width despite scaling.' );
|
||||
}
|
||||
else // we do need to scale
|
||||
{
|
||||
}
|
||||
|
||||
# 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
Loading…
Reference in New Issue