Merge branch 'master' of https://github.com/ZoneMinder/ZoneMinder into plugin_support
This commit is contained in:
commit
dac1756d0d
|
@ -224,7 +224,11 @@ else(GCRYPT_LIBRARIES)
|
|||
endif(GCRYPT_LIBRARIES)
|
||||
|
||||
# gnutls (using find_library and find_path)
|
||||
find_library(GNUTLS_LIBRARIES gnutls)
|
||||
find_library(GNUTLS_LIBRARIES gnutls-openssl)
|
||||
if(NOT GNUTLS_LIBRARIES)
|
||||
find_library(GNUTLS_LIBRARIES gnutls)
|
||||
endif(NOT GNUTLS_LIBRARIES)
|
||||
|
||||
if(GNUTLS_LIBRARIES)
|
||||
set(HAVE_LIBGNUTLS 1)
|
||||
list(APPEND ZM_BIN_LIBS "${GNUTLS_LIBRARIES}")
|
||||
|
|
|
@ -577,7 +577,7 @@ INSERT INTO Controls VALUES (NULL,'Foscam FI9821W','Ffmpeg','FI9821W_Y2k',1,0,1,
|
|||
INSERT INTO Controls VALUES (NULL,'Loftek Sentinel','Remote','LoftekSentinel',0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,255,16,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,6,1,1,0,0,0,1,10,0,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||
INSERT INTO Controls VALUES (NULL,'Toshiba IK-WB11A','Remote','Toshiba_IK_WB11A',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,10,0,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||
INSERT INTO Controls VALUES (NULL,'WanscamPT','Remote','Wanscam',1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,16,0,0,0,0,0,1,16,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||
|
||||
INSERT INTO Controls VALUES (NULL,'3S Domo N5071', 'Remote', '3S', 0, 0, 1, 1, 0, 1, 1, 0, 0, 9999, 0, 9999, 0, 0, 0, 1, 1, 1, 1, 0, 0, 9999, 20, 9999, 0, 0, 0, 1, 1, 1, 1, 0, 0, 9999, 1, 9999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 1, 0, 1, 1, 0, 0, 0, 0, 1, -180, 180, 40, 100, 1, 40, 100, 0, 0, 1, -180, 180, 40, 100, 1, 40, 100, 0, 0, 0, 0);
|
||||
--
|
||||
-- Add some monitor preset values
|
||||
--
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
usr/bin
|
||||
usr/lib/cgi-bin
|
||||
usr/share/man
|
||||
usr/share/perl5/ZoneMinder
|
||||
usr/share/perl5/ZoneMinder.pm
|
||||
usr/share/zoneminder
|
||||
etc/zm
|
|
@ -0,0 +1,4 @@
|
|||
var/cache/zoneminder/events usr/share/zoneminder/events
|
||||
var/cache/zoneminder/images usr/share/zoneminder/images
|
||||
var/cache/zoneminder/temp usr/share/zoneminder/temp
|
||||
usr/lib/cgi-bin usr/share/zoneminder/cgi-bin
|
|
@ -0,0 +1,51 @@
|
|||
zoneminder for Debian
|
||||
---------------------
|
||||
|
||||
There is one manual step to get the web interface working.
|
||||
You need to link /etc/zm/apache.conf to /etc/apache2/conf.d/zoneminder.conf,
|
||||
then reload the apache config (i.e. /etc/init.d/apache2 reload)
|
||||
|
||||
Changing the location for images and events
|
||||
-------------------------------------------
|
||||
|
||||
Zoneminder, in its upstream form, stores data in /usr/share/zoneminder/. This
|
||||
package modifies that by changing /usr/share/zoneminder/images and
|
||||
/usr/share/zoneminder/events to symlinks to directories under
|
||||
/var/cache/zoneminder.
|
||||
|
||||
There are numerous places these could be put and ways to do it. But, at the
|
||||
moment, if you change this, an upgrade will fail with a warning about these
|
||||
locations having changed (the reason for this was that previously, an upgrade
|
||||
would silently revert the changes and cause event loss - refer
|
||||
bug #608793).
|
||||
|
||||
If you do want to change the location, here are a couple of suggestions.
|
||||
|
||||
These lines would mount /dev/sdX1 to /video_storage, and then 'link' /video_storage
|
||||
to the locations that ZoneMinder expects them to be at.
|
||||
|
||||
/dev/sdX1 /video_storage ext4 defaults 0 2
|
||||
/video_storage/zoneminder/images /var/cache/zoneminder/images none bind 0 2
|
||||
/video_storage/zoneminder/events /var/cache/zoneminder/events none bind 0 2
|
||||
|
||||
or if you have a separate partition for each:
|
||||
|
||||
/dev/sdX1 /var/cache/zoneminder/images ext4 defaults 0 2
|
||||
/dev/sdX2 /var/cache/zoneminder/events ext4 defaults 0 2
|
||||
|
||||
|
||||
|
||||
-- Peter Howard <pjh@northern-ridge.com.au>, Sun, 16 Jan 2010 01:35:51 +1100
|
||||
|
||||
Access to /dev/video*
|
||||
---------------------
|
||||
|
||||
For cameras which require access to /dev/video*, zoneminder may need the
|
||||
www-data user added to the video group in order to see those cameras:
|
||||
|
||||
adduser www-data video
|
||||
|
||||
Note that all web applications running on the zoneminder server will then have
|
||||
access to all video devices on the system.
|
||||
|
||||
-- Vagrant Cascadian <vagrant@debian.org> Sun, 27 Mar 2011 13:06:56 -0700
|
|
@ -0,0 +1,9 @@
|
|||
Alias /zm /usr/share/zoneminder
|
||||
|
||||
<Directory /usr/share/zoneminder>
|
||||
php_flag register_globals off
|
||||
Options Indexes FollowSymLinks
|
||||
<IfModule mod_dir.c>
|
||||
DirectoryIndex index.php
|
||||
</IfModule>
|
||||
</Directory>
|
|
@ -0,0 +1,29 @@
|
|||
zoneminder (1.28.0-0.1) wheezy; urgency=low
|
||||
|
||||
* Use CMake instead of Autotools to simplify
|
||||
debian/rules and have less build-depends.
|
||||
* Some lintian love in debian/{control,copyright}
|
||||
and perl ZoneMinder modules.
|
||||
* Don't purge database if we use a remote
|
||||
MySQL server.
|
||||
|
||||
-- Cosme Domínguez Díaz <cosme.ddiaz@gmail.com> Sun, 09 Nov 2014 02:20:20 +0100
|
||||
|
||||
zoneminder (1.28.0-wheezy) wheezy; urgency=medium
|
||||
|
||||
* Release
|
||||
|
||||
-- Isaac Connor <iconnor@connortechnology.com> Fri, 17 Oct 2014 09:27:22 -0400
|
||||
|
||||
zoneminder (1.27.99+1-testing-SNAPSHOT2014072901) testing; urgency=medium
|
||||
|
||||
* improve error messages
|
||||
* Make zmupdate re-run the most recent patch so that people running the daily builds get their db updates
|
||||
|
||||
-- Isaac Connor <iconnor@connortechnology.com> Tue, 29 Jul 2014 14:50:20 -0400
|
||||
|
||||
zoneminder (1.27.0+1-testing-v4ltomonitor-1) testing; urgency=high
|
||||
|
||||
* Snapshot release -
|
||||
|
||||
-- Isaac Connor <iconnor@connortechnology.com> Wed, 09 Jul 2014 21:35:29 -0400
|
|
@ -0,0 +1 @@
|
|||
9
|
|
@ -0,0 +1,40 @@
|
|||
Source: zoneminder
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Isaac Connor <iconnor@connortechnology.com>
|
||||
Build-Depends: debhelper (>= 9), cmake, libphp-serialization-perl, libgnutls-dev, libmysqlclient-dev | libmariadbclient-dev, libdbd-mysql-perl, libdate-manip-perl, libwww-perl, libjpeg8-dev, libpcre3-dev, libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libv4l-dev (>= 0.8.3), libbz2-dev, libsys-mmap-perl, libav-tools, libnetpbm10-dev, libavdevice-dev, libdevice-serialport-perl, libarchive-zip-perl, libmime-lite-perl, libvlccore-dev, libvlc-dev, libcurl4-gnutls-dev | libcurl4-nss-dev | libcurl4-openssl-dev, libgcrypt11-dev, libpolkit-gobject-1-dev
|
||||
Standards-Version: 3.9.4
|
||||
|
||||
Package: zoneminder
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, apache2 | httpd, libapache2-mod-php5 | libapache2-mod-fcgid | php5-fpm, php5-mysqlnd | php5-mysql, libphp-serialization-perl, libdate-manip-perl, libmime-lite-perl, libmime-tools-perl, mariadb-client | mysql-client, libwww-perl, libarchive-tar-perl, libarchive-zip-perl, libdevice-serialport-perl, libpcre3, libav-tools, rsyslog | system-log-daemon, libmodule-load-perl, libsys-mmap-perl, libjson-any-perl, netpbm, libavdevice53, libjpeg8, zip, libnet-sftp-foreign-perl, libio-pty-perl, libexpect-perl, libvlccore5 | libvlccore7, libvlc5, libcurl4-gnutls-dev | libcurl4-nss-dev | libcurl4-openssl-dev, libpolkit-gobject-1-0
|
||||
Recommends: mysql-server | mariadb-server
|
||||
Description: Video camera security and surveillance solution
|
||||
ZoneMinder is intended for use in single or multi-camera video security
|
||||
applications, including commercial or home CCTV, theft prevention and child
|
||||
or family member or home monitoring and other care scenarios. It
|
||||
supports capture, analysis, recording, and monitoring of video data coming
|
||||
from one or more video or network cameras attached to a Linux system.
|
||||
ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom
|
||||
cameras using a variety of protocols. It is suitable for use as a home
|
||||
video security system and for commercial or professional video security
|
||||
and surveillance. It can also be integrated into a home automation system
|
||||
via X.10 or other protocols.
|
||||
|
||||
Package: zoneminder-dbg
|
||||
Architecture: any
|
||||
Priority: extra
|
||||
Section: debug
|
||||
Depends: zoneminder (= ${binary:Version}), ${misc:Depends}
|
||||
Description: debugging syumbols for zoneminder.
|
||||
ZoneMinder is a video camera security and surveillance solution.
|
||||
ZoneMinder is intended for use in single or multi-camera video security
|
||||
applications, including commercial or home CCTV, theft prevention and child
|
||||
or family member or home monitoring and other care scenarios. It
|
||||
supports capture, analysis, recording, and monitoring of video data coming
|
||||
from one or more video or network cameras attached to a Linux system.
|
||||
ZoneMinder also support web and semi-automatic control of Pan/Tilt/Zoom
|
||||
cameras using a variety of protocols. It is suitable for use as a home
|
||||
video security system and for commercial or professional video security
|
||||
and surveillance. It can also be integrated into a home automation system
|
||||
via X.10 or other protocols.
|
|
@ -0,0 +1,57 @@
|
|||
Copyright:
|
||||
|
||||
Copyright 2002 Philip Coombes <philip.coombes@zoneminder.com>
|
||||
|
||||
License:
|
||||
|
||||
This package 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 package 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 package; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
On Debian GNU/Linux systems, the text of the GPL can be found in
|
||||
/usr/share/common-licenses/GPL.
|
||||
|
||||
/usr/share/zoneminder/api/lib/Cake/*:
|
||||
Copyright:
|
||||
|
||||
Copyright (c) 2005-2013, Cake Software Foundation, Inc.
|
||||
|
||||
License:
|
||||
|
||||
CakePHP(tm) : The Rapid Development PHP Framework (http://cakephp.org)
|
||||
|
||||
The MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Cake Software Foundation, Inc.
|
||||
1785 E. Sahara Avenue,
|
||||
Suite 490-204
|
||||
Las Vegas, Nevada 89104,
|
||||
United States of America.
|
|
@ -0,0 +1,5 @@
|
|||
var/log/zm
|
||||
var/lib/zm
|
||||
var/cache/zoneminder/events
|
||||
var/cache/zoneminder/images
|
||||
var/cache/zoneminder/temp
|
|
@ -0,0 +1 @@
|
|||
README.md
|
|
@ -0,0 +1,87 @@
|
|||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: zoneminder
|
||||
# Required-Start: $network $remote_fs $syslog
|
||||
# Required-Stop: $network $remote_fs $syslog
|
||||
# Should-Start: mysql
|
||||
# Should-Stop: mysql
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Control ZoneMinder as a Service
|
||||
### END INIT INFO
|
||||
# description: Control ZoneMinder as a Service
|
||||
# chkconfig: 2345 20 20
|
||||
|
||||
# Source function library.
|
||||
#. /etc/rc.d/init.d/functions
|
||||
|
||||
prog=ZoneMinder
|
||||
ZM_PATH_BIN="/usr/bin"
|
||||
RUNDIR=/var/run/zm
|
||||
TMPDIR=/tmp/zm
|
||||
command="$ZM_PATH_BIN/zmpkg.pl"
|
||||
|
||||
start() {
|
||||
echo -n "Starting $prog: "
|
||||
mkdir -p $RUNDIR $TMPDIR && chown www-data:www-data $RUNDIR $TMPDIR
|
||||
$command start
|
||||
RETVAL=$?
|
||||
[ $RETVAL = 0 ] && echo success || echo failure
|
||||
echo
|
||||
[ $RETVAL = 0 ] && touch /var/lock/zm
|
||||
return $RETVAL
|
||||
}
|
||||
stop() {
|
||||
echo -n "Stopping $prog: "
|
||||
#
|
||||
# Why is this status check being done?
|
||||
# as $command stop returns 1 if zoneminder
|
||||
# is stopped, which will result in
|
||||
# this returning 1, which will stuff
|
||||
# dpkg when it tries to stop zoneminder before
|
||||
# uninstalling . . .
|
||||
#
|
||||
result=`$command status`
|
||||
if [ ! "$result" = "running" ]; then
|
||||
echo "Zoneminder already stopped"
|
||||
echo
|
||||
RETVAL=0
|
||||
else
|
||||
$command stop
|
||||
RETVAL=$?
|
||||
[ $RETVAL = 0 ] && echo success || echo failure
|
||||
echo
|
||||
[ $RETVAL = 0 ] && rm -f /var/lock/zm
|
||||
fi
|
||||
}
|
||||
status() {
|
||||
result=`$command status`
|
||||
if [ "$result" = "running" ]; then
|
||||
echo "ZoneMinder is running"
|
||||
RETVAL=0
|
||||
else
|
||||
echo "ZoneMinder is stopped"
|
||||
RETVAL=1
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'start')
|
||||
start
|
||||
;;
|
||||
'stop')
|
||||
stop
|
||||
;;
|
||||
'restart' | 'force-reload')
|
||||
stop
|
||||
start
|
||||
;;
|
||||
'status')
|
||||
status
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 { start | stop | restart | status }"
|
||||
RETVAL=1
|
||||
;;
|
||||
esac
|
||||
exit $RETVAL
|
|
@ -0,0 +1,7 @@
|
|||
usr/bin
|
||||
usr/lib/cgi-bin
|
||||
usr/share/man
|
||||
usr/share/perl5/ZoneMinder
|
||||
usr/share/perl5/ZoneMinder.pm
|
||||
usr/share/zoneminder
|
||||
etc/zm
|
|
@ -0,0 +1,4 @@
|
|||
var/cache/zoneminder/events usr/share/zoneminder/events
|
||||
var/cache/zoneminder/images usr/share/zoneminder/images
|
||||
var/cache/zoneminder/temp usr/share/zoneminder/temp
|
||||
usr/lib/cgi-bin usr/share/zoneminder/cgi-bin
|
|
@ -0,0 +1,53 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$1" = "configure" ]; then
|
||||
if [ -e "/etc/init.d/mysql" ]; then
|
||||
#
|
||||
# Get mysql started if it isn't
|
||||
#
|
||||
if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then
|
||||
invoke-rc.d mysql start
|
||||
fi
|
||||
if $(/etc/init.d/mysql status >/dev/null 2>&1); then
|
||||
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
|
||||
# test if database if already present...
|
||||
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
|
||||
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
|
||||
echo 'grant lock tables, alter,select,insert,update,delete on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
fi
|
||||
|
||||
invoke-rc.d zoneminder stop || true
|
||||
zmupdate.pl --nointeractive
|
||||
|
||||
else
|
||||
echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.'
|
||||
fi
|
||||
else
|
||||
echo 'mysql not found, assuming remote server.'
|
||||
fi
|
||||
chown www-data:www-data /var/log/zm
|
||||
chown www-data:www-data /var/lib/zm/
|
||||
if [ -z "$2" ]; then
|
||||
chown www-data:www-data -R /var/cache/zoneminder
|
||||
fi
|
||||
fi
|
||||
# Ensure zoneminder is stopped...
|
||||
if [ -x "/etc/init.d/zoneminder" ]; then
|
||||
if invoke-rc.d zoneminder status ; then
|
||||
invoke-rc.d zoneminder stop || exit $?
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "configure" ]; then
|
||||
if [ -z "$2" ]; then
|
||||
chown www-data:www-data /var/log/zm
|
||||
chown www-data:www-data /var/lib/zm/
|
||||
chown www-data:www-data -R /var/cache/zoneminder
|
||||
else
|
||||
chown www-data:www-data /var/log/zm
|
||||
zmupdate.pl
|
||||
fi
|
||||
fi
|
||||
#DEBHELPER#
|
|
@ -0,0 +1,11 @@
|
|||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$1" = "purge" ]; then
|
||||
if [ -e "/etc/init.d/mysql" ]; then
|
||||
echo 'delete from user where User="zmuser";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
echo 'delete from db where User="zmuser";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f drop zm
|
||||
fi
|
||||
fi
|
||||
#DEBHELPER#
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
abort=false
|
||||
if [ -L /usr/share/zoneminder/events ]; then
|
||||
l=$(readlink /usr/share/zoneminder/events)
|
||||
if [ "$l" != "/var/cache/zoneminder/events" ]; then
|
||||
abort=true
|
||||
fi
|
||||
fi
|
||||
if [ -L /usr/share/zoneminder/images ]; then
|
||||
l=$(readlink /usr/share/zoneminder/images )
|
||||
if [ "$l" != "/var/cache/zoneminder/images" ]; then
|
||||
abort=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$abort" = "true" ]; then
|
||||
cat >&2 << EOF
|
||||
Aborting installation of zoneminder due to non-default symlinks in
|
||||
/usr/share/zoneminder for the images and/or events directory, which could
|
||||
result in loss of data. Please move your data in each of these directories to
|
||||
/var/cache/zoneminder before installing zoneminder from the package.
|
||||
EOF
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
export CFLAGS = -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -pipe
|
||||
export CXXFLAGS = -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -pipe
|
||||
INSTDIR = debian/tmp
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_SKIP_RPATH=ON \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=OFF \
|
||||
-DCMAKE_COLOR_MAKEFILE=ON \
|
||||
-DZM_RUNDIR=/var/run/zm \
|
||||
-DZM_SOCKDIR=/var/run/zm \
|
||||
-DZM_TMPDIR=/var/tmp/zm \
|
||||
-DZM_LOGDIR=/var/log/zm \
|
||||
-DZM_WEBDIR=/usr/share/zoneminder \
|
||||
-DZM_CONTENTDIR=/var/cache/zoneminder \
|
||||
-DZM_CGIDIR=/usr/lib/cgi-bin \
|
||||
-DZM_WEB_USER=www-data \
|
||||
-DZM_WEB_GROUP=www-data \
|
||||
-DZM_PERL_SUBPREFIX=/share/perl5 \
|
||||
-DCMAKE_INSTALL_SYSCONFDIR=etc/zm
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install --buildsystem=cmake
|
||||
install -D -m 0644 debian/apache.conf $(INSTDIR)/etc/zm/apache.conf
|
||||
rm $(INSTDIR)/usr/share/zoneminder/api/lib/Cake/LICENSE.txt
|
||||
rm $(INSTDIR)/usr/share/zoneminder/api/.gitignore
|
||||
rm -r $(INSTDIR)/usr/share/zoneminder/api/lib/Cake/Test
|
||||
|
||||
override_dh_auto_test:
|
||||
# do not run tests...
|
||||
|
||||
override_dh_strip:
|
||||
dh_strip --dbg-package=zoneminder-dbg
|
||||
|
||||
%:
|
||||
dh $@ --buildsystem=cmake --parallel
|
|
@ -0,0 +1,3 @@
|
|||
version=3
|
||||
http://www.zoneminder.com/downloads.html \
|
||||
.*/ZoneMinder-(.*).tar.gz
|
|
@ -442,6 +442,15 @@ our @options =
|
|||
type => $types{string},
|
||||
category => "images",
|
||||
},
|
||||
{
|
||||
name => "ZM_FFMPEG_OPEN_TIMEOUT",
|
||||
default => "10",
|
||||
description => "Timeout in seconds when opening a stream.",
|
||||
help => "When Ffmpeg is opening a stream, it can take a long time before failing; certain circumstances even seem to be able to lock indefinitely. This option allows you to set a maximum time in seconds to pass before closing the stream and trying to reopen it again.",
|
||||
requires => [ { name=>"ZM_OPT_FFMPEG", value=>"yes" } ],
|
||||
type => $types{integer},
|
||||
category => "images",
|
||||
},
|
||||
{
|
||||
name => "ZM_LOG_LEVEL_SYSLOG",
|
||||
default => "0",
|
||||
|
|
|
@ -0,0 +1,606 @@
|
|||
# ==========================================================================
|
||||
#
|
||||
# ZoneMinder 3S API Control Protocol Module, $Date: 2014-11-12 08:00:00 +0300 (Tue, 21 Jun 2011) $, $Revision: 1 $
|
||||
# Copyright (C) 2014 Juan Manuel Castro
|
||||
#
|
||||
# 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 implementation of the 3S camera control
|
||||
# protocol
|
||||
#Model: N5071
|
||||
#Hardware Version: 00
|
||||
#Firmware Version: V1.03_STD-1
|
||||
#Firmware Build Time: Jun 19 2012 15:28:17
|
||||
|
||||
package ZoneMinder::Control::3S;
|
||||
|
||||
use 5.006;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require ZoneMinder::Base;
|
||||
require ZoneMinder::Control;
|
||||
|
||||
our @ISA = qw(ZoneMinder::Control);
|
||||
|
||||
our $VERSION = $ZoneMinder::Base::VERSION;
|
||||
|
||||
# ==========================================================================
|
||||
#
|
||||
# 3S Control Protocol
|
||||
#
|
||||
# ==========================================================================
|
||||
|
||||
use ZoneMinder::Logger qw(:all);
|
||||
use ZoneMinder::Config qw(:all);
|
||||
|
||||
use Time::HiRes qw( usleep );
|
||||
|
||||
sub new
|
||||
{
|
||||
my $class = shift;
|
||||
my $id = shift;
|
||||
my $self = ZoneMinder::Control->new( $id );
|
||||
bless( $self, $class );
|
||||
srand( time() );
|
||||
return $self;
|
||||
}
|
||||
|
||||
our $AUTOLOAD;
|
||||
|
||||
sub AUTOLOAD
|
||||
{
|
||||
my $self = shift;
|
||||
my $class = ref($self) || croak( "$self not object" );
|
||||
my $name = $AUTOLOAD;
|
||||
$name =~ s/.*://;
|
||||
if ( exists($self->{$name}) )
|
||||
{
|
||||
return( $self->{$name} );
|
||||
}
|
||||
Fatal( "Can't access $name member of object of class $class" );
|
||||
}
|
||||
|
||||
sub open
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
$self->loadMonitor();
|
||||
|
||||
use LWP::UserAgent;
|
||||
$self->{ua} = LWP::UserAgent->new;
|
||||
#$self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION );
|
||||
$self->{ua}->agent( "ZoneMinder Control Agent/" . ZoneMinder::Base::ZM_VERSION );
|
||||
$self->{state} = 'open';
|
||||
}
|
||||
|
||||
sub close
|
||||
{
|
||||
my $self = shift;
|
||||
$self->{state} = 'closed';
|
||||
}
|
||||
|
||||
sub printMsg
|
||||
{
|
||||
my $self = shift;
|
||||
my $msg = shift;
|
||||
my $msg_len = length($msg);
|
||||
|
||||
Debug( $msg."[".$msg_len."]" );
|
||||
}
|
||||
|
||||
sub sendCmd
|
||||
{
|
||||
my $self = shift;
|
||||
my $cmd = shift;
|
||||
|
||||
my $result = undef;
|
||||
|
||||
printMsg( $cmd, "Tx" );
|
||||
|
||||
#print("http://".$self->{Monitor}->{ControlAddress}."/$cmd");
|
||||
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd" );
|
||||
my $res = $self->{ua}->request($req);
|
||||
|
||||
if ( $res->is_success )
|
||||
{
|
||||
$result = !undef;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error( "Error check failed: '".$res->status_line()."'" );
|
||||
}
|
||||
|
||||
return( $result );
|
||||
}
|
||||
|
||||
sub cameraReset
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Camera Reset" );
|
||||
my $cmd = "/restart.cgi";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
#Custom#
|
||||
#Move X or Y Axis
|
||||
sub Up
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up" );
|
||||
my $cmd = "/ptz.cgi?move=up";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub Down
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down" );
|
||||
my $cmd = "/ptz.cgi?move=down";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub Left
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Left" );
|
||||
my $cmd = "/ptz.cgi?move=left";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub Right
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Right" );
|
||||
my $cmd = "/ptz.cgi?move=right";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
##Zoom
|
||||
sub Tele
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Zoom Tele" );
|
||||
my $cmd = "/ptz.cgi?rzoom=$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub Wide
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Zoom Wide" );
|
||||
my $cmd = "/ptz.cgi?rzoom=-$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
#Move X and Y Axis
|
||||
sub UpRight
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up/Right" );
|
||||
my $cmd = "/ptz.cgi?move=upright";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub UpLeft
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up/Left" );
|
||||
my $cmd = "/ptz.cgi?move=upleft";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub DownRight
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down/Right" );
|
||||
my $cmd = "/ptz.cgi?move=downright";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub DownLeft
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down/Left" );
|
||||
my $cmd = "/ptz.cgi?move=downleft";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
#Foco
|
||||
sub focusAuto
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Focus Auto" );
|
||||
my $cmd = "/ptz.cgi?Autofocus=on";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub focusMan
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Focus Manual" );
|
||||
my $cmd = "/ptz.cgi?Autofocus=off";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub Near
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Focus Near" );
|
||||
my $cmd = "/ptz.cgi?rfocus=-$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub Far
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Focus Far" );
|
||||
my $cmd = "/ptz.cgi?rfocus=$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
#Iris
|
||||
sub Open
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Iris Open" );
|
||||
my $cmd = "/ptz.cgi?riris=$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub Close
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Iris Close" );
|
||||
my $cmd = "/ptz.cgi?riris=-$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
#Custom#
|
||||
|
||||
sub moveConUp
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up" );
|
||||
my $cmd = "/ptz.cgi?move=up";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveConDown
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down" );
|
||||
my $cmd = "/ptz.cgi?move=down";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveConLeft
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Left" );
|
||||
my $cmd = "/ptz.cgi?move=left";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveConRight
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Right" );
|
||||
my $cmd = "/ptz.cgi?move=right";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveConUpRight
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up/Right" );
|
||||
my $cmd = "/ptz.cgi?move=upright";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveConUpLeft
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up/Left" );
|
||||
my $cmd = "/ptz.cgi?move=upleft";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveConDownRight
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down/Right" );
|
||||
my $cmd = "/ptz.cgi?move=downright";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveConDownLeft
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down/Left" );
|
||||
my $cmd = "/ptz.cgi?move=downleft";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelUp
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'tiltstep' );
|
||||
Debug( "Step Up $step" );
|
||||
my $cmd = "/ptz.cgi?tilt=$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelDown
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'tiltstep' );
|
||||
Debug( "Step Down $step" );
|
||||
my $cmd = "/ptz.cgi?tilt=-$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelLeft
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'panstep' );
|
||||
Debug( "Step Left $step" );
|
||||
my $cmd = "/ptz.cgi?pan=-$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelRight
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'panstep' );
|
||||
Debug( "Step Right $step" );
|
||||
my $cmd = "/ptz.cgi?pan=$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelUpRight
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $panstep = $self->getParam( $params, 'panstep' );
|
||||
my $tiltstep = $self->getParam( $params, 'tiltstep' );
|
||||
Debug( "Step Up/Right $tiltstep/$panstep" );
|
||||
my $cmd = "/ptz.cgi?pan=$panstep&tilt=$tiltstep";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelUpLeft
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $panstep = $self->getParam( $params, 'panstep' );
|
||||
my $tiltstep = $self->getParam( $params, 'tiltstep' );
|
||||
Debug( "Step Up/Left $tiltstep/$panstep" );
|
||||
my $cmd = "/ptz.cgi?pan=-$panstep&tilt=$tiltstep";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelDownRight
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $panstep = $self->getParam( $params, 'panstep' );
|
||||
my $tiltstep = $self->getParam( $params, 'tiltstep' );
|
||||
Debug( "Step Down/Right $tiltstep/$panstep" );
|
||||
my $cmd = "/ptz.cgi?pan=$panstep&tilt=-$tiltstep";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveRelDownLeft
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $panstep = $self->getParam( $params, 'panstep' );
|
||||
my $tiltstep = $self->getParam( $params, 'tiltstep' );
|
||||
Debug( "Step Down/Left $tiltstep/$panstep" );
|
||||
my $cmd = "/ptz.cgi?pan=-$panstep&tilt=-$tiltstep";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub zoomRelTele
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Zoom Tele" );
|
||||
my $cmd = "/ptz.cgi?rzoom=$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub zoomRelWide
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Zoom Wide" );
|
||||
my $cmd = "/ptz.cgi?rzoom=-$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub focusRelNear
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Focus Near" );
|
||||
my $cmd = "/ptz.cgi?rfocus=-$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub focusRelFar
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Focus Far" );
|
||||
my $cmd = "/ptz.cgi?rfocus=$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub focusAuto
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Focus Auto" );
|
||||
my $cmd = "/ptz.cgi?Autofocus=on";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub focusMan
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Focus Manual" );
|
||||
my $cmd = "/ptz.cgi?Autofocus=off";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub irisRelOpen
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Iris Open" );
|
||||
my $cmd = "/ptz.cgi?riris=$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub irisRelClose
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $step = $self->getParam( $params, 'step' );
|
||||
Debug( "Iris Close" );
|
||||
my $cmd = "/ptz.cgi?riris=-$step";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub irisAuto
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Iris Auto" );
|
||||
my $cmd = "/ptz.cgi?autoiris=on";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub irisMan
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Iris Manual" );
|
||||
my $cmd = "/ptz.cgi?autoiris=off";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub presetClear
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset = $self->getParam( $params, 'preset' );
|
||||
Debug( "Clear Preset $preset" );
|
||||
my $cmd = "/ptz.cgi?removeserverpresetno=$preset";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub presetGoto
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset = $self->getParam( $params, 'preset' );
|
||||
Debug( "Goto Preset $preset" );
|
||||
my $cmd = "/ptz.cgi?gotoserverpresetno=$preset";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub presetHome
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Home Preset" );
|
||||
my $cmd = "/ptz.cgi?move=home";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
# Below is stub documentation for your module. You'd better edit it!
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ZoneMinder::Database - Perl extension for blah blah blah
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use ZoneMinder::Database;
|
||||
blah blah blah
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Stub documentation for ZoneMinder, created by h2xs. It looks like the
|
||||
author of the extension was negligent enough to leave the stub
|
||||
unedited.
|
||||
|
||||
Blah blah blah.
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
None by default.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Mention other useful documentation such as the documentation of
|
||||
related modules or operating system documentation (such as man pages
|
||||
in UNIX), or any relevant external documentation such as RFCs or
|
||||
standards.
|
||||
|
||||
If you have a mailing list set up for your module, mention it here.
|
||||
|
||||
If you have a web site set up for your module, mention it here.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Juan Manuel Castro, E<lt>juanmanuel.castro@gmail.comE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2014 Juan Manuel Castro
|
||||
|
||||
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
|
|
@ -151,7 +151,7 @@ public:
|
|||
{
|
||||
if ( mSize == 0 )
|
||||
mHead = mTail = mStorage;
|
||||
else if ( level >= 1 )
|
||||
else if ( level )
|
||||
{
|
||||
if ( (mHead-mStorage) > mSize )
|
||||
{
|
||||
|
@ -159,12 +159,6 @@ public:
|
|||
mHead = mStorage;
|
||||
mTail = mHead + mSize;
|
||||
}
|
||||
else if ( level >= 2 )
|
||||
{
|
||||
memmove( mStorage, mHead, mSize );
|
||||
mHead = mStorage;
|
||||
mTail = mHead + mSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
|
||||
#include "zm_ffmpeg_camera.h"
|
||||
|
||||
#ifndef AV_ERROR_MAX_STRING_SIZE
|
||||
#define AV_ERROR_MAX_STRING_SIZE 64
|
||||
#endif
|
||||
|
||||
FfmpegCamera::FfmpegCamera( int p_id, const std::string &p_path, const std::string &p_method, const std::string &p_options, int p_width, int p_height, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture ) :
|
||||
Camera( p_id, FFMPEG_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture ),
|
||||
mPath( p_path ),
|
||||
|
@ -41,6 +45,10 @@ FfmpegCamera::FfmpegCamera( int p_id, const std::string &p_path, const std::stri
|
|||
mRawFrame = NULL;
|
||||
mFrame = NULL;
|
||||
frameCount = 0;
|
||||
mIsOpening = false;
|
||||
mCanCapture = false;
|
||||
mOpenStart = 0;
|
||||
mReopenThread = 0;
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
mConvertContext = NULL;
|
||||
|
@ -63,31 +71,7 @@ FfmpegCamera::FfmpegCamera( int p_id, const std::string &p_path, const std::stri
|
|||
|
||||
FfmpegCamera::~FfmpegCamera()
|
||||
{
|
||||
av_freep( &mFrame );
|
||||
av_freep( &mRawFrame );
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( mConvertContext )
|
||||
{
|
||||
sws_freeContext( mConvertContext );
|
||||
mConvertContext = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( mCodecContext )
|
||||
{
|
||||
avcodec_close( mCodecContext );
|
||||
mCodecContext = NULL; // Freed by av_close_input_file
|
||||
}
|
||||
if ( mFormatContext )
|
||||
{
|
||||
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0)
|
||||
avformat_close_input( &mFormatContext );
|
||||
#else
|
||||
av_close_input_file( mFormatContext );
|
||||
#endif
|
||||
mFormatContext = NULL;
|
||||
}
|
||||
CloseFfmpeg();
|
||||
|
||||
if ( capture )
|
||||
{
|
||||
|
@ -112,116 +96,11 @@ void FfmpegCamera::Terminate()
|
|||
int FfmpegCamera::PrimeCapture()
|
||||
{
|
||||
Info( "Priming capture from %s", mPath.c_str() );
|
||||
|
||||
|
||||
|
||||
// Open the input, not necessarily a file
|
||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 4, 0)
|
||||
if ( av_open_input_file( &mFormatContext, mPath.c_str(), NULL, 0, NULL ) !=0 )
|
||||
#else
|
||||
// Handle options
|
||||
AVDictionary *opts = 0;
|
||||
StringVector opVect = split(Options(), ",");
|
||||
|
||||
// Set transport method as specified by method field, rtpUni is default
|
||||
if ( Method() == "rtpMulti" )
|
||||
opVect.push_back("rtsp_transport=udp_multicast");
|
||||
else if ( Method() == "rtpRtsp" )
|
||||
opVect.push_back("rtsp_transport=tcp");
|
||||
else if ( Method() == "rtpRtspHttp" )
|
||||
opVect.push_back("rtsp_transport=http");
|
||||
|
||||
Debug(2, "Number of Options: %d",opVect.size());
|
||||
for (size_t i=0; i<opVect.size(); i++)
|
||||
{
|
||||
StringVector parts = split(opVect[i],"=");
|
||||
if (parts.size() > 1) {
|
||||
parts[0] = trimSpaces(parts[0]);
|
||||
parts[1] = trimSpaces(parts[1]);
|
||||
if ( av_dict_set(&opts, parts[0].c_str(), parts[1].c_str(), 0) == 0 ) {
|
||||
Debug(2, "set option %d '%s' to '%s'", i, parts[0].c_str(), parts[1].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Error trying to set option %d '%s' to '%s'", i, parts[0].c_str(), parts[1].c_str() );
|
||||
}
|
||||
|
||||
}
|
||||
if (OpenFfmpeg() != 0){
|
||||
ReopenFfmpeg();
|
||||
}
|
||||
|
||||
if ( avformat_open_input( &mFormatContext, mPath.c_str(), NULL, &opts ) !=0 )
|
||||
#endif
|
||||
Fatal( "Unable to open input %s due to: %s", mPath.c_str(), strerror(errno) );
|
||||
|
||||
// Locate stream info from input
|
||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 4, 0)
|
||||
if ( av_find_stream_info( mFormatContext ) < 0 )
|
||||
#else
|
||||
if ( avformat_find_stream_info( mFormatContext, 0 ) < 0 )
|
||||
#endif
|
||||
Fatal( "Unable to find stream info from %s due to: %s", mPath.c_str(), strerror(errno) );
|
||||
|
||||
// Find first video stream present
|
||||
mVideoStreamId = -1;
|
||||
for (unsigned int i=0; i < mFormatContext->nb_streams; i++ )
|
||||
{
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51,2,1)
|
||||
if ( mFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO )
|
||||
#else
|
||||
if ( mFormatContext->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
|
||||
#endif
|
||||
{
|
||||
mVideoStreamId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( mVideoStreamId == -1 )
|
||||
Fatal( "Unable to locate video stream in %s", mPath.c_str() );
|
||||
|
||||
mCodecContext = mFormatContext->streams[mVideoStreamId]->codec;
|
||||
|
||||
// Try and get the codec from the codec context
|
||||
if ( (mCodec = avcodec_find_decoder( mCodecContext->codec_id )) == NULL )
|
||||
Fatal( "Can't find codec for video stream from %s", mPath.c_str() );
|
||||
|
||||
// Open the codec
|
||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 7, 0)
|
||||
if ( avcodec_open( mCodecContext, mCodec ) < 0 )
|
||||
#else
|
||||
if ( avcodec_open2( mCodecContext, mCodec, 0 ) < 0 )
|
||||
#endif
|
||||
Fatal( "Unable to open codec for video stream from %s", mPath.c_str() );
|
||||
|
||||
// Allocate space for the native video frame
|
||||
mRawFrame = avcodec_alloc_frame();
|
||||
|
||||
// Allocate space for the converted video frame
|
||||
mFrame = avcodec_alloc_frame();
|
||||
|
||||
if(mRawFrame == NULL || mFrame == NULL)
|
||||
Fatal( "Unable to allocate frame for %s", mPath.c_str() );
|
||||
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0, 8, 0)
|
||||
if(!sws_isSupportedInput(mCodecContext->pix_fmt)) {
|
||||
Fatal("swscale does not support the codec format: %c%c%c%c",(mCodecContext->pix_fmt)&0xff,((mCodecContext->pix_fmt>>8)&0xff),((mCodecContext->pix_fmt>>16)&0xff),((mCodecContext->pix_fmt>>24)&0xff));
|
||||
}
|
||||
|
||||
if(!sws_isSupportedOutput(imagePixFormat)) {
|
||||
Fatal("swscale does not support the target format: %c%c%c%c",(imagePixFormat)&0xff,((imagePixFormat>>8)&0xff),((imagePixFormat>>16)&0xff),((imagePixFormat>>24)&0xff));
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" );
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
|
||||
return( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FfmpegCamera::PreCapture()
|
||||
|
@ -232,6 +111,24 @@ int FfmpegCamera::PreCapture()
|
|||
|
||||
int FfmpegCamera::Capture( Image &image )
|
||||
{
|
||||
if (!mCanCapture){
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If the reopen thread has a value, but mCanCapture != 0, then we have just reopened the connection to the ffmpeg device, and we can clean up the thread.
|
||||
if (mReopenThread != 0) {
|
||||
void *retval = 0;
|
||||
int ret;
|
||||
|
||||
ret = pthread_tryjoin_np(mReopenThread, &retval);
|
||||
if (ret != 0){
|
||||
Error("Could not join reopen thread.");
|
||||
}
|
||||
|
||||
Info( "Successfully reopened stream." );
|
||||
mReopenThread = 0;
|
||||
}
|
||||
|
||||
AVPacket packet;
|
||||
uint8_t* directbuffer;
|
||||
|
||||
|
@ -248,7 +145,20 @@ int FfmpegCamera::Capture( Image &image )
|
|||
int avResult = av_read_frame( mFormatContext, &packet );
|
||||
if ( avResult < 0 )
|
||||
{
|
||||
Error( "Unable to read packet from stream %d: error %d", packet.stream_index, avResult );
|
||||
char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
||||
av_strerror(avResult, errbuf, AV_ERROR_MAX_STRING_SIZE);
|
||||
if (
|
||||
// Check if EOF.
|
||||
(avResult == AVERROR_EOF || (mFormatContext->pb && mFormatContext->pb->eof_reached)) ||
|
||||
// Check for Connection failure.
|
||||
(avResult == -110)
|
||||
)
|
||||
{
|
||||
Info( "av_read_frame returned \"%s\". Reopening stream.", errbuf);
|
||||
ReopenFfmpeg();
|
||||
}
|
||||
|
||||
Error( "Unable to read packet from stream %d: error %d \"%s\".", packet.stream_index, avResult, errbuf );
|
||||
return( -1 );
|
||||
}
|
||||
Debug( 5, "Got packet from stream %d", packet.stream_index );
|
||||
|
@ -300,4 +210,235 @@ int FfmpegCamera::PostCapture()
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
int FfmpegCamera::OpenFfmpeg() {
|
||||
|
||||
Debug ( 2, "OpenFfmpeg called." );
|
||||
|
||||
mOpenStart = time(NULL);
|
||||
mIsOpening = true;
|
||||
|
||||
// Open the input, not necessarily a file
|
||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 4, 0)
|
||||
Debug ( 1, "Calling av_open_input_file" );
|
||||
if ( av_open_input_file( &mFormatContext, mPath.c_str(), NULL, 0, NULL ) !=0 )
|
||||
#else
|
||||
// Handle options
|
||||
AVDictionary *opts = 0;
|
||||
StringVector opVect = split(Options(), ",");
|
||||
|
||||
// Set transport method as specified by method field, rtpUni is default
|
||||
if ( Method() == "rtpMulti" )
|
||||
opVect.push_back("rtsp_transport=udp_multicast");
|
||||
else if ( Method() == "rtpRtsp" )
|
||||
opVect.push_back("rtsp_transport=tcp");
|
||||
else if ( Method() == "rtpRtspHttp" )
|
||||
opVect.push_back("rtsp_transport=http");
|
||||
|
||||
Debug(2, "Number of Options: %d",opVect.size());
|
||||
for (size_t i=0; i<opVect.size(); i++)
|
||||
{
|
||||
StringVector parts = split(opVect[i],"=");
|
||||
if (parts.size() > 1) {
|
||||
parts[0] = trimSpaces(parts[0]);
|
||||
parts[1] = trimSpaces(parts[1]);
|
||||
if ( av_dict_set(&opts, parts[0].c_str(), parts[1].c_str(), 0) == 0 ) {
|
||||
Debug(2, "set option %d '%s' to '%s'", i, parts[0].c_str(), parts[1].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Error trying to set option %d '%s' to '%s'", i, parts[0].c_str(), parts[1].c_str() );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Debug ( 1, "Calling avformat_open_input" );
|
||||
|
||||
mFormatContext = avformat_alloc_context( );
|
||||
mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback;
|
||||
mFormatContext->interrupt_callback.opaque = this;
|
||||
|
||||
if ( avformat_open_input( &mFormatContext, mPath.c_str(), NULL, &opts ) !=0 )
|
||||
#endif
|
||||
{
|
||||
mIsOpening = false;
|
||||
Error( "Unable to open input %s due to: %s", mPath.c_str(), strerror(errno) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
mIsOpening = false;
|
||||
Debug ( 1, "Opened input" );
|
||||
|
||||
// Locate stream info from avformat_open_input
|
||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 4, 0)
|
||||
Debug ( 1, "Calling av_find_stream_info" );
|
||||
if ( av_find_stream_info( mFormatContext ) < 0 )
|
||||
#else
|
||||
Debug ( 1, "Calling avformat_find_stream_info" );
|
||||
if ( avformat_find_stream_info( mFormatContext, 0 ) < 0 )
|
||||
#endif
|
||||
Fatal( "Unable to find stream info from %s due to: %s", mPath.c_str(), strerror(errno) );
|
||||
|
||||
Debug ( 1, "Got stream info" );
|
||||
|
||||
// Find first video stream present
|
||||
mVideoStreamId = -1;
|
||||
for (unsigned int i=0; i < mFormatContext->nb_streams; i++ )
|
||||
{
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51,2,1)
|
||||
if ( mFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO )
|
||||
#else
|
||||
if ( mFormatContext->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )
|
||||
#endif
|
||||
{
|
||||
mVideoStreamId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( mVideoStreamId == -1 )
|
||||
Fatal( "Unable to locate video stream in %s", mPath.c_str() );
|
||||
|
||||
Debug ( 1, "Found video stream" );
|
||||
|
||||
mCodecContext = mFormatContext->streams[mVideoStreamId]->codec;
|
||||
|
||||
// Try and get the codec from the codec context
|
||||
if ( (mCodec = avcodec_find_decoder( mCodecContext->codec_id )) == NULL )
|
||||
Fatal( "Can't find codec for video stream from %s", mPath.c_str() );
|
||||
|
||||
Debug ( 1, "Found decoder" );
|
||||
|
||||
// Open the codec
|
||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 7, 0)
|
||||
Debug ( 1, "Calling avcodec_open" );
|
||||
if ( avcodec_open( mCodecContext, mCodec ) < 0 )
|
||||
#else
|
||||
Debug ( 1, "Calling avcodec_open2" );
|
||||
if ( avcodec_open2( mCodecContext, mCodec, 0 ) < 0 )
|
||||
#endif
|
||||
Fatal( "Unable to open codec for video stream from %s", mPath.c_str() );
|
||||
|
||||
Debug ( 1, "Opened codec" );
|
||||
|
||||
// Allocate space for the native video frame
|
||||
mRawFrame = avcodec_alloc_frame();
|
||||
|
||||
// Allocate space for the converted video frame
|
||||
mFrame = avcodec_alloc_frame();
|
||||
|
||||
if(mRawFrame == NULL || mFrame == NULL)
|
||||
Fatal( "Unable to allocate frame for %s", mPath.c_str() );
|
||||
|
||||
Debug ( 1, "Allocated frames" );
|
||||
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
|
||||
Debug ( 1, "Validated imagesize" );
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
Debug ( 1, "Calling sws_isSupportedInput" );
|
||||
if(!sws_isSupportedInput(mCodecContext->pix_fmt)) {
|
||||
Fatal("swscale does not support the codec format: %c%c%c%c",(mCodecContext->pix_fmt)&0xff,((mCodecContext->pix_fmt>>8)&0xff),((mCodecContext->pix_fmt>>16)&0xff),((mCodecContext->pix_fmt>>24)&0xff));
|
||||
}
|
||||
|
||||
if(!sws_isSupportedOutput(imagePixFormat)) {
|
||||
Fatal("swscale does not support the target format: %c%c%c%c",(imagePixFormat)&0xff,((imagePixFormat>>8)&0xff),((imagePixFormat>>16)&0xff),((imagePixFormat>>24)&0xff));
|
||||
}
|
||||
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" );
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
|
||||
mCanCapture = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FfmpegCamera::ReopenFfmpeg() {
|
||||
|
||||
Debug(2, "ReopenFfmpeg called.");
|
||||
|
||||
mCanCapture = false;
|
||||
if (pthread_create( &mReopenThread, NULL, ReopenFfmpegThreadCallback, (void*) this) != 0){
|
||||
// Log a fatal error and exit the process.
|
||||
Fatal( "ReopenFfmpeg failed to create worker thread." );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FfmpegCamera::CloseFfmpeg(){
|
||||
|
||||
Debug(2, "CloseFfmpeg called.");
|
||||
|
||||
mCanCapture = false;
|
||||
|
||||
av_freep( &mFrame );
|
||||
av_freep( &mRawFrame );
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( mConvertContext )
|
||||
{
|
||||
sws_freeContext( mConvertContext );
|
||||
mConvertContext = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( mCodecContext )
|
||||
{
|
||||
avcodec_close( mCodecContext );
|
||||
mCodecContext = NULL; // Freed by av_close_input_file
|
||||
}
|
||||
if ( mFormatContext )
|
||||
{
|
||||
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 4, 0)
|
||||
av_close_input_file( mFormatContext );
|
||||
#else
|
||||
avformat_close_input( &mFormatContext );
|
||||
#endif
|
||||
mFormatContext = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FfmpegCamera::FfmpegInterruptCallback(void *ctx)
|
||||
{
|
||||
FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
|
||||
if (camera->mIsOpening){
|
||||
int now = time(NULL);
|
||||
if ((now - camera->mOpenStart) > config.ffmpeg_open_timeout) {
|
||||
Error ( "Open video took more than %d seconds.", config.ffmpeg_open_timeout );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *FfmpegCamera::ReopenFfmpegThreadCallback(void *ctx){
|
||||
if (ctx == NULL) return NULL;
|
||||
|
||||
FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
|
||||
|
||||
while (1){
|
||||
// Close current stream.
|
||||
camera->CloseFfmpeg();
|
||||
|
||||
// Sleep if neccessary to not reconnect too fast.
|
||||
int wait = config.ffmpeg_open_timeout - (time(NULL) - camera->mOpenStart);
|
||||
wait = wait < 0 ? 0 : wait;
|
||||
if (wait > 0){
|
||||
Debug( 1, "Sleeping %d seconds before reopening stream.", wait );
|
||||
sleep(wait);
|
||||
}
|
||||
|
||||
if (camera->OpenFfmpeg() == 0){
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_LIBAVFORMAT
|
||||
|
|
|
@ -47,6 +47,16 @@ protected:
|
|||
AVFrame *mRawFrame;
|
||||
AVFrame *mFrame;
|
||||
PixelFormat imagePixFormat;
|
||||
|
||||
int OpenFfmpeg();
|
||||
int ReopenFfmpeg();
|
||||
int CloseFfmpeg();
|
||||
static int FfmpegInterruptCallback(void *ctx);
|
||||
static void* ReopenFfmpegThreadCallback(void *ctx);
|
||||
bool mIsOpening;
|
||||
bool mCanCapture;
|
||||
int mOpenStart;
|
||||
pthread_t mReopenThread;
|
||||
#endif // HAVE_LIBAVFORMAT
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
|
|
|
@ -10,7 +10,8 @@ switch ( $_REQUEST['task'] )
|
|||
logInit( array( 'id' => "web_js" ) );
|
||||
|
||||
$string = $_POST['message'];
|
||||
$file = preg_replace( '/\w+:\/\/\w+\//', '', $_POST['file'] );
|
||||
|
||||
$file = !empty($_POST['file']) ? preg_replace( '/\w+:\/\/\w+\//', '', $_POST['file'] ) : '';
|
||||
if ( !empty( $_POST['line'] ) )
|
||||
$line = $_POST['line'];
|
||||
else
|
||||
|
|
|
@ -659,21 +659,14 @@ if ( !empty($action) )
|
|||
}
|
||||
|
||||
// System view actions
|
||||
if ( canView( 'System' ) )
|
||||
{
|
||||
if ( $action == "setgroup" )
|
||||
{
|
||||
if ( !empty($_REQUEST['gid']) )
|
||||
{
|
||||
setcookie( "zmGroup", validInt($_REQUEST['gid']), time()+3600*24*30*12*10 );
|
||||
}
|
||||
else
|
||||
{
|
||||
setcookie( "zmGroup", "", time()-3600*24*2 );
|
||||
}
|
||||
$refreshParent = true;
|
||||
}
|
||||
}
|
||||
if ( $action == "setgroup" ) {
|
||||
if ( !empty($_REQUEST['gid']) ) {
|
||||
setcookie( "zmGroup", validInt($_REQUEST['gid']), time()+3600*24*30*12*10 );
|
||||
} else {
|
||||
setcookie( "zmGroup", "", time()-3600*24*2 );
|
||||
}
|
||||
$refreshParent = true;
|
||||
}
|
||||
|
||||
// System edit actions
|
||||
if ( canEdit( 'System' ) )
|
||||
|
@ -866,13 +859,10 @@ if ( !empty($action) )
|
|||
}
|
||||
elseif ( $action == "group" )
|
||||
{
|
||||
if ( !empty($_REQUEST['gid']) )
|
||||
{
|
||||
dbQuery( "update Groups set Name=?, MonitorIds=? WHERE Id=?", array($_REQUEST['newGroup']['Name'], join(',',$_REQUEST['newGroup']['MonitorIds']), $_REQUEST['gid']) );
|
||||
}
|
||||
else
|
||||
{
|
||||
dbQuery( "insert into Groups set Name=?, MonitorIds=?", array( $_REQUEST['newGroup']['Name'], join(',',$_REQUEST['newGroup']['MonitorIds'])) );
|
||||
if ( !empty($_POST['gid']) ) {
|
||||
dbQuery( "UPDATE Groups SET Name=?, MonitorIds=? WHERE Id=?", array($_POST['newGroup']['Name'], $_POST['newGroup']['MonitorIds'], $_POST['gid']) );
|
||||
} else {
|
||||
dbQuery( "INSERT INTO Groups SET Name=?, MonitorIds=?", array( $_POST['newGroup']['Name'], empty($_POST['newGroup']['MonitorIds']) ? array() : $_POST['newGroup']['MonitorIds'] ) );
|
||||
}
|
||||
$refreshParent = true;
|
||||
$view = 'none';
|
||||
|
|
|
@ -57,8 +57,10 @@ function logReport( level, message, file, line )
|
|||
requestParms += "&level="+level+"&message="+encodeURIComponent(message);
|
||||
if ( file )
|
||||
requestParms += "&file="+file;
|
||||
else
|
||||
else if ( location.search ) {
|
||||
//location.search is the querystring part, so ?blah=blah but there is almost never any value to this
|
||||
requestParms += "&file="+location.search;
|
||||
}
|
||||
if ( line )
|
||||
requestParms += "&line="+line;
|
||||
debugReq.send( requestParms );
|
||||
|
|
|
@ -190,7 +190,7 @@ xhtmlHeaders( __FILE__, $SLANG['Console'] );
|
|||
<h3 id="systemStats"><?= $SLANG['Load'] ?>: <?= getLoad() ?> / <?= $SLANG['Disk'] ?>: <?= getDiskPercent() ?>%</h3>
|
||||
<h2 id="title"><a href="http://www.zoneminder.com" target="ZoneMinder">ZoneMinder</a> <?= $SLANG['Console'] ?> - <?= makePopupLink( '?view=state', 'zmState', 'state', $status, canEdit( 'System' ) ) ?> - <?= makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="'.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?></h2>
|
||||
<div class="clear"></div>
|
||||
<div id="monitorSummary"><?= makePopupLink( '?view=groups', 'zmGroups', 'groups', sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ).($group?' ('.$group['Name'].')':''), canView( 'System' ) ); ?></div>
|
||||
<div id="monitorSummary"><?= makePopupLink( '?view=groups', 'zmGroups', 'groups', 'Group: ' . ($group?' ('.$group['Name'].')':'All').': '. sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ) ); ?></div>
|
||||
<?php
|
||||
if ( ZM_OPT_X10 && canView( 'Devices' ) )
|
||||
{
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'System' ) )
|
||||
{
|
||||
$view = "error";
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "select * from Groups order by Name";
|
||||
$groups = array();
|
||||
|
@ -66,18 +61,13 @@ xhtmlHeaders(__FILE__, $SLANG['Groups'] );
|
|||
<td class="colIds"><?= $SLANG['All'] ?></td>
|
||||
<td class="colSelect"><input type="radio" name="gid" value="0"<?= !$selected?' checked="checked"':'' ?> onclick="configureButtons( this );"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ( $groups as $group )
|
||||
{
|
||||
?>
|
||||
<?php foreach ( $groups as $group ) { ?>
|
||||
<tr>
|
||||
<td class="colName"><?= validHtmlStr($group['Name']) ?></td>
|
||||
<td class="colIds"><?= monitorIdsToNames( $group['MonitorIds'], 30 ) ?></td>
|
||||
<td class="colSelect"><input type="radio" name="gid" value="<?= $group['Id'] ?>"<?= $group['selected']?' checked="checked"':'' ?> onclick="configureButtons( this );"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="contentButtons">
|
||||
|
|
|
@ -73,7 +73,7 @@ $status = $running?$SLANG['Running']:$SLANG['Stopped'];
|
|||
|
||||
$group = NULL;
|
||||
if ( ! empty($_COOKIE['zmGroup']) ) {
|
||||
if ( $group = dbFetchOne( 'SELECT * FROM Groups WHERE Id = ?', NULL, array($_COOKIE['zmGroup']) ) )
|
||||
if ( $group = dbFetchOne( 'select * from Groups where Id = ?', NULL, array($_COOKIE['zmGroup'])) )
|
||||
$groupIds = array_flip(explode( ',', $group['MonitorIds'] ));
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ $cycleCount = 0;
|
|||
$minSequence = 0;
|
||||
$maxSequence = 1;
|
||||
$seqIdList = array();
|
||||
$monitors = dbFetchAll( 'SELECT * FROM Monitors ORDER BY Sequence ASC' );
|
||||
$monitors = dbFetchAll( "select * from Monitors order by Sequence asc" );
|
||||
$displayMonitors = array();
|
||||
for ( $i = 0; $i < count($monitors); $i++ )
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ for ( $i = 0; $i < count($monitors); $i++ )
|
|||
}
|
||||
$monitors[$i]['zmc'] = zmcStatus( $monitors[$i] );
|
||||
$monitors[$i]['zma'] = zmaStatus( $monitors[$i] );
|
||||
$monitors[$i]['ZoneCount'] = dbFetchOne( 'SELECT count(Id) AS ZoneCount FROM Zones WHERE MonitorId = ?', 'ZoneCount', array( $monitors[$i]['Id'] ) );
|
||||
$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++ )
|
||||
{
|
||||
|
@ -117,8 +117,8 @@ for ( $i = 0; $i < count($monitors); $i++ )
|
|||
$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 = ?';
|
||||
$counts = dbFetchOne( $sql, NULL, array( $monitors[$i]['Id'] ) );
|
||||
$sql = "select ".join($counts,", ")." from Events as E where MonitorId = ?";
|
||||
$counts = dbFetchOne( $sql, NULL, array($monitors[$i]['Id']) );
|
||||
if ( $monitors[$i]['Function'] != 'None' )
|
||||
{
|
||||
$cycleCount++;
|
||||
|
@ -190,7 +190,7 @@ xhtmlHeaders( __FILE__, $SLANG['Console'] );
|
|||
<h3 id="systemStats"><?= $SLANG['Load'] ?>: <?= getLoad() ?> / <?= $SLANG['Disk'] ?>: <?= getDiskPercent() ?>%</h3>
|
||||
<h2 id="title"><a href="http://www.zoneminder.com" target="ZoneMinder">ZoneMinder</a> <?= $SLANG['Console'] ?> - <?= makePopupLink( '?view=state', 'zmState', 'state', $status, canEdit( 'System' ) ) ?> - <?= makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="'.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?></h2>
|
||||
<div class="clear"></div>
|
||||
<div id="monitorSummary"><?= makePopupLink( '?view=groups', 'zmGroups', 'groups', sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ).($group?' ('.$group['Name'].')':''), canView( 'System' ) ); ?></div>
|
||||
<div id="monitorSummary"><?= makePopupLink( '?view=groups', 'zmGroups', 'groups', 'Group: ' . ($group?' ('.$group['Name'].')':'All').': '. sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ) ); ?></div>
|
||||
<?php
|
||||
if ( ZM_OPT_X10 && canView( 'Devices' ) )
|
||||
{
|
||||
|
@ -226,7 +226,7 @@ else
|
|||
{
|
||||
?><?= $SLANG['ConfiguredFor'] ?><?php
|
||||
}
|
||||
?> <?= makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', $bwArray[$_COOKIE['zmBandwidth']], ($user && $user['MaxBandwidth'] != 'low' ) ) ?> <?= $SLANG['Bandwidth'] ?></h3>
|
||||
?> <?= makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', $bwArray[$_COOKIE['zmBandwidth']], ($user && $user['MaxBandwidth'] != 'low' ) ) ?> <?= $SLANG['BandwidthHead'] ?></h3>
|
||||
</div>
|
||||
<div id="content">
|
||||
<table id="consoleTable" cellspacing="0">
|
||||
|
@ -302,7 +302,7 @@ foreach( $displayMonitors as $monitor )
|
|||
$scale = max( reScale( SCALE_BASE, $monitor['DefaultScale'], ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
|
||||
?>
|
||||
<td class="colName"><?= makePopupLink( '?view=watch&mid='.$monitor['Id'], 'zmWatch'.$monitor['Id'], array( 'watch', reScale( $monitor['Width'], $scale ), reScale( $monitor['Height'], $scale ) ), $monitor['Name'], $running && ($monitor['Function'] != 'None') && canView( 'Stream' ) ) ?></td>
|
||||
<td class="colFunction"><?= makePopupLink( '?view=function&mid='.$monitor['Id'], 'zmFunction', 'function', '<span class="'.$fclass.'">'.$monitor['Function'].( empty($monitor['Enabled']) ? ', disabled' : '' ).'</span>', canEdit( 'Monitors' ) ) ?></td>
|
||||
<td class="colFunction"><?= makePopupLink( '?view=function&mid='.$monitor['Id'], 'zmFunction', 'function', '<span class="'.$fclass.'">'.$SLANG['Fn'.$monitor['Function']].( empty($monitor['Enabled']) ? ', disabled' : '' ) .'</span>', canEdit( 'Monitors' ) ) ?></td>
|
||||
<?php if ( $monitor['Type'] == "Local" ) { ?>
|
||||
<td class="colSource"><?= makePopupLink( '?view=monitor&mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$dclass.'">'.$monitor['Device'].' ('.$monitor['Channel'].')</span>', canEdit( 'Monitors' ) ) ?></td>
|
||||
<?php } elseif ( $monitor['Type'] == "Remote" ) { ?>
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'System' ) )
|
||||
{
|
||||
$view = "error";
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "select * from Groups order by Name";
|
||||
$groups = array();
|
||||
|
@ -66,18 +61,13 @@ xhtmlHeaders(__FILE__, $SLANG['Groups'] );
|
|||
<td class="colIds"><?= $SLANG['All'] ?></td>
|
||||
<td class="colSelect"><input type="radio" name="gid" value="0"<?= !$selected?' checked="checked"':'' ?> onclick="configureButtons( this );"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ( $groups as $group )
|
||||
{
|
||||
?>
|
||||
<?php foreach ( $groups as $group ) { ?>
|
||||
<tr>
|
||||
<td class="colName"><?= validHtmlStr($group['Name']) ?></td>
|
||||
<td class="colIds"><?= monitorIdsToNames( $group['MonitorIds'], 30 ) ?></td>
|
||||
<td class="colSelect"><input type="radio" name="gid" value="<?= $group['Id'] ?>"<?= $group['selected']?' checked="checked"':'' ?> onclick="configureButtons( this );"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="contentButtons">
|
||||
|
|
Loading…
Reference in New Issue