Merge branch 'storageareas' of github.com:/connortechnology/ZoneMinder into storageareas
This commit is contained in:
commit
f702b37445
|
@ -5,6 +5,8 @@ You should only file an issue if you found a bug. Feature and enhancement reque
|
||||||
|
|
||||||
**Do not post feature or enhancement requests, general discussions or support questions here.**
|
**Do not post feature or enhancement requests, general discussions or support questions here.**
|
||||||
|
|
||||||
|
Docker related issues should be posted here: https://github.com/ZoneMinder/zmdockerfiles
|
||||||
|
|
||||||
Make sure you are running the latest version of ZoneMinder before reporting an issue.
|
Make sure you are running the latest version of ZoneMinder before reporting an issue.
|
||||||
|
|
||||||
**ZoneMinder Version (`zmaudit.pl -v`):**
|
**ZoneMinder Version (`zmaudit.pl -v`):**
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
branch = 3.0
|
branch = 3.0
|
||||||
[submodule "web/api/app/Plugin/CakePHP-Enum-Behavior"]
|
[submodule "web/api/app/Plugin/CakePHP-Enum-Behavior"]
|
||||||
path = web/api/app/Plugin/CakePHP-Enum-Behavior
|
path = web/api/app/Plugin/CakePHP-Enum-Behavior
|
||||||
url = https://github.com/asper/CakePHP-Enum-Behavior.git
|
url = https://github.com/connortechnology/CakePHP-Enum-Behavior.git
|
||||||
|
|
|
@ -28,7 +28,6 @@ env:
|
||||||
- OS=el DIST=6
|
- OS=el DIST=6
|
||||||
- OS=el DIST=6 ARCH=i386 DOCKER_REPO=knnniggett/packpack
|
- OS=el DIST=6 ARCH=i386 DOCKER_REPO=knnniggett/packpack
|
||||||
- OS=el DIST=7
|
- OS=el DIST=7
|
||||||
- OS=fedora DIST=25
|
|
||||||
- OS=fedora DIST=26 DOCKER_REPO=knnniggett/packpack
|
- OS=fedora DIST=26 DOCKER_REPO=knnniggett/packpack
|
||||||
- OS=fedora DIST=27 DOCKER_REPO=knnniggett/packpack
|
- OS=fedora DIST=27 DOCKER_REPO=knnniggett/packpack
|
||||||
- OS=ubuntu DIST=trusty
|
- OS=ubuntu DIST=trusty
|
||||||
|
|
111
Dockerfile
111
Dockerfile
|
@ -1,111 +0,0 @@
|
||||||
# ZoneMinder, you need the GIT repository code and submodules (git submodule update --init --recursive)
|
|
||||||
|
|
||||||
FROM ubuntu:xenial
|
|
||||||
MAINTAINER Markos Vakondios <mvakondios@gmail.com>
|
|
||||||
|
|
||||||
# Resynchronize the package index files
|
|
||||||
RUN apt-get update \
|
|
||||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
|
||||||
apache2 \
|
|
||||||
build-essential \
|
|
||||||
cmake \
|
|
||||||
dh-autoreconf \
|
|
||||||
dpatch \
|
|
||||||
libapache2-mod-php \
|
|
||||||
libarchive-zip-perl \
|
|
||||||
libavcodec-dev \
|
|
||||||
libavdevice-dev \
|
|
||||||
libavfilter-dev \
|
|
||||||
libavformat-dev \
|
|
||||||
libavresample-dev \
|
|
||||||
libav-tools \
|
|
||||||
libavutil-dev \
|
|
||||||
libbz2-dev \
|
|
||||||
libcurl4-openssl-dev \
|
|
||||||
libdate-manip-perl \
|
|
||||||
libdbd-mysql-perl \
|
|
||||||
libdbi-perl \
|
|
||||||
libdevice-serialport-perl \
|
|
||||||
libjpeg-turbo8 \
|
|
||||||
libjpeg-turbo8-dev \
|
|
||||||
libmime-lite-perl \
|
|
||||||
libmime-perl \
|
|
||||||
libmp4v2-dev \
|
|
||||||
libmysqlclient-dev \
|
|
||||||
libnetpbm10-dev \
|
|
||||||
libpcre3 \
|
|
||||||
libpcre3-dev \
|
|
||||||
libpolkit-gobject-1-dev \
|
|
||||||
libpostproc-dev \
|
|
||||||
libssl-dev \
|
|
||||||
libswscale-dev \
|
|
||||||
libsys-mmap-perl \
|
|
||||||
libtheora-dev \
|
|
||||||
libtool \
|
|
||||||
libv4l-dev \
|
|
||||||
libvlc5 \
|
|
||||||
libvlccore8 \
|
|
||||||
libvlccore-dev \
|
|
||||||
libvlc-dev \
|
|
||||||
libvorbis-dev \
|
|
||||||
libvpx-dev \
|
|
||||||
libwww-perl \
|
|
||||||
libx264-dev \
|
|
||||||
mysql-client \
|
|
||||||
mysql-server \
|
|
||||||
php \
|
|
||||||
php-cli \
|
|
||||||
php-mysql \
|
|
||||||
vlc-data \
|
|
||||||
yasm \
|
|
||||||
zip \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Copy local code into our container
|
|
||||||
ADD cmake /ZoneMinder/cmake/
|
|
||||||
ADD db /ZoneMinder/db/
|
|
||||||
ADD misc /ZoneMinder/misc/
|
|
||||||
ADD onvif /ZoneMinder/onvif/
|
|
||||||
ADD scripts /ZoneMinder/scripts/
|
|
||||||
ADD src /ZoneMinder/src/
|
|
||||||
ADD umutils /ZoneMinder/umutils/
|
|
||||||
ADD web /ZoneMinder/web/
|
|
||||||
ADD cmakecacheimport.sh CMakeLists.txt version zm.conf.in zmconfgen.pl.in zmlinkcontent.sh.in zoneminder-config.cmake /ZoneMinder/
|
|
||||||
ADD conf.d /ZoneMinder/conf.d
|
|
||||||
|
|
||||||
# Change into the ZoneMinder directory
|
|
||||||
WORKDIR /ZoneMinder
|
|
||||||
|
|
||||||
# Setup the ZoneMinder build environment
|
|
||||||
#RUN aclocal && autoheader && automake --force-missing --add-missing && autoconf
|
|
||||||
|
|
||||||
# Configure ZoneMinder
|
|
||||||
#RUN ./configure --with-libarch=lib/$DEB_HOST_GNU_TYPE --disable-debug --host=$DEB_HOST_GNU_TYPE --build=$DEB_BUILD_GNU_TYPE --with-mysql=/usr --with-webdir=/var/www/zm --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-mmap=yes --enable-onvif ZM_SSL_LIB=openssl ZM_DB_USER=zm ZM_DB_PASS=zm
|
|
||||||
RUN cmake .
|
|
||||||
|
|
||||||
# Build & install ZoneMinder
|
|
||||||
RUN make && make install
|
|
||||||
|
|
||||||
# ensure writable folders
|
|
||||||
RUN ./zmlinkcontent.sh
|
|
||||||
|
|
||||||
# Adding the start script
|
|
||||||
ADD utils/docker/start.sh /tmp/start.sh
|
|
||||||
|
|
||||||
# Settings rights for /usr/local/share/zoneminder/
|
|
||||||
RUN chown -R www-data:www-data /usr/local/share/zoneminder/
|
|
||||||
|
|
||||||
# Adding apache virtual hosts file
|
|
||||||
RUN cp misc/apache.conf /etc/apache2/sites-available/000-default.conf
|
|
||||||
|
|
||||||
# Expose http port
|
|
||||||
EXPOSE 80
|
|
||||||
|
|
||||||
VOLUME /var/lib/zoneminder/images /var/lib/zoneminder/events /var/lib/mysql /var/log/zm
|
|
||||||
|
|
||||||
# To speed up configuration testing, we put it here
|
|
||||||
ADD utils/docker /ZoneMinder/utils/docker/
|
|
||||||
|
|
||||||
CMD /ZoneMinder/utils/docker/setup.sh && /ZoneMinder/utils/docker/start.sh >/var/log/start.log 2>&1 & /bin/bash
|
|
||||||
|
|
||||||
# Run example docker run -it -p 1080:80 -e PHP_TIMEZONE='Europe/Paris' -v /disk/zoneminder/events:/var/lib/zoneminder/events -v /disk/zoneminder/images:/var/lib/zoneminder/images -v /disk/zoneminder/mysql:/var/lib/mysql -v /disk/zoneminder/logs:/var/log/zm --name zoneminder zoneminder/zoneminder
|
|
|
@ -13,6 +13,10 @@ ZoneMinder is an integrated set of applications which provide a complete surveil
|
||||||
Before creating an issue in our github forum, please read our posting rules:
|
Before creating an issue in our github forum, please read our posting rules:
|
||||||
https://github.com/ZoneMinder/ZoneMinder/wiki/Github-Posting-Rules
|
https://github.com/ZoneMinder/ZoneMinder/wiki/Github-Posting-Rules
|
||||||
|
|
||||||
|
## Our Dockerfile has moved
|
||||||
|
Please file issues against the ZoneMinder Dockerfile here:
|
||||||
|
https://github.com/ZoneMinder/zmdockerfiles
|
||||||
|
|
||||||
## Installation Methods
|
## Installation Methods
|
||||||
|
|
||||||
### Building from Source is Discouraged
|
### Building from Source is Discouraged
|
||||||
|
|
|
@ -273,10 +273,26 @@ CREATE TABLE `Events_Archived` (
|
||||||
) ENGINE=@ZM_MYSQL_ENGINE@;
|
) ENGINE=@ZM_MYSQL_ENGINE@;
|
||||||
|
|
||||||
|
|
||||||
drop trigger if exists event_update_trigger;
|
drop procedure if exists update_storage_stats;
|
||||||
|
|
||||||
delimiter //
|
delimiter //
|
||||||
|
|
||||||
|
create procedure update_storage_stats(IN StorageId smallint(5), IN space BIGINT)
|
||||||
|
|
||||||
|
sql security invoker
|
||||||
|
|
||||||
|
deterministic
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
update Storage set DiskSpace = DiskSpace + space where Id = StorageId;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
drop trigger if exists event_update_trigger//
|
||||||
|
|
||||||
CREATE TRIGGER event_update_trigger AFTER UPDATE ON Events
|
CREATE TRIGGER event_update_trigger AFTER UPDATE ON Events
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -504,7 +520,7 @@ CREATE TABLE `MonitorPresets` (
|
||||||
`Name` varchar(64) NOT NULL default '',
|
`Name` varchar(64) NOT NULL default '',
|
||||||
`Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL','NVSocket') NOT NULL default 'Local',
|
`Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL','NVSocket') NOT NULL default 'Local',
|
||||||
`Device` tinytext,
|
`Device` tinytext,
|
||||||
`Channel` tinytext,
|
`Channel` tinyint(3) unsigned default NULL,
|
||||||
`Format` int(10) unsigned default NULL,
|
`Format` int(10) unsigned default NULL,
|
||||||
`Protocol` varchar(16) default NULL,
|
`Protocol` varchar(16) default NULL,
|
||||||
`Method` varchar(16) default NULL,
|
`Method` varchar(16) default NULL,
|
||||||
|
@ -546,7 +562,7 @@ CREATE TABLE `Monitors` (
|
||||||
`V4LMultiBuffer` tinyint(1) unsigned,
|
`V4LMultiBuffer` tinyint(1) unsigned,
|
||||||
`V4LCapturesPerFrame` tinyint(3) unsigned,
|
`V4LCapturesPerFrame` tinyint(3) unsigned,
|
||||||
`Protocol` varchar(16),
|
`Protocol` varchar(16),
|
||||||
`Method` varchar(16) NOT NULL default '',
|
`Method` varchar(16) default '',
|
||||||
`Host` varchar(64),
|
`Host` varchar(64),
|
||||||
`Port` varchar(8) NOT NULL default '',
|
`Port` varchar(8) NOT NULL default '',
|
||||||
`SubPath` varchar(64) NOT NULL default '',
|
`SubPath` varchar(64) NOT NULL default '',
|
||||||
|
@ -628,11 +644,11 @@ CREATE INDEX `Monitors_ServerId_idx` ON `Monitors` (`ServerId`);
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `Monitor_Status`;
|
DROP TABLE IF EXISTS `Monitor_Status`;
|
||||||
CREATE TABLE `Monitor_Status` (
|
CREATE TABLE `Monitor_Status` (
|
||||||
`Id` int(10) unsigned NOT NULL,
|
`MonitorId` int(10) unsigned NOT NULL,
|
||||||
`Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown',
|
`Status` enum('Unknown','NotRunning','Running','Connected','Signal') NOT NULL default 'Unknown',
|
||||||
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
|
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
|
||||||
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
|
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
|
||||||
PRIMARY KEY (`Id`)
|
PRIMARY KEY (`MonitorId`)
|
||||||
) ENGINE=MEMORY;
|
) ENGINE=MEMORY;
|
||||||
--
|
--
|
||||||
-- Table structure for table `States`
|
-- Table structure for table `States`
|
||||||
|
@ -825,7 +841,7 @@ CREATE TABLE `Storage` (
|
||||||
`Path` varchar(64) NOT NULL default '',
|
`Path` varchar(64) NOT NULL default '',
|
||||||
`Name` varchar(64) NOT NULL default '',
|
`Name` varchar(64) NOT NULL default '',
|
||||||
`Type` enum('local','s3fs') NOT NULL default 'local',
|
`Type` enum('local','s3fs') NOT NULL default 'local',
|
||||||
`DiskSpace` bigint unsigned default NULL,
|
`DiskSpace` bigint default NULL,
|
||||||
`Scheme` enum('Deep','Medium','Shallow') NOT NULL default 'Medium',
|
`Scheme` enum('Deep','Medium','Shallow') NOT NULL default 'Medium',
|
||||||
`ServerId` int(10) unsigned,
|
`ServerId` int(10) unsigned,
|
||||||
PRIMARY KEY (`Id`)
|
PRIMARY KEY (`Id`)
|
||||||
|
@ -885,7 +901,7 @@ INSERT INTO `Controls` VALUES (NULL,'Foscam 9831W','Ffmpeg','FI9831W',0,0,1,0,0,
|
||||||
INSERT INTO `Controls` VALUES (NULL,'Foscam FI8918W','Ffmpeg','FI8918W',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,8,0,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,1,0,4,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'Foscam FI8918W','Ffmpeg','FI8918W',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,8,0,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,1,0,4,0,0,0,0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','SPP1802SWPTZ',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,0,0,0,1,8,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,64,0,0,1,0,0,0,0,1,0,64,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','SPP1802SWPTZ',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,0,0,0,1,8,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,64,0,0,1,0,0,0,0,1,0,64,0,0,0,0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'Wanscam HW0025','Libvlc','WanscamHW0025', 1, 1, 1, 1, 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, 1, 16, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 350, 0, 0, 1, 0, 10, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0);
|
INSERT INTO `Controls` VALUES (NULL,'Wanscam HW0025','Libvlc','WanscamHW0025', 1, 1, 1, 1, 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, 1, 16, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 350, 0, 0, 1, 0, 10, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'IPCC 7210W','Libvlc','IPCC7210W', 1, 1, 1, 1, 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, 1, 16, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 350, 0, 0, 1, 0, 10, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0);
|
INSERT INTO `Controls` VALUES (NULL,'IPCC 7210W','Remote','IPCC7210W', 1, 1, 1, 1, 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, 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,'Vivotek ePTZ','Remote','Vivotek_ePTZ',0,0,1,1,0,0,0,1,0,0,0,0,1,0,5,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,0,0,0,0,1,1,0,0,0,0,1,0,5,0,0,1,0,0,0,0,1,0,5,0,0,0,0);
|
INSERT INTO `Controls` VALUES (NULL,'Vivotek ePTZ','Remote','Vivotek_ePTZ',0,0,1,1,0,0,0,1,0,0,0,0,1,0,5,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,0,0,0,0,1,1,0,0,0,0,1,0,5,0,0,1,0,0,0,0,1,0,5,0,0,0,0);
|
||||||
INSERT INTO `Controls` VALUES (NULL,'Netcat ONVIF','Ffmpeg','Netcat',0,0,1,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,100,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,100,5,5,0,0,0,1,255,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,'Netcat ONVIF','Ffmpeg','Netcat',0,0,1,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,100,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,100,5,5,0,0,0,1,255,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,'Keekoon','Remote','Keekoon', 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, 0, 0, 0, 1, 6, 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,'Keekoon','Remote','Keekoon', 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, 0, 0, 0, 1, 6, 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);
|
||||||
|
@ -896,67 +912,67 @@ INSERT INTO `Controls` VALUES (NULL,'Floureon 1080P','Ffmpeg','Floureon',0,0,0,1
|
||||||
--
|
--
|
||||||
-- Add some monitor preset values
|
-- Add some monitor preset values
|
||||||
--
|
--
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, B&W','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&color=0',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, B&W','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&color=0',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, B&W','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&color=0',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, B&W','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&color=0',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,1,4,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,1,4,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,1,4,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,1,4,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, unicast','Remote','rtsp','rtpUni',NULL,NULL,NULL,'<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, unicast','Remote','rtsp',0,255,'rtsp','rtpUni','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, multicast','Remote','rtsp','rtpMulti',NULL,NULL,NULL,'<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, multicast','Remote','rtsp',0,255,'rtsp','rtpMulti','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp','rtpRtsp',NULL,NULL,NULL,'<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp',0,255,'rtsp','rtpRtsp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,1,5,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,1,5,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,1,5,NULL,'<ip-address>:<port>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,1,5,NULL,'<ip-address>:<port>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/GetData.cgi',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/GetData.cgi',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'VEO Observer, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'VEO Observer, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Blue Net Video Server, jpeg','Remote','http','simple',NULL,NULL,NULL,'<ip-address>',80,'/cgi-bin/image.cgi?control=0&id=admin&passwd=admin',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Blue Net Video Server, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/cgi-bin/image.cgi?control=0&id=admin&passwd=admin',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT into MonitorPresets VALUES (NULL,'ACTi IP, mpeg4, unicast','Remote',NULL,NULL,NULL,'rtsp','rtpUni','<ip-address>',7070,'','/track',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT into MonitorPresets VALUES (NULL,'ACTi IP, mpeg4, unicast','Remote',NULL,NULL,NULL,'rtsp','rtpUni','<ip-address>',7070,'','/track',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://<host/address>/axis-media/media.amp?videocodec=h264',NULL,NULL,NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://<host/address>/axis-media/media.amp?videocodec=h264',NULL,NULL,NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Vivotek FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://<host/address>:554/live.sdp',NULL,NULL,NULL,352,240,NULL,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Vivotek FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://<host/address>:554/live.sdp',NULL,NULL,NULL,352,240,NULL,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://<host/address>/axis-media/media.amp',NULL,NULL,NULL,640,480,NULL,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://<host/address>/axis-media/media.amp',NULL,NULL,NULL,640,480,NULL,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'ACTi TCM FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://admin:123456@<host/address>:7070',NULL,NULL,NULL,320,240,NULL,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'ACTi TCM FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://admin:123456@<host/address>:7070',NULL,NULL,NULL,320,240,NULL,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240','Local','/dev/video<?>','<?>',255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240','Local','/dev/video<?>',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240, max 5 FPS','Local','/dev/video<?>','<?>',255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240, max 5 FPS','Local','/dev/video<?>',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480','Local','/dev/video<?>','<?>',255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480','Local','/dev/video<?>',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480, max 5 FPS','Local','/dev/video<?>','<?>',255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480, max 5 FPS','Local','/dev/video<?>',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240','Local','/dev/video<?>','<?>',45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240','Local','/dev/video<?>',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240, max 5 FPS','Local','/dev/video<?>','<?>',45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240, max 5 FPS','Local','/dev/video<?>',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480','Local','/dev/video<?>','<?>',45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480','Local','/dev/video<?>',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480, max 5 FPS','Local','/dev/video<?>','<?>',45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480, max 5 FPS','Local','/dev/video<?>',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240','Local','/dev/video<?>','<?>',0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240','Local','/dev/video<?>',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240, max 5 FPS','Local','/dev/video<?>','<?>',0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240, max 5 FPS','Local','/dev/video<?>',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480','Local','/dev/video<?>','<?>',0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480','Local','/dev/video<?>',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480, max 5 FPS','Local','/dev/video<?>','<?>',0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480, max 5 FPS','Local','/dev/video<?>',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240','Local','/dev/video<?>','<?>',1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240','Local','/dev/video<?>',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240, max 5 FPS','Local','/dev/video<?>','<?>',1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240, max 5 FPS','Local','/dev/video<?>',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480','Local','/dev/video<?>','<?>',1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480','Local','/dev/video<?>',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480, max 5 FPS','Local','/dev/video<?>','<?>',1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480, max 5 FPS','Local','/dev/video<?>',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Remote ZoneMinder','Remote',NULL,NULL,NULL,'http','simple','<ip-address>',80,'/cgi-bin/nph-zms?mode=jpeg&monitor=<monitor-id>&scale=100&maxfps=5&buffer=0',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Remote ZoneMinder','Remote',NULL,NULL,NULL,'http','simple','<ip-address>',80,'/cgi-bin/nph-zms?mode=jpeg&monitor=<monitor-id>&scale=100&maxfps=5&buffer=0',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI8620 FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://<username>:<pwd>@<ip-address>:554/11',NULL,704,576,0,NULL,1,'10','<admin_pwd>','<ip-address>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI8620 FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://<username>:<pwd>@<ip-address>:554/11',NULL,704,576,0,NULL,1,'10','<admin_pwd>','<ip-address>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI8608W FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://<username>:<pwd>@<ip-address>:554/11',NULL,640,480,0,NULL,1,'11','<admin_pwd>','<ip-address>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI8608W FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://<username>:<pwd>@<ip-address>:554/11',NULL,640,480,0,NULL,1,'11','<admin_pwd>','<ip-address>',100,100);
|
||||||
|
@ -964,8 +980,8 @@ INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI9821W FFMPEG H.264','Ffmpeg',N
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Loftek Sentinel PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,'<ip-address>','80','/videostream.cgi?user=<username>&pwd=<password>&resolution=32&rate=11',NULL,640,480,4,NULL,1,'13','','<username>:<pwd>@<ip-address>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Loftek Sentinel PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,'<ip-address>','80','/videostream.cgi?user=<username>&pwd=<password>&resolution=32&rate=11',NULL,640,480,4,NULL,1,'13','','<username>:<pwd>@<ip-address>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Airlink 777W PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,'<username>:<password>@<ip-address>','80','/cgi/mjpg/mjpg.cgi',NULL,640,480,4,NULL,1,'7','','<username>:<pwd>@<ip-address>',100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Airlink 777W PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,'<username>:<password>@<ip-address>','80','/cgi/mjpg/mjpg.cgi',NULL,640,480,4,NULL,1,'7','','<username>:<pwd>@<ip-address>',100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','/dev/video<?>','0',255,'','rtpMulti','','80','rtsp://<ip-address>:554/11','',1920,1080,0,0.00,1,'16','-speed=64','<ip-address>:<port>',100,33);
|
INSERT INTO MonitorPresets VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','/dev/video<?>','0',255,'','rtpMulti','','80','rtsp://<ip-address>:554/11','',1920,1080,0,0.00,1,'16','-speed=64','<ip-address>:<port>',100,33);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1280x720, RTP/RTSP','Ffmpeg','rtsp','rtpRtsp',255,'rtsp','rtpRtsp',NULL,554,'rtsp://<ip-address>/tcp_live/ch0_0',NULL,1280,720,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1280x720, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp',NULL,554,'rtsp://<ip-address>/tcp_live/ch0_0',NULL,1280,720,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1920x1080, RTP/RTSP','Ffmpeg','rtsp','rtpRtsp',255,'rtsp','rtpRtsp',NULL,554,'rtsp://<ip-address>/tcp_live/ch0_0',NULL,1920,1080,3,NULL,0,NULL,NULL,NULL,100,100);
|
INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1920x1080, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp',NULL,554,'rtsp://<ip-address>/tcp_live/ch0_0',NULL,1920,1080,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Add some zone preset values
|
-- Add some zone preset values
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
DROP TABLE IF EXISTS `Monitor_Status`;
|
||||||
|
CREATE TABLE `Monitor_Status` (
|
||||||
|
`MonitorId` int(10) unsigned NOT NULL,
|
||||||
|
`Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown',
|
||||||
|
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
|
||||||
|
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
|
||||||
|
PRIMARY KEY (`MonitorId`)
|
||||||
|
) ENGINE=MEMORY;
|
|
@ -0,0 +1,20 @@
|
||||||
|
DROP TABLE IF EXISTS `Monitor_Status`;
|
||||||
|
CREATE TABLE `Monitor_Status` (
|
||||||
|
`MonitorId` int(10) unsigned NOT NULL,
|
||||||
|
`Status` enum('Unknown','NotRunning','Running','Connected','Signal') NOT NULL default 'Unknown',
|
||||||
|
`CaptureFPS` DECIMAL(10,2) NOT NULL default 0,
|
||||||
|
`AnalysisFPS` DECIMAL(5,2) NOT NULL default 0,
|
||||||
|
PRIMARY KEY (`MonitorId`)
|
||||||
|
) ENGINE=MEMORY;
|
||||||
|
|
||||||
|
SET SESSION sql_mode='NO_AUTO_VALUE_ON_ZERO';
|
||||||
|
|
||||||
|
SET @s = (SELECT IF(
|
||||||
|
(SELECT COUNT(*) FROM Storage WHERE Name = 'Default' AND Id=0 AND Path='/var/cache/zoneminder/events'
|
||||||
|
) > 0,
|
||||||
|
"SELECT 'Default Storage Area already exists.'",
|
||||||
|
"INSERT INTO Storage (Id,Name,Path,Scheme,ServerId) VALUES (0,'Default','/var/cache/zoneminder/events','Medium',NULL)"
|
||||||
|
));
|
||||||
|
|
||||||
|
PREPARE stmt FROM @s;
|
||||||
|
EXECUTE stmt;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE Storage MODIFY DiskSpace BIGINT default NULL;
|
|
@ -0,0 +1,3 @@
|
||||||
|
ALTER TABLE Monitors MODIFY TotalEventDiskSpace BIGINT default NULL;
|
||||||
|
ALTER TABLE Monitors MODIFY Method VARCHAR(16) default NULL;
|
||||||
|
|
|
@ -110,6 +110,7 @@ Requires: perl(Net::SMTP)
|
||||||
Requires: perl(Net::FTP)
|
Requires: perl(Net::FTP)
|
||||||
Requires: perl(LWP::Protocol::https)
|
Requires: perl(LWP::Protocol::https)
|
||||||
Requires: ca-certificates
|
Requires: ca-certificates
|
||||||
|
Requires: zip
|
||||||
|
|
||||||
%{?with_init_systemd:Requires(post): systemd}
|
%{?with_init_systemd:Requires(post): systemd}
|
||||||
%{?with_init_systemd:Requires(post): systemd-sysv}
|
%{?with_init_systemd:Requires(post): systemd-sysv}
|
||||||
|
|
|
@ -31,9 +31,9 @@ if [ "$1" = "configure" ]; then
|
||||||
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
|
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
|
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
|
||||||
# This creates the user.
|
# This creates the user.
|
||||||
echo "grant lock tables, alter,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
else
|
else
|
||||||
echo "grant lock tables, alter,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
fi
|
fi
|
||||||
|
|
||||||
zmupdate.pl --nointeractive
|
zmupdate.pl --nointeractive
|
||||||
|
|
|
@ -33,9 +33,9 @@ if [ "$1" = "configure" ]; then
|
||||||
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
|
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
|
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
|
||||||
# This creates the user.
|
# This creates the user.
|
||||||
echo "grant lock tables,alter,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
echo "grant lock tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
else
|
else
|
||||||
echo "grant lock tables,alter,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
echo "grant lock tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||||
fi
|
fi
|
||||||
|
|
||||||
zmupdate.pl --nointeractive
|
zmupdate.pl --nointeractive
|
||||||
|
|
|
@ -44,7 +44,7 @@ Clone the ZoneMinder project if you have not done so already.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
git clone ZoneMinder
|
git clone https://ZoneMinder/ZoneMinder
|
||||||
cd ZoneMinder
|
cd ZoneMinder
|
||||||
|
|
||||||
Alternatively, if you have already cloned the repo and wish to update it, do the following.
|
Alternatively, if you have already cloned the repo and wish to update it, do the following.
|
||||||
|
|
|
@ -30,9 +30,14 @@ guide you with a quick search.
|
||||||
|
|
||||||
.. topic :: Latest Release
|
.. topic :: Latest Release
|
||||||
|
|
||||||
ZoneMinder 1.29.0 is now part of the current standard Ubuntu repository. But
|
ZoneMinder is now part of the current standard Ubuntu repository, but
|
||||||
if you wish to install the later releases of ZoneMinder you will need
|
sometimes the official repository can lag behind. To find out check our
|
||||||
to add the iconnor/zoneminder PPA.
|
`releases page <https://github.com/ZoneMinder/zoneminder/releases>`_ for
|
||||||
|
the latest release.
|
||||||
|
|
||||||
|
Alternatively, the ZoneMinder project team maintains a ppa, which is updated immediately
|
||||||
|
following a new release of ZoneMinder. To use this repository instead of the
|
||||||
|
official Ubuntu repository, enter the following from the command line:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
ServerAdmin webmaster@localhost
|
ServerAdmin webmaster@localhost
|
||||||
|
|
||||||
DocumentRoot "@WEB_PREFIX@"
|
DocumentRoot "@WEB_PREFIX@"
|
||||||
Alias /zm/ "@WEB_PREFIX@/"
|
Alias /zm "@WEB_PREFIX@"
|
||||||
<Directory "@WEB_PREFIX@">
|
<Directory "@WEB_PREFIX@">
|
||||||
Options -Indexes +FollowSymLinks
|
Options -Indexes +FollowSymLinks
|
||||||
AllowOverride All
|
AllowOverride All
|
||||||
|
|
|
@ -3,5 +3,3 @@
|
||||||
# Process the perl modules subdirectory
|
# Process the perl modules subdirectory
|
||||||
add_subdirectory(proxy)
|
add_subdirectory(proxy)
|
||||||
add_subdirectory(modules)
|
add_subdirectory(modules)
|
||||||
add_subdirectory(scripts)
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
# CMakeLists.txt for the ZoneMinder perl scripts.
|
|
||||||
|
|
||||||
# If this is an out-of-source build, copy the files we need to the binary directory
|
|
||||||
if(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))
|
|
||||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/zmonvif-probe.pl" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
|
||||||
endif(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))
|
|
||||||
|
|
||||||
# Install the perl scripts
|
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmonvif-probe.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
|
|
@ -1,405 +0,0 @@
|
||||||
#!/usr/bin/perl -w
|
|
||||||
use strict;
|
|
||||||
#
|
|
||||||
# ==========================================================================
|
|
||||||
#
|
|
||||||
# ZoneMinder ONVIF Control Protocol Module
|
|
||||||
# Copyright (C) 2014 Jan M. Hochstein
|
|
||||||
#
|
|
||||||
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
#
|
|
||||||
# ==========================================================================
|
|
||||||
#
|
|
||||||
# This module contains the implementation of the ONVIF capability prober
|
|
||||||
#
|
|
||||||
|
|
||||||
use Getopt::Std;
|
|
||||||
use Data::UUID;
|
|
||||||
|
|
||||||
require ONVIF::Client;
|
|
||||||
|
|
||||||
require WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort;
|
|
||||||
require WSDiscovery10::Elements::Header;
|
|
||||||
require WSDiscovery10::Elements::Types;
|
|
||||||
require WSDiscovery10::Elements::Scopes;
|
|
||||||
|
|
||||||
require WSDiscovery::TransportUDP;
|
|
||||||
|
|
||||||
#
|
|
||||||
# ========================================================================
|
|
||||||
# Globals
|
|
||||||
|
|
||||||
my $verbose = 0;
|
|
||||||
my $soap_version = undef;
|
|
||||||
my $client;
|
|
||||||
|
|
||||||
# =========================================================================
|
|
||||||
# internal functions
|
|
||||||
|
|
||||||
sub deserialize_message
|
|
||||||
{
|
|
||||||
my ($wsdl_client, $response) = @_;
|
|
||||||
|
|
||||||
# copied and adapted from SOAP::WSDL::Client
|
|
||||||
|
|
||||||
# get deserializer
|
|
||||||
my $deserializer = $wsdl_client->get_deserializer();
|
|
||||||
|
|
||||||
if(! $deserializer) {
|
|
||||||
$deserializer = SOAP::WSDL::Factory::Deserializer->get_deserializer({
|
|
||||||
soap_version => $wsdl_client->get_soap_version(),
|
|
||||||
%{ $wsdl_client->get_deserializer_args() },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
# set class resolver if serializer supports it
|
|
||||||
$deserializer->set_class_resolver( $wsdl_client->get_class_resolver() )
|
|
||||||
if ( $deserializer->can('set_class_resolver') );
|
|
||||||
|
|
||||||
# Try deserializing response - there may be some,
|
|
||||||
# even if transport did not succeed (got a 500 response)
|
|
||||||
if ( $response ) {
|
|
||||||
# as our faults are false, returning a success marker is the only
|
|
||||||
# reliable way of determining whether the deserializer succeeded.
|
|
||||||
# Custom deserializers may return an empty list, or undef,
|
|
||||||
# and $@ is not guaranteed to be undefined.
|
|
||||||
my ($success, $result_body, $result_header) = eval {
|
|
||||||
(1, $deserializer->deserialize( $response ));
|
|
||||||
};
|
|
||||||
if (defined $success) {
|
|
||||||
return wantarray
|
|
||||||
? ($result_body, $result_header)
|
|
||||||
: $result_body;
|
|
||||||
}
|
|
||||||
elsif (blessed $@) { #}&& $@->isa('SOAP::WSDL::SOAP::Typelib::Fault11')) {
|
|
||||||
return $@;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return $deserializer->generate_fault({
|
|
||||||
code => 'soap:Server',
|
|
||||||
role => 'urn:localhost',
|
|
||||||
message => "Error deserializing message: $@. \n"
|
|
||||||
. "Message was: \n$response"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub interpret_messages
|
|
||||||
{
|
|
||||||
my ($svc_discover, $services, @responses ) = @_;
|
|
||||||
|
|
||||||
foreach my $response ( @responses ) {
|
|
||||||
|
|
||||||
if($verbose) {
|
|
||||||
print "Received message:\n" . $response . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
my $result = deserialize_message($svc_discover, $response);
|
|
||||||
if(not $result) {
|
|
||||||
if($verbose) {
|
|
||||||
print "Error deserializing message. No message returned from deserializer.\n";
|
|
||||||
}
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $xaddr;
|
|
||||||
foreach my $l_xaddr (split ' ', $result->get_ProbeMatch()->get_XAddrs()) {
|
|
||||||
# find IPv4 address
|
|
||||||
if($verbose) {
|
|
||||||
print "l_xaddr = $l_xaddr\n";
|
|
||||||
}
|
|
||||||
if($l_xaddr =~ m|//[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[:/]|) {
|
|
||||||
$xaddr = $l_xaddr;
|
|
||||||
last;
|
|
||||||
} else {
|
|
||||||
print STDERR "Unable to find IPv4 address from xaddr $l_xaddr\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# No usable address found
|
|
||||||
next if not $xaddr;
|
|
||||||
|
|
||||||
# ignore multiple responses from one service
|
|
||||||
next if defined $services->{$xaddr};
|
|
||||||
$services->{$xaddr} = 1;
|
|
||||||
|
|
||||||
print "$xaddr, " . $svc_discover->get_soap_version() . ", ";
|
|
||||||
|
|
||||||
print "(";
|
|
||||||
my $scopes = $result->get_ProbeMatch()->get_Scopes();
|
|
||||||
my $count = 0;
|
|
||||||
foreach my $scope(split ' ', $scopes) {
|
|
||||||
if($scope =~ m|onvif://www\.onvif\.org/(.+)/(.*)|) {
|
|
||||||
my ($attr, $value) = ($1,$2);
|
|
||||||
if( 0 < $count ++) {
|
|
||||||
print ", ";
|
|
||||||
}
|
|
||||||
print $attr . "=\'" . $value . "\'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print ")\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# =========================================================================
|
|
||||||
# functions
|
|
||||||
|
|
||||||
sub discover
|
|
||||||
{
|
|
||||||
## collect all responses
|
|
||||||
my @responses = ();
|
|
||||||
|
|
||||||
no warnings 'redefine';
|
|
||||||
|
|
||||||
*WSDiscovery::TransportUDP::_notify_response = sub {
|
|
||||||
my ($transport, $response) = @_;
|
|
||||||
push @responses, $response;
|
|
||||||
};
|
|
||||||
|
|
||||||
## try both soap versions
|
|
||||||
my %services;
|
|
||||||
|
|
||||||
my $uuid_gen = Data::UUID->new();
|
|
||||||
|
|
||||||
if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) {
|
|
||||||
|
|
||||||
if($verbose) {
|
|
||||||
print "Probing for SOAP 1.1\n"
|
|
||||||
}
|
|
||||||
my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({
|
|
||||||
# no_dispatch => '1',
|
|
||||||
});
|
|
||||||
$svc_discover->set_soap_version('1.1');
|
|
||||||
|
|
||||||
my $uuid = $uuid_gen->create_str();
|
|
||||||
|
|
||||||
my $result = $svc_discover->ProbeOp(
|
|
||||||
{ # WSDiscovery::Types::ProbeType
|
|
||||||
Types => 'http://www.onvif.org/ver10/network/wsdl:NetworkVideoTransmitter http://www.onvif.org/ver10/device/wsdl:Device', # QNameListType
|
|
||||||
Scopes => { value => '' },
|
|
||||||
},
|
|
||||||
WSDiscovery10::Elements::Header->new({
|
|
||||||
Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' },
|
|
||||||
MessageID => { value => "urn:uuid:$uuid" },
|
|
||||||
To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' },
|
|
||||||
})
|
|
||||||
);
|
|
||||||
print $result . "\n" if $verbose;
|
|
||||||
|
|
||||||
interpret_messages($svc_discover, \%services, @responses);
|
|
||||||
@responses = ();
|
|
||||||
} # end if doing soap 1.1
|
|
||||||
|
|
||||||
if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) {
|
|
||||||
if($verbose) {
|
|
||||||
print "Probing for SOAP 1.2\n"
|
|
||||||
}
|
|
||||||
my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({
|
|
||||||
# no_dispatch => '1',
|
|
||||||
});
|
|
||||||
$svc_discover->set_soap_version('1.2');
|
|
||||||
|
|
||||||
# copies of the same Probe message must have the same MessageID.
|
|
||||||
# This is not a copy. So we generate a new uuid.
|
|
||||||
my $uuid = $uuid_gen->create_str();
|
|
||||||
|
|
||||||
# Everyone else, like the nodejs onvif code and odm only ask for NetworkVideoTransmitter
|
|
||||||
my $result = $svc_discover->ProbeOp(
|
|
||||||
{ # WSDiscovery::Types::ProbeType
|
|
||||||
xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', },
|
|
||||||
Types => 'dn:NetworkVideoTransmitter', # QNameListType
|
|
||||||
Scopes => { value => '' },
|
|
||||||
},
|
|
||||||
WSDiscovery10::Elements::Header->new({
|
|
||||||
Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' },
|
|
||||||
MessageID => { value => "urn:uuid:$uuid" },
|
|
||||||
To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' },
|
|
||||||
})
|
|
||||||
);
|
|
||||||
print $result . "\n" if $verbose;
|
|
||||||
interpret_messages($svc_discover, \%services, @responses);
|
|
||||||
} # end if doing soap 1.2
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub profiles
|
|
||||||
{
|
|
||||||
# my $result = $services{media}{ep}->GetVideoSources( { } ,, );
|
|
||||||
# die $result if not $result;
|
|
||||||
# print $result . "\n";
|
|
||||||
|
|
||||||
my $result = $client->get_endpoint('media')->GetProfiles( { } ,, );
|
|
||||||
die $result if not $result;
|
|
||||||
if($verbose) {
|
|
||||||
print "Received message:\n" . $result . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
my $profiles = $result->get_Profiles();
|
|
||||||
|
|
||||||
foreach my $profile ( @{ $profiles } ) {
|
|
||||||
|
|
||||||
my $token = $profile->attr()->get_token() ;
|
|
||||||
|
|
||||||
# Specification gives conflicting values for unicast stream types, try both.
|
|
||||||
# http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl#op.GetStreamUri
|
|
||||||
foreach my $streamtype ( 'RTP_unicast', 'RTP-Unicast' ) {
|
|
||||||
$result = $client->get_endpoint('media')->GetStreamUri( {
|
|
||||||
StreamSetup => { # ONVIF::Media::Types::StreamSetup
|
|
||||||
Stream => $streamtype, # StreamType
|
|
||||||
Transport => { # ONVIF::Media::Types::Transport
|
|
||||||
Protocol => 'RTSP', # TransportProtocol
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProfileToken => $token, # ReferenceToken
|
|
||||||
} ,, );
|
|
||||||
last if $result;
|
|
||||||
}
|
|
||||||
die $result if not $result;
|
|
||||||
# print $result . "\n";
|
|
||||||
|
|
||||||
my $VideoEncoderConfiguration = $profile->get_VideoEncoderConfiguration();
|
|
||||||
print join(', ', $token,
|
|
||||||
$profile->get_Name(),
|
|
||||||
( $VideoEncoderConfiguration ? (
|
|
||||||
$VideoEncoderConfiguration->get_Encoding(),
|
|
||||||
$VideoEncoderConfiguration->get_Resolution()->get_Width(),
|
|
||||||
$VideoEncoderConfiguration->get_Resolution()->get_Height(),
|
|
||||||
$VideoEncoderConfiguration->get_RateControl()->get_FrameRateLimit(),
|
|
||||||
) : () ),
|
|
||||||
$result->get_MediaUri()->get_Uri() ,
|
|
||||||
). "\n";
|
|
||||||
} # end foreach profile
|
|
||||||
|
|
||||||
#
|
|
||||||
# use message parser without schema validation ???
|
|
||||||
#
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sub move
|
|
||||||
{
|
|
||||||
my ($dir) = @_;
|
|
||||||
|
|
||||||
|
|
||||||
my $result = $client->get_endpoint('ptz')->GetNodes( { } ,, );
|
|
||||||
|
|
||||||
die $result if not $result;
|
|
||||||
print $result . "\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sub metadata
|
|
||||||
{
|
|
||||||
my $result = $client->get_endpoint('media')->GetMetadataConfigurations( { } ,, );
|
|
||||||
die $result if not $result;
|
|
||||||
print $result . "\n";
|
|
||||||
|
|
||||||
$result = $client->get_endpoint('media')->GetVideoAnalyticsConfigurations( { } ,, );
|
|
||||||
die $result if not $result;
|
|
||||||
print $result . "\n";
|
|
||||||
|
|
||||||
# $result = $client->get_endpoint('analytics')->GetServiceCapabilities( { } ,, );
|
|
||||||
# die $result if not $result;
|
|
||||||
# print $result . "\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# ========================================================================
|
|
||||||
# options processing
|
|
||||||
|
|
||||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
|
||||||
|
|
||||||
our ($opt_v);
|
|
||||||
|
|
||||||
my $OPTIONS = "v";
|
|
||||||
|
|
||||||
sub HELP_MESSAGE
|
|
||||||
{
|
|
||||||
my ($fh, $pkg, $ver, $opts) = @_;
|
|
||||||
print $fh "Usage: " . __FILE__ . " [-v] probe <soap version>\n";
|
|
||||||
print $fh " " . __FILE__ . " [-v] <command> <device URI> <soap version> <user> <password>\n";
|
|
||||||
print $fh <<EOF
|
|
||||||
Commands are:
|
|
||||||
probe - scan for devices on the local network and list them
|
|
||||||
profiles - print the device's supported stream configurations
|
|
||||||
metadata - print some of the device's configuration settings
|
|
||||||
move - move the device (only ptz cameras)
|
|
||||||
Common parameters:
|
|
||||||
-v - increase verbosity
|
|
||||||
Device access parameters (for all commands but 'probe'):
|
|
||||||
device URL - the ONVIF Device service URL
|
|
||||||
soap version - SOAP version (1.1 or 1.2)
|
|
||||||
user - username of a user with access to the device
|
|
||||||
password - password for the user
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ========================================================================
|
|
||||||
# MAIN
|
|
||||||
|
|
||||||
if(!getopts($OPTIONS)) {
|
|
||||||
HELP_MESSAGE(\*STDOUT);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(defined $opt_v) {
|
|
||||||
$verbose = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $action = shift;
|
|
||||||
|
|
||||||
if(!defined $action) {
|
|
||||||
HELP_MESSAGE(\*STDOUT);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($action eq "probe") {
|
|
||||||
$soap_version = shift;
|
|
||||||
discover();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
# all other actions need URI and credentials
|
|
||||||
my $url_svc_device = shift @ARGV;
|
|
||||||
$soap_version = shift @ARGV;
|
|
||||||
my $username = @ARGV ? shift @ARGV : '';
|
|
||||||
my $password = @ARGV ? shift @ARGV: '';
|
|
||||||
|
|
||||||
$client = ONVIF::Client->new( {
|
|
||||||
'url_svc_device' => $url_svc_device,
|
|
||||||
'soap_version' => $soap_version } );
|
|
||||||
|
|
||||||
$client->set_credentials($username, $password, 1);
|
|
||||||
|
|
||||||
$client->create_services();
|
|
||||||
|
|
||||||
|
|
||||||
if($action eq "profiles") {
|
|
||||||
|
|
||||||
profiles();
|
|
||||||
}
|
|
||||||
elsif($action eq "move") {
|
|
||||||
my $dir = shift;
|
|
||||||
move($dir);
|
|
||||||
}
|
|
||||||
elsif($action eq "metadata") {
|
|
||||||
metadata();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
print("Error: Unknown command\"$action\"");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,6 +8,7 @@ configure_file(zmaudit.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" @ONLY)
|
||||||
configure_file(zmcontrol.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" @ONLY)
|
configure_file(zmcontrol.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" @ONLY)
|
||||||
configure_file(zmdc.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" @ONLY)
|
configure_file(zmdc.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" @ONLY)
|
||||||
configure_file(zmfilter.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" @ONLY)
|
configure_file(zmfilter.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" @ONLY)
|
||||||
|
configure_file(zmonvif-probe.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmonvif-probe.pl" @ONLY)
|
||||||
configure_file(zmpkg.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" @ONLY)
|
configure_file(zmpkg.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" @ONLY)
|
||||||
configure_file(zmtrack.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" @ONLY)
|
configure_file(zmtrack.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" @ONLY)
|
||||||
configure_file(zmtrigger.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" @ONLY)
|
configure_file(zmtrigger.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" @ONLY)
|
||||||
|
@ -34,7 +35,7 @@ FOREACH(PERLSCRIPT ${perlscripts})
|
||||||
ENDFOREACH(PERLSCRIPT ${perlscripts})
|
ENDFOREACH(PERLSCRIPT ${perlscripts})
|
||||||
|
|
||||||
# Install the perl scripts
|
# Install the perl scripts
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmupdate.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtelemetry.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmstats.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmonvif-probe.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmupdate.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtelemetry.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmstats.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
if(NOT ZM_NO_X10)
|
if(NOT ZM_NO_X10)
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
endif(NOT ZM_NO_X10)
|
endif(NOT ZM_NO_X10)
|
||||||
|
|
|
@ -139,7 +139,7 @@ sub moveConUp
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $params = shift;
|
my $params = shift;
|
||||||
Debug( "Move Up" );
|
Debug( "Move Up" );
|
||||||
my $cmd = "decoder_control.cgi?command=0&onestep=1&";
|
my $cmd = "decoder_control.cgi?command=2&onestep=1&";
|
||||||
$self->sendCmd( $cmd );
|
$self->sendCmd( $cmd );
|
||||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||||
|
@ -155,7 +155,7 @@ sub moveConDown
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $params = shift;
|
my $params = shift;
|
||||||
Debug( "Move Down" );
|
Debug( "Move Down" );
|
||||||
my $cmd = "decoder_control.cgi?command=2&onestep=1&";
|
my $cmd = "decoder_control.cgi?command=0&onestep=1&";
|
||||||
$self->sendCmd( $cmd );
|
$self->sendCmd( $cmd );
|
||||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||||
|
@ -203,7 +203,7 @@ sub moveConUpRight
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $params = shift;
|
my $params = shift;
|
||||||
Debug( "Move Diagonally Up Right" );
|
Debug( "Move Diagonally Up Right" );
|
||||||
my $cmd = "decoder_control.cgi?command=91&onestep=1&";
|
my $cmd = "decoder_control.cgi?command=93&onestep=1&";
|
||||||
$self->sendCmd( $cmd );
|
$self->sendCmd( $cmd );
|
||||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||||
|
@ -219,7 +219,7 @@ sub moveConDownRight
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $params = shift;
|
my $params = shift;
|
||||||
Debug( "Move Diagonally Down Right" );
|
Debug( "Move Diagonally Down Right" );
|
||||||
my $cmd = "decoder_control.cgi?command=93&onestep=1&";
|
my $cmd = "decoder_control.cgi?command=91&onestep=1&";
|
||||||
$self->sendCmd( $cmd );
|
$self->sendCmd( $cmd );
|
||||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||||
|
@ -235,7 +235,7 @@ sub moveConUpLeft
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $params = shift;
|
my $params = shift;
|
||||||
Debug( "Move Diagonally Up Left" );
|
Debug( "Move Diagonally Up Left" );
|
||||||
my $cmd = "decoder_control.cgi?command=90&onestep=1&";
|
my $cmd = "decoder_control.cgi?command=92&onestep=1&";
|
||||||
$self->sendCmd( $cmd );
|
$self->sendCmd( $cmd );
|
||||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||||
|
@ -251,7 +251,7 @@ sub moveConDownLeft
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $params = shift;
|
my $params = shift;
|
||||||
Debug( "Move Diagonally Down Left" );
|
Debug( "Move Diagonally Down Left" );
|
||||||
my $cmd = "decoder_control.cgi?command=92&onestep=1&";
|
my $cmd = "decoder_control.cgi?command=90&onestep=1&";
|
||||||
$self->sendCmd( $cmd );
|
$self->sendCmd( $cmd );
|
||||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||||
|
@ -275,7 +275,7 @@ sub presetHome
|
||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
Debug( "Home Preset" );
|
Debug( "Home Preset" );
|
||||||
my $cmd = "decoder_control.cgi?command=25&onestep=0&";
|
my $cmd = "decoder_control.cgi?command=4&onestep=0&";
|
||||||
$self->sendCmd( $cmd );
|
$self->sendCmd( $cmd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,8 +173,7 @@ sub runCommand {
|
||||||
chomp( $output );
|
chomp( $output );
|
||||||
if ( $status || logDebugging() ) {
|
if ( $status || logDebugging() ) {
|
||||||
if ( $status ) {
|
if ( $status ) {
|
||||||
Error( "Unable to run \"$command\", output is \"$output\"\n" );
|
Error( "Unable to run \"$command\", output is \"$output\", status is $status\n" );
|
||||||
exit( -1 );
|
|
||||||
} else {
|
} else {
|
||||||
Debug( "Output: $output\n" );
|
Debug( "Output: $output\n" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ our @EXPORT = qw();
|
||||||
|
|
||||||
our $VERSION = $ZoneMinder::Base::VERSION;
|
our $VERSION = $ZoneMinder::Base::VERSION;
|
||||||
|
|
||||||
use Getopt::Std;
|
|
||||||
use Data::UUID;
|
use Data::UUID;
|
||||||
|
|
||||||
use vars qw( $verbose $soap_version );
|
use vars qw( $verbose $soap_version );
|
||||||
|
@ -185,11 +184,11 @@ sub discover {
|
||||||
};
|
};
|
||||||
|
|
||||||
## try both soap versions
|
## try both soap versions
|
||||||
my %services;
|
|
||||||
|
|
||||||
my $uuid_gen = Data::UUID->new();
|
my $uuid_gen = Data::UUID->new();
|
||||||
|
|
||||||
if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) {
|
if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) {
|
||||||
|
my %services;
|
||||||
|
|
||||||
if($verbose) {
|
if($verbose) {
|
||||||
print "Probing for SOAP 1.1\n"
|
print "Probing for SOAP 1.1\n"
|
||||||
|
@ -219,6 +218,7 @@ sub discover {
|
||||||
} # end if doing soap 1.1
|
} # end if doing soap 1.1
|
||||||
|
|
||||||
if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) {
|
if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) {
|
||||||
|
my %services;
|
||||||
if($verbose) {
|
if($verbose) {
|
||||||
print "Probing for SOAP 1.2\n"
|
print "Probing for SOAP 1.2\n"
|
||||||
}
|
}
|
||||||
|
@ -253,8 +253,17 @@ sub discover {
|
||||||
sub profiles {
|
sub profiles {
|
||||||
my ( $client ) = @_;
|
my ( $client ) = @_;
|
||||||
|
|
||||||
my $result = $client->get_endpoint('media')->GetProfiles( { } ,, );
|
my $endpoint = $client->get_endpoint('media');
|
||||||
die $result if not $result;
|
if ( ! $endpoint ) {
|
||||||
|
print "No media enpoint for client.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $result = $endpoint->GetProfiles( { } ,, );
|
||||||
|
if ( ! $result ) {
|
||||||
|
print "No result from GetProfiles\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
if($verbose) {
|
if($verbose) {
|
||||||
print "Received message:\n" . $result . "\n";
|
print "Received message:\n" . $result . "\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,9 @@ MAIN: while( $loop ) {
|
||||||
Info("Auditing Storage Area $Storage_Areas[0]{Id} $Storage_Areas[0]{Name} at $Storage_Areas[0]{Path}");
|
Info("Auditing Storage Area $Storage_Areas[0]{Id} $Storage_Areas[0]{Name} at $Storage_Areas[0]{Path}");
|
||||||
} elsif ( $Config{ZM_SERVER_ID} ) {
|
} elsif ( $Config{ZM_SERVER_ID} ) {
|
||||||
@Storage_Areas = ZoneMinder::Storage->find( ServerId => $Config{ZM_SERVER_ID} );
|
@Storage_Areas = ZoneMinder::Storage->find( ServerId => $Config{ZM_SERVER_ID} );
|
||||||
|
if ( ! @Storage_Areas ) {
|
||||||
|
Fatal("No Storage Area found with ServerId =" . $Config{ZM_SERVER_ID});
|
||||||
|
}
|
||||||
Info("Auditing All Storage Areas on Server " . $Storage_Areas[0]->Server()->Name());
|
Info("Auditing All Storage Areas on Server " . $Storage_Areas[0]->Server()->Name());
|
||||||
} else {
|
} else {
|
||||||
@Storage_Areas = ZoneMinder::Storage->find();
|
@Storage_Areas = ZoneMinder::Storage->find();
|
||||||
|
@ -210,11 +213,10 @@ MAIN: while( $loop ) {
|
||||||
$db_events->{$event->{Id}} = $event->{Age};
|
$db_events->{$event->{Id}} = $event->{Age};
|
||||||
}
|
}
|
||||||
Debug( 'Got '.int(keys(%$db_events))." events for monitor $monitor->{Id}" );
|
Debug( 'Got '.int(keys(%$db_events))." events for monitor $monitor->{Id}" );
|
||||||
}
|
} # end while monitors
|
||||||
|
|
||||||
my $fs_monitors;
|
my $fs_monitors;
|
||||||
|
|
||||||
|
|
||||||
foreach my $Storage ( @Storage_Areas ) {
|
foreach my $Storage ( @Storage_Areas ) {
|
||||||
Debug('Checking events in ' . $Storage->Path() );
|
Debug('Checking events in ' . $Storage->Path() );
|
||||||
if ( ! chdir( $Storage->Path() ) ) {
|
if ( ! chdir( $Storage->Path() ) ) {
|
||||||
|
@ -224,7 +226,14 @@ MAIN: while( $loop ) {
|
||||||
|
|
||||||
# Please note that this glob will take all files beginning with a digit.
|
# Please note that this glob will take all files beginning with a digit.
|
||||||
foreach my $monitor ( glob('[0-9]*') ) {
|
foreach my $monitor ( glob('[0-9]*') ) {
|
||||||
next if $monitor =~ /\D/;
|
if ( $monitor =~ /\D/ ) {
|
||||||
|
Debug("Weird non digit characters in $monitor");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if ( $monitor_id and ( $monitor_id != $monitor ) ) {
|
||||||
|
Debug("Skipping monitor $monitor because we are only interested in monitor $monitor_id");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
Debug( "Found filesystem monitor '$monitor'" );
|
Debug( "Found filesystem monitor '$monitor'" );
|
||||||
$fs_monitors->{$monitor} = {} if ! $fs_monitors->{$monitor};
|
$fs_monitors->{$monitor} = {} if ! $fs_monitors->{$monitor};
|
||||||
|
@ -233,8 +242,10 @@ MAIN: while( $loop ) {
|
||||||
# De-taint
|
# De-taint
|
||||||
( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ );
|
( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ );
|
||||||
|
|
||||||
#if ( $$Storage{Scheme} eq 'Deep' ) {
|
{
|
||||||
foreach my $day_dir ( glob("$monitor_dir/[0-9][0-9]/[0-9][0-9]/[0-9][0-9]") ) {
|
my @day_dirs = glob("$monitor_dir/[0-9][0-9]/[0-9][0-9]/[0-9][0-9]");
|
||||||
|
Debug(qq`Checking for Deep Events under using glob("$monitor_dir/[0-9][0-9]/[0-9][0-9]/[0-9][0-9]") returned `. scalar @day_dirs . " events");
|
||||||
|
foreach my $day_dir ( @day_dirs ) {
|
||||||
Debug( "Checking day dir $day_dir" );
|
Debug( "Checking day dir $day_dir" );
|
||||||
( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint
|
( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint
|
||||||
if ( ! chdir( $day_dir ) ) {
|
if ( ! chdir( $day_dir ) ) {
|
||||||
|
@ -258,7 +269,7 @@ MAIN: while( $loop ) {
|
||||||
#Event path is hour/minute/sec
|
#Event path is hour/minute/sec
|
||||||
my $event_path = readlink( $event_link );
|
my $event_path = readlink( $event_link );
|
||||||
|
|
||||||
if ( !-e $event_path ) {
|
if ( !($event_path and -e $event_path) ) {
|
||||||
aud_print( "Event link $day_dir/$event_link does not point to valid target" );
|
aud_print( "Event link $day_dir/$event_link does not point to valid target" );
|
||||||
if ( confirm() ) {
|
if ( confirm() ) {
|
||||||
( $event_link ) = ( $event_link =~ /^(.*)$/ ); # De-taint
|
( $event_link ) = ( $event_link =~ /^(.*)$/ ); # De-taint
|
||||||
|
@ -279,9 +290,17 @@ MAIN: while( $loop ) {
|
||||||
} # end foreach event_link
|
} # end foreach event_link
|
||||||
chdir( $Storage->Path() );
|
chdir( $Storage->Path() );
|
||||||
} # end foreach day dir
|
} # end foreach day dir
|
||||||
|
}
|
||||||
|
|
||||||
foreach my $event_dir ( glob("$monitor_dir/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/*") ) {
|
Debug("Checking for Medium Scheme Events under $monitor_dir");
|
||||||
next if ! -d $event_dir;
|
{
|
||||||
|
my @event_dirs = glob("$monitor_dir/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/*");
|
||||||
|
Debug(qq`glob("$monitor_dir/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/*") returned ` . scalar @event_dirs . " entries." );
|
||||||
|
foreach my $event_dir ( @event_dirs ) {
|
||||||
|
if ( ! -d $event_dir ) {
|
||||||
|
Debug( "$event_dir is not a dir. Skipping" );
|
||||||
|
next;
|
||||||
|
}
|
||||||
my ( $date, $event_id ) = $event_dir =~ /^$monitor_dir\/(\d{4}\-\d{2}\-\d{2})\/(\d+)$/;
|
my ( $date, $event_id ) = $event_dir =~ /^$monitor_dir\/(\d{4}\-\d{2}\-\d{2})\/(\d+)$/;
|
||||||
if ( ! $event_id ) {
|
if ( ! $event_id ) {
|
||||||
Debug("Unable to parse date/event_id from $event_dir");
|
Debug("Unable to parse date/event_id from $event_dir");
|
||||||
|
@ -290,13 +309,16 @@ MAIN: while( $loop ) {
|
||||||
my $Event = $fs_events->{$event_id} = new ZoneMinder::Event();
|
my $Event = $fs_events->{$event_id} = new ZoneMinder::Event();
|
||||||
$$Event{Id} = $event_id;
|
$$Event{Id} = $event_id;
|
||||||
$$Event{Path} = join('/', $Storage->Path(), $event_dir );
|
$$Event{Path} = join('/', $Storage->Path(), $event_dir );
|
||||||
|
Debug("Have event $$Event{Id} at $$Event{Path}");
|
||||||
$$Event{Scheme} = 'Medium';
|
$$Event{Scheme} = 'Medium';
|
||||||
$$Event{RelativePath} = $event_dir;
|
$$Event{RelativePath} = $event_dir;
|
||||||
$Event->MonitorId( $monitor_dir );
|
$Event->MonitorId( $monitor_dir );
|
||||||
$Event->StorageId( $Storage->Id() );
|
$Event->StorageId( $Storage->Id() );
|
||||||
} # end foreach event
|
} # end foreach event
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! $$Storage{Scheme} ) {
|
if ( ! $$Storage{Scheme} ) {
|
||||||
|
Debug("Storage Scheme not set on $$Storage{Name}");
|
||||||
if ( ! chdir( $monitor_dir ) ) {
|
if ( ! chdir( $monitor_dir ) ) {
|
||||||
Error( "Can't chdir directory '$$Storage{Path}/$monitor_dir': $!" );
|
Error( "Can't chdir directory '$$Storage{Path}/$monitor_dir': $!" );
|
||||||
next;
|
next;
|
||||||
|
@ -321,12 +343,21 @@ MAIN: while( $loop ) {
|
||||||
|
|
||||||
#delete_empty_directories( $monitor_dir );
|
#delete_empty_directories( $monitor_dir );
|
||||||
} # end foreach monitor
|
} # end foreach monitor
|
||||||
redo MAIN if ( $cleaned );
|
|
||||||
|
if ( $cleaned ) {
|
||||||
|
Debug("First stage cleaning done. Restarting.");
|
||||||
|
redo MAIN;
|
||||||
|
}
|
||||||
|
|
||||||
$cleaned = 0;
|
$cleaned = 0;
|
||||||
while ( my ( $monitor_id, $fs_events ) = each(%$fs_monitors) ) {
|
while ( my ( $monitor_id, $fs_events ) = each(%$fs_monitors) ) {
|
||||||
if ( my $db_events = $db_monitors->{$monitor_id} ) {
|
if ( my $db_events = $db_monitors->{$monitor_id} ) {
|
||||||
next if ! $fs_events;
|
if ( ! $fs_events ) {
|
||||||
|
Debug("No fs_events for database monitor $monitor_id");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
my @event_ids = keys %$fs_events;
|
||||||
|
Debug("Have " .scalar @event_ids . " events for monitor $monitor_id");
|
||||||
|
|
||||||
foreach my $fs_event_id ( sort { $a <=> $b } keys %$fs_events ) {
|
foreach my $fs_event_id ( sort { $a <=> $b } keys %$fs_events ) {
|
||||||
|
|
||||||
|
@ -347,6 +378,7 @@ MAIN: while( $loop ) {
|
||||||
} # end foreach fs event
|
} # end foreach fs event
|
||||||
} else {
|
} else {
|
||||||
aud_print( "Filesystem monitor '$monitor_id' in $$Storage{Path} does not exist in database" );
|
aud_print( "Filesystem monitor '$monitor_id' in $$Storage{Path} does not exist in database" );
|
||||||
|
|
||||||
if ( confirm() ) {
|
if ( confirm() ) {
|
||||||
my $command = "rm -rf $monitor_id";
|
my $command = "rm -rf $monitor_id";
|
||||||
executeShellCommand( $command );
|
executeShellCommand( $command );
|
||||||
|
@ -477,7 +509,7 @@ MAIN: while( $loop ) {
|
||||||
$res = $selectEmptyEventsSth->execute()
|
$res = $selectEmptyEventsSth->execute()
|
||||||
or Fatal( "Can't execute: ".$selectEmptyEventsSth->errstr() );
|
or Fatal( "Can't execute: ".$selectEmptyEventsSth->errstr() );
|
||||||
while( my $event = $selectEmptyEventsSth->fetchrow_hashref() ) {
|
while( my $event = $selectEmptyEventsSth->fetchrow_hashref() ) {
|
||||||
aud_print( "Found empty event with no frame records '$event->{Id}'" );
|
aud_print( "Found empty event with no frame records '$event->{Id}' at $$event{StartTime}" );
|
||||||
if ( confirm() ) {
|
if ( confirm() ) {
|
||||||
$res = $deleteEventSth->execute( $event->{Id} )
|
$res = $deleteEventSth->execute( $event->{Id} )
|
||||||
or Fatal( "Can't execute: ".$deleteEventSth->errstr() );
|
or Fatal( "Can't execute: ".$deleteEventSth->errstr() );
|
||||||
|
@ -689,7 +721,7 @@ sub confirm {
|
||||||
if ( $report ) {
|
if ( $report ) {
|
||||||
print( "\n" );
|
print( "\n" );
|
||||||
} elsif ( $interactive ) {
|
} elsif ( $interactive ) {
|
||||||
print( ", $prompt y/n: " );
|
print( ", $prompt Y/n/q: " );
|
||||||
my $char = <>;
|
my $char = <>;
|
||||||
chomp( $char );
|
chomp( $char );
|
||||||
if ( $char eq 'q' ) {
|
if ( $char eq 'q' ) {
|
||||||
|
@ -784,6 +816,7 @@ yet.
|
||||||
-c, --continuous - Run continuously
|
-c, --continuous - Run continuously
|
||||||
-f, --force - Run even if pid file exists
|
-f, --force - Run even if pid file exists
|
||||||
-i, --interactive - Ask before applying any changes
|
-i, --interactive - Ask before applying any changes
|
||||||
|
-m, --monitor_id - Only consider the given monitor
|
||||||
-r, --report - Just report don't actually do anything
|
-r, --report - Just report don't actually do anything
|
||||||
-s, --storage_id - Specify a storage area to audit instead of all
|
-s, --storage_id - Specify a storage area to audit instead of all
|
||||||
-v, --version - Print the installed version of ZoneMinder
|
-v, --version - Print the installed version of ZoneMinder
|
||||||
|
|
|
@ -183,39 +183,39 @@ use Sys::CpuLoad;
|
||||||
|
|
||||||
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
|
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
|
||||||
my $attempts = 0;
|
my $attempts = 0;
|
||||||
while( !connect( CLIENT, $saddr ) ) {
|
while( !connect(CLIENT, $saddr) ) {
|
||||||
$attempts++;
|
$attempts++;
|
||||||
Debug("Waiting for zmdc.pl server process at ".SOCK_FILE.", attempt $attempts" );
|
Debug("Waiting for zmdc.pl server process at ".SOCK_FILE.", attempt $attempts");
|
||||||
Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY);
|
Fatal("Can't connect: $!") if $attempts > MAX_CONNECT_DELAY;
|
||||||
usleep(200000);
|
usleep(200000);
|
||||||
} # end while
|
} # end while
|
||||||
} elsif ( defined($cpid) ) {
|
} elsif ( defined($cpid) ) {
|
||||||
ZMServer::run();
|
ZMServer::run();
|
||||||
} else {
|
} else {
|
||||||
Fatal( "Can't fork: $!" );
|
Fatal("Can't fork: $!");
|
||||||
}
|
}
|
||||||
} # end if ! server is up
|
} # end if ! server is up
|
||||||
|
|
||||||
if ( $command eq 'check' && ! $daemon ) {
|
if ( ($command eq 'check') && !$daemon ) {
|
||||||
print( "running\n" );
|
print("running\n");
|
||||||
exit();
|
exit();
|
||||||
} elsif ( $command eq 'startup' ) {
|
} elsif ( $command eq 'startup' ) {
|
||||||
# Our work here is done
|
# Our work here is done
|
||||||
exit() if ( !$server_up );
|
exit() if !$server_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
# The server is there, connect to it
|
# The server is there, connect to it
|
||||||
#print( "Writing commands\n" );
|
#print( "Writing commands\n" );
|
||||||
CLIENT->autoflush();
|
CLIENT->autoflush();
|
||||||
my $message = join(';', $command, ( $daemon ? $daemon : () ), @args );
|
my $message = join(';', $command, ( $daemon ? $daemon : () ), @args );
|
||||||
print( CLIENT $message );
|
print(CLIENT $message);
|
||||||
shutdown( CLIENT, 1 );
|
shutdown(CLIENT, 1);
|
||||||
while( my $line = <CLIENT> ) {
|
while( my $line = <CLIENT> ) {
|
||||||
chomp( $line );
|
chomp($line);
|
||||||
print( "$line\n" );
|
print("$line\n");
|
||||||
}
|
}
|
||||||
# And we're done!
|
# And we're done!
|
||||||
close( CLIENT );
|
close(CLIENT);
|
||||||
#print( "Finished writing, bye\n" );
|
#print( "Finished writing, bye\n" );
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
|
@ -344,9 +344,9 @@ sub run {
|
||||||
} else {
|
} else {
|
||||||
dPrint( ZoneMinder::Logger::ERROR, "Invalid command '$command'\n" );
|
dPrint( ZoneMinder::Logger::ERROR, "Invalid command '$command'\n" );
|
||||||
}
|
}
|
||||||
close( CLIENT );
|
close(CLIENT);
|
||||||
} else {
|
} else {
|
||||||
Fatal( 'Bogus descriptor' );
|
Fatal('Bogus descriptor');
|
||||||
}
|
}
|
||||||
} elsif ( $nfound < 0 ) {
|
} elsif ( $nfound < 0 ) {
|
||||||
if ( $! == EINTR ) {
|
if ( $! == EINTR ) {
|
||||||
|
@ -355,9 +355,9 @@ sub run {
|
||||||
# See if it needs to start up again
|
# See if it needs to start up again
|
||||||
restartPending();
|
restartPending();
|
||||||
} elsif ( $! == EPIPE ) {
|
} elsif ( $! == EPIPE ) {
|
||||||
Error( "Can't select: $!" );
|
Error("Can't select: $!");
|
||||||
} else {
|
} else {
|
||||||
Fatal( "Can't select: $!" );
|
Fatal("Can't select: $!");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#print( "Select timed out\n" );
|
#print( "Select timed out\n" );
|
||||||
|
@ -566,19 +566,19 @@ sub restart {
|
||||||
|
|
||||||
my $command = $daemon;
|
my $command = $daemon;
|
||||||
$command .= ' '.join( ' ', ( @args ) ) if @args;
|
$command .= ' '.join( ' ', ( @args ) ) if @args;
|
||||||
dPrint ( ZoneMinder::Logger::WARNING, "Restarting $command\n");
|
dPrint ( ZoneMinder::Logger::DEBUG, "Restarting $command\n");
|
||||||
my $process = $cmd_hash{$command};
|
my $process = $cmd_hash{$command};
|
||||||
if ( $process ) {
|
if ( $process ) {
|
||||||
dPrint ( ZoneMinder::Logger::WARNING, "Have process" );
|
dPrint( ZoneMinder::Logger::DEBUG, "Have process" );
|
||||||
if ( $process->{pid} ) {
|
if ( $process->{pid} ) {
|
||||||
dPrint ( ZoneMinder::Logger::WARNING, "Have process pid " .$process->{pid} );
|
dPrint( ZoneMinder::Logger::DEBUG, "Have process pid " .$process->{pid} );
|
||||||
my $cpid = $process->{pid};
|
my $cpid = $process->{pid};
|
||||||
if ( defined($pid_hash{$cpid}) ) {
|
if ( defined($pid_hash{$cpid}) ) {
|
||||||
dPrint ( ZoneMinder::Logger::WARNING, "Have process pid hash " .$process->{pid} );
|
dPrint( ZoneMinder::Logger::DEBUG, "Have process pid hash " .$process->{pid} );
|
||||||
_stop( 0, $process );
|
_stop( 0, $process );
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
dPrint ( ZoneMinder::Logger::WARNING, "Not sending stop" );
|
dPrint( ZoneMinder::Logger::DEBUG, "Not sending stop" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ use autouse 'Data::Dumper'=>qw(Dumper);
|
||||||
my $filter_name = '';
|
my $filter_name = '';
|
||||||
my $filter_id;
|
my $filter_id;
|
||||||
my $version = 0;
|
my $version = 0;
|
||||||
|
my $zm_terminate = 0;
|
||||||
|
|
||||||
GetOptions(
|
GetOptions(
|
||||||
'filter=s' =>\$filter_name,
|
'filter=s' =>\$filter_name,
|
||||||
|
@ -94,7 +95,20 @@ use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|)
|
||||||
;
|
;
|
||||||
|
|
||||||
logInit();
|
logInit();
|
||||||
logSetSignal();
|
sub HupHandler {
|
||||||
|
Info("Received HUP, reloading");
|
||||||
|
&ZoneMinder::Logger::logHupHandler();
|
||||||
|
}
|
||||||
|
sub TermHandler {
|
||||||
|
Info("Received TERM, exiting");
|
||||||
|
$zm_terminate = 1;
|
||||||
|
}
|
||||||
|
sub Term {
|
||||||
|
exit( 0 );
|
||||||
|
}
|
||||||
|
$SIG{HUP} = \&HupHandler;
|
||||||
|
$SIG{TERM} = \&TermHandler;
|
||||||
|
$SIG{INT} = \&TermHandler;
|
||||||
|
|
||||||
if ( $Config{ZM_OPT_UPLOAD} ) {
|
if ( $Config{ZM_OPT_UPLOAD} ) {
|
||||||
# Comment these out if you don't have them and don't want to upload
|
# Comment these out if you don't have them and don't want to upload
|
||||||
|
@ -166,7 +180,7 @@ if ( ! ( $filter_name or $filter_id ) ) {
|
||||||
my @filters;
|
my @filters;
|
||||||
my $last_action = 0;
|
my $last_action = 0;
|
||||||
|
|
||||||
while( 1 ) {
|
while( ! $zm_terminate ) {
|
||||||
my $now = time;
|
my $now = time;
|
||||||
if ( ($now - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} ) {
|
if ( ($now - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} ) {
|
||||||
Debug( "Reloading filters\n" );
|
Debug( "Reloading filters\n" );
|
||||||
|
@ -175,6 +189,7 @@ while( 1 ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $filter ( @filters ) {
|
foreach my $filter ( @filters ) {
|
||||||
|
last if $zm_terminate;
|
||||||
if ( $$filter{Concurrent} and ! ( $filter_id or $filter_name ) ) {
|
if ( $$filter{Concurrent} and ! ( $filter_id or $filter_name ) ) {
|
||||||
my ( $proc ) = $0 =~ /(\S+)/;
|
my ( $proc ) = $0 =~ /(\S+)/;
|
||||||
my ( $id ) = $$filter{Id} =~ /(\d+)/;
|
my ( $id ) = $$filter{Id} =~ /(\d+)/;
|
||||||
|
@ -186,7 +201,7 @@ while( 1 ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last if ( $filter_name or $filter_id );
|
last if $filter_name or $filter_id or $zm_terminate;
|
||||||
|
|
||||||
Debug( "Sleeping for $delay seconds\n" );
|
Debug( "Sleeping for $delay seconds\n" );
|
||||||
sleep( $delay );
|
sleep( $delay );
|
||||||
|
@ -266,6 +281,7 @@ sub checkFilter {
|
||||||
) );
|
) );
|
||||||
|
|
||||||
foreach my $event ( @Events ) {
|
foreach my $event ( @Events ) {
|
||||||
|
last if $zm_terminate;
|
||||||
Debug( "Checking event $event->{Id}" );
|
Debug( "Checking event $event->{Id}" );
|
||||||
my $delete_ok = !undef;
|
my $delete_ok = !undef;
|
||||||
$dbh->ping();
|
$dbh->ping();
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
#
|
||||||
|
# ==========================================================================
|
||||||
|
#
|
||||||
|
# ZoneMinder ONVIF Control Protocol Module
|
||||||
|
# Copyright (C) 2014 Jan M. Hochstein
|
||||||
|
#
|
||||||
|
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
#
|
||||||
|
# ==========================================================================
|
||||||
|
#
|
||||||
|
# This module contains the implementation of the ONVIF capability prober
|
||||||
|
#
|
||||||
|
|
||||||
|
use Getopt::Std;
|
||||||
|
|
||||||
|
require ONVIF::Client;
|
||||||
|
|
||||||
|
|
||||||
|
# ========================================================================
|
||||||
|
# options processing
|
||||||
|
|
||||||
|
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||||
|
|
||||||
|
our ($opt_v);
|
||||||
|
|
||||||
|
my $OPTIONS = "v";
|
||||||
|
|
||||||
|
sub HELP_MESSAGE
|
||||||
|
{
|
||||||
|
my ($fh, $pkg, $ver, $opts) = @_;
|
||||||
|
print $fh "Usage: " . __FILE__ . " [-v] probe <soap version>\n";
|
||||||
|
print $fh " " . __FILE__ . " [-v] <command> <device URI> <soap version> <user> <password>\n";
|
||||||
|
print $fh <<EOF
|
||||||
|
Commands are:
|
||||||
|
probe - scan for devices on the local network and list them
|
||||||
|
profiles - print the device's supported stream configurations
|
||||||
|
metadata - print some of the device's configuration settings
|
||||||
|
move - move the device (only ptz cameras)
|
||||||
|
Common parameters:
|
||||||
|
-v - increase verbosity
|
||||||
|
Device access parameters (for all commands but 'probe'):
|
||||||
|
device URL - the ONVIF Device service URL
|
||||||
|
soap version - SOAP version (1.1 or 1.2)
|
||||||
|
user - username of a user with access to the device
|
||||||
|
password - password for the user
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# ========================================================================
|
||||||
|
# MAIN
|
||||||
|
|
||||||
|
if ( !getopts($OPTIONS) ) {
|
||||||
|
HELP_MESSAGE(\*STDOUT);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $action = shift;
|
||||||
|
|
||||||
|
if(!defined $action) {
|
||||||
|
HELP_MESSAGE(\*STDOUT);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EXTRA_PERL_LIB@
|
||||||
|
require ZoneMinder::ONVIF;
|
||||||
|
if ( defined $opt_v ) {
|
||||||
|
$ZoneMinder::ONVIF::verbose = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $action eq "probe" ) {
|
||||||
|
my $soap_version = shift;
|
||||||
|
ZoneMinder::ONVIF::discover($soap_version);
|
||||||
|
} else {
|
||||||
|
# all other actions need URI and credentials
|
||||||
|
my $url_svc_device = shift @ARGV;
|
||||||
|
my $soap_version = shift @ARGV;
|
||||||
|
my $username = @ARGV ? shift @ARGV : '';
|
||||||
|
my $password = @ARGV ? shift @ARGV: '';
|
||||||
|
|
||||||
|
my $client = ONVIF::Client->new( {
|
||||||
|
'url_svc_device' => $url_svc_device,
|
||||||
|
'soap_version' => $soap_version } );
|
||||||
|
|
||||||
|
$client->set_credentials($username, $password, 1);
|
||||||
|
|
||||||
|
$client->create_services();
|
||||||
|
|
||||||
|
|
||||||
|
if ( $action eq "profiles" ) {
|
||||||
|
ZoneMinder::ONVIF::profiles($client);
|
||||||
|
} elsif( $action eq "move" ) {
|
||||||
|
my $dir = shift;
|
||||||
|
ZoneMinder::ONVIF::move($client, $dir);
|
||||||
|
} elsif ( $action eq "metadata" ) {
|
||||||
|
ZoneMinder::ONVIF::metadata($client);
|
||||||
|
} else {
|
||||||
|
print("Error: Unknown command\"$action\"");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
zmonvif-probe.pl - ZoneMinder ONVIF probing tool
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
zmonfig-probe.pl [-v] probe <soap version>
|
||||||
|
[-v] <command> <device URI> <soap version> <user> <password>\n";
|
||||||
|
|
||||||
|
Commands are:
|
||||||
|
probe - scan for devices on the local network and list them
|
||||||
|
profiles - print the device's supported stream configurations
|
||||||
|
metadata - print some of the device's configuration settings
|
||||||
|
move - move the device (only ptz cameras)
|
||||||
|
Common parameters:
|
||||||
|
-v - increase verbosity
|
||||||
|
Device access parameters (for all commands but 'probe'):
|
||||||
|
device URL - the ONVIF Device service URL
|
||||||
|
soap version - SOAP version (1.1 or 1.2)
|
||||||
|
user - username of a user with access to the device
|
||||||
|
password - password for the user
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
|
||||||
|
=head1 OPTIONS
|
||||||
|
|
||||||
|
-c, --continuous - Run continuously
|
||||||
|
-f, --force - Run even if pid file exists
|
||||||
|
-i, --interactive - Ask before applying any changes
|
||||||
|
-m, --monitor_id - Only consider the given monitor
|
||||||
|
-r, --report - Just report don't actually do anything
|
||||||
|
-s, --storage_id - Specify a storage area to audit instead of all
|
||||||
|
-v, --version - Print the installed version of ZoneMinder
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
|
@ -43,7 +43,12 @@ int Event::pre_alarm_count = 0;
|
||||||
|
|
||||||
Event::PreAlarmData Event::pre_alarm_data[MAX_PRE_ALARM_FRAMES] = { { 0 } };
|
Event::PreAlarmData Event::pre_alarm_data[MAX_PRE_ALARM_FRAMES] = { { 0 } };
|
||||||
|
|
||||||
Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string &p_cause, const StringSetMap &p_noteSetMap, bool p_videoEvent ) :
|
Event::Event(
|
||||||
|
Monitor *p_monitor,
|
||||||
|
struct timeval p_start_time,
|
||||||
|
const std::string &p_cause,
|
||||||
|
const StringSetMap &p_noteSetMap,
|
||||||
|
bool p_videoEvent ) :
|
||||||
monitor( p_monitor ),
|
monitor( p_monitor ),
|
||||||
start_time( p_start_time ),
|
start_time( p_start_time ),
|
||||||
cause( p_cause ),
|
cause( p_cause ),
|
||||||
|
@ -53,12 +58,18 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string notes;
|
std::string notes;
|
||||||
createNotes( notes );
|
createNotes(notes);
|
||||||
|
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
|
||||||
bool untimedEvent = false;
|
bool untimedEvent = false;
|
||||||
if ( !start_time.tv_sec ) {
|
if ( !start_time.tv_sec ) {
|
||||||
untimedEvent = true;
|
untimedEvent = true;
|
||||||
gettimeofday( &start_time, 0 );
|
start_time = now;
|
||||||
|
} else if ( start_time.tv_sec > now.tv_sec ) {
|
||||||
|
Error("StartTime in the future");
|
||||||
|
start_time = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
Storage * storage = monitor->getStorage();
|
Storage * storage = monitor->getStorage();
|
||||||
|
@ -216,7 +227,8 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
|
||||||
Event::~Event() {
|
Event::~Event() {
|
||||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||||
struct DeltaTimeval delta_time;
|
struct DeltaTimeval delta_time;
|
||||||
DELTA_TIMEVAL( delta_time, end_time, start_time, DT_PREC_2 );
|
DELTA_TIMEVAL(delta_time, end_time, start_time, DT_PREC_2);
|
||||||
|
Debug(2, "start_time:%d.%d end_time%d.%d", start_time.tv_sec, start_time.tv_usec, end_time.tv_sec, end_time.tv_usec );
|
||||||
|
|
||||||
if ( frames > last_db_frame ) {
|
if ( frames > last_db_frame ) {
|
||||||
|
|
||||||
|
@ -462,6 +474,12 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st
|
||||||
|
|
||||||
struct DeltaTimeval delta_time;
|
struct DeltaTimeval delta_time;
|
||||||
DELTA_TIMEVAL( delta_time, *(timestamps[i]), start_time, DT_PREC_2 );
|
DELTA_TIMEVAL( delta_time, *(timestamps[i]), start_time, DT_PREC_2 );
|
||||||
|
// Delta is Decimal(8,2) so 6 integer digits and 2 decimal digits
|
||||||
|
if ( delta_time.sec > 999999 ) {
|
||||||
|
Warning("Invalid delta_time from_unixtime(%ld), %s%ld.%02ld",
|
||||||
|
timestamps[i]->tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec );
|
||||||
|
delta_time.sec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int sql_len = strlen(sql);
|
int sql_len = strlen(sql);
|
||||||
snprintf( sql+sql_len, sizeof(sql)-sql_len, "( %d, %d, from_unixtime(%ld), %s%ld.%02ld ), ", id, frames, timestamps[i]->tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec );
|
snprintf( sql+sql_len, sizeof(sql)-sql_len, "( %d, %d, from_unixtime(%ld), %s%ld.%02ld ), ", id, frames, timestamps[i]->tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec );
|
||||||
|
@ -474,7 +492,6 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st
|
||||||
*(sql+strlen(sql)-2) = '\0';
|
*(sql+strlen(sql)-2) = '\0';
|
||||||
if ( mysql_query( &dbconn, sql ) ) {
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
Error( "Can't insert frames: %s, sql was (%s)", mysql_error( &dbconn ), sql );
|
Error( "Can't insert frames: %s, sql was (%s)", mysql_error( &dbconn ), sql );
|
||||||
exit( mysql_errno( &dbconn ) );
|
|
||||||
}
|
}
|
||||||
last_db_frame = frames;
|
last_db_frame = frames;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -458,5 +458,5 @@ void dumpPacket(AVPacket *pkt, const char *text) {
|
||||||
pkt->flags & AV_PKT_FLAG_KEY,
|
pkt->flags & AV_PKT_FLAG_KEY,
|
||||||
pkt->pos,
|
pkt->pos,
|
||||||
pkt->duration);
|
pkt->duration);
|
||||||
Debug(1, "%s:%d:%s: %s", __FILE__, __LINE__, text, b);
|
Debug(2, "%s:%d:%s: %s", __FILE__, __LINE__, text, b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,6 @@ FfmpegCamera::FfmpegCamera( int p_id, const std::string &p_path, const std::stri
|
||||||
mIsOpening = false;
|
mIsOpening = false;
|
||||||
mCanCapture = false;
|
mCanCapture = false;
|
||||||
mOpenStart = 0;
|
mOpenStart = 0;
|
||||||
mReopenThread = 0;
|
|
||||||
videoStore = NULL;
|
videoStore = NULL;
|
||||||
video_last_pts = 0;
|
video_last_pts = 0;
|
||||||
have_video_keyframe = false;
|
have_video_keyframe = false;
|
||||||
|
@ -162,21 +161,18 @@ void FfmpegCamera::Terminate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int FfmpegCamera::PrimeCapture() {
|
int FfmpegCamera::PrimeCapture() {
|
||||||
|
if ( mCanCapture ) {
|
||||||
|
CloseFfmpeg();
|
||||||
|
}
|
||||||
mVideoStreamId = -1;
|
mVideoStreamId = -1;
|
||||||
mAudioStreamId = -1;
|
mAudioStreamId = -1;
|
||||||
Info( "Priming capture from %s", mPath.c_str() );
|
Info( "Priming capture from %s", mPath.c_str() );
|
||||||
|
|
||||||
#if THREAD
|
|
||||||
if ( OpenFfmpeg() != 0 ) {
|
|
||||||
ReopenFfmpeg();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
return OpenFfmpeg();
|
return OpenFfmpeg();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FfmpegCamera::PreCapture() {
|
int FfmpegCamera::PreCapture() {
|
||||||
|
Debug(1, "PreCapture");
|
||||||
// If Reopen was called, then ffmpeg is closed and we need to reopen it.
|
// If Reopen was called, then ffmpeg is closed and we need to reopen it.
|
||||||
if ( ! mCanCapture )
|
if ( ! mCanCapture )
|
||||||
return OpenFfmpeg();
|
return OpenFfmpeg();
|
||||||
|
@ -190,18 +186,6 @@ int FfmpegCamera::Capture( Image &image ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the reopen thread has a value, but mCanCapture != 0, then we have just reopened the connection to the ffmpeg device, and we can clean up the thread.
|
// If the reopen thread has a value, but mCanCapture != 0, then we have just reopened the connection to the ffmpeg device, and we can clean up the thread.
|
||||||
if ( mReopenThread != 0 ) {
|
|
||||||
void *retval = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = pthread_join(mReopenThread, &retval);
|
|
||||||
if ( ret != 0 ) {
|
|
||||||
Error("Could not join reopen thread.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Info( "Successfully reopened stream." );
|
|
||||||
mReopenThread = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int frameComplete = false;
|
int frameComplete = false;
|
||||||
while ( !frameComplete ) {
|
while ( !frameComplete ) {
|
||||||
|
@ -217,6 +201,7 @@ int FfmpegCamera::Capture( Image &image ) {
|
||||||
) {
|
) {
|
||||||
Info( "av_read_frame returned \"%s\". Reopening stream.", errbuf );
|
Info( "av_read_frame returned \"%s\". Reopening stream.", errbuf );
|
||||||
ReopenFfmpeg();
|
ReopenFfmpeg();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error( "Unable to read packet from stream %d: error %d \"%s\".", packet.stream_index, avResult, errbuf );
|
Error( "Unable to read packet from stream %d: error %d \"%s\".", packet.stream_index, avResult, errbuf );
|
||||||
|
@ -292,7 +277,7 @@ int FfmpegCamera::Capture( Image &image ) {
|
||||||
directbuffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
directbuffer = image.WriteBuffer(width, height, colours, subpixelorder);
|
||||||
if ( directbuffer == NULL ) {
|
if ( directbuffer == NULL ) {
|
||||||
Error("Failed requesting writeable buffer for the captured image.");
|
Error("Failed requesting writeable buffer for the captured image.");
|
||||||
return (-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
|
@ -304,8 +289,10 @@ int FfmpegCamera::Capture( Image &image ) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_LIBSWSCALE
|
#if HAVE_LIBSWSCALE
|
||||||
if ( sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0 )
|
if ( sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0 ) {
|
||||||
Fatal("Unable to convert raw format %u to target format %u at frame %d", mVideoCodecContext->pix_fmt, imagePixFormat, frameCount);
|
Error("Unable to convert raw format %u to target format %u at frame %d", mVideoCodecContext->pix_fmt, imagePixFormat, frameCount);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#else // HAVE_LIBSWSCALE
|
#else // HAVE_LIBSWSCALE
|
||||||
Fatal("You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras");
|
Fatal("You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras");
|
||||||
#endif // HAVE_LIBSWSCALE
|
#endif // HAVE_LIBSWSCALE
|
||||||
|
@ -327,10 +314,10 @@ int FfmpegCamera::PostCapture() {
|
||||||
|
|
||||||
int FfmpegCamera::OpenFfmpeg() {
|
int FfmpegCamera::OpenFfmpeg() {
|
||||||
|
|
||||||
Debug ( 2, "OpenFfmpeg called." );
|
Debug(2, "OpenFfmpeg called.");
|
||||||
uint32_t last_event_id = monitor->GetLastEventId() ;
|
uint32_t last_event_id = monitor->GetLastEventId() ;
|
||||||
uint32_t video_writer_event_id = monitor->GetVideoWriterEventId();
|
uint32_t video_writer_event_id = monitor->GetVideoWriterEventId();
|
||||||
Debug(2, "last_event(%d), our current (%d)", last_event_id, video_writer_event_id );
|
Debug(2, "last_event(%d), our current (%d)", last_event_id, video_writer_event_id);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -369,8 +356,6 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
Debug ( 1, "Calling avformat_open_input for %s", mPath.c_str() );
|
Debug ( 1, "Calling avformat_open_input for %s", mPath.c_str() );
|
||||||
|
|
||||||
mFormatContext = avformat_alloc_context( );
|
mFormatContext = avformat_alloc_context( );
|
||||||
//mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback;
|
|
||||||
//mFormatContext->interrupt_callback.opaque = this;
|
|
||||||
// Speed up find_stream_info
|
// Speed up find_stream_info
|
||||||
//FIXME can speed up initial analysis but need sensible parameters...
|
//FIXME can speed up initial analysis but need sensible parameters...
|
||||||
//mFormatContext->probesize = 32;
|
//mFormatContext->probesize = 32;
|
||||||
|
@ -380,7 +365,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
mIsOpening = false;
|
mIsOpening = false;
|
||||||
Error( "Unable to open input %s due to: %s", mPath.c_str(), strerror(errno) );
|
Error("Unable to open input %s due to: %s", mPath.c_str(), strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
AVDictionaryEntry *e=NULL;
|
AVDictionaryEntry *e=NULL;
|
||||||
|
@ -391,19 +376,19 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
mIsOpening = false;
|
mIsOpening = false;
|
||||||
Debug ( 1, "Opened input" );
|
Debug ( 1, "Opened input" );
|
||||||
|
|
||||||
Info( "Stream open %s", mPath.c_str() );
|
Info( "Stream open %s, parsing streams...", mPath.c_str() );
|
||||||
|
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 6, 0, 6, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 6, 0, 6, 0)
|
||||||
Debug ( 1, "Calling av_find_stream_info" );
|
Debug(4, "Calling av_find_stream_info");
|
||||||
if ( av_find_stream_info( mFormatContext ) < 0 )
|
if ( av_find_stream_info( mFormatContext ) < 0 )
|
||||||
#else
|
#else
|
||||||
Debug ( 1, "Calling avformat_find_stream_info" );
|
Debug(4, "Calling avformat_find_stream_info");
|
||||||
if ( avformat_find_stream_info( mFormatContext, 0 ) < 0 )
|
if ( avformat_find_stream_info( mFormatContext, 0 ) < 0 )
|
||||||
#endif
|
#endif
|
||||||
Fatal( "Unable to find stream info from %s due to: %s", mPath.c_str(), strerror(errno) );
|
Fatal("Unable to find stream info from %s due to: %s", mPath.c_str(), strerror(errno));
|
||||||
|
|
||||||
startTime = av_gettime();//FIXME here or after find_Stream_info
|
startTime = av_gettime();//FIXME here or after find_Stream_info
|
||||||
Debug ( 1, "Got stream info" );
|
Debug(4, "Got stream info");
|
||||||
|
|
||||||
// Find first video stream present
|
// Find first video stream present
|
||||||
// The one we want Might not be the first
|
// The one we want Might not be the first
|
||||||
|
@ -448,11 +433,11 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
if ( mAudioStreamId == -1 )
|
if ( mAudioStreamId == -1 )
|
||||||
Debug( 3, "Unable to locate audio stream in %s", mPath.c_str() );
|
Debug( 3, "Unable to locate audio stream in %s", mPath.c_str() );
|
||||||
|
|
||||||
Debug ( 3, "Found video stream at index %d", mVideoStreamId );
|
Debug(3, "Found video stream at index %d", mVideoStreamId);
|
||||||
Debug ( 3, "Found audio stream at index %d", mAudioStreamId );
|
Debug(3, "Found audio stream at index %d", mAudioStreamId);
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
mVideoCodecContext = avcodec_alloc_context3( NULL );
|
mVideoCodecContext = avcodec_alloc_context3(NULL);
|
||||||
avcodec_parameters_to_context( mVideoCodecContext, mFormatContext->streams[mVideoStreamId]->codecpar );
|
avcodec_parameters_to_context( mVideoCodecContext, mFormatContext->streams[mVideoStreamId]->codecpar );
|
||||||
#else
|
#else
|
||||||
mVideoCodecContext = mFormatContext->streams[mVideoStreamId]->codec;
|
mVideoCodecContext = mFormatContext->streams[mVideoStreamId]->codec;
|
||||||
|
@ -505,7 +490,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
Debug( 1, "Input stream appears to be h265. The stored event file may not be viewable in browser." );
|
Debug( 1, "Input stream appears to be h265. The stored event file may not be viewable in browser." );
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
Error( "Input stream is not h264. The stored event file may not be viewable in browser." );
|
Warning( "Input stream is not h264. The stored event file may not be viewable in browser." );
|
||||||
#ifdef AV_CODEC_ID_H265
|
#ifdef AV_CODEC_ID_H265
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -514,7 +499,8 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
|
|
||||||
if ( (!mVideoCodec) and ( (mVideoCodec = avcodec_find_decoder(mVideoCodecContext->codec_id)) == NULL ) ) {
|
if ( (!mVideoCodec) and ( (mVideoCodec = avcodec_find_decoder(mVideoCodecContext->codec_id)) == NULL ) ) {
|
||||||
// Try and get the codec from the codec context
|
// Try and get the codec from the codec context
|
||||||
Fatal("Can't find codec for video stream from %s", mPath.c_str());
|
Error("Can't find codec for video stream from %s", mPath.c_str());
|
||||||
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
Debug(1, "Video Found decoder");
|
Debug(1, "Video Found decoder");
|
||||||
zm_dump_stream_format(mFormatContext, mVideoStreamId, 0, 0);
|
zm_dump_stream_format(mFormatContext, mVideoStreamId, 0, 0);
|
||||||
|
@ -530,7 +516,8 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) {
|
||||||
Warning( "Option %s not recognized by ffmpeg", e->key);
|
Warning( "Option %s not recognized by ffmpeg", e->key);
|
||||||
}
|
}
|
||||||
Fatal( "Unable to open codec for video stream from %s", mPath.c_str() );
|
Error( "Unable to open codec for video stream from %s", mPath.c_str() );
|
||||||
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
AVDictionaryEntry *e = NULL;
|
AVDictionaryEntry *e = NULL;
|
||||||
|
@ -557,18 +544,20 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
} else {
|
} else {
|
||||||
Debug(1, "Audio Found decoder");
|
Debug(1, "Audio Found decoder");
|
||||||
zm_dump_stream_format(mFormatContext, mAudioStreamId, 0, 0);
|
zm_dump_stream_format(mFormatContext, mAudioStreamId, 0, 0);
|
||||||
// Open the codec
|
// Open the codec
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
|
||||||
Debug ( 1, "Calling avcodec_open" );
|
Debug ( 1, "Calling avcodec_open" );
|
||||||
if ( avcodec_open(mAudioCodecContext, mAudioCodec) < 0 )
|
if ( avcodec_open(mAudioCodecContext, mAudioCodec) < 0 ) {
|
||||||
#else
|
#else
|
||||||
Debug ( 1, "Calling avcodec_open2" );
|
Debug ( 1, "Calling avcodec_open2" );
|
||||||
if ( avcodec_open2(mAudioCodecContext, mAudioCodec, 0) < 0 )
|
if ( avcodec_open2(mAudioCodecContext, mAudioCodec, 0) < 0 ) {
|
||||||
#endif
|
#endif
|
||||||
Fatal( "Unable to open codec for video stream from %s", mPath.c_str() );
|
Error( "Unable to open codec for video stream from %s", mPath.c_str() );
|
||||||
}
|
return -1;
|
||||||
Debug ( 1, "Opened audio codec" );
|
}
|
||||||
}
|
Debug(2, "Opened audio codec");
|
||||||
|
} // end if find decoder
|
||||||
|
} // end if have audio_context
|
||||||
|
|
||||||
// Allocate space for the native video frame
|
// Allocate space for the native video frame
|
||||||
mRawFrame = zm_av_frame_alloc();
|
mRawFrame = zm_av_frame_alloc();
|
||||||
|
@ -576,10 +565,12 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
// Allocate space for the converted video frame
|
// Allocate space for the converted video frame
|
||||||
mFrame = zm_av_frame_alloc();
|
mFrame = zm_av_frame_alloc();
|
||||||
|
|
||||||
if ( mRawFrame == NULL || mFrame == NULL )
|
if ( mRawFrame == NULL || mFrame == NULL ) {
|
||||||
Fatal( "Unable to allocate frame for %s", mPath.c_str() );
|
Error("Unable to allocate frame for %s", mPath.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Debug ( 1, "Allocated frames" );
|
Debug( 3, "Allocated frames");
|
||||||
|
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 );
|
int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 );
|
||||||
|
@ -588,19 +579,22 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( (unsigned int)pSize != imagesize ) {
|
if ( (unsigned int)pSize != imagesize ) {
|
||||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
Error("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug ( 1, "Validated imagesize" );
|
Debug(4, "Validated imagesize");
|
||||||
|
|
||||||
#if HAVE_LIBSWSCALE
|
#if HAVE_LIBSWSCALE
|
||||||
Debug ( 1, "Calling sws_isSupportedInput" );
|
Debug(1, "Calling sws_isSupportedInput");
|
||||||
if ( !sws_isSupportedInput(mVideoCodecContext->pix_fmt) ) {
|
if ( !sws_isSupportedInput(mVideoCodecContext->pix_fmt) ) {
|
||||||
Fatal("swscale does not support the codec format: %c%c%c%c", (mVideoCodecContext->pix_fmt)&0xff, ((mVideoCodecContext->pix_fmt >> 8)&0xff), ((mVideoCodecContext->pix_fmt >> 16)&0xff), ((mVideoCodecContext->pix_fmt >> 24)&0xff));
|
Error("swscale does not support the codec format: %c%c%c%c", (mVideoCodecContext->pix_fmt)&0xff, ((mVideoCodecContext->pix_fmt >> 8)&0xff), ((mVideoCodecContext->pix_fmt >> 16)&0xff), ((mVideoCodecContext->pix_fmt >> 24)&0xff));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !sws_isSupportedOutput(imagePixFormat) ) {
|
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));
|
Error("swscale does not support the target format: %c%c%c%c",(imagePixFormat)&0xff,((imagePixFormat>>8)&0xff),((imagePixFormat>>16)&0xff),((imagePixFormat>>24)&0xff));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mConvertContext = sws_getContext(mVideoCodecContext->width,
|
mConvertContext = sws_getContext(mVideoCodecContext->width,
|
||||||
|
@ -609,8 +603,10 @@ int FfmpegCamera::OpenFfmpeg() {
|
||||||
width, height,
|
width, height,
|
||||||
imagePixFormat, SWS_BICUBIC, NULL,
|
imagePixFormat, SWS_BICUBIC, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if ( mConvertContext == NULL )
|
if ( mConvertContext == NULL ) {
|
||||||
Fatal( "Unable to create conversion context for %s", mPath.c_str() );
|
Error( "Unable to create conversion context for %s", mPath.c_str() );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#else // HAVE_LIBSWSCALE
|
#else // HAVE_LIBSWSCALE
|
||||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" );
|
Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" );
|
||||||
#endif // HAVE_LIBSWSCALE
|
#endif // HAVE_LIBSWSCALE
|
||||||
|
@ -628,19 +624,8 @@ int FfmpegCamera::ReopenFfmpeg() {
|
||||||
|
|
||||||
Debug(2, "ReopenFfmpeg called.");
|
Debug(2, "ReopenFfmpeg called.");
|
||||||
|
|
||||||
#if THREAD
|
|
||||||
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." );
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
CloseFfmpeg();
|
CloseFfmpeg();
|
||||||
OpenFfmpeg();
|
return OpenFfmpeg();
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FfmpegCamera::CloseFfmpeg() {
|
int FfmpegCamera::CloseFfmpeg() {
|
||||||
|
@ -690,45 +675,7 @@ int FfmpegCamera::CloseFfmpeg() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} // end FfmpegCamera::Close
|
||||||
|
|
||||||
int FfmpegCamera::FfmpegInterruptCallback(void *ctx) {
|
|
||||||
Debug(3,"FfmpegInteruptCallback");
|
|
||||||
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){
|
|
||||||
Debug(3,"FfmpegReopenThreadtCallback");
|
|
||||||
if ( ctx == NULL ) return NULL;
|
|
||||||
|
|
||||||
FfmpegCamera* camera = reinterpret_cast<FfmpegCamera*>(ctx);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
// Close current stream.
|
|
||||||
camera->CloseFfmpeg();
|
|
||||||
|
|
||||||
// Sleep if necessary 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Function to handle capture and store
|
//Function to handle capture and store
|
||||||
int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event_file ) {
|
int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event_file ) {
|
||||||
|
@ -738,20 +685,6 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
||||||
int ret;
|
int ret;
|
||||||
static char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
static char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
||||||
|
|
||||||
// If the reopen thread has a value, but mCanCapture != 0, then we have just reopened
|
|
||||||
// the connection to the ffmpeg device, and we can clean up the thread.
|
|
||||||
if ( mReopenThread != 0 ) {
|
|
||||||
void *retval = 0;
|
|
||||||
|
|
||||||
ret = pthread_join(mReopenThread, &retval);
|
|
||||||
if (ret != 0){
|
|
||||||
Error("Could not join reopen thread.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Info( "Successfully reopened stream." );
|
|
||||||
mReopenThread = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int frameComplete = false;
|
int frameComplete = false;
|
||||||
while ( ! frameComplete ) {
|
while ( ! frameComplete ) {
|
||||||
av_init_packet( &packet );
|
av_init_packet( &packet );
|
||||||
|
@ -995,8 +928,9 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event
|
||||||
|
|
||||||
if (sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize,
|
if (sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize,
|
||||||
0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0) {
|
0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0) {
|
||||||
Fatal("Unable to convert raw format %u to target format %u at frame %d",
|
Error("Unable to convert raw format %u to target format %u at frame %d",
|
||||||
mVideoCodecContext->pix_fmt, imagePixFormat, frameCount);
|
mVideoCodecContext->pix_fmt, imagePixFormat, frameCount);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
frameCount++;
|
frameCount++;
|
||||||
|
|
|
@ -76,12 +76,9 @@ class FfmpegCamera : public Camera {
|
||||||
int OpenFfmpeg();
|
int OpenFfmpeg();
|
||||||
int ReopenFfmpeg();
|
int ReopenFfmpeg();
|
||||||
int CloseFfmpeg();
|
int CloseFfmpeg();
|
||||||
static int FfmpegInterruptCallback(void *ctx);
|
|
||||||
static void* ReopenFfmpegThreadCallback(void *ctx);
|
|
||||||
bool mIsOpening;
|
bool mIsOpening;
|
||||||
bool mCanCapture;
|
bool mCanCapture;
|
||||||
int mOpenStart;
|
int mOpenStart;
|
||||||
pthread_t mReopenThread;
|
|
||||||
#endif // HAVE_LIBAVFORMAT
|
#endif // HAVE_LIBAVFORMAT
|
||||||
|
|
||||||
VideoStore *videoStore;
|
VideoStore *videoStore;
|
||||||
|
|
|
@ -479,12 +479,12 @@ Debug(2,"last_write_index(%d), last_write_time(%d)", shared_data->last_write_ind
|
||||||
while(
|
while(
|
||||||
( shared_data->last_write_index == (unsigned int)image_buffer_count )
|
( shared_data->last_write_index == (unsigned int)image_buffer_count )
|
||||||
&&
|
&&
|
||||||
( shared_data->last_write_time == 0)
|
( shared_data->last_write_time == 0 )
|
||||||
&&
|
&&
|
||||||
( !zm_terminate )
|
( !zm_terminate )
|
||||||
) {
|
) {
|
||||||
Warning( "Waiting for capture daemon" );
|
Debug(1, "Waiting for capture daemon");
|
||||||
sleep( 1 );
|
sleep(1);
|
||||||
}
|
}
|
||||||
ref_image.Assign( width, height, camera->Colours(), camera->SubpixelOrder(), image_buffer[shared_data->last_write_index].image->Buffer(), camera->ImageSize());
|
ref_image.Assign( width, height, camera->Colours(), camera->SubpixelOrder(), image_buffer[shared_data->last_write_index].image->Buffer(), camera->ImageSize());
|
||||||
adaptive_skip = true;
|
adaptive_skip = true;
|
||||||
|
@ -1205,7 +1205,7 @@ bool Monitor::Analyse() {
|
||||||
fps = double(fps_report_interval)/(now.tv_sec - last_fps_time);
|
fps = double(fps_report_interval)/(now.tv_sec - last_fps_time);
|
||||||
Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps );
|
Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps );
|
||||||
static char sql[ZM_SQL_SML_BUFSIZ];
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
snprintf( sql, sizeof(sql), "INSERT INTO Monitor_Status (Id,AnalysisFPS) VALUES (%d, %.2lf) ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf", id, fps, fps );
|
snprintf( sql, sizeof(sql), "INSERT INTO Monitor_Status (MonitorId,AnalysisFPS) VALUES (%d, %.2lf) ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf", id, fps, fps );
|
||||||
if ( mysql_query( &dbconn, sql ) ) {
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
}
|
}
|
||||||
|
@ -1937,7 +1937,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose
|
||||||
}
|
}
|
||||||
Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
|
Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
|
||||||
col++;
|
col++;
|
||||||
const char *method = dbrow[col]; col++;
|
const char *method = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
|
||||||
int width = atoi(dbrow[col]); col++;
|
int width = atoi(dbrow[col]); col++;
|
||||||
int height = atoi(dbrow[col]); col++;
|
int height = atoi(dbrow[col]); col++;
|
||||||
|
@ -2438,7 +2438,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose
|
||||||
const char *linked_monitors = dbrow[col] ? dbrow[col] : ""; col++;
|
const char *linked_monitors = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
|
||||||
const char *path = dbrow[col]; col++;
|
const char *path = dbrow[col]; col++;
|
||||||
const char *method = dbrow[col]; col++;
|
const char *method = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
const char *options = dbrow[col] ? dbrow[col] : ""; col++;
|
const char *options = dbrow[col] ? dbrow[col] : ""; col++;
|
||||||
|
|
||||||
int width = atoi(dbrow[col]); col++;
|
int width = atoi(dbrow[col]); col++;
|
||||||
|
@ -3022,7 +3022,7 @@ Debug(4, "Return from Capture (%d)", captureResult);
|
||||||
Info( "%s: images:%d - Capturing at %.2lf fps", name, image_count, fps );
|
Info( "%s: images:%d - Capturing at %.2lf fps", name, image_count, fps );
|
||||||
last_fps_time = now;
|
last_fps_time = now;
|
||||||
static char sql[ZM_SQL_SML_BUFSIZ];
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
snprintf( sql, sizeof(sql), "INSERT INTO Monitor_Status (Id,CaptureFPS) VALUES (%d, %.2lf) ON DUPLICATE KEY UPDATE CaptureFPS = %.2lf", id, fps, fps );
|
snprintf( sql, sizeof(sql), "INSERT INTO Monitor_Status (MonitorId,CaptureFPS) VALUES (%d, %.2lf) ON DUPLICATE KEY UPDATE CaptureFPS = %.2lf", id, fps, fps );
|
||||||
if ( mysql_query( &dbconn, sql ) ) {
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,7 +338,7 @@ void MonitorStream::processCommand( const CmdMsg *msg ) {
|
||||||
//exit( -1 );
|
//exit( -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Debug(2, "NUmber of bytes sent: (%d)", nbytes );
|
Debug(2, "NUmber of bytes sent to (%s): (%d)", rem_addr.sun_path, nbytes );
|
||||||
|
|
||||||
// quit after sending a status, if this was a quit request
|
// quit after sending a status, if this was a quit request
|
||||||
if ( (MsgCommand)msg->msg_data[0]==CMD_QUIT ) {
|
if ( (MsgCommand)msg->msg_data[0]==CMD_QUIT ) {
|
||||||
|
@ -396,7 +396,7 @@ bool MonitorStream::sendFrame( const char *filepath, struct timeval *timestamp )
|
||||||
int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime );
|
int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime );
|
||||||
if ( frameSendTime > 1000/maxfps ) {
|
if ( frameSendTime > 1000/maxfps ) {
|
||||||
maxfps /= 2;
|
maxfps /= 2;
|
||||||
Error( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps );
|
Info( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps );
|
||||||
}
|
}
|
||||||
|
|
||||||
last_frame_sent = TV_2_FLOAT( now );
|
last_frame_sent = TV_2_FLOAT( now );
|
||||||
|
@ -579,7 +579,6 @@ void MonitorStream::runStream() {
|
||||||
gettimeofday( &now, NULL );
|
gettimeofday( &now, NULL );
|
||||||
|
|
||||||
if ( connkey ) {
|
if ( connkey ) {
|
||||||
Debug(2, "checking command Queue for connkey: %d", connkey );
|
|
||||||
while(checkCommandQueue()) {
|
while(checkCommandQueue()) {
|
||||||
Debug(2, "Have checking command Queue for connkey: %d", connkey );
|
Debug(2, "Have checking command Queue for connkey: %d", connkey );
|
||||||
got_command = true;
|
got_command = true;
|
||||||
|
@ -664,7 +663,7 @@ Debug(2, "Have checking command Queue for connkey: %d", connkey );
|
||||||
if ( last_read_index != monitor->shared_data->last_write_index ) {
|
if ( last_read_index != monitor->shared_data->last_write_index ) {
|
||||||
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; // % shouldn't be neccessary
|
int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; // % shouldn't be neccessary
|
||||||
last_read_index = monitor->shared_data->last_write_index;
|
last_read_index = monitor->shared_data->last_write_index;
|
||||||
Debug( 1, "index: %d: frame_mod: %d frame count: %d", index, frame_mod, frame_count );
|
Debug( 3, "index: %d: frame_mod: %d frame count: %d", index, frame_mod, frame_count );
|
||||||
if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) {
|
if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) {
|
||||||
if ( !paused && !delayed ) {
|
if ( !paused && !delayed ) {
|
||||||
// Send the next frame
|
// Send the next frame
|
||||||
|
@ -713,11 +712,11 @@ Debug(2, "Have checking command Queue for connkey: %d", connkey );
|
||||||
} // end if buffered playback
|
} // end if buffered playback
|
||||||
frame_count++;
|
frame_count++;
|
||||||
} else {
|
} else {
|
||||||
Debug(2,"Waiting for capture");
|
Debug(5,"Waiting for capture");
|
||||||
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index )
|
} // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index )
|
||||||
|
|
||||||
unsigned long sleep_time = (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2)));
|
unsigned long sleep_time = (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2)));
|
||||||
Debug(2, "Sleeping for (%d)", sleep_time);
|
Debug(4, "Sleeping for (%d)", sleep_time);
|
||||||
usleep( sleep_time );
|
usleep( sleep_time );
|
||||||
if ( ttl ) {
|
if ( ttl ) {
|
||||||
if ( (now.tv_sec - stream_start_time) > ttl ) {
|
if ( (now.tv_sec - stream_start_time) > ttl ) {
|
||||||
|
|
|
@ -99,6 +99,7 @@ void VideoStream::SetupFormat( ) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
Debug(1,"No allocating priv_data");
|
||||||
s->priv_data = NULL;
|
s->priv_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +121,6 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
/* ffmpeg format matching */
|
/* ffmpeg format matching */
|
||||||
switch(colours) {
|
switch(colours) {
|
||||||
case ZM_COLOUR_RGB24:
|
case ZM_COLOUR_RGB24:
|
||||||
{
|
|
||||||
if(subpixelorder == ZM_SUBPIX_ORDER_BGR) {
|
if(subpixelorder == ZM_SUBPIX_ORDER_BGR) {
|
||||||
/* BGR subpixel order */
|
/* BGR subpixel order */
|
||||||
pf = AV_PIX_FMT_BGR24;
|
pf = AV_PIX_FMT_BGR24;
|
||||||
|
@ -129,9 +129,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
pf = AV_PIX_FMT_RGB24;
|
pf = AV_PIX_FMT_RGB24;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ZM_COLOUR_RGB32:
|
case ZM_COLOUR_RGB32:
|
||||||
{
|
|
||||||
if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) {
|
if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) {
|
||||||
/* ARGB subpixel order */
|
/* ARGB subpixel order */
|
||||||
pf = AV_PIX_FMT_ARGB;
|
pf = AV_PIX_FMT_ARGB;
|
||||||
|
@ -146,7 +144,6 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
pf = AV_PIX_FMT_RGBA;
|
pf = AV_PIX_FMT_RGBA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case ZM_COLOUR_GRAY8:
|
case ZM_COLOUR_GRAY8:
|
||||||
pf = AV_PIX_FMT_GRAY8;
|
pf = AV_PIX_FMT_GRAY8;
|
||||||
break;
|
break;
|
||||||
|
@ -159,6 +156,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
// RTP must have a packet_size.
|
// RTP must have a packet_size.
|
||||||
// Not sure what this value should be really...
|
// Not sure what this value should be really...
|
||||||
ofc->packet_size = width*height;
|
ofc->packet_size = width*height;
|
||||||
|
Debug(1,"Setting packet_size to %d", ofc->packet_size);
|
||||||
|
|
||||||
if ( of->video_codec == AV_CODEC_ID_NONE ) {
|
if ( of->video_codec == AV_CODEC_ID_NONE ) {
|
||||||
// RTP does not have a default codec in ffmpeg <= 0.8.
|
// RTP does not have a default codec in ffmpeg <= 0.8.
|
||||||
|
@ -171,6 +169,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
AVCodec *a = avcodec_find_encoder_by_name(codec_name);
|
AVCodec *a = avcodec_find_encoder_by_name(codec_name);
|
||||||
if ( a ) {
|
if ( a ) {
|
||||||
codec_id = a->id;
|
codec_id = a->id;
|
||||||
|
Debug( 1, "Using codec \"%s\"", codec_name );
|
||||||
} else {
|
} else {
|
||||||
#if (LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 11, 0) && (LIBAVFORMAT_VERSION_MICRO >= 100))
|
#if (LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 11, 0) && (LIBAVFORMAT_VERSION_MICRO >= 100))
|
||||||
Debug( 1, "Could not find codec \"%s\". Using default \"%s\"", codec_name, avcodec_get_name( codec_id ) );
|
Debug( 1, "Could not find codec \"%s\". Using default \"%s\"", codec_name, avcodec_get_name( codec_id ) );
|
||||||
|
@ -209,13 +208,13 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
Fatal( "Could not alloc stream" );
|
Fatal( "Could not alloc stream" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Debug( 1, "Allocated stream (%d) !=? (%d)", ost->id , ofc->nb_streams - 1 );
|
||||||
ost->id = ofc->nb_streams - 1;
|
ost->id = ofc->nb_streams - 1;
|
||||||
|
|
||||||
Debug( 1, "Allocated stream" );
|
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
codec_context = avcodec_alloc_context3(NULL);
|
|
||||||
avcodec_parameters_to_context(codec_context, ost->codecpar);
|
codec_context = avcodec_alloc_context3(NULL);
|
||||||
|
//avcodec_parameters_to_context(codec_context, ost->codecpar);
|
||||||
#else
|
#else
|
||||||
codec_context = ost->codec;
|
codec_context = ost->codec;
|
||||||
#endif
|
#endif
|
||||||
|
@ -223,7 +222,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
codec_context->codec_id = codec->id;
|
codec_context->codec_id = codec->id;
|
||||||
codec_context->codec_type = codec->type;
|
codec_context->codec_type = codec->type;
|
||||||
|
|
||||||
codec_context->pix_fmt = strcmp( "mjpeg", ofc->oformat->name ) == 0 ? AV_PIX_FMT_YUVJ422P : AV_PIX_FMT_YUV420P;
|
codec_context->pix_fmt = strcmp("mjpeg", ofc->oformat->name) == 0 ? AV_PIX_FMT_YUVJ422P : AV_PIX_FMT_YUV420P;
|
||||||
if ( bitrate <= 100 ) {
|
if ( bitrate <= 100 ) {
|
||||||
// Quality based bitrate control (VBR). Scale is 1..31 where 1 is best.
|
// Quality based bitrate control (VBR). Scale is 1..31 where 1 is best.
|
||||||
// This gets rid of artifacts in the beginning of the movie; and well, even quality.
|
// This gets rid of artifacts in the beginning of the movie; and well, even quality.
|
||||||
|
@ -246,8 +245,11 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
identically 1. */
|
identically 1. */
|
||||||
codec_context->time_base.den = frame_rate;
|
codec_context->time_base.den = frame_rate;
|
||||||
codec_context->time_base.num = 1;
|
codec_context->time_base.num = 1;
|
||||||
|
ost->time_base.den = frame_rate;
|
||||||
|
ost->time_base.num = 1;
|
||||||
|
|
||||||
|
|
||||||
Debug( 1, "Will encode in %d fps.", codec_context->time_base.den );
|
Debug( 1, "Will encode in %d fps. %dx%d", codec_context->time_base.den, width, height );
|
||||||
|
|
||||||
/* emit one intra frame every second */
|
/* emit one intra frame every second */
|
||||||
codec_context->gop_size = frame_rate;
|
codec_context->gop_size = frame_rate;
|
||||||
|
@ -258,6 +260,10 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei
|
||||||
codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
#else
|
#else
|
||||||
codec_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
codec_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
#endif
|
||||||
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
|
avcodec_parameters_from_context(ost->codecpar, codec_context);
|
||||||
|
zm_dump_codecpar(ost->codecpar);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
Fatal( "of->video_codec == AV_CODEC_ID_NONE" );
|
Fatal( "of->video_codec == AV_CODEC_ID_NONE" );
|
||||||
|
@ -271,7 +277,7 @@ const char *VideoStream::MimeType( ) const {
|
||||||
for ( unsigned int i = 0; i < sizeof (mime_data) / sizeof (*mime_data); i++ ) {
|
for ( unsigned int i = 0; i < sizeof (mime_data) / sizeof (*mime_data); i++ ) {
|
||||||
if ( strcmp( format, mime_data[i].format ) == 0 ) {
|
if ( strcmp( format, mime_data[i].format ) == 0 ) {
|
||||||
Debug( 1, "MimeType is \"%s\"", mime_data[i].mime_type );
|
Debug( 1, "MimeType is \"%s\"", mime_data[i].mime_type );
|
||||||
return ( mime_data[i].mime_type);
|
return mime_data[i].mime_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const char *mime_type = of->mime_type;
|
const char *mime_type = of->mime_type;
|
||||||
|
@ -282,9 +288,9 @@ const char *VideoStream::MimeType( ) const {
|
||||||
Warning( "Unable to determine mime type for '%s' format, using '%s' as default", format, mime_type );
|
Warning( "Unable to determine mime type for '%s' format, using '%s' as default", format, mime_type );
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( 1, "MimeType is \"%s\"", mime_type );
|
Debug(1, "MimeType is \"%s\"", mime_type );
|
||||||
|
|
||||||
return ( mime_type);
|
return mime_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoStream::OpenStream( ) {
|
void VideoStream::OpenStream( ) {
|
||||||
|
@ -293,11 +299,13 @@ void VideoStream::OpenStream( ) {
|
||||||
/* now that all the parameters are set, we can open the
|
/* now that all the parameters are set, we can open the
|
||||||
video codecs and allocate the necessary encode buffers */
|
video codecs and allocate the necessary encode buffers */
|
||||||
if ( ost ) {
|
if ( ost ) {
|
||||||
|
Debug(1,"Opening codec");
|
||||||
|
|
||||||
/* open the codec */
|
/* open the codec */
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
|
||||||
if ( (ret = avcodec_open( codec_context, codec )) < 0 )
|
if ( (ret = avcodec_open(codec_context, codec)) < 0 )
|
||||||
#else
|
#else
|
||||||
if ( (ret = avcodec_open2( codec_context, codec, 0 )) < 0 )
|
if ( (ret = avcodec_open2(codec_context, codec, 0)) < 0 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
Fatal( "Could not open codec. Error code %d \"%s\"", ret, av_err2str(ret) );
|
Fatal( "Could not open codec. Error code %d \"%s\"", ret, av_err2str(ret) );
|
||||||
|
@ -310,6 +318,9 @@ void VideoStream::OpenStream( ) {
|
||||||
if ( !opicture ) {
|
if ( !opicture ) {
|
||||||
Panic( "Could not allocate opicture" );
|
Panic( "Could not allocate opicture" );
|
||||||
}
|
}
|
||||||
|
opicture->width = codec_context->width;
|
||||||
|
opicture->height = codec_context->height;
|
||||||
|
opicture->format = codec_context->pix_fmt;
|
||||||
|
|
||||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||||
int size = av_image_get_buffer_size( codec_context->pix_fmt, codec_context->width, codec_context->height, 1 );
|
int size = av_image_get_buffer_size( codec_context->pix_fmt, codec_context->width, codec_context->height, 1 );
|
||||||
|
@ -362,7 +373,7 @@ void VideoStream::OpenStream( ) {
|
||||||
tmp_opicture_buf, pf, codec_context->width, codec_context->height );
|
tmp_opicture_buf, pf, codec_context->width, codec_context->height );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
} // end if ost
|
||||||
|
|
||||||
/* open the output file, if needed */
|
/* open the output file, if needed */
|
||||||
if ( !(of->flags & AVFMT_NOFILE) ) {
|
if ( !(of->flags & AVFMT_NOFILE) ) {
|
||||||
|
@ -384,8 +395,8 @@ void VideoStream::OpenStream( ) {
|
||||||
|
|
||||||
video_outbuf = NULL;
|
video_outbuf = NULL;
|
||||||
#if LIBAVFORMAT_VERSION_CHECK(57, 0, 0, 0, 0)
|
#if LIBAVFORMAT_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||||
if (codec_context->codec_type == AVMEDIA_TYPE_VIDEO &&
|
if (codec_context->codec_type == AVMEDIA_TYPE_VIDEO &&
|
||||||
codec_context->codec_id == AV_CODEC_ID_RAWVIDEO) {
|
codec_context->codec_id == AV_CODEC_ID_RAWVIDEO) {
|
||||||
#else
|
#else
|
||||||
if ( !(of->flags & AVFMT_RAWPICTURE) ) {
|
if ( !(of->flags & AVFMT_RAWPICTURE) ) {
|
||||||
#endif
|
#endif
|
||||||
|
@ -408,7 +419,7 @@ void VideoStream::OpenStream( ) {
|
||||||
#if !LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 4, 0)
|
#if !LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 4, 0)
|
||||||
ret = av_write_header( ofc );
|
ret = av_write_header( ofc );
|
||||||
#else
|
#else
|
||||||
ret = avformat_write_header( ofc, NULL );
|
ret = avformat_write_header(ofc, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
|
@ -451,6 +462,7 @@ VideoStream::VideoStream( const char *in_filename, const char *in_format, int bi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
codec_context = NULL;
|
||||||
SetupFormat( );
|
SetupFormat( );
|
||||||
SetupCodec( colours, subpixelorder, width, height, bitrate, frame_rate );
|
SetupCodec( colours, subpixelorder, width, height, bitrate, frame_rate );
|
||||||
SetParameters( );
|
SetParameters( );
|
||||||
|
@ -466,7 +478,6 @@ VideoStream::VideoStream( const char *in_filename, const char *in_format, int bi
|
||||||
Fatal("pthread_mutex_init failed");
|
Fatal("pthread_mutex_init failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
codec_context = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoStream::~VideoStream( ) {
|
VideoStream::~VideoStream( ) {
|
||||||
|
@ -627,7 +638,6 @@ double VideoStream::ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size,
|
||||||
opicture_ptr->quality = codec_context->global_quality;
|
opicture_ptr->quality = codec_context->global_quality;
|
||||||
|
|
||||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||||
// Put encoder into flushing mode
|
|
||||||
avcodec_send_frame(codec_context, opicture_ptr);
|
avcodec_send_frame(codec_context, opicture_ptr);
|
||||||
int ret = avcodec_receive_packet(codec_context, pkt);
|
int ret = avcodec_receive_packet(codec_context, pkt);
|
||||||
if ( ret < 0 ) {
|
if ( ret < 0 ) {
|
||||||
|
|
|
@ -75,7 +75,6 @@ void StreamBase::updateFrameRate( double fps ) {
|
||||||
|
|
||||||
bool StreamBase::checkCommandQueue() {
|
bool StreamBase::checkCommandQueue() {
|
||||||
if ( sd >= 0 ) {
|
if ( sd >= 0 ) {
|
||||||
Debug(2, "sd is (%d)", sd );
|
|
||||||
CmdMsg msg;
|
CmdMsg msg;
|
||||||
memset( &msg, 0, sizeof(msg) );
|
memset( &msg, 0, sizeof(msg) );
|
||||||
int nbytes = recvfrom( sd, &msg, sizeof(msg), MSG_DONTWAIT, 0, 0 );
|
int nbytes = recvfrom( sd, &msg, sizeof(msg), MSG_DONTWAIT, 0, 0 );
|
||||||
|
|
|
@ -235,7 +235,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||||
#else
|
#else
|
||||||
avformat_new_stream(oc, (AVCodec *)audio_in_ctx->codec);
|
avformat_new_stream(oc, (AVCodec *)audio_in_ctx->codec);
|
||||||
#endif
|
#endif
|
||||||
if (!audio_out_stream) {
|
if ( !audio_out_stream ) {
|
||||||
Error("Unable to create audio out stream\n");
|
Error("Unable to create audio out stream\n");
|
||||||
audio_out_stream = NULL;
|
audio_out_stream = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|
191
src/zmc.cpp
191
src/zmc.cpp
|
@ -223,7 +223,7 @@ int main(int argc, char *argv[]) {
|
||||||
Info("Starting Capture version %s", ZM_VERSION);
|
Info("Starting Capture version %s", ZM_VERSION);
|
||||||
static char sql[ZM_SQL_SML_BUFSIZ];
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
for ( int i = 0; i < n_monitors; i ++ ) {
|
for ( int i = 0; i < n_monitors; i ++ ) {
|
||||||
snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (Id, Status ) VALUES ('%d','Running')", monitors[i]->Id() );
|
snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (MonitorId, Status) VALUES ('%d','Running')", monitors[i]->Id() );
|
||||||
if ( mysql_query( &dbconn, sql ) ) {
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
}
|
}
|
||||||
|
@ -238,102 +238,119 @@ int main(int argc, char *argv[]) {
|
||||||
sigaddset(&block_set, SIGUSR1);
|
sigaddset(&block_set, SIGUSR1);
|
||||||
sigaddset(&block_set, SIGUSR2);
|
sigaddset(&block_set, SIGUSR2);
|
||||||
|
|
||||||
monitors[0]->setStartupTime((time_t)time(NULL));
|
|
||||||
if ( monitors[0]->PrimeCapture() < 0 ) {
|
|
||||||
Error("Failed to prime capture of initial monitor");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
long *capture_delays = new long[n_monitors];
|
|
||||||
long *alarm_capture_delays = new long[n_monitors];
|
|
||||||
long *next_delays = new long[n_monitors];
|
|
||||||
struct timeval * last_capture_times = new struct timeval[n_monitors];
|
|
||||||
for ( int i = 0; i < n_monitors; i++ ) {
|
|
||||||
last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0;
|
|
||||||
capture_delays[i] = monitors[i]->GetCaptureDelay();
|
|
||||||
alarm_capture_delays[i] = monitors[i]->GetAlarmCaptureDelay();
|
|
||||||
}
|
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
struct timeval now;
|
|
||||||
struct DeltaTimeval delta_time;
|
|
||||||
while ( !zm_terminate ) {
|
|
||||||
sigprocmask(SIG_BLOCK, &block_set, 0);
|
|
||||||
for ( int i = 0; i < n_monitors; i++ ) {
|
|
||||||
long min_delay = MAXINT;
|
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
while( ! zm_terminate ) {
|
||||||
for ( int j = 0; j < n_monitors; j++ ) {
|
for ( int i = 0; i < n_monitors; i ++ ) {
|
||||||
if ( last_capture_times[j].tv_sec ) {
|
time_t now = (time_t)time(NULL);
|
||||||
DELTA_TIMEVAL(delta_time, now, last_capture_times[j], DT_PREC_3);
|
monitors[i]->setStartupTime(now);
|
||||||
if ( monitors[i]->GetState() == Monitor::ALARM )
|
|
||||||
next_delays[j] = alarm_capture_delays[j]-delta_time.delta;
|
|
||||||
else
|
|
||||||
next_delays[j] = capture_delays[j]-delta_time.delta;
|
|
||||||
if ( next_delays[j] < 0 )
|
|
||||||
next_delays[j] = 0;
|
|
||||||
} else {
|
|
||||||
next_delays[j] = 0;
|
|
||||||
}
|
|
||||||
if ( next_delays[j] <= min_delay ) {
|
|
||||||
min_delay = next_delays[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( next_delays[i] <= min_delay || next_delays[i] <= 0 ) {
|
|
||||||
if ( monitors[i]->PreCapture() < 0 ) {
|
|
||||||
Error("Failed to pre-capture monitor %d %d (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors);
|
|
||||||
zm_terminate = true;
|
|
||||||
result = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ( monitors[i]->Capture() < 0 ) {
|
|
||||||
Error("Failed to capture image from monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors);
|
|
||||||
zm_terminate = true;
|
|
||||||
result = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ( monitors[i]->PostCapture() < 0 ) {
|
|
||||||
Error("Failed to post-capture monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors);
|
|
||||||
zm_terminate = true;
|
|
||||||
result = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( next_delays[i] > 0 ) {
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
DELTA_TIMEVAL(delta_time, now, last_capture_times[i], DT_PREC_3);
|
|
||||||
long sleep_time = next_delays[i]-delta_time.delta;
|
|
||||||
if ( sleep_time > 0 ) {
|
|
||||||
usleep(sleep_time*(DT_MAXGRAN/DT_PREC_3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gettimeofday(&(last_capture_times[i]), NULL);
|
|
||||||
} // end if next_delay <= min_delay || next_delays[i] <= 0 )
|
|
||||||
|
|
||||||
} // end foreach n_monitors
|
|
||||||
sigprocmask(SIG_UNBLOCK, &block_set, 0);
|
|
||||||
if ( zm_reload ) {
|
|
||||||
for ( int i = 0; i < n_monitors; i++ ) {
|
|
||||||
monitors[i]->Reload();
|
|
||||||
}
|
|
||||||
logTerm();
|
|
||||||
logInit( log_id_string );
|
|
||||||
zm_reload = false;
|
|
||||||
}
|
}
|
||||||
} // end while ! zm_terminate
|
// Outer primary loop, handles connection to camera
|
||||||
|
if ( monitors[0]->PrimeCapture() < 0 ) {
|
||||||
|
Error("Failed to prime capture of initial monitor");
|
||||||
|
sleep(10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
|
for ( int i = 0; i < n_monitors; i ++ ) {
|
||||||
|
snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (MonitorId, Status) VALUES ('%d','Connected')", monitors[i]->Id() );
|
||||||
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long *capture_delays = new long[n_monitors];
|
||||||
|
long *alarm_capture_delays = new long[n_monitors];
|
||||||
|
long *next_delays = new long[n_monitors];
|
||||||
|
struct timeval * last_capture_times = new struct timeval[n_monitors];
|
||||||
|
for ( int i = 0; i < n_monitors; i++ ) {
|
||||||
|
last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0;
|
||||||
|
capture_delays[i] = monitors[i]->GetCaptureDelay();
|
||||||
|
alarm_capture_delays[i] = monitors[i]->GetAlarmCaptureDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timeval now;
|
||||||
|
struct DeltaTimeval delta_time;
|
||||||
|
while ( !zm_terminate ) {
|
||||||
|
sigprocmask(SIG_BLOCK, &block_set, 0);
|
||||||
|
for ( int i = 0; i < n_monitors; i++ ) {
|
||||||
|
long min_delay = MAXINT;
|
||||||
|
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
for ( int j = 0; j < n_monitors; j++ ) {
|
||||||
|
if ( last_capture_times[j].tv_sec ) {
|
||||||
|
DELTA_TIMEVAL(delta_time, now, last_capture_times[j], DT_PREC_3);
|
||||||
|
if ( monitors[i]->GetState() == Monitor::ALARM )
|
||||||
|
next_delays[j] = alarm_capture_delays[j]-delta_time.delta;
|
||||||
|
else
|
||||||
|
next_delays[j] = capture_delays[j]-delta_time.delta;
|
||||||
|
if ( next_delays[j] < 0 )
|
||||||
|
next_delays[j] = 0;
|
||||||
|
} else {
|
||||||
|
next_delays[j] = 0;
|
||||||
|
}
|
||||||
|
if ( next_delays[j] <= min_delay ) {
|
||||||
|
min_delay = next_delays[j];
|
||||||
|
}
|
||||||
|
} // end foreach monitor
|
||||||
|
|
||||||
|
if ( next_delays[i] <= min_delay || next_delays[i] <= 0 ) {
|
||||||
|
if ( monitors[i]->PreCapture() < 0 ) {
|
||||||
|
Error("Failed to pre-capture monitor %d %d (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors);
|
||||||
|
result = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( monitors[i]->Capture() < 0 ) {
|
||||||
|
Error("Failed to capture image from monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors);
|
||||||
|
result = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( monitors[i]->PostCapture() < 0 ) {
|
||||||
|
Error("Failed to post-capture monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors);
|
||||||
|
result = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( next_delays[i] > 0 ) {
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
DELTA_TIMEVAL(delta_time, now, last_capture_times[i], DT_PREC_3);
|
||||||
|
long sleep_time = next_delays[i]-delta_time.delta;
|
||||||
|
if ( sleep_time > 0 ) {
|
||||||
|
usleep(sleep_time*(DT_MAXGRAN/DT_PREC_3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gettimeofday(&(last_capture_times[i]), NULL);
|
||||||
|
} // end if next_delay <= min_delay || next_delays[i] <= 0 )
|
||||||
|
|
||||||
|
} // end foreach n_monitors
|
||||||
|
sigprocmask(SIG_UNBLOCK, &block_set, 0);
|
||||||
|
if ( zm_reload ) {
|
||||||
|
for ( int i = 0; i < n_monitors; i++ ) {
|
||||||
|
monitors[i]->Reload();
|
||||||
|
}
|
||||||
|
logTerm();
|
||||||
|
logInit( log_id_string );
|
||||||
|
zm_reload = false;
|
||||||
|
}
|
||||||
|
if ( result < 0 ) {
|
||||||
|
// Failure, try reconnecting
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // end while ! zm_terminate
|
||||||
|
delete [] alarm_capture_delays;
|
||||||
|
delete [] capture_delays;
|
||||||
|
delete [] next_delays;
|
||||||
|
delete [] last_capture_times;
|
||||||
|
} // end while ! zm_terminate outer connection loop
|
||||||
|
|
||||||
for ( int i = 0; i < n_monitors; i++ ) {
|
for ( int i = 0; i < n_monitors; i++ ) {
|
||||||
delete monitors[i];
|
delete monitors[i];
|
||||||
}
|
}
|
||||||
delete [] monitors;
|
delete [] monitors;
|
||||||
delete [] alarm_capture_delays;
|
|
||||||
delete [] capture_delays;
|
|
||||||
delete [] next_delays;
|
|
||||||
delete [] last_capture_times;
|
|
||||||
|
|
||||||
Image::Deinitialise();
|
Image::Deinitialise();
|
||||||
logTerm();
|
logTerm();
|
||||||
zmDbClose();
|
zmDbClose();
|
||||||
|
|
||||||
return( result );
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,4 @@
|
||||||
# Overview
|
## Docker Support Files
|
||||||
|
|
||||||
[Docker](https://www.docker.io/) allows you to quickly spin up application containers,
|
Docker support files have been moved to the zmdockerfiles repo:
|
||||||
which are similar to very lightweight virtual machines. The ZoneMinder Dockerfile will
|
https://github.com/ZoneMinder/zmdockerfiles
|
||||||
start an Ubuntu 12.04 container with MySql, Apache, and PHP properly configured, and
|
|
||||||
will then compile and install ZoneMinder.
|
|
||||||
|
|
||||||
It will also start an SSH server that you can use to log into the container.
|
|
||||||
|
|
||||||
This is still a bit of a work in progress.
|
|
||||||
|
|
||||||
## How To Use
|
|
||||||
|
|
||||||
1. Install [Docker](https://www.docker.io/)
|
|
||||||
2. Build ZoneMinder container
|
|
||||||
```sudo docker build -t yourname/zoneminder github.com/ZoneMinder/ZoneMinder```
|
|
||||||
3. Run it
|
|
||||||
```CID=$(sudo docker run -d -p 222:22 -p 8080:80 --name zoneminder yourname/zoneminder)```
|
|
||||||
4. Use it -- you can now SSH to port 222 on your host as user root with password root.
|
|
||||||
You can also browse to your host on port 8080 to access the zoneminder web interface
|
|
||||||
|
|
||||||
## Developing With Docker
|
|
||||||
|
|
||||||
If you wish to contribute to ZoneMinder, Docker can be helpful. By re-running
|
|
||||||
```docker build``` in your working directory, any code modifications you have
|
|
||||||
made will be pulled into a new container, compiled, and started, all without
|
|
||||||
modifying your base system.
|
|
||||||
|
|
||||||
Development is not totally without annoyances, as any change
|
|
||||||
to the project will require a full rebuild of all C++. Docker notices that the
|
|
||||||
directory which has been ADD'ed is now different, and therefore all steps after
|
|
||||||
the ADD command must be recomputed. A fix for this is to update the Dockerfile to
|
|
||||||
move the configure and make commands into start.sh, and then use a volume mount
|
|
||||||
to cache the build directory (I think it's ```/tmp```) on your host filesystem.
|
|
||||||
This would be really useful for a developer, and would remove the annoying build
|
|
||||||
problem, but some of the Docker push/pull benefits would be lost.
|
|
||||||
|
|
||||||
Docker containers can be both CPU and memory limited, so this can be a practical
|
|
||||||
method to compile or run multiple development builds of ZoneFinder simultaneously
|
|
||||||
without taxing your host system.
|
|
||||||
|
|
||||||
## Use Cases
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
- Describe how to connect to monitors by mounting devices
|
|
||||||
- Create a 'development' dockerfile to remove the need to rebuild the entire project
|
|
||||||
after each small change
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[Date]
|
|
||||||
; Defines the default timezone used by the date functions
|
|
||||||
; http://php.net/date.timezone
|
|
||||||
date.timezone = GMT
|
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
setup_mysql_first_time(){
|
|
||||||
if [ "$(ls /var/lib/mysql)" ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set MySQL in the volume
|
|
||||||
rm -rf /var/lib/mysql/*
|
|
||||||
chown -R mysql:mysql /var/lib/mysql
|
|
||||||
mysqld --initialize-insecure
|
|
||||||
|
|
||||||
# Start MySQL
|
|
||||||
# For Xenial the following won't start mysqld
|
|
||||||
#/usr/bin/mysqld_safe &
|
|
||||||
# Use this instead:
|
|
||||||
service mysql start
|
|
||||||
|
|
||||||
# Give MySQL time to wake up
|
|
||||||
SECONDS_LEFT=120
|
|
||||||
while true; do
|
|
||||||
sleep 1
|
|
||||||
mysqladmin ping
|
|
||||||
if [ $? -eq 0 ];then
|
|
||||||
break; # Success
|
|
||||||
fi
|
|
||||||
let SECONDS_LEFT=SECONDS_LEFT-1
|
|
||||||
|
|
||||||
# If we have waited >120 seconds, give up
|
|
||||||
# ZM should never have a database that large!
|
|
||||||
# if $COUNTER -lt 120
|
|
||||||
if [ $SECONDS_LEFT -eq 0 ];then
|
|
||||||
return -1;
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Create the ZoneMinder database
|
|
||||||
mysql -u root < db/zm_create.sql
|
|
||||||
|
|
||||||
# Add the ZoneMinder DB user
|
|
||||||
mysql -u root -e "grant insert,select,update,delete,lock tables,alter on zm.* to 'zmuser'@'localhost' identified by 'zmpass';"
|
|
||||||
|
|
||||||
# Shut down mysql cleanly:
|
|
||||||
kill $(cat /var/run/mysqld/mysqld.pid)
|
|
||||||
sleep 5
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_mysql() {
|
|
||||||
# To configure MySQL if no container did it before
|
|
||||||
setup_mysql_first_time
|
|
||||||
|
|
||||||
# Add configuration to avoid SQL error when adding monitor
|
|
||||||
echo "sql_mode=NO_ENGINE_SUBSTITUTION" >> /etc/mysql/mysql.conf.d/mysqld.cnf
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_php() {
|
|
||||||
# Activate CGI
|
|
||||||
a2enmod cgi
|
|
||||||
|
|
||||||
# Activate modrewrite
|
|
||||||
a2enmod rewrite
|
|
||||||
|
|
||||||
# Setting timezone
|
|
||||||
sed -i "s#;date.timezone =#date.timezone = $PHP_TIMEZONE#" /etc/php/7.0/apache2/php.ini
|
|
||||||
|
|
||||||
# Settings rights for volume
|
|
||||||
chown -R www-data:www-data /var/lib/zoneminder/events
|
|
||||||
chown -R www-data:www-data /var/lib/zoneminder/images
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setup_mysql
|
|
||||||
setup_php
|
|
||||||
|
|
||||||
exit 0
|
|
|
@ -1,48 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Prepare proper amount of shared memory
|
|
||||||
# For H.264 cameras it may be necessary to increase the amount of shared memory
|
|
||||||
# to 2048 megabytes.
|
|
||||||
umount /dev/shm
|
|
||||||
mount -t tmpfs -o rw,nosuid,nodev,noexec,relatime,size=512M tmpfs /dev/shm
|
|
||||||
|
|
||||||
# Start MySQL
|
|
||||||
test -e /var/run/mysqld || install -m 755 -o mysql -g root -d /var/run/mysqld
|
|
||||||
su - mysql -s /bin/sh -c "/usr/bin/mysqld_safe > /dev/null 2>&1 &"
|
|
||||||
|
|
||||||
# Ensure we shut down mysql cleanly later:
|
|
||||||
trap close_mysql SIGTERM
|
|
||||||
|
|
||||||
# Give MySQL time to wake up
|
|
||||||
SECONDS_LEFT=120
|
|
||||||
while true; do
|
|
||||||
sleep 1
|
|
||||||
mysqladmin ping
|
|
||||||
if [ $? -eq 0 ];then
|
|
||||||
break; # Success
|
|
||||||
fi
|
|
||||||
let SECONDS_LEFT=SECONDS_LEFT-1
|
|
||||||
|
|
||||||
# If we have waited >120 seconds, give up
|
|
||||||
# ZM should never have a database that large!
|
|
||||||
# if $COUNTER -lt 120
|
|
||||||
if [ $SECONDS_LEFT -eq 0 ];then
|
|
||||||
return -1;
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Restart apache
|
|
||||||
service apache2 restart
|
|
||||||
|
|
||||||
# Start ZoneMinder
|
|
||||||
/usr/local/bin/zmpkg.pl start && echo "Zone Minder started"
|
|
||||||
|
|
||||||
while :
|
|
||||||
do
|
|
||||||
sleep 3600
|
|
||||||
done
|
|
||||||
|
|
||||||
function close_mysql {
|
|
||||||
kill $(cat /var/run/mysqld/mysqld.pid)
|
|
||||||
sleep 5
|
|
||||||
}
|
|
|
@ -12,9 +12,33 @@ $defaultMonitor->set(array(
|
||||||
) );
|
) );
|
||||||
|
|
||||||
function probe( &$url_bits ) {
|
function probe( &$url_bits ) {
|
||||||
|
error_reporting(0);
|
||||||
global $defaultMonitor;
|
global $defaultMonitor;
|
||||||
$available_streams = array();
|
$available_streams = array();
|
||||||
if ( ! isset($url_bits['port']) ) {
|
if ( ! isset($url_bits['port']) ) {
|
||||||
|
|
||||||
|
$cam_list_html = file_get_contents('http://'.$url_bits['host'].':5000/monitoring/');
|
||||||
|
if ( $cam_list_html ) {
|
||||||
|
Logger::Debug("Have content at port 5000/monitoring");
|
||||||
|
$matches_count = preg_match_all(
|
||||||
|
'/<a href="http:\/\/([.[:digit:]]+):([[:digit:]]+)\/\?action=stream" target="_blank">([^<]+)<\/a>/',
|
||||||
|
$cam_list_html, $cam_list );
|
||||||
|
Logger::Debug(print_r($cam_list,true));
|
||||||
|
}
|
||||||
|
if ( $matches_count ) {
|
||||||
|
for( $index = 0; $index < $matches_count; $index ++ ) {
|
||||||
|
$new_stream = $url_bits; // make a copy
|
||||||
|
$new_stream['port'] = $cam_list[2][$index];
|
||||||
|
$new_stream['Name'] = trim($cam_list[3][$index]);
|
||||||
|
if ( ! isset($new_stream['scheme'] ) )
|
||||||
|
$new_stream['scheme'] = 'http';
|
||||||
|
$available_streams[] = $new_stream;
|
||||||
|
Logger::Debug("Have new stream " . print_r($new_stream,true) );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Info('No matches');
|
||||||
|
}
|
||||||
|
if ( 0 ) {
|
||||||
// No port given, do a port scan
|
// No port given, do a port scan
|
||||||
foreach ( range( 2000, 2007 ) as $port ) {
|
foreach ( range( 2000, 2007 ) as $port ) {
|
||||||
$socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
|
$socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
|
||||||
|
@ -61,15 +85,17 @@ Info("Testing connection to " . $url_bits['host'].':'.$port);
|
||||||
$available_streams[] = $new_stream;
|
$available_streams[] = $new_stream;
|
||||||
} // end if new_Stream
|
} // end if new_Stream
|
||||||
} // end foreach port to scan
|
} // end foreach port to scan
|
||||||
|
} # end if 0
|
||||||
} else {
|
} else {
|
||||||
// A port was specified, so don't need to port scan.
|
// A port was specified, so don't need to port scan.
|
||||||
$available_streams[] = $url_bits;
|
$available_streams[] = $url_bits;
|
||||||
}
|
}
|
||||||
foreach ( $available_streams as &$stream ) {
|
foreach ( $available_streams as &$stream ) {
|
||||||
# check for existence in db.
|
# check for existence in db.
|
||||||
$stream['url'] = unparse_url( $stream, array( 'path'=>'/','query'=>'action=stream' ) );
|
$stream['url'] = unparse_url( $stream, array('path'=>'/','query'=>'action=stream') );
|
||||||
$monitors = Monitor::find_all( array( 'Path'=>$stream['url'] ) );
|
$monitors = Monitor::find_all( array('Path'=>$stream['url']) );
|
||||||
if ( count($monitors ) ) {
|
if ( count($monitors) ) {
|
||||||
|
Info("Found monitors matching " . $stream['url'] );
|
||||||
$stream['Monitor'] = $monitors[0];
|
$stream['Monitor'] = $monitors[0];
|
||||||
if ( isset( $stream['Width'] ) and ( $stream['Monitor']->Width() != $stream['Width'] ) ) {
|
if ( isset( $stream['Width'] ) and ( $stream['Monitor']->Width() != $stream['Width'] ) ) {
|
||||||
$stream['Warning'] .= 'Monitor width ('.$stream['Monitor']->Width().') and stream width ('.$stream['Width'].") do not match!\n";
|
$stream['Warning'] .= 'Monitor width ('.$stream['Monitor']->Width().') and stream width ('.$stream['Width'].") do not match!\n";
|
||||||
|
@ -78,11 +104,14 @@ Info("Testing connection to " . $url_bits['host'].':'.$port);
|
||||||
$stream['Warning'] .= 'Monitor height ('.$stream['Monitor']->Height().') and stream width ('.$stream['Height'].") do not match!\n";
|
$stream['Warning'] .= 'Monitor height ('.$stream['Monitor']->Height().') and stream width ('.$stream['Height'].") do not match!\n";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$stream['Monitor'] = $defaultMonitor;
|
$stream['Monitor'] = clone $defaultMonitor;
|
||||||
if ( isset($stream['Width']) ) {
|
if ( isset($stream['Width']) ) {
|
||||||
$stream['Monitor']->Width( $stream['Width'] );
|
$stream['Monitor']->Width( $stream['Width'] );
|
||||||
$stream['Monitor']->Height( $stream['Height'] );
|
$stream['Monitor']->Height( $stream['Height'] );
|
||||||
}
|
}
|
||||||
|
if ( isset($stream['Name']) ) {
|
||||||
|
$stream['Monitor']->Name( $stream['Name'] );
|
||||||
|
}
|
||||||
} // Monitor found or not
|
} // Monitor found or not
|
||||||
} // end foreach Stream
|
} // end foreach Stream
|
||||||
|
|
||||||
|
|
|
@ -382,6 +382,11 @@ function getNearEvents() {
|
||||||
else
|
else
|
||||||
$midSql = '';
|
$midSql = '';
|
||||||
|
|
||||||
|
# When listing, it may make sense to list them in descending order. But when viewing Prev should timewise earlier and Next should be after.
|
||||||
|
if ( $sortColumn == 'E.Id' or $sortColumn == 'E.StartTime' ) {
|
||||||
|
$sortOrder = 'asc';
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "SELECT E.Id AS Id, E.StartTime AS StartTime FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE $sortColumn ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." ORDER BY $sortColumn ".($sortOrder=='asc'?'desc':'asc') . ' LIMIT 2';
|
$sql = "SELECT E.Id AS Id, E.StartTime AS StartTime FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE $sortColumn ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." ORDER BY $sortColumn ".($sortOrder=='asc'?'desc':'asc') . ' LIMIT 2';
|
||||||
$result = dbQuery( $sql );
|
$result = dbQuery( $sql );
|
||||||
while ( $id = dbFetchNext( $result, 'Id' ) ) {
|
while ( $id = dbFetchNext( $result, 'Id' ) ) {
|
||||||
|
|
|
@ -1,31 +1,36 @@
|
||||||
<?php
|
<?php
|
||||||
|
error_reporting(0);
|
||||||
|
|
||||||
$start_time = time();
|
$start_time = time();
|
||||||
|
|
||||||
define( "MSG_TIMEOUT", ZM_WEB_AJAX_TIMEOUT );
|
define( 'MSG_TIMEOUT', ZM_WEB_AJAX_TIMEOUT/2 );
|
||||||
define( "MSG_DATA_SIZE", 4+256 );
|
define( 'MSG_DATA_SIZE', 4+256 );
|
||||||
|
|
||||||
if ( !($_REQUEST['connkey'] && $_REQUEST['command']) ) {
|
if ( !($_REQUEST['connkey'] && $_REQUEST['command']) ) {
|
||||||
ajaxError( "Unexpected received message type '$type'" );
|
ajaxError( "Unexpected received message type '$type'" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !($socket = @socket_create( AF_UNIX, SOCK_DGRAM, 0 )) ) {
|
$key = ftok(ZM_PATH_SOCKS.'/zms-'.sprintf("%06d",$_REQUEST['connkey']).'w.lock', 'Z');
|
||||||
ajaxError( "socket_create() failed: ".socket_strerror(socket_last_error()) );
|
$semaphore = sem_get($key,1);
|
||||||
}
|
if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
$locSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf("%06d",$_REQUEST['connkey']).'w.sock';
|
if ( !($socket = @socket_create( AF_UNIX, SOCK_DGRAM, 0 )) ) {
|
||||||
if ( file_exists( $locSockFile ) ) {
|
ajaxError( 'socket_create() failed: '.socket_strerror(socket_last_error()) );
|
||||||
Warning("sock file $locSockFile already exists?! Is someone else talking to zms?");
|
}
|
||||||
// They could be. We can maybe have concurrent requests from a browser.
|
|
||||||
} else {
|
|
||||||
Logger::Debug("socket file does not exist, we should be good to connect.");
|
|
||||||
}
|
|
||||||
if ( !@socket_bind( $socket, $locSockFile ) ) {
|
|
||||||
ajaxError( "socket_bind( $locSockFile ) failed: ".socket_strerror(socket_last_error()) );
|
|
||||||
} else {
|
|
||||||
Logger::Debug("Bound to $locSockFile");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( $_REQUEST['command'] ) {
|
$localSocketFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'w.sock';
|
||||||
|
if ( file_exists( $localSocketFile ) ) {
|
||||||
|
Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?");
|
||||||
|
// They could be. We can maybe have concurrent requests from a browser.
|
||||||
|
} else {
|
||||||
|
Logger::Debug("socket file does not exist, we should be good to connect.");
|
||||||
|
}
|
||||||
|
if ( ! socket_bind( $socket, $localSocketFile ) ) {
|
||||||
|
ajaxError( "socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) );
|
||||||
|
} else {
|
||||||
|
Logger::Debug("Bound to $localSocketFile");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( $_REQUEST['command'] ) {
|
||||||
case CMD_VARPLAY :
|
case CMD_VARPLAY :
|
||||||
Logger::Debug( 'Varplaying to '.$_REQUEST['rate'] );
|
Logger::Debug( 'Varplaying to '.$_REQUEST['rate'] );
|
||||||
$msg = pack( 'lcn', MSG_CMD, $_REQUEST['command'], $_REQUEST['rate']+32768 );
|
$msg = pack( 'lcn', MSG_CMD, $_REQUEST['command'], $_REQUEST['rate']+32768 );
|
||||||
|
@ -49,50 +54,54 @@ switch ( $_REQUEST['command'] ) {
|
||||||
default :
|
default :
|
||||||
$msg = pack( 'lc', MSG_CMD, $_REQUEST['command'] );
|
$msg = pack( 'lc', MSG_CMD, $_REQUEST['command'] );
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
$remSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'s.sock';
|
|
||||||
$max_socket_tries = 10;
|
|
||||||
// FIXME This should not exceed web_ajax_timeout
|
|
||||||
while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second.
|
|
||||||
//Logger::Debug("$remSockFile does not exist, waiting, current " . (time() - $start_time) . ' seconds' );
|
|
||||||
usleep(200000);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !file_exists($remSockFile) ) {
|
|
||||||
ajaxError("Socket $remSockFile does not exist. This file is created by zms, and since it does not exist, either zms did not run, or zms exited early. Please check your zms logs and ensure that CGI is enabled in apache and check that the PATH_ZMS is set correctly. Make sure that ZM is actually recording. If you are trying to view a live stream and the capture process (zmc) is not running then zms will exit. Please go to http://zoneminder.readthedocs.io/en/latest/faq.html#why-can-t-i-see-streamed-images-when-i-can-see-stills-in-the-zone-window-etc for more information.");
|
|
||||||
} else {
|
|
||||||
if ( !@socket_sendto( $socket, $msg, strlen($msg), 0, $remSockFile ) ) {
|
|
||||||
ajaxError( "socket_sendto( $remSockFile ) failed: ".socket_strerror(socket_last_error()) );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$rSockets = array( $socket );
|
$remSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'s.sock';
|
||||||
$wSockets = NULL;
|
$max_socket_tries = 10;
|
||||||
$eSockets = NULL;
|
// FIXME This should not exceed web_ajax_timeout
|
||||||
|
while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second.
|
||||||
|
// WHY? We will just send another one...
|
||||||
|
// ANSWER: Because otherwise we get a log of errors logged
|
||||||
|
|
||||||
$timeout = MSG_TIMEOUT - ( time() - $start_time );
|
//Logger::Debug("$remSockFile does not exist, waiting, current " . (time() - $start_time) . ' seconds' );
|
||||||
Logger::Debug("TImeout is: $timeout " );
|
usleep(1000);
|
||||||
|
|
||||||
$numSockets = @socket_select( $rSockets, $wSockets, $eSockets, intval($timeout/1000), ($timeout%1000)*1000 );
|
|
||||||
|
|
||||||
if ( $numSockets === false ) {
|
|
||||||
Error("socket_select failed: " . socket_strerror(socket_last_error()) );
|
|
||||||
ajaxError( "socket_select failed: ".socket_strerror(socket_last_error()) );
|
|
||||||
} else if ( $numSockets < 0 ) {
|
|
||||||
Error( "Socket closed $remSockFile" );
|
|
||||||
ajaxError( "Socket closed $remSockFile" );
|
|
||||||
} else if ( $numSockets == 0 ) {
|
|
||||||
Error( "Timed out waiting for msg $remSockFile" );
|
|
||||||
ajaxError( "Timed out waiting for msg $remSockFile" );
|
|
||||||
} else if ( $numSockets > 0 ) {
|
|
||||||
if ( count($rSockets) != 1 ) {
|
|
||||||
Error( "Bogus return from select, ".count($rSockets).' sockets available' );
|
|
||||||
ajaxError( "Bogus return from select, ".count($rSockets).' sockets available' );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch( $nbytes = @socket_recvfrom( $socket, $msg, MSG_DATA_SIZE, 0, $remSockFile ) ) {
|
if ( !file_exists($remSockFile) ) {
|
||||||
|
ajaxError("Socket $remSockFile does not exist. This file is created by zms, and since it does not exist, either zms did not run, or zms exited early. Please check your zms logs and ensure that CGI is enabled in apache and check that the PATH_ZMS is set correctly. Make sure that ZM is actually recording. If you are trying to view a live stream and the capture process (zmc) is not running then zms will exit. Please go to http://zoneminder.readthedocs.io/en/latest/faq.html#why-can-t-i-see-streamed-images-when-i-can-see-stills-in-the-zone-window-etc for more information.");
|
||||||
|
} else {
|
||||||
|
if ( !@socket_sendto( $socket, $msg, strlen($msg), 0, $remSockFile ) ) {
|
||||||
|
ajaxError( "socket_sendto( $remSockFile ) failed: ".socket_strerror(socket_last_error()) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rSockets = array( $socket );
|
||||||
|
$wSockets = NULL;
|
||||||
|
$eSockets = NULL;
|
||||||
|
|
||||||
|
$timeout = MSG_TIMEOUT - ( time() - $start_time );
|
||||||
|
Logger::Debug("TImeout is: $timeout/1000 seconds. " );
|
||||||
|
|
||||||
|
$numSockets = socket_select( $rSockets, $wSockets, $eSockets, intval($timeout/1000), ($timeout%1000)*1000 );
|
||||||
|
|
||||||
|
if ( $numSockets === false ) {
|
||||||
|
Error('socket_select failed: ' . socket_strerror(socket_last_error()) );
|
||||||
|
ajaxError( 'socket_select failed: '.socket_strerror(socket_last_error()) );
|
||||||
|
} else if ( $numSockets < 0 ) {
|
||||||
|
Error( "Socket closed $remSockFile" );
|
||||||
|
ajaxError( "Socket closed $remSockFile" );
|
||||||
|
} else if ( $numSockets == 0 ) {
|
||||||
|
Error( "Timed out waiting for msg $remSockFile" );
|
||||||
|
socket_Set_nonblock($socket);
|
||||||
|
#ajaxError( "Timed out waiting for msg $remSockFile" );
|
||||||
|
} else if ( $numSockets > 0 ) {
|
||||||
|
if ( count($rSockets) != 1 ) {
|
||||||
|
Error( 'Bogus return from select, '.count($rSockets).' sockets available' );
|
||||||
|
ajaxError( 'Bogus return from select, '.count($rSockets).' sockets available' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( $nbytes = @socket_recvfrom( $socket, $msg, MSG_DATA_SIZE, 0, $remSockFile ) ) {
|
||||||
case -1 :
|
case -1 :
|
||||||
{
|
{
|
||||||
ajaxError( "socket_recvfrom( $remSockFile ) failed: ".socket_strerror(socket_last_error()) );
|
ajaxError( "socket_recvfrom( $remSockFile ) failed: ".socket_strerror(socket_last_error()) );
|
||||||
|
@ -109,10 +118,11 @@ switch( $nbytes = @socket_recvfrom( $socket, $msg, MSG_DATA_SIZE, 0, $remSockFil
|
||||||
ajaxError( "Got unexpected message size, got $nbytes, expected ".MSG_DATA_SIZE );
|
ajaxError( "Got unexpected message size, got $nbytes, expected ".MSG_DATA_SIZE );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = unpack( 'ltype', $msg );
|
|
||||||
switch ( $data['type'] ) {
|
$data = unpack( 'ltype', $msg );
|
||||||
|
switch ( $data['type'] ) {
|
||||||
case MSG_DATA_WATCH :
|
case MSG_DATA_WATCH :
|
||||||
{
|
{
|
||||||
$data = unpack( "ltype/imonitor/istate/dfps/ilevel/irate/ddelay/izoom/Cdelayed/Cpaused/Cenabled/Cforced", $msg );
|
$data = unpack( "ltype/imonitor/istate/dfps/ilevel/irate/ddelay/izoom/Cdelayed/Cpaused/Cenabled/Cforced", $msg );
|
||||||
|
@ -156,15 +166,20 @@ switch ( $data['type'] ) {
|
||||||
{
|
{
|
||||||
ajaxError( "Unexpected received message type '$type'" );
|
ajaxError( "Unexpected received message type '$type'" );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
sem_release($semaphore);
|
||||||
|
} else {
|
||||||
|
Logger::Debug("Couldn't get semaphore");
|
||||||
|
ajaxResponse( array() );
|
||||||
}
|
}
|
||||||
|
|
||||||
ajaxError( 'Unrecognised action or insufficient permissions' );
|
ajaxError('Unrecognised action or insufficient permissions in ajax/stream');
|
||||||
|
|
||||||
function ajaxCleanup() {
|
function ajaxCleanup() {
|
||||||
global $socket, $locSockFile;
|
global $socket, $localSocketFile;
|
||||||
if ( !empty( $socket ) )
|
if ( !empty( $socket ) )
|
||||||
@socket_close( $socket );
|
@socket_close( $socket );
|
||||||
if ( !empty( $locSockFile ) )
|
if ( !empty( $localSocketFile ) )
|
||||||
@unlink( $locSockFile );
|
@unlink( $localSocketFile );
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -148,13 +148,27 @@ class MonitorsController extends AppController {
|
||||||
throw new NotFoundException(__('Invalid monitor'));
|
throw new NotFoundException(__('Invalid monitor'));
|
||||||
}
|
}
|
||||||
if ($this->Session->Read('monitorPermission') != 'Edit') {
|
if ($this->Session->Read('monitorPermission') != 'Edit') {
|
||||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($this->Monitor->save($this->request->data)) {
|
|
||||||
|
$message = '';
|
||||||
|
if ( $this->Monitor->save($this->request->data) ) {
|
||||||
$message = 'Saved';
|
$message = 'Saved';
|
||||||
|
$Monitor = $this->Monitor->find('first', array(
|
||||||
|
'fields' => array('Function','ServerId'),
|
||||||
|
'conditions' => array('Id' => $id)
|
||||||
|
))['Monitor'];
|
||||||
|
|
||||||
|
// - restart or stop this monitor after change
|
||||||
|
$func = $Monitor['Function'];
|
||||||
|
// We don't pass the request data as the monitor object because it may be a subset of the full monitor array
|
||||||
|
$this->daemonControl( $this->Monitor->id, 'stop' );
|
||||||
|
if ( ( $func != 'None' ) and ( (!defined('ZM_SERVER_ID')) or ($Monitor['ServerId']==ZM_SERVER_ID) ) ) {
|
||||||
|
$this->daemonControl( $this->Monitor->id, 'start' );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$message = 'Error';
|
$message = 'Error ' . print_r($this->Monitor->invalidFields(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->set(array(
|
$this->set(array(
|
||||||
|
@ -162,18 +176,6 @@ class MonitorsController extends AppController {
|
||||||
'_serialize' => array('message')
|
'_serialize' => array('message')
|
||||||
));
|
));
|
||||||
|
|
||||||
$Monitor = $this->Monitor->find('first', array(
|
|
||||||
'fields' => array('Function','ServerId'),
|
|
||||||
'conditions' => array('Id' => $id)
|
|
||||||
))['Monitor'];
|
|
||||||
|
|
||||||
// - restart or stop this monitor after change
|
|
||||||
$func = $Monitor['Function'];
|
|
||||||
// We don't pass the request data as the monitor object because it may be a subset of the full monitor array
|
|
||||||
$this->daemonControl( $this->Monitor->id, 'stop' );
|
|
||||||
if ( ( $func != 'None' ) and ( (!defined('ZM_SERVER_ID')) or ($Monitor['ServerId']==ZM_SERVER_ID) ) ) {
|
|
||||||
$this->daemonControl( $this->Monitor->id, 'start' );
|
|
||||||
}
|
|
||||||
} // end function edit
|
} // end function edit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -110,13 +110,13 @@ class Monitor extends AppModel {
|
||||||
);
|
);
|
||||||
public $actsAs = array(
|
public $actsAs = array(
|
||||||
'CakePHP-Enum-Behavior.Enum' => array(
|
'CakePHP-Enum-Behavior.Enum' => array(
|
||||||
'Type' => array('Local','Remote','File','Ffmpeg','Libvlc','cURL'),
|
'Type' => array('Local','Remote','File','Ffmpeg','Libvlc','cURL'),
|
||||||
'Function' => array('None','Monitor','Modect','Record','Mocord','Nodect'),
|
'Function' => array('None','Monitor','Modect','Record','Mocord','Nodect'),
|
||||||
'Orientation' => array('0','90','180','270','hori','vert'),
|
'Orientation' => array('0','90','180','270','hori','vert'),
|
||||||
'OutputCodec' => array('h264','mjpeg','mpeg1','mpeg2'),
|
'OutputCodec' => array('h264','mjpeg','mpeg1','mpeg2'),
|
||||||
'OutputContainer' => array('auto','mp4','mkv'),
|
'OutputContainer' => array('auto','mp4','mkv'),
|
||||||
'DefaultView' => array('Events','Control'),
|
'DefaultView' => array('Events','Control'),
|
||||||
'Status' => array('Unknown','NotRunning','Running','NoSignal','Signal'),
|
'Status' => array('Unknown','NotRunning','Running','NoSignal','Signal'),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7108489f218c54d36d235d3af91d6da2f8311237
|
Subproject commit ca91b87fda8e006e4fca2ed870f24f9a29c2905d
|
|
@ -249,7 +249,7 @@ $group_options[$Group->Id()] = str_repeat( ' ', $depth ) . $Group->Name();
|
||||||
|
|
||||||
$MonitorIds = array_merge( $MonitorIds, dbFetchAll( 'SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId = ?)', 'MonitorId', array($group_id) ) );
|
$MonitorIds = array_merge( $MonitorIds, dbFetchAll( 'SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId = ?)', 'MonitorId', array($group_id) ) );
|
||||||
}
|
}
|
||||||
$groupSql = " find_in_set( Id, '".implode( ',', $MonitorIds )."' )";
|
$groupSql = " find_in_set( M.Id, '".implode( ',', $MonitorIds )."' )";
|
||||||
}
|
}
|
||||||
return $groupSql;
|
return $groupSql;
|
||||||
} # end public static function get_group_sql( $group_id )
|
} # end public static function get_group_sql( $group_id )
|
||||||
|
|
|
@ -5,20 +5,22 @@ require_once( 'Server.php' );
|
||||||
class Monitor {
|
class Monitor {
|
||||||
|
|
||||||
private $defaults = array(
|
private $defaults = array(
|
||||||
'Id' => null,
|
'Id' => null,
|
||||||
'Name' => '',
|
'Name' => '',
|
||||||
'StorageId' => 0,
|
'StorageId' => 0,
|
||||||
'ServerId' => 0,
|
'ServerId' => 0,
|
||||||
'Function' => 'None',
|
'Function' => 'None',
|
||||||
'Enabled' => 1,
|
'Enabled' => 1,
|
||||||
'Width' => null,
|
'Width' => null,
|
||||||
'Height' => null,
|
'Height' => null,
|
||||||
'Orientation' => null,
|
'Orientation' => null,
|
||||||
'AnalysisFPSLimit' => null,
|
'AnalysisFPSLimit' => null,
|
||||||
'AnalysisFPS' => null,
|
'ZoneCount' => 0,
|
||||||
'CaptureFPS' => null,
|
'Triggers' => null,
|
||||||
'ZoneCount' => 0,
|
);
|
||||||
'Triggers' => null,
|
private $status_fields = array(
|
||||||
|
'AnalysisFPS' => null,
|
||||||
|
'CaptureFPS' => null,
|
||||||
);
|
);
|
||||||
private $control_fields = array(
|
private $control_fields = array(
|
||||||
'Name' => '',
|
'Name' => '',
|
||||||
|
@ -312,7 +314,7 @@ private $control_fields = array(
|
||||||
} // end function save
|
} // end function save
|
||||||
|
|
||||||
function zmcControl( $mode=false ) {
|
function zmcControl( $mode=false ) {
|
||||||
if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$this->{'ServerId'} ) ) {
|
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
|
||||||
if ( $this->{'Type'} == 'Local' ) {
|
if ( $this->{'Type'} == 'Local' ) {
|
||||||
$zmcArgs = '-d '.$this->{'Device'};
|
$zmcArgs = '-d '.$this->{'Device'};
|
||||||
} else {
|
} else {
|
||||||
|
@ -329,7 +331,7 @@ private $control_fields = array(
|
||||||
daemonControl( 'start', 'zmc', $zmcArgs );
|
daemonControl( 'start', 'zmc', $zmcArgs );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if ( $this->ServerId() ) {
|
||||||
$Server = $this->Server();
|
$Server = $this->Server();
|
||||||
|
|
||||||
$url = $Server->Url() . '/zm/api/monitors/'.$this->{'Id'}.'.json';
|
$url = $Server->Url() . '/zm/api/monitors/'.$this->{'Id'}.'.json';
|
||||||
|
@ -367,7 +369,7 @@ Logger::Debug("sending command to $url");
|
||||||
} // end function zmcControl
|
} // end function zmcControl
|
||||||
|
|
||||||
function zmaControl( $mode=false ) {
|
function zmaControl( $mode=false ) {
|
||||||
if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$this->{'ServerId'} ) ) {
|
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
|
||||||
if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) {
|
if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) {
|
||||||
if ( ZM_OPT_CONTROL ) {
|
if ( ZM_OPT_CONTROL ) {
|
||||||
daemonControl( 'stop', 'zmtrack.pl', '-m '.$this->{'Id'} );
|
daemonControl( 'stop', 'zmtrack.pl', '-m '.$this->{'Id'} );
|
||||||
|
|
|
@ -126,7 +126,7 @@ if ( $action == 'login' && isset($_REQUEST['username']) && ( ZM_AUTH_TYPE == 're
|
||||||
userLogin( $username, $password );
|
userLogin( $username, $password );
|
||||||
$refreshParent = true;
|
$refreshParent = true;
|
||||||
$view = 'console';
|
$view = 'console';
|
||||||
$redirect = true;
|
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=console';
|
||||||
} else if ( $action == 'logout' ) {
|
} else if ( $action == 'logout' ) {
|
||||||
userLogout();
|
userLogout();
|
||||||
$refreshParent = true;
|
$refreshParent = true;
|
||||||
|
@ -483,6 +483,18 @@ if ( canEdit( 'Monitors' ) ) {
|
||||||
'RecordAudio' => 'toggle',
|
'RecordAudio' => 'toggle',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ( $_REQUEST['newMonitor']['ServerId'] == 'auto' ) {
|
||||||
|
Logger::Debug("Auto selecting server");
|
||||||
|
$_REQUEST['newMonitor']['ServerId'] = dbFetchOne( 'SELECT Id FROM Servers WHERE Status=\'Running\' ORDER BY FreeMem ASC, CpuLoad ASC LIMIT 1', 'Id' );
|
||||||
|
Logger::Debug("Auto selecting server: Got " . $_REQUEST['newMonitor']['ServerId'] );
|
||||||
|
if ( ( ! $_REQUEST['newMonitor'] ) and defined('ZM_SERVER_ID') ) {
|
||||||
|
$_REQUEST['newMonitor']['ServerId'] = ZM_SERVER_ID;
|
||||||
|
Logger::Debug("Auto selecting server to " . ZM_SERVER_ID);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger::Debug("NOT Auto selecting server" . $_REQUEST['newMonitor']['ServerId']);
|
||||||
|
}
|
||||||
|
|
||||||
$columns = getTableColumns( 'Monitors' );
|
$columns = getTableColumns( 'Monitors' );
|
||||||
$changes = getFormChanges( $monitor, $_REQUEST['newMonitor'], $types, $columns );
|
$changes = getFormChanges( $monitor, $_REQUEST['newMonitor'], $types, $columns );
|
||||||
|
|
||||||
|
@ -538,22 +550,26 @@ if ( canEdit( 'Monitors' ) ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$restart = true;
|
$restart = true;
|
||||||
} elseif ( ! $user['MonitorIds'] ) { // Can only create new monitors if we are not restricted to specific monitors
|
} else if ( ! $user['MonitorIds'] ) { // Can only create new monitors if we are not restricted to specific monitors
|
||||||
# FIXME This is actually a race condition. Should lock the table.
|
# FIXME This is actually a race condition. Should lock the table.
|
||||||
$maxSeq = dbFetchOne( 'SELECT max(Sequence) AS MaxSequence FROM Monitors', 'MaxSequence' );
|
$maxSeq = dbFetchOne('SELECT MAX(Sequence) AS MaxSequence FROM Monitors', 'MaxSequence');
|
||||||
$changes[] = 'Sequence = '.($maxSeq+1);
|
$changes[] = 'Sequence = '.($maxSeq+1);
|
||||||
|
|
||||||
dbQuery( 'INSERT INTO Monitors SET '.implode( ', ', $changes ) );
|
if ( dbQuery( 'INSERT INTO Monitors SET '.implode( ', ', $changes ) ) ) {
|
||||||
$mid = dbInsertId();
|
$mid = dbInsertId();
|
||||||
$zoneArea = $_REQUEST['newMonitor']['Width'] * $_REQUEST['newMonitor']['Height'];
|
$zoneArea = $_REQUEST['newMonitor']['Width'] * $_REQUEST['newMonitor']['Height'];
|
||||||
dbQuery( "insert into Zones set MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, sprintf( "%d,%d %d,%d %d,%d %d,%d", 0, 0, $_REQUEST['newMonitor']['Width']-1, 0, $_REQUEST['newMonitor']['Width']-1, $_REQUEST['newMonitor']['Height']-1, 0, $_REQUEST['newMonitor']['Height']-1 ), $zoneArea, intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*2)/100) ) );
|
dbQuery( "insert into Zones set MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, sprintf( "%d,%d %d,%d %d,%d %d,%d", 0, 0, $_REQUEST['newMonitor']['Width']-1, 0, $_REQUEST['newMonitor']['Width']-1, $_REQUEST['newMonitor']['Height']-1, 0, $_REQUEST['newMonitor']['Height']-1 ), $zoneArea, intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*2)/100) ) );
|
||||||
//$view = 'none';
|
//$view = 'none';
|
||||||
$Storage = new Storage( $_REQUEST['newMonitor']['StorageId'] );
|
$Storage = new Storage( $_REQUEST['newMonitor']['StorageId'] );
|
||||||
mkdir( $Storage->Path().'/'.$mid, 0755 );
|
mkdir( $Storage->Path().'/'.$mid, 0755 );
|
||||||
$saferName = basename($_REQUEST['newMonitor']['Name']);
|
$saferName = basename($_REQUEST['newMonitor']['Name']);
|
||||||
symlink( $mid, $Storage->Path().'/'.$saferName );
|
symlink( $mid, $Storage->Path().'/'.$saferName );
|
||||||
if ( isset($_COOKIE['zmGroup']) ) {
|
if ( isset($_COOKIE['zmGroup']) ) {
|
||||||
dbQuery( 'INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($_COOKIE['zmGroup'],$mid) );
|
dbQuery( 'INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($_COOKIE['zmGroup'],$mid) );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Error("Error saving new Monitor.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error("Users with Monitors restrictions cannot create new monitors.");
|
Error("Users with Monitors restrictions cannot create new monitors.");
|
||||||
|
@ -726,7 +742,7 @@ if ( canEdit( 'System' ) ) {
|
||||||
$_SESSION['zmMontageLayout'] = $Layout->Id();
|
$_SESSION['zmMontageLayout'] = $Layout->Id();
|
||||||
setcookie('zmMontageLayout', $Layout->Id(), 1 );
|
setcookie('zmMontageLayout', $Layout->Id(), 1 );
|
||||||
session_write_close();
|
session_write_close();
|
||||||
$redirect = true;
|
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=montagereview';
|
||||||
} // end if save
|
} // end if save
|
||||||
|
|
||||||
} else if ( $_REQUEST['object'] == 'server' ) {
|
} else if ( $_REQUEST['object'] == 'server' ) {
|
||||||
|
@ -893,6 +909,7 @@ if ( canEdit( 'System' ) ) {
|
||||||
case 'lowband' :
|
case 'lowband' :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=options&tab='.$_REQUEST['tab'];
|
||||||
}
|
}
|
||||||
loadConfig( false );
|
loadConfig( false );
|
||||||
} elseif ( $action == 'user' ) {
|
} elseif ( $action == 'user' ) {
|
||||||
|
|
|
@ -98,7 +98,7 @@ function dbLog( $sql, $update=false ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbError( $sql ) {
|
function dbError( $sql ) {
|
||||||
Fatal( "SQL-ERR '".$dbConn->errorInfo()."', statement was '".$sql."'" );
|
Error( "SQL-ERR '".$dbConn->errorInfo()."', statement was '".$sql."'" );
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbEscape( $string ) {
|
function dbEscape( $string ) {
|
||||||
|
@ -142,21 +142,26 @@ function dbQuery( $sql, $params=NULL ) {
|
||||||
}
|
}
|
||||||
} catch(PDOException $e) {
|
} catch(PDOException $e) {
|
||||||
Error( "SQL-ERR '".$e->getMessage()."', statement was '".$sql."' params:" . ($params?implode(',',$params):'') );
|
Error( "SQL-ERR '".$e->getMessage()."', statement was '".$sql."' params:" . ($params?implode(',',$params):'') );
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return( $result );
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbFetchOne( $sql, $col=false, $params=NULL ) {
|
function dbFetchOne( $sql, $col=false, $params=NULL ) {
|
||||||
$result = dbQuery( $sql, $params );
|
$result = dbQuery( $sql, $params );
|
||||||
if ( ! $result ) {
|
if ( ! $result ) {
|
||||||
Fatal( "SQL-ERR dbFetchOne no result, statement was '".$sql."'" . ( $params ? 'params: ' . join(',',$params) : '' ) );
|
Error( "SQL-ERR dbFetchOne no result, statement was '".$sql."'" . ( $params ? 'params: ' . join(',',$params) : '' ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( ! $result->rowCount() ) {
|
||||||
|
# No rows is not an error
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $result && $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) {
|
if ( $result && $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) {
|
||||||
if ( $col ) {
|
if ( $col ) {
|
||||||
if ( ! isset( $dbRow[$col] ) ) {
|
if ( ! isset( $dbRow[$col] ) ) {
|
||||||
Warning( "$col does not exist in the returned row" );
|
Warning( "$col does not exist in the returned row " . print_r($dbRow, true) );
|
||||||
}
|
}
|
||||||
return $dbRow[$col];
|
return $dbRow[$col];
|
||||||
}
|
}
|
||||||
|
@ -168,7 +173,7 @@ function dbFetchOne( $sql, $col=false, $params=NULL ) {
|
||||||
function dbFetchAll( $sql, $col=false, $params=NULL ) {
|
function dbFetchAll( $sql, $col=false, $params=NULL ) {
|
||||||
$result = dbQuery( $sql, $params );
|
$result = dbQuery( $sql, $params );
|
||||||
if ( ! $result ) {
|
if ( ! $result ) {
|
||||||
Fatal( "SQL-ERR dbFetchAll no result, statement was '".$sql."'" . ( $params ? 'params: ' .join(',', $params) : '' ) );
|
Error( "SQL-ERR dbFetchAll no result, statement was '".$sql."'" . ( $params ? 'params: ' .join(',', $params) : '' ) );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,14 +269,14 @@ function getVideoStreamHTML( $id, $src, $width, $height, $format, $title='' ) {
|
||||||
if ( isWindows() ) {
|
if ( isWindows() ) {
|
||||||
return '<object id="'.$id.'" width="'.$width.'" height="'.$height.'
|
return '<object id="'.$id.'" width="'.$width.'" height="'.$height.'
|
||||||
classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
|
classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
|
||||||
codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902"
|
codebase="'.ZM_BASE_PROTOCOL.'://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902"
|
||||||
standby="Loading Microsoft Windows Media Player components..."
|
standby="Loading Microsoft Windows Media Player components..."
|
||||||
type="'.$mimeType.'">
|
type="'.$mimeType.'">
|
||||||
<param name="FileName" value="'.$src.'"/>
|
<param name="FileName" value="'.$src.'"/>
|
||||||
<param name="autoStart" value="1"/>
|
<param name="autoStart" value="1"/>
|
||||||
<param name="showControls" value="0"/>
|
<param name="showControls" value="0"/>
|
||||||
<embed type="'.$mimeType.'"
|
<embed type="'.$mimeType.'"
|
||||||
pluginspage="http://www.microsoft.com/Windows/MediaPlayer/"
|
pluginspage="'.ZM_BASE_PROTOCOL.'://www.microsoft.com/Windows/MediaPlayer/"
|
||||||
src="'.$src.'"
|
src="'.$src.'"
|
||||||
name="'.$title.'"
|
name="'.$title.'"
|
||||||
width="'.$width.'"
|
width="'.$width.'"
|
||||||
|
@ -291,14 +291,14 @@ function getVideoStreamHTML( $id, $src, $width, $height, $format, $title='' ) {
|
||||||
{
|
{
|
||||||
return '<object id="'.$id.'" width="'.$width.'" height="'.$height.'"
|
return '<object id="'.$id.'" width="'.$width.'" height="'.$height.'"
|
||||||
classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
|
classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
|
||||||
codebase="http://www.apple.com/qtactivex/qtplugin.cab"
|
codebase="'.ZM_BASE_PROTOCOL.'://www.apple.com/qtactivex/qtplugin.cab"
|
||||||
type="'.$mimeType.'">
|
type="'.$mimeType.'">
|
||||||
<param name="src" value="'.$src.'"/>
|
<param name="src" value="'.$src.'"/>
|
||||||
<param name="autoplay" VALUE="true"/>
|
<param name="autoplay" VALUE="true"/>
|
||||||
<param name="controller" VALUE="false"/>
|
<param name="controller" VALUE="false"/>
|
||||||
<embed type="'.$mimeType.'"
|
<embed type="'.$mimeType.'"
|
||||||
src="'.$src.'"
|
src="'.$src.'"
|
||||||
pluginspage="http://www.apple.com/quicktime/download/"
|
pluginspage="'.ZM_BASE_PROTOCOL.'://www.apple.com/quicktime/download/"
|
||||||
name="'.$title.'" width="'.$width.'" height="'.$height.'"
|
name="'.$title.'" width="'.$width.'" height="'.$height.'"
|
||||||
autoplay="true"
|
autoplay="true"
|
||||||
controller="true">
|
controller="true">
|
||||||
|
@ -309,13 +309,13 @@ function getVideoStreamHTML( $id, $src, $width, $height, $format, $title='' ) {
|
||||||
{
|
{
|
||||||
return '<object id="'.$id.'" width="'.$width.'" height="'.$height.'"
|
return '<object id="'.$id.'" width="'.$width.'" height="'.$height.'"
|
||||||
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
|
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
|
||||||
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"
|
codebase="'.ZM_BASE_PROTOCOL.'://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"
|
||||||
type="'.$mimeType.'">
|
type="'.$mimeType.'">
|
||||||
<param name="movie" value="'.$src.'"/>
|
<param name="movie" value="'.$src.'"/>
|
||||||
<param name="quality" value="high"/>
|
<param name="quality" value="high"/>
|
||||||
<param name="bgcolor" value="#ffffff"/>
|
<param name="bgcolor" value="#ffffff"/>
|
||||||
<embed type="'.$mimeType.'"
|
<embed type="'.$mimeType.'"
|
||||||
pluginspage="http://www.macromedia.com/go/getflashplayer"
|
pluginspage="'.ZM_BASE_PROTOCOL.'://www.macromedia.com/go/getflashplayer"
|
||||||
src="'.$src.'"
|
src="'.$src.'"
|
||||||
name="'.$title.'"
|
name="'.$title.'"
|
||||||
width="'.$width.'"
|
width="'.$width.'"
|
||||||
|
@ -2132,10 +2132,11 @@ function ajaxResponse( $result=false ) {
|
||||||
if ( function_exists( 'ajaxCleanup' ) )
|
if ( function_exists( 'ajaxCleanup' ) )
|
||||||
ajaxCleanup();
|
ajaxCleanup();
|
||||||
$response = array( 'result'=>'Ok' );
|
$response = array( 'result'=>'Ok' );
|
||||||
if ( is_array( $result ) )
|
if ( is_array( $result ) ) {
|
||||||
$response = array_merge( $response, $result );
|
$response = array_merge( $response, $result );
|
||||||
elseif ( !empty($result) )
|
} elseif ( !empty($result) ) {
|
||||||
$response['message'] = $result;
|
$response['message'] = $result;
|
||||||
|
}
|
||||||
header( 'Content-type: text/plain' );
|
header( 'Content-type: text/plain' );
|
||||||
exit( jsonEncode( $response ) );
|
exit( jsonEncode( $response ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,18 +173,17 @@ if ( isset($_REQUEST['request']) )
|
||||||
foreach ( getSkinIncludes( 'skin.php' ) as $includeFile )
|
foreach ( getSkinIncludes( 'skin.php' ) as $includeFile )
|
||||||
require_once $includeFile;
|
require_once $includeFile;
|
||||||
|
|
||||||
if ( ZM_OPT_USE_AUTH && ZM_AUTH_HASH_LOGINS ) {
|
if ( ZM_OPT_USE_AUTH ) {
|
||||||
Logger::Debug("Useing hash");
|
if ( ZM_AUTH_HASH_LOGINS ) {
|
||||||
if ( empty($user) && ! empty($_REQUEST['auth']) ) {
|
if ( empty($user) && ! empty($_REQUEST['auth']) ) {
|
||||||
if ( $authUser = getAuthUser( $_REQUEST['auth'] ) ) {
|
if ( $authUser = getAuthUser( $_REQUEST['auth'] ) ) {
|
||||||
userLogin( $authUser['Username'], $authUser['Password'], true );
|
userLogin( $authUser['Username'], $authUser['Password'], true );
|
||||||
}
|
}
|
||||||
} else if ( ! empty($user) ) {
|
}
|
||||||
Logger::Debug("generating hash");
|
}
|
||||||
|
if ( ! empty($user) ) {
|
||||||
// generate it once here, while session is open. Value will be cached in session and return when called later on
|
// generate it once here, while session is open. Value will be cached in session and return when called later on
|
||||||
generateAuthHash( ZM_AUTH_HASH_IPS );
|
generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||||
} else {
|
|
||||||
Logger::Debug(" not generating hash");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,11 +217,11 @@ if ( ZM_OPT_USE_AUTH and ! isset($user) ) {
|
||||||
session_write_close();
|
session_write_close();
|
||||||
|
|
||||||
if ( $redirect ) {
|
if ( $redirect ) {
|
||||||
header('Location: '.ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view='.$view);
|
header('Location: '.$redirect);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset( $_REQUEST['request'] ) ) {
|
if ( $request ) {
|
||||||
foreach ( getSkinIncludes( 'ajax/'.$request.'.php', true, true ) as $includeFile ) {
|
foreach ( getSkinIncludes( 'ajax/'.$request.'.php', true, true ) as $includeFile ) {
|
||||||
if ( !file_exists( $includeFile ) )
|
if ( !file_exists( $includeFile ) )
|
||||||
Fatal( "Request '$request' does not exist" );
|
Fatal( "Request '$request' does not exist" );
|
||||||
|
|
|
@ -71,7 +71,9 @@ html ul.tabs li.active, html ul.tabs li.active a:hover {
|
||||||
}
|
}
|
||||||
-->
|
-->
|
||||||
</style>
|
</style>
|
||||||
<script type="text/javascript" src="<?php echo ZM_SKIN_PATH; ?>/js/jquery.js"></script>
|
<script type="text/javascript">
|
||||||
|
<?php include(ZM_SKIN_PATH.'/js/jquery.js'
|
||||||
|
</script>
|
||||||
<script type="text/javascript" language="javascript" charset="utf-8">
|
<script type="text/javascript" language="javascript" charset="utf-8">
|
||||||
|
|
||||||
/*==========[tab code]==========*/
|
/*==========[tab code]==========*/
|
||||||
|
@ -579,14 +581,9 @@ else if (document.layers) window.onload=start_slider;
|
||||||
return( ob_get_clean() );
|
return( ob_get_clean() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function exportEventImagesMaster( $eids ) {
|
||||||
|
ob_start();
|
||||||
|
exportHeader( translate('Images').' Master' );
|
||||||
|
|
||||||
function exportEventImagesMaster( $eids )
|
|
||||||
{
|
|
||||||
ob_start();
|
|
||||||
exportHeader( translate('Images').' Master' );
|
|
||||||
?>
|
?>
|
||||||
<body>
|
<body>
|
||||||
<h2><?php echo translate('Images') ?> Master</h2>
|
<h2><?php echo translate('Images') ?> Master</h2>
|
||||||
|
@ -611,32 +608,27 @@ function exportEventImagesMaster( $eids )
|
||||||
//trigger_error(print_r($monitorNames,1));
|
//trigger_error(print_r($monitorNames,1));
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div id= 'tabs'>
|
<div id="tabs">
|
||||||
<ul class= 'tabs'>
|
<ul class="tabs">
|
||||||
<li class = 'active' ><a href='#all' > All </a></li>
|
<li class="active"><a href="#all"> All </a></li>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
foreach ($monitors as $monitor) {
|
foreach ($monitors as $monitor) {
|
||||||
# code...
|
# code...
|
||||||
echo "<li><a href='#tab$monitor'>" . $monitorNames[$monitor] . "</a></li>";
|
echo "<li><a href='#tab$monitor'>" . $monitorNames[$monitor] . '</a></li>';
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<table width="100%" height="100%" ><tr>
|
<table width="100%" height="100%" ><tr>
|
||||||
<td valign="top" bgcolor="#dddddd" style="padding:10px;">
|
<td valign="top" bgcolor="#dddddd" style="padding:10px;">
|
||||||
<div class='tab_content' id='all'>
|
<div class='tab_content' id='all'>
|
||||||
<h2> All </h2>
|
<h2> All </h2>
|
||||||
<?php
|
<?php
|
||||||
if (!is_array($eids))
|
if (!is_array($eids)) {
|
||||||
{
|
|
||||||
echo "<div><a href=\"javascript:switchevent('$eids/zm/EventImages.html');\"> $eids </div>";
|
echo "<div><a href=\"javascript:switchevent('$eids/zm/EventImages.html');\"> $eids </div>";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<?php foreach($eids as $eid)
|
<?php foreach($eids as $eid) {
|
||||||
{
|
|
||||||
?>
|
?>
|
||||||
<div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div>
|
<div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div>
|
||||||
<?php
|
<?php
|
||||||
|
@ -644,15 +636,11 @@ function exportEventImagesMaster( $eids )
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
|
foreach ($monitors as $monitor) {
|
||||||
foreach ($monitors as $monitor)
|
|
||||||
{
|
|
||||||
echo "<div class='tab_content' id='tab$monitor'>";
|
echo "<div class='tab_content' id='tab$monitor'>";
|
||||||
echo "<h2>Monitor: " . $monitorNames[$monitor] . " </h2>";
|
echo "<h2>Monitor: " . $monitorNames[$monitor] . " </h2>";
|
||||||
foreach ($eids as $eid)
|
foreach ($eids as $eid) {
|
||||||
{
|
if ($eventMonitorId[$eid] == $monitor) {
|
||||||
if ($eventMonitorId[$eid] == $monitor)
|
|
||||||
{
|
|
||||||
?>
|
?>
|
||||||
<div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div>
|
<div><a href="javascript:switchevent('<?php echo $eventPath[$eid]; ?>/zmEventImages.html');"><?php echo$eid?></a></div>
|
||||||
<?php
|
<?php
|
||||||
|
@ -660,7 +648,6 @@ function exportEventImagesMaster( $eids )
|
||||||
}
|
}
|
||||||
echo'</div>';
|
echo'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</td><td>
|
</td><td>
|
||||||
|
@ -750,204 +737,168 @@ function loadintoIframe(iframeid, url){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc )
|
function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) {
|
||||||
{
|
|
||||||
|
|
||||||
if ( canView( 'Events' ) && $eid )
|
if ( (!canView('Events')) or ! $eid ) {
|
||||||
{
|
return;
|
||||||
$event = new Event( $eid );
|
}
|
||||||
$eventPath = $event->Path();
|
|
||||||
$files = array();
|
|
||||||
if ( $dir = opendir( $eventPath ) )
|
|
||||||
{
|
|
||||||
while ( ($file = readdir( $dir )) !== false )
|
|
||||||
{
|
|
||||||
if ( is_file( $eventPath."/".$file ) )
|
|
||||||
{
|
|
||||||
$files[$file] = $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir( $dir );
|
|
||||||
}
|
|
||||||
|
|
||||||
$exportFileList = array();
|
$event = new Event($eid);
|
||||||
|
$eventPath = $event->Path();
|
||||||
if ( $exportDetail )
|
$files = array();
|
||||||
{
|
if ( $dir = opendir($eventPath) ) {
|
||||||
$file = "zmEventDetail.html";
|
while ( ($file = readdir($dir)) !== false ) {
|
||||||
if ( !($fp = fopen( $eventPath."/".$file, "w" )) )
|
if ( is_file($eventPath.'/'.$file) ) {
|
||||||
{
|
$files[$file] = $file;
|
||||||
Fatal( "Can't open event detail export file '$file'" );
|
}
|
||||||
}
|
|
||||||
fwrite( $fp, exportEventDetail( $event, $exportFrames, $exportImages ) );
|
|
||||||
fclose( $fp );
|
|
||||||
$exportFileList[$file] = $eventPath."/".$file;
|
|
||||||
}
|
|
||||||
if ( $exportFrames )
|
|
||||||
{
|
|
||||||
$file = "zmEventFrames.html";
|
|
||||||
if ( !($fp = fopen( $eventPath."/".$file, "w" )) )
|
|
||||||
{
|
|
||||||
Fatal( "Can't open event frames export file '$file'" );
|
|
||||||
}
|
|
||||||
fwrite( $fp, exportEventFrames( $event, $exportDetail, $exportImages ) );
|
|
||||||
fclose( $fp );
|
|
||||||
$exportFileList[$file] = $eventPath."/".$file;
|
|
||||||
}
|
|
||||||
if ( $exportImages )
|
|
||||||
{
|
|
||||||
$filesLeft = array();
|
|
||||||
$myfilelist = array();
|
|
||||||
foreach ( $files as $file )
|
|
||||||
{
|
|
||||||
if ( preg_match( "/-(?:capture|analyse).jpg$/", $file ) )
|
|
||||||
{
|
|
||||||
$exportFileList[$file] = $eventPath."/".$file;
|
|
||||||
$myfilelist[$file] = $eventPath."/".$file;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$filesLeft[$file] = $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$files = $filesLeft;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// create an image slider
|
|
||||||
if(!empty($myfilelist)) {
|
|
||||||
$file = "zmEventImages.html";
|
|
||||||
if ( !($fp = fopen( $eventPath."/".$file, "w" )) ) Fatal( "Can't open event images export file '$file'" );
|
|
||||||
fwrite( $fp, exportEventImages( $event, $exportDetail, $exportFrames, $myfilelist ) );
|
|
||||||
fclose( $fp );
|
|
||||||
$exportFileList[$file] = $eventPath."/".$file;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
if ( $exportVideo )
|
|
||||||
{
|
|
||||||
$filesLeft = array();
|
|
||||||
foreach ( $files as $file )
|
|
||||||
{
|
|
||||||
if ( preg_match( "/\.(?:mpg|mpeg|mp4|avi|asf|3gp)$/", $file ) )
|
|
||||||
{
|
|
||||||
$exportFileList[$file] = $eventPath."/".$file;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$filesLeft[$file] = $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$files = $filesLeft;
|
|
||||||
}
|
|
||||||
if ( $exportMisc )
|
|
||||||
{
|
|
||||||
foreach ( $files as $file )
|
|
||||||
{
|
|
||||||
$exportFileList[$file] = $eventPath."/".$file;
|
|
||||||
}
|
|
||||||
$files = array();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return( array_values( $exportFileList ) );
|
closedir($dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
$exportFileList = array();
|
||||||
|
|
||||||
|
if ( $exportDetail ) {
|
||||||
|
$file = 'zmEventDetail.html';
|
||||||
|
if ( !($fp = fopen( $eventPath.'/'.$file, 'w' )) ) {
|
||||||
|
Fatal( "Can't open event detail export file '$file'" );
|
||||||
|
}
|
||||||
|
fwrite( $fp, exportEventDetail( $event, $exportFrames, $exportImages ) );
|
||||||
|
fclose( $fp );
|
||||||
|
$exportFileList[$file] = $eventPath."/".$file;
|
||||||
|
}
|
||||||
|
if ( $exportFrames ) {
|
||||||
|
$file = 'zmEventFrames.html';
|
||||||
|
if ( !($fp = fopen( $eventPath.'/'.$file, 'w' )) ) {
|
||||||
|
Fatal( "Can't open event frames export file '$file'" );
|
||||||
|
}
|
||||||
|
fwrite( $fp, exportEventFrames( $event, $exportDetail, $exportImages ) );
|
||||||
|
fclose( $fp );
|
||||||
|
$exportFileList[$file] = $eventPath."/".$file;
|
||||||
|
}
|
||||||
|
if ( $exportImages ) {
|
||||||
|
$filesLeft = array();
|
||||||
|
$myfilelist = array();
|
||||||
|
foreach ( $files as $file ) {
|
||||||
|
if ( preg_match( '/-(?:capture|analyse).jpg$/', $file ) ) {
|
||||||
|
$exportFileList[$file] = $eventPath."/".$file;
|
||||||
|
$myfilelist[$file] = $eventPath."/".$file;
|
||||||
|
} else {
|
||||||
|
$filesLeft[$file] = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$files = $filesLeft;
|
||||||
|
|
||||||
|
// create an image slider
|
||||||
|
if ( !empty($myfilelist) ) {
|
||||||
|
$file = 'zmEventImages.html';
|
||||||
|
if ( !($fp = fopen($eventPath.'/'.$file, 'w')) ) Fatal( "Can't open event images export file '$file'" );
|
||||||
|
fwrite( $fp, exportEventImages( $event, $exportDetail, $exportFrames, $myfilelist ) );
|
||||||
|
fclose( $fp );
|
||||||
|
$exportFileList[$file] = $eventPath."/".$file;
|
||||||
|
}
|
||||||
|
} # end if exportImages
|
||||||
|
|
||||||
|
if ( $exportVideo ) {
|
||||||
|
$filesLeft = array();
|
||||||
|
foreach ( $files as $file ) {
|
||||||
|
if ( preg_match( '/\.(?:mpg|mpeg|mov|swf|mp4|mkv|avi|asf|3gp)$/', $file ) ) {
|
||||||
|
$exportFileList[$file] = $eventPath.'/'.$file;
|
||||||
|
} else {
|
||||||
|
$filesLeft[$file] = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$files = $filesLeft;
|
||||||
|
} # end if exportVideo
|
||||||
|
|
||||||
|
if ( $exportMisc ) {
|
||||||
|
foreach ( $files as $file ) {
|
||||||
|
$exportFileList[$file] = $eventPath.'/'.$file;
|
||||||
|
}
|
||||||
|
$files = array();
|
||||||
|
}
|
||||||
|
return( array_values( $exportFileList ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat, $exportStructure = false )
|
function exportEvents( $eids, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat, $exportStructure = false ) {
|
||||||
{
|
|
||||||
|
|
||||||
if ( canView( 'Events' ) && !empty($eids) )
|
|
||||||
{
|
|
||||||
$export_root = "zmExport";
|
|
||||||
$export_listFile = "zmFileList.txt";
|
|
||||||
$exportFileList = array();
|
|
||||||
$html_eventMaster = '';
|
|
||||||
|
|
||||||
if ( is_array( $eids ) )
|
if ( (!canView('Events')) || empty($eids) ) {
|
||||||
{
|
return false;
|
||||||
foreach ( $eids as $eid )
|
}
|
||||||
{
|
$export_root = 'zmExport';
|
||||||
$exportFileList = array_merge( $exportFileList, exportFileList( $eid , $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) );
|
$export_listFile = 'zmFileList.txt';
|
||||||
}
|
$exportFileList = array();
|
||||||
|
$html_eventMaster = '';
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$eid = $eids;
|
|
||||||
$exportFileList = exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc );
|
|
||||||
}
|
|
||||||
|
|
||||||
// create an master image slider
|
|
||||||
if($exportImages)
|
|
||||||
{
|
|
||||||
if ( !is_array($eids) )
|
|
||||||
{
|
|
||||||
$eids = array($eids);
|
|
||||||
}
|
|
||||||
$monitorPath = ZM_DIR_EVENTS."/";
|
|
||||||
$html_eventMaster = 'zmEventImagesMaster_'.date('Ymd_His'). '.html';
|
|
||||||
if ( !($fp = fopen( $monitorPath."/".$html_eventMaster, "w" )) ) Fatal( "Can't open event images export file '$html_eventMaster'" );
|
|
||||||
fwrite( $fp, exportEventImagesMaster( $eids ) );
|
|
||||||
fclose( $fp );
|
|
||||||
$exportFileList[] = $monitorPath."/".$html_eventMaster;
|
|
||||||
}
|
|
||||||
|
|
||||||
$listFile = ZM_DIR_EXPORTS."/".$export_listFile;
|
|
||||||
if ( !($fp = fopen( $listFile, "w" )) )
|
|
||||||
{
|
|
||||||
Fatal( "Can't open event export list file '$listFile'" );
|
|
||||||
}
|
|
||||||
foreach ( $exportFileList as $exportFile )
|
|
||||||
{
|
|
||||||
fwrite( $fp, "$exportFile\n" );
|
|
||||||
}
|
|
||||||
fclose( $fp );
|
|
||||||
$archive = "";
|
|
||||||
if ( $exportFormat == "tar" )
|
|
||||||
{
|
|
||||||
$archive = ZM_DIR_EXPORTS."/".$export_root.".tar.gz";
|
|
||||||
@unlink( $archive );
|
|
||||||
if ($exportStructure == 'flat') { //strip file paths if we choose
|
|
||||||
$command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile)." --xform='s#^.+/##x'";
|
|
||||||
} else {
|
|
||||||
$command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile);
|
|
||||||
}
|
|
||||||
exec( $command, $output, $status );
|
|
||||||
if ( $status )
|
|
||||||
{
|
|
||||||
Error( "Command '$command' returned with status $status" );
|
|
||||||
if ( $output[0] )
|
|
||||||
Error( "First line of output is '".$output[0]."'" );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif ( $exportFormat == "zip" )
|
|
||||||
{
|
|
||||||
$archive = ZM_DIR_EXPORTS."/".$export_root.".zip";
|
|
||||||
@unlink( $archive );
|
|
||||||
if ($exportStructure == 'flat') {
|
|
||||||
$command = "cat ".escapeshellarg($listFile)." | nice -10 zip -q -j ".escapeshellarg($archive)." -@";
|
|
||||||
} else {
|
|
||||||
$command = "cat ".escapeshellarg($listFile)." | nice -10 zip -q ".escapeshellarg($archive)." -@";
|
|
||||||
}
|
|
||||||
//cat zmFileList.txt | zip -q zm_export.zip -@
|
|
||||||
//-bash: zip: command not found
|
|
||||||
|
|
||||||
exec( $command, $output, $status );
|
|
||||||
if ( $status )
|
|
||||||
{
|
|
||||||
Error( "Command '$command' returned with status $status" );
|
|
||||||
if ( $output[0] )
|
|
||||||
Error( "First line of output is '".$output[0]."'" );
|
|
||||||
return( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//clean up temporary files
|
|
||||||
if(!empty($html_eventMaster)) {
|
|
||||||
unlink($monitorPath.'/'.$html_eventMaster);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ( is_array($eids) ) {
|
||||||
|
foreach ( $eids as $eid ) {
|
||||||
|
$exportFileList = array_merge( $exportFileList, exportFileList( $eid , $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc ) );
|
||||||
}
|
}
|
||||||
return( '?view=archive%26type='.$exportFormat );
|
} else {
|
||||||
|
$eid = $eids;
|
||||||
|
$exportFileList = exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc );
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an master image slider
|
||||||
|
if ( $exportImages ) {
|
||||||
|
if ( !is_array($eids) ) {
|
||||||
|
$eids = array($eids);
|
||||||
|
}
|
||||||
|
$monitorPath = ZM_DIR_EVENTS.'/';
|
||||||
|
$html_eventMaster = 'zmEventImagesMaster_'.date('Ymd_His'). '.html';
|
||||||
|
if ( !($fp = fopen( $monitorPath.'/'.$html_eventMaster, 'w' )) ) Fatal( "Can't open event images export file '$html_eventMaster'" );
|
||||||
|
fwrite($fp, exportEventImagesMaster($eids));
|
||||||
|
fclose($fp);
|
||||||
|
$exportFileList[] = $monitorPath.'/'.$html_eventMaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
$listFile = ZM_DIR_EXPORTS.'/'.$export_listFile;
|
||||||
|
if ( !($fp = fopen($listFile, 'w')) ) {
|
||||||
|
Fatal( "Can't open event export list file '$listFile'" );
|
||||||
|
}
|
||||||
|
foreach ( $exportFileList as $exportFile ) {
|
||||||
|
fwrite( $fp, "$exportFile\n" );
|
||||||
|
}
|
||||||
|
fclose( $fp );
|
||||||
|
$archive = '';
|
||||||
|
if ( $exportFormat == 'tar' ) {
|
||||||
|
$archive = ZM_DIR_EXPORTS.'/'.$export_root.'.tar.gz';
|
||||||
|
@unlink( $archive );
|
||||||
|
if ( $exportStructure == 'flat' ) { //strip file paths if we choose
|
||||||
|
$command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile)." --xform='s#^.+/##x'";
|
||||||
|
} else {
|
||||||
|
$command = "nice -10 tar --create --gzip --file=".escapeshellarg($archive)." --files-from=".escapeshellarg($listFile);
|
||||||
|
}
|
||||||
|
exec( $command, $output, $status );
|
||||||
|
if ( $status ) {
|
||||||
|
Error( "Command '$command' returned with status $status" );
|
||||||
|
if ( $output[0] )
|
||||||
|
Error( "First line of output is '".$output[0]."'" );
|
||||||
|
return( false );
|
||||||
|
}
|
||||||
|
} elseif ( $exportFormat == 'zip' ) {
|
||||||
|
$archive = ZM_DIR_EXPORTS.'/'.$export_root.'.zip';
|
||||||
|
@unlink( $archive );
|
||||||
|
if ($exportStructure == 'flat') {
|
||||||
|
$command = "cat ".escapeshellarg($listFile)." | nice -10 zip -q -j ".escapeshellarg($archive)." -@";
|
||||||
|
} else {
|
||||||
|
$command = "cat ".escapeshellarg($listFile)." | nice -10 zip -q ".escapeshellarg($archive)." -@";
|
||||||
|
}
|
||||||
|
//cat zmFileList.txt | zip -q zm_export.zip -@
|
||||||
|
//-bash: zip: command not found
|
||||||
|
|
||||||
|
exec( $command, $output, $status );
|
||||||
|
if ( $status ) {
|
||||||
|
Error("Command '$command' returned with status $status");
|
||||||
|
if ( $output[0] )
|
||||||
|
Error("First line of output is '".$output[0]."'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//clean up temporary files
|
||||||
|
if ( !empty($html_eventMaster) ) {
|
||||||
|
unlink($monitorPath.'/'.$html_eventMaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
return( '?view=archive%26type='.$exportFormat );
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,11 +85,11 @@ if ( ! is_array( $selected_monitor_ids ) ) {
|
||||||
} # end foreach filter
|
} # end foreach filter
|
||||||
if ( ! empty( $user['MonitorIds'] ) ) {
|
if ( ! empty( $user['MonitorIds'] ) ) {
|
||||||
$ids = explode(',', $user['MonitorIds'] );
|
$ids = explode(',', $user['MonitorIds'] );
|
||||||
$conditions[] = 'Id IN ('.implode(',',array_map( function(){return '?';}, $ids) ).')';
|
$conditions[] = 'M.Id IN ('.implode(',',array_map( function(){return '?';}, $ids) ).')';
|
||||||
$values += $ids;
|
$values += $ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = 'SELECT *,S.Status AS Status, S.CaptureFPS AS CaptureFPS FROM Monitors AS M LEFT JOIN Monitor_Status AS S ON S.Id=M.Id ' . ( count($conditions) ? ' WHERE ' . implode(' AND ', $conditions ) : '' ).' ORDER BY Sequence ASC';
|
$sql = 'SELECT *,S.Status AS Status, S.CaptureFPS AS CaptureFPS FROM Monitors AS M LEFT JOIN Monitor_Status AS S ON MonitorId=Id ' . ( count($conditions) ? ' WHERE ' . implode(' AND ', $conditions ) : '' ).' ORDER BY Sequence ASC';
|
||||||
$monitors = dbFetchAll( $sql, null, $values );
|
$monitors = dbFetchAll( $sql, null, $values );
|
||||||
$displayMonitors = array();
|
$displayMonitors = array();
|
||||||
$monitors_dropdown = array();
|
$monitors_dropdown = array();
|
||||||
|
|
|
@ -44,6 +44,11 @@ xhtmlHeaders(__FILE__, translate('AddMonitors'));
|
||||||
</div>
|
</div>
|
||||||
<div style="width:50%;position: absolute; top:0; left: 0;height: 100%;">
|
<div style="width:50%;position: absolute; top:0; left: 0;height: 100%;">
|
||||||
<fieldset><legend>Enter by IP or URL</legend>
|
<fieldset><legend>Enter by IP or URL</legend>
|
||||||
|
<p>
|
||||||
|
Simply enter the ip address or full url to the stream.
|
||||||
|
It will be probed for available streams, or checked to see if it has already been entered.
|
||||||
|
If streams are found, they will be listed in the results column. Click Add to add them.
|
||||||
|
</p>
|
||||||
<!--<input type="text" name="newMonitor[Name]" />-->
|
<!--<input type="text" name="newMonitor[Name]" />-->
|
||||||
<input type="text" name="newMonitor[Url]" oninput="probe(this);"/>
|
<input type="text" name="newMonitor[Url]" oninput="probe(this);"/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -61,7 +66,9 @@ xhtmlHeaders(__FILE__, translate('AddMonitors'));
|
||||||
<td>MN1</td>
|
<td>MN1</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<p>
|
||||||
Defaults to apply to each monitor:<br/>
|
Defaults to apply to each monitor:<br/>
|
||||||
|
</p>
|
||||||
<table><tr><th>Setting</th><th>Value</th></tr>
|
<table><tr><th>Setting</th><th>Value</th></tr>
|
||||||
<tr><td><?php echo translate('Function') ?></td><td>
|
<tr><td><?php echo translate('Function') ?></td><td>
|
||||||
<?php
|
<?php
|
||||||
|
@ -69,7 +76,7 @@ xhtmlHeaders(__FILE__, translate('AddMonitors'));
|
||||||
foreach ( getEnumValues('Monitors', 'Function') as $opt ) {
|
foreach ( getEnumValues('Monitors', 'Function') as $opt ) {
|
||||||
$options[$opt] = translate('Fn'.$opt);
|
$options[$opt] = translate('Fn'.$opt);
|
||||||
}
|
}
|
||||||
echo htmlSelect( 'newMonitor[Function]', $options, 'Record' );
|
echo htmlSelect( 'newMonitor[Function]', $options, 'Mocord' );
|
||||||
?>
|
?>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<?php
|
<?php
|
||||||
|
@ -100,7 +107,7 @@ xhtmlHeaders(__FILE__, translate('AddMonitors'));
|
||||||
?>
|
?>
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
<br/>
|
||||||
<input type="file" name="import_file" id="import_file"/>
|
<input type="file" name="import_file" id="import_file"/>
|
||||||
<input type="button" value="Import" onclick="import_csv(this.form);"/>
|
<input type="button" value="Import" onclick="import_csv(this.form);"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -238,12 +238,21 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
$source = $monitor['Device'].' ('.$monitor['Channel'].')';
|
$source = $monitor['Device'].' ('.$monitor['Channel'].')';
|
||||||
} elseif ( $monitor['Type'] == 'Remote' ) {
|
} elseif ( $monitor['Type'] == 'Remote' ) {
|
||||||
$source = preg_replace( '/^.*@/', '', $monitor['Host'] );
|
$source = preg_replace( '/^.*@/', '', $monitor['Host'] );
|
||||||
|
if ( $monitor['Port'] != '80' and $monitor['Port'] != '554' ) {
|
||||||
|
$source .= ':'.$monitor['Port'];
|
||||||
|
}
|
||||||
} elseif ( $monitor['Type'] == 'File' || $monitor['Type'] == 'cURL' ) {
|
} elseif ( $monitor['Type'] == 'File' || $monitor['Type'] == 'cURL' ) {
|
||||||
$source = preg_replace( '/^.*\//', '', $monitor['Path'] );
|
$source = preg_replace( '/^.*\//', '', $monitor['Path'] );
|
||||||
} elseif ( $monitor['Type'] == 'Ffmpeg' || $monitor['Type'] == 'Libvlc' ) {
|
} elseif ( $monitor['Type'] == 'Ffmpeg' || $monitor['Type'] == 'Libvlc' ) {
|
||||||
$url_parts = parse_url( $monitor['Path'] );
|
$url_parts = parse_url( $monitor['Path'] );
|
||||||
$source = $url_parts['host']. (
|
unset($url_parts['user']);
|
||||||
( isset($url_parts['port']) and ( $url_parts['port'] != '554' and $url_parts['port'] != '80' ) ) ? ':'.$url_parts['port'] : '' );
|
unset($url_parts['pass']);
|
||||||
|
unset($url_parts['scheme']);
|
||||||
|
unset($url_parts['query']);
|
||||||
|
unset($url_parts['path']);
|
||||||
|
if ( isset($url_parts['port']) and ( $url_parts['port'] == '80' or $url_parts['port'] == '554' ) )
|
||||||
|
unset($url_parts['port']);
|
||||||
|
$source = unparse_url( $url_parts );
|
||||||
}
|
}
|
||||||
if ( $source == '' ) {
|
if ( $source == '' ) {
|
||||||
$source = 'Monitor ' . $monitor['Id'];
|
$source = 'Monitor ' . $monitor['Id'];
|
||||||
|
@ -283,8 +292,10 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
||||||
<td class="colId"><?php echo count($displayMonitors) ?></td>
|
<td class="colId"><?php echo count($displayMonitors) ?></td>
|
||||||
<td class="colLeftButtons" colspan="<?php echo $left_columns -1?>">
|
<td class="colLeftButtons" colspan="<?php echo $left_columns -1?>">
|
||||||
<input type="button" value="<?php echo translate('Refresh') ?>" onclick="location.reload(true);"/>
|
<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);"/>
|
<!--<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 (canEdit( 'Monitors' ) && !$user['MonitorIds']) ? '' : ' disabled="disabled"' ?>
|
||||||
|
/>-->
|
||||||
|
<?php echo makePopupButton( '?view=monitor', 'zmMonitor0', 'monitor', translate('AddNewMonitor'), (canEdit( 'Monitors' ) && !$user['MonitorIds']) ) ?>
|
||||||
<input type="button" name="editBtn" value="<?php echo translate('Edit') ?>" onclick="editMonitor( this )" disabled="disabled"/>
|
<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"/>
|
<input type="button" name="deleteBtn" value="<?php echo translate('Delete') ?>" onclick="deleteMonitor( this )" disabled="disabled"/>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -43,6 +43,8 @@ $filterQuery = $_REQUEST['filter']['query'];
|
||||||
if ( $_REQUEST['filter']['sql'] ) {
|
if ( $_REQUEST['filter']['sql'] ) {
|
||||||
$countSql .= $_REQUEST['filter']['sql'];
|
$countSql .= $_REQUEST['filter']['sql'];
|
||||||
$eventsSql .= $_REQUEST['filter']['sql'];
|
$eventsSql .= $_REQUEST['filter']['sql'];
|
||||||
|
} else {
|
||||||
|
Error("No filtering in events, will load ALL!");
|
||||||
}
|
}
|
||||||
$eventsSql .= " ORDER BY $sortColumn $sortOrder";
|
$eventsSql .= " ORDER BY $sortColumn $sortOrder";
|
||||||
|
|
||||||
|
@ -141,6 +143,7 @@ if ( $pages > 1 ) {
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$disk_space_total = 0;
|
$disk_space_total = 0;
|
||||||
|
|
||||||
|
Logger::Debug("EventSql: $eventsSql");
|
||||||
$results = dbQuery( $eventsSql );
|
$results = dbQuery( $eventsSql );
|
||||||
while ( $event_row = dbFetchNext( $results ) ) {
|
while ( $event_row = dbFetchNext( $results ) ) {
|
||||||
$event = new Event( $event_row );
|
$event = new Event( $event_row );
|
||||||
|
|
|
@ -24,18 +24,18 @@ if ( !canView( 'Events' ) ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( isset($_SESSION['export']) ) {
|
if ( isset($_SESSION['export']) ) {
|
||||||
if ( isset($_SESSION['export']['detail']) )
|
if ( isset($_SESSION['export']['detail']) )
|
||||||
$_REQUEST['exportDetail'] = $_SESSION['export']['detail'];
|
$_REQUEST['exportDetail'] = $_SESSION['export']['detail'];
|
||||||
if ( isset($_SESSION['export']['frames']) )
|
if ( isset($_SESSION['export']['frames']) )
|
||||||
$_REQUEST['exportFrames'] = $_SESSION['export']['frames'];
|
$_REQUEST['exportFrames'] = $_SESSION['export']['frames'];
|
||||||
if ( isset($_SESSION['export']['images']) )
|
if ( isset($_SESSION['export']['images']) )
|
||||||
$_REQUEST['exportImages'] = $_SESSION['export']['images'];
|
$_REQUEST['exportImages'] = $_SESSION['export']['images'];
|
||||||
if ( isset($_SESSION['export']['video']) )
|
if ( isset($_SESSION['export']['video']) )
|
||||||
$_REQUEST['exportVideo'] = $_SESSION['export']['video'];
|
$_REQUEST['exportVideo'] = $_SESSION['export']['video'];
|
||||||
if ( isset($_SESSION['export']['misc']) )
|
if ( isset($_SESSION['export']['misc']) )
|
||||||
$_REQUEST['exportMisc'] = $_SESSION['export']['misc'];
|
$_REQUEST['exportMisc'] = $_SESSION['export']['misc'];
|
||||||
if ( isset($_SESSION['export']['format']) )
|
if ( isset($_SESSION['export']['format']) )
|
||||||
$_REQUEST['exportFormat'] = $_SESSION['export']['format'];
|
$_REQUEST['exportFormat'] = $_SESSION['export']['format'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
@ -101,24 +101,20 @@ elseif ( !empty($_REQUEST['eids']) )
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<input type="button" id="exportButton" name="exportButton" value="<?php echo translate('Export') ?>" onclick="exportEvent( this.form );" disabled="disabled"/>
|
<button id="exportButton" name="exportButton" value="Export" onclick="exportEvent(this.form);" disabled="disabled"><?php echo translate('Export') ?></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
if ( isset($_REQUEST['generated']) )
|
if ( isset($_REQUEST['generated']) ) {
|
||||||
{
|
|
||||||
?>
|
?>
|
||||||
<h2 id="exportProgress" class="<?php echo $_REQUEST['generated']?'infoText':'errorText' ?>"><span id="exportProgressText"><?php echo $_REQUEST['generated']?translate('ExportSucceeded'):translate('ExportFailed') ?></span><span id="exportProgressTicker"></span></h2>
|
<h2 id="exportProgress" class="<?php echo $_REQUEST['generated']?'infoText':'errorText' ?>"><span id="exportProgressText"><?php echo $_REQUEST['generated']?translate('ExportSucceeded'):translate('ExportFailed') ?></span><span id="exportProgressTicker"></span></h2>
|
||||||
<?php
|
<?php
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
?>
|
?>
|
||||||
<h2 id="exportProgress" class="hidden warnText"><span id="exportProgressText"><?php echo translate('Exporting') ?></span><span id="exportProgressTicker"></span></h2>
|
<h2 id="exportProgress" class="hidden warnText"><span id="exportProgressText"><?php echo translate('Exporting') ?></span><span id="exportProgressTicker"></span></h2>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( !empty($_REQUEST['generated']) )
|
if ( !empty($_REQUEST['generated']) ) {
|
||||||
{
|
|
||||||
?>
|
?>
|
||||||
<h3 id="downloadLink"><a href="<?php echo validHtmlStr($_REQUEST['exportFile']) ?>"><?php echo translate('Download') ?></a></h3>
|
<h3 id="downloadLink"><a href="<?php echo validHtmlStr($_REQUEST['exportFile']) ?>"><?php echo translate('Download') ?></a></h3>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -102,7 +102,7 @@ echo htmlSelect( 'newGroup[ParentId]', $options, $newGroup->ParentId(), array('o
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Monitor') ?></th>
|
<th scope="row"><?php echo translate('Monitor') ?></th>
|
||||||
<td>
|
<td>
|
||||||
<select name="newGroup[MonitorIds][]" size="4" multiple="multiple" onchange="configureButtons(this);">
|
<select name="newGroup[MonitorIds][]" class="chosen" multiple="multiple" onchange="configureButtons(this);">
|
||||||
<?php
|
<?php
|
||||||
$monitors = dbFetchAll( 'SELECT Id,Name FROM Monitors ORDER BY Sequence ASC' );
|
$monitors = dbFetchAll( 'SELECT Id,Name FROM Monitors ORDER BY Sequence ASC' );
|
||||||
$monitorIds = $newGroup->MonitorIds();
|
$monitorIds = $newGroup->MonitorIds();
|
||||||
|
@ -127,4 +127,7 @@ echo htmlSelect( 'newGroup[ParentId]', $options, $newGroup->ParentId(), array('o
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$j('.chosen').chosen();
|
||||||
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,21 +8,22 @@ function probe( url_e ) {
|
||||||
var ProbeResults;
|
var ProbeResults;
|
||||||
|
|
||||||
function getProbeResponse( respObj, respText ) {
|
function getProbeResponse( respObj, respText ) {
|
||||||
if ( checkStreamForErrors( "getProbeResponse", respObj ) )
|
if ( checkStreamForErrors( "getProbeResponse", respObj ) ) {
|
||||||
|
console.log(respText);
|
||||||
return;
|
return;
|
||||||
//alert(respText);
|
}
|
||||||
|
|
||||||
if ( respObj.Streams ) {
|
if ( respObj.Streams && respObj.Streams.length ) {
|
||||||
parseStreams( respObj.Streams );
|
parseStreams( respObj.Streams );
|
||||||
} else {
|
//} else {
|
||||||
alert("No Streams");
|
//console.log("No streams: " + respText);
|
||||||
}
|
}
|
||||||
} // end function getProbeResponse
|
} // end function getProbeResponse
|
||||||
|
|
||||||
function parseStreams( Streams ) {
|
function parseStreams( Streams ) {
|
||||||
ProbeResults = Array();
|
ProbeResults = Array();
|
||||||
|
|
||||||
var results_div = $j('#url_results')[0];
|
var results_div = $j('#results')[0];
|
||||||
if ( ! results_div ) {
|
if ( ! results_div ) {
|
||||||
console.log("No results div found.");
|
console.log("No results div found.");
|
||||||
return;
|
return;
|
||||||
|
@ -33,7 +34,7 @@ function parseStreams( Streams ) {
|
||||||
for( i in Streams ) {
|
for( i in Streams ) {
|
||||||
var stream = Streams[i];
|
var stream = Streams[i];
|
||||||
if ( stream.url ) {
|
if ( stream.url ) {
|
||||||
html += '<p>'+stream.url;
|
html += '<p>'+stream.Monitor.Name + ' at ' + stream.url;
|
||||||
if ( stream.Monitor.Id ) {
|
if ( stream.Monitor.Id ) {
|
||||||
html += ' is already entered into the system by Monitor ' + stream.Monitor.Id + ' ' + stream.Monitor.Name + '<br/>';
|
html += ' is already entered into the system by Monitor ' + stream.Monitor.Id + ' ' + stream.Monitor.Name + '<br/>';
|
||||||
html += '<input type="button" value="Edit" onclick="addMonitor(\''+stream.url+'\');"/>';
|
html += '<input type="button" value="Edit" onclick="addMonitor(\''+stream.url+'\');"/>';
|
||||||
|
|
|
@ -34,8 +34,11 @@ function addMonitor(element) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dupParam = (monitorId == -1 ) ? '': '&dupId='+monitorId;
|
if ( monitorId != -1 ) {
|
||||||
createPopup( '?view=monitor'+dupParam, 'zmMonitor0', 'monitor' );
|
createPopup( '?view=monitor&dupId='+monitorId, 'zmMonitor0', 'monitor' );
|
||||||
|
} else {
|
||||||
|
window.location = '?view=add_monitors';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function editMonitor( element ) {
|
function editMonitor( element ) {
|
||||||
|
|
|
@ -56,64 +56,66 @@ function Monitor( monitorData ) {
|
||||||
var stream = $j('#liveStream'+this.id)[0];
|
var stream = $j('#liveStream'+this.id)[0];
|
||||||
|
|
||||||
if ( respObj.result == 'Ok' ) {
|
if ( respObj.result == 'Ok' ) {
|
||||||
this.status = respObj.status;
|
if ( respObj.status ) {
|
||||||
this.alarmState = this.status.state;
|
this.status = respObj.status;
|
||||||
|
this.alarmState = this.status.state;
|
||||||
|
|
||||||
var stateClass = "";
|
var stateClass = "";
|
||||||
if ( this.alarmState == STATE_ALARM )
|
if ( this.alarmState == STATE_ALARM )
|
||||||
stateClass = "alarm";
|
stateClass = "alarm";
|
||||||
else if ( this.alarmState == STATE_ALERT )
|
else if ( this.alarmState == STATE_ALERT )
|
||||||
stateClass = "alert";
|
stateClass = "alert";
|
||||||
else
|
else
|
||||||
stateClass = "idle";
|
stateClass = "idle";
|
||||||
|
|
||||||
if ( !COMPACT_MONTAGE ) {
|
if ( !COMPACT_MONTAGE ) {
|
||||||
$('fpsValue'+this.id).set( 'text', this.status.fps );
|
$('fpsValue'+this.id).set( 'text', this.status.fps );
|
||||||
$('stateValue'+this.id).set( 'text', stateStrings[this.alarmState] );
|
$('stateValue'+this.id).set( 'text', stateStrings[this.alarmState] );
|
||||||
this.setStateClass( $('monitorState'+this.id), stateClass );
|
this.setStateClass( $('monitorState'+this.id), stateClass );
|
||||||
}
|
}
|
||||||
this.setStateClass( $('monitor'+this.id), stateClass );
|
this.setStateClass( $('monitor'+this.id), stateClass );
|
||||||
|
|
||||||
/*Stream could be an applet so can't use moo tools*/
|
/*Stream could be an applet so can't use moo tools*/
|
||||||
stream.className = stateClass;
|
stream.className = stateClass;
|
||||||
|
|
||||||
var isAlarmed = ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT );
|
var isAlarmed = ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT );
|
||||||
var wasAlarmed = ( this.lastAlarmState == STATE_ALARM || this.lastAlarmState == STATE_ALERT );
|
var wasAlarmed = ( this.lastAlarmState == STATE_ALARM || this.lastAlarmState == STATE_ALERT );
|
||||||
|
|
||||||
var newAlarm = ( isAlarmed && !wasAlarmed );
|
var newAlarm = ( isAlarmed && !wasAlarmed );
|
||||||
var oldAlarm = ( !isAlarmed && wasAlarmed );
|
var oldAlarm = ( !isAlarmed && wasAlarmed );
|
||||||
|
|
||||||
if ( newAlarm ) {
|
if ( newAlarm ) {
|
||||||
|
if ( false && SOUND_ON_ALARM ) {
|
||||||
|
// Enable the alarm sound
|
||||||
|
$('alarmSound').removeClass( 'hidden' );
|
||||||
|
}
|
||||||
|
if ( POPUP_ON_ALARM ) {
|
||||||
|
windowToFront();
|
||||||
|
}
|
||||||
|
}
|
||||||
if ( false && SOUND_ON_ALARM ) {
|
if ( false && SOUND_ON_ALARM ) {
|
||||||
// Enable the alarm sound
|
if ( oldAlarm ) {
|
||||||
$('alarmSound').removeClass( 'hidden' );
|
// Disable alarm sound
|
||||||
|
$('alarmSound').addClass( 'hidden' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( POPUP_ON_ALARM ) {
|
if ( this.status.auth ) {
|
||||||
windowToFront();
|
if ( this.status.auth != auth_hash ) {
|
||||||
}
|
// Try to reload the image stream.
|
||||||
}
|
if ( stream )
|
||||||
if ( false && SOUND_ON_ALARM ) {
|
stream.src = stream.src.replace( /auth=\w+/i, 'auth='+this.status.auth );
|
||||||
if ( oldAlarm ) {
|
console.log("Changed auth from " + auth_hash + " to " + this.status.auth );
|
||||||
// Disable alarm sound
|
auth_hash = this.status.auth;
|
||||||
$('alarmSound').addClass( 'hidden' );
|
}
|
||||||
}
|
} // end if have a new auth hash
|
||||||
}
|
} // end if has state
|
||||||
if ( this.status.auth ) {
|
|
||||||
if ( this.status.auth != auth_hash ) {
|
|
||||||
// Try to reload the image stream.
|
|
||||||
if ( stream )
|
|
||||||
stream.src = stream.src.replace( /auth=\w+/i, 'auth='+this.status.auth );
|
|
||||||
console.log("Changed auth from " + auth_hash + " to " + this.status.auth );
|
|
||||||
auth_hash = this.status.auth;
|
|
||||||
}
|
|
||||||
} // end if have a new auth hash
|
|
||||||
} else {
|
} else {
|
||||||
console.error( respObj.message );
|
console.error( respObj.message );
|
||||||
// Try to reload the image stream.
|
// Try to reload the image stream.
|
||||||
if ( stream ) {
|
if ( stream ) {
|
||||||
if ( stream.src ) {
|
if ( stream.src ) {
|
||||||
console.log('Reloading stream: ' + stream.src );
|
console.log('Reloading stream: ' + stream.src );
|
||||||
stream.src = stream.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) ));
|
stream.src = stream.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) ));
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -35,7 +35,7 @@ monitorData[monitorData.length] = {
|
||||||
'connKey': <?php echo $monitor->connKey() ?>,
|
'connKey': <?php echo $monitor->connKey() ?>,
|
||||||
'width': <?php echo $monitor->Width() ?>,
|
'width': <?php echo $monitor->Width() ?>,
|
||||||
'height':<?php echo $monitor->Height() ?>,
|
'height':<?php echo $monitor->Height() ?>,
|
||||||
'server_url': '<?php echo $monitor->Server()->Url().(ZM_MIN_STREAMING_PORT?':'.(ZM_MIN_STREAMING_PORT+$monitor->Id()):'').$_SERVER['PHP_SELF'] ?>',
|
'server_url': '<?php echo $monitor->Server()->Url().$_SERVER['PHP_SELF'] ?>',
|
||||||
'onclick': function(){createPopup( '?view=watch&mid=<?php echo $monitor->Id() ?>', 'zmWatch<?php echo $monitor->Id() ?>', 'watch', <?php echo reScale( $monitor->Width(), $monitor->PopupScale() ); ?>, <?php echo reScale( $monitor->Height(), $monitor->PopupScale() ); ?> );}
|
'onclick': function(){createPopup( '?view=watch&mid=<?php echo $monitor->Id() ?>', 'zmWatch<?php echo $monitor->Id() ?>', 'watch', <?php echo reScale( $monitor->Width(), $monitor->PopupScale() ); ?>, <?php echo reScale( $monitor->Height(), $monitor->PopupScale() ); ?> );}
|
||||||
};
|
};
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -38,7 +38,6 @@ function changeScale() {
|
||||||
newHeight = monitorHeight * scale / SCALE_BASE;
|
newHeight = monitorHeight * scale / SCALE_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Cookie.write( 'zmWatchScale'+monitorId, scale, { duration: 10*365 } );
|
Cookie.write( 'zmWatchScale'+monitorId, scale, { duration: 10*365 } );
|
||||||
|
|
||||||
/*Stream could be an applet so can't use moo tools*/
|
/*Stream could be an applet so can't use moo tools*/
|
||||||
|
@ -107,101 +106,112 @@ function setAlarmState( currentAlarmState ) {
|
||||||
var streamCmdParms = "view=request&request=stream&connkey="+connKey;
|
var streamCmdParms = "view=request&request=stream&connkey="+connKey;
|
||||||
if ( auth_hash )
|
if ( auth_hash )
|
||||||
streamCmdParms += '&auth='+auth_hash;
|
streamCmdParms += '&auth='+auth_hash;
|
||||||
|
var streamCmdReq = new Request.JSON( {
|
||||||
var streamCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStreamCmdResponse } );
|
url: monitorUrl+thisUrl,
|
||||||
|
method: 'get',
|
||||||
|
timeout: AJAX_TIMEOUT,
|
||||||
|
link: 'chain',
|
||||||
|
onSuccess: getStreamCmdResponse,
|
||||||
|
onFailure: getStreamCmdFailure
|
||||||
|
} );
|
||||||
var streamCmdTimer = null;
|
var streamCmdTimer = null;
|
||||||
|
|
||||||
var streamStatus;
|
var streamStatus;
|
||||||
|
|
||||||
|
function getStreamCmdFailure(xhr) {
|
||||||
|
console.log(xhr);
|
||||||
|
}
|
||||||
function getStreamCmdResponse( respObj, respText ) {
|
function getStreamCmdResponse( respObj, respText ) {
|
||||||
watchdogOk("stream");
|
watchdogOk("stream");
|
||||||
if ( streamCmdTimer )
|
if ( streamCmdTimer )
|
||||||
streamCmdTimer = clearTimeout( streamCmdTimer );
|
streamCmdTimer = clearTimeout( streamCmdTimer );
|
||||||
|
|
||||||
if ( respObj.result == 'Ok' ) {
|
if ( respObj.result == 'Ok' ) {
|
||||||
streamStatus = respObj.status;
|
// The get status command can get backed up, in which case we won't be able to get the semaphore and will exit.
|
||||||
$('fpsValue').set( 'text', streamStatus.fps );
|
if ( respObj.status ) {
|
||||||
|
streamStatus = respObj.status;
|
||||||
|
$('fpsValue').set( 'text', streamStatus.fps );
|
||||||
|
|
||||||
setAlarmState( streamStatus.state );
|
setAlarmState( streamStatus.state );
|
||||||
|
|
||||||
$('levelValue').set( 'text', streamStatus.level );
|
$('levelValue').set( 'text', streamStatus.level );
|
||||||
if ( streamStatus.level > 95 )
|
if ( streamStatus.level > 95 )
|
||||||
$('levelValue').className = "alarm";
|
$('levelValue').className = "alarm";
|
||||||
else if ( streamStatus.level > 80 )
|
else if ( streamStatus.level > 80 )
|
||||||
$('levelValue').className = "alert";
|
$('levelValue').className = "alert";
|
||||||
else
|
else
|
||||||
$('levelValue').className = "ok";
|
$('levelValue').className = "ok";
|
||||||
|
|
||||||
var delayString = secsToTime( streamStatus.delay );
|
var delayString = secsToTime( streamStatus.delay );
|
||||||
|
|
||||||
if ( streamStatus.paused == true ) {
|
if ( streamStatus.paused == true ) {
|
||||||
$('modeValue').set( 'text', "Paused" );
|
$('modeValue').set( 'text', "Paused" );
|
||||||
$('rate').addClass( 'hidden' );
|
$('rate').addClass( 'hidden' );
|
||||||
$('delayValue').set( 'text', delayString );
|
$('delayValue').set( 'text', delayString );
|
||||||
$('delay').removeClass( 'hidden' );
|
$('delay').removeClass( 'hidden' );
|
||||||
$('level').removeClass( 'hidden' );
|
$('level').removeClass( 'hidden' );
|
||||||
streamCmdPause( false );
|
streamCmdPause( false );
|
||||||
} else if ( streamStatus.delayed == true ) {
|
} else if ( streamStatus.delayed == true ) {
|
||||||
$('modeValue').set( 'text', "Replay" );
|
$('modeValue').set( 'text', "Replay" );
|
||||||
$('rateValue').set( 'text', streamStatus.rate );
|
$('rateValue').set( 'text', streamStatus.rate );
|
||||||
$('rate').removeClass( 'hidden' );
|
$('rate').removeClass( 'hidden' );
|
||||||
$('delayValue').set( 'text', delayString );
|
$('delayValue').set( 'text', delayString );
|
||||||
$('delay').removeClass( 'hidden' );
|
$('delay').removeClass( 'hidden' );
|
||||||
$('level').removeClass( 'hidden' );
|
$('level').removeClass( 'hidden' );
|
||||||
if ( streamStatus.rate == 1 ) {
|
if ( streamStatus.rate == 1 ) {
|
||||||
streamCmdPlay( false );
|
streamCmdPlay( false );
|
||||||
} else if ( streamStatus.rate > 0 ) {
|
} else if ( streamStatus.rate > 0 ) {
|
||||||
if ( streamStatus.rate < 1 )
|
if ( streamStatus.rate < 1 )
|
||||||
streamCmdSlowFwd( false );
|
streamCmdSlowFwd( false );
|
||||||
else
|
else
|
||||||
streamCmdFastFwd( false );
|
streamCmdFastFwd( false );
|
||||||
} else {
|
|
||||||
if ( streamStatus.rate > -1 )
|
|
||||||
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' );
|
|
||||||
else
|
|
||||||
setButtonState( $('zoomOutBtn'), 'inactive' );
|
|
||||||
|
|
||||||
if ( canEditMonitors ) {
|
|
||||||
if ( streamStatus.enabled ) {
|
|
||||||
$('enableAlarmsLink').addClass( 'hidden' );
|
|
||||||
$('disableAlarmsLink').removeClass( 'hidden' );
|
|
||||||
if ( streamStatus.forced ) {
|
|
||||||
$('forceAlarmLink').addClass( 'hidden' );
|
|
||||||
$('cancelAlarmLink').removeClass( 'hidden' );
|
|
||||||
} else {
|
} else {
|
||||||
$('forceAlarmLink').removeClass( 'hidden' );
|
if ( streamStatus.rate > -1 )
|
||||||
$('cancelAlarmLink').addClass( 'hidden' );
|
streamCmdSlowRev( false );
|
||||||
}
|
else
|
||||||
$('forceCancelAlarm').removeClass( 'hidden' );
|
streamCmdFastRev( false );
|
||||||
|
} // rate
|
||||||
} else {
|
} else {
|
||||||
$('enableAlarmsLink').removeClass( 'hidden' );
|
$('modeValue').set( 'text', "Live" );
|
||||||
$('disableAlarmsLink').addClass( 'hidden' );
|
$('rate').addClass( 'hidden' );
|
||||||
$('forceCancelAlarm').addClass( 'hidden' );
|
$('delay').addClass( 'hidden' );
|
||||||
}
|
$('level').addClass( 'hidden' );
|
||||||
$('enableDisableAlarms').removeClass( 'hidden' );
|
streamCmdPlay( false );
|
||||||
} // end if canEditMonitors
|
} // end if paused or delayed
|
||||||
|
|
||||||
if ( streamStatus.auth ) {
|
$('zoomValue').set( 'text', streamStatus.zoom );
|
||||||
console.log("Haev a new auth hash" + streamStatus.auth);
|
if ( streamStatus.zoom == "1.0" )
|
||||||
// Try to reload the image stream.
|
setButtonState( $('zoomOutBtn'), 'unavail' );
|
||||||
var streamImg = $('liveStream');
|
else
|
||||||
if ( streamImg )
|
setButtonState( $('zoomOutBtn'), 'inactive' );
|
||||||
streamImg.src = streamImg.src.replace( /auth=\w+/i, 'auth='+streamStatus.auth );
|
|
||||||
} // end if haev a new auth hash
|
if ( canEditMonitors ) {
|
||||||
|
if ( streamStatus.enabled ) {
|
||||||
|
$('enableAlarmsLink').addClass( 'hidden' );
|
||||||
|
$('disableAlarmsLink').removeClass( 'hidden' );
|
||||||
|
if ( streamStatus.forced ) {
|
||||||
|
$('forceAlarmLink').addClass( 'hidden' );
|
||||||
|
$('cancelAlarmLink').removeClass( 'hidden' );
|
||||||
|
} else {
|
||||||
|
$('forceAlarmLink').removeClass( 'hidden' );
|
||||||
|
$('cancelAlarmLink').addClass( 'hidden' );
|
||||||
|
}
|
||||||
|
$('forceCancelAlarm').removeClass( 'hidden' );
|
||||||
|
} else {
|
||||||
|
$('enableAlarmsLink').removeClass( 'hidden' );
|
||||||
|
$('disableAlarmsLink').addClass( 'hidden' );
|
||||||
|
$('forceCancelAlarm').addClass( 'hidden' );
|
||||||
|
}
|
||||||
|
$('enableDisableAlarms').removeClass( 'hidden' );
|
||||||
|
} // end if canEditMonitors
|
||||||
|
|
||||||
|
if ( streamStatus.auth ) {
|
||||||
|
console.log("Haev a new auth hash" + streamStatus.auth);
|
||||||
|
// Try to reload the image stream.
|
||||||
|
var streamImg = $('liveStream');
|
||||||
|
if ( streamImg )
|
||||||
|
streamImg.src = streamImg.src.replace( /auth=\w+/i, 'auth='+streamStatus.auth );
|
||||||
|
} // end if haev a new auth hash
|
||||||
|
} // end if respObj.status
|
||||||
} else {
|
} else {
|
||||||
checkStreamForErrors("getStreamCmdResponse",respObj);//log them
|
checkStreamForErrors("getStreamCmdResponse",respObj);//log them
|
||||||
// Try to reload the image stream.
|
// Try to reload the image stream.
|
||||||
|
|
|
@ -48,7 +48,7 @@ var maxDisplayEvents = <?php echo 2 * MAX_EVENTS ?>;
|
||||||
var monitorId = <?php echo $monitor->Id() ?>;
|
var monitorId = <?php echo $monitor->Id() ?>;
|
||||||
var monitorWidth = <?php echo $monitor->Width() ?>;
|
var monitorWidth = <?php echo $monitor->Width() ?>;
|
||||||
var monitorHeight = <?php echo $monitor->Height() ?>;
|
var monitorHeight = <?php echo $monitor->Height() ?>;
|
||||||
var monitorUrl = '<?php echo ( $monitor->Server()->Url() ) ?>';
|
var monitorUrl = '<?php echo ( $monitor->Server()->Url() . ( ZM_MIN_STREAMING_PORT ? ':'. (ZM_MIN_STREAMING_PORT+$monitor->Id()) : '' ) ) ?>';
|
||||||
|
|
||||||
var scale = '<?php echo $scale ?>';
|
var scale = '<?php echo $scale ?>';
|
||||||
|
|
||||||
|
|
|
@ -72,11 +72,11 @@ if ( ! $monitor ) {
|
||||||
$monitor->set( array(
|
$monitor->set( array(
|
||||||
'Id' => 0,
|
'Id' => 0,
|
||||||
'Name' => translate('Monitor').'-'.$nextId,
|
'Name' => translate('Monitor').'-'.$nextId,
|
||||||
'Function' => 'Monitor',
|
'Function' => 'Mocord',
|
||||||
'Enabled' => true,
|
'Enabled' => true,
|
||||||
'LinkedMonitors' => '',
|
'LinkedMonitors' => '',
|
||||||
'Type' => '',
|
'Type' => 'Ffmpeg',
|
||||||
'Device' => "/dev/video0",
|
'Device' => '/dev/video0',
|
||||||
'Channel' => '0',
|
'Channel' => '0',
|
||||||
'Format' => 0x000000ff,
|
'Format' => 0x000000ff,
|
||||||
'Protocol' => '',
|
'Protocol' => '',
|
||||||
|
@ -87,26 +87,26 @@ if ( ! $monitor ) {
|
||||||
'Port' => '80',
|
'Port' => '80',
|
||||||
'User' => '',
|
'User' => '',
|
||||||
'Pass' => '',
|
'Pass' => '',
|
||||||
'Colours' => 3,
|
'Colours' => 4,
|
||||||
'Palette' => 0,
|
'Palette' => 0,
|
||||||
'Width' => '320',
|
'Width' => '1280',
|
||||||
'Height' => '240',
|
'Height' => '962',
|
||||||
'Orientation' => '0',
|
'Orientation' => '0',
|
||||||
'Deinterlacing' => 0,
|
'Deinterlacing' => 0,
|
||||||
'RTSPDescribe' => 0,
|
'RTSPDescribe' => 0,
|
||||||
'SaveJPEGs' => '3',
|
'SaveJPEGs' => '4',
|
||||||
'VideoWriter' => '0',
|
'VideoWriter' => '1',
|
||||||
'EncoderParameters' => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n",
|
'EncoderParameters' => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n",
|
||||||
'RecordAudio' => '0',
|
'RecordAudio' => '0',
|
||||||
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
|
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
|
||||||
'LabelX' => 0,
|
'LabelX' => 0,
|
||||||
'LabelY' => 0,
|
'LabelY' => 0,
|
||||||
'LabelSize' => 1,
|
'LabelSize' => 1,
|
||||||
'ImageBufferCount' => 50,
|
'ImageBufferCount' => 40,
|
||||||
'WarmupCount' => 25,
|
'WarmupCount' => 1,
|
||||||
'PreEventCount' => 25,
|
'PreEventCount' => 1,
|
||||||
'PostEventCount' => 25,
|
'PostEventCount' => 5,
|
||||||
'StreamReplayBuffer' => 1000,
|
'StreamReplayBuffer' => 0,
|
||||||
'AlarmFrameCount' => 1,
|
'AlarmFrameCount' => 1,
|
||||||
'Controllable' => 0,
|
'Controllable' => 0,
|
||||||
'ControlId' => '',
|
'ControlId' => '',
|
||||||
|
@ -124,9 +124,9 @@ if ( ! $monitor ) {
|
||||||
'EventPrefix' => 'Event-',
|
'EventPrefix' => 'Event-',
|
||||||
'AnalysisFPSLimit' => '',
|
'AnalysisFPSLimit' => '',
|
||||||
'AnalysisUpdateDelay' => 0,
|
'AnalysisUpdateDelay' => 0,
|
||||||
'MaxFPS' => '',
|
'MaxFPS' => '30',
|
||||||
'AlarmMaxFPS' => '',
|
'AlarmMaxFPS' => '30',
|
||||||
'FPSReportInterval' => 1000,
|
'FPSReportInterval' => 100,
|
||||||
'RefBlendPerc' => 6,
|
'RefBlendPerc' => 6,
|
||||||
'AlarmRefBlendPerc' => 6,
|
'AlarmRefBlendPerc' => 6,
|
||||||
'DefaultView' => 'Events',
|
'DefaultView' => 'Events',
|
||||||
|
@ -138,8 +138,8 @@ if ( ! $monitor ) {
|
||||||
'Triggers' => '',
|
'Triggers' => '',
|
||||||
'V4LMultiBuffer' => '',
|
'V4LMultiBuffer' => '',
|
||||||
'V4LCapturesPerFrame' => 1,
|
'V4LCapturesPerFrame' => 1,
|
||||||
'ServerId' => $Server['Id'],
|
'ServerId' => 'auto',
|
||||||
'StorageId' => '0',
|
'StorageId' => '1',
|
||||||
) );
|
) );
|
||||||
} # end if $_REQUEST['dupID']
|
} # end if $_REQUEST['dupID']
|
||||||
} # end if $_REQUEST['mid']
|
} # end if $_REQUEST['mid']
|
||||||
|
@ -674,7 +674,7 @@ switch ( $tab ) {
|
||||||
<tr class="Name"><td><?php echo translate('Name') ?></td><td><input type="text" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>" /></td></tr>
|
<tr class="Name"><td><?php echo translate('Name') ?></td><td><input type="text" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>" /></td></tr>
|
||||||
<tr><td><?php echo translate('Server') ?></td><td>
|
<tr><td><?php echo translate('Server') ?></td><td>
|
||||||
<?php
|
<?php
|
||||||
$servers = array(''=>'None');
|
$servers = array(''=>'None','auto'=>'Auto');
|
||||||
$result = dbQuery( 'SELECT * FROM Servers ORDER BY Name');
|
$result = dbQuery( 'SELECT * FROM Servers ORDER BY Name');
|
||||||
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Server' );
|
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Server' );
|
||||||
foreach ( $results as $row => $server_obj ) {
|
foreach ( $results as $row => $server_obj ) {
|
||||||
|
|
|
@ -158,7 +158,7 @@ if( !isset($_REQUEST['step']) || ($_REQUEST['step'] == "1")) {
|
||||||
*/
|
*/
|
||||||
// $sourceDesc = htmlspecialchars(serialize($camera['monitor']));
|
// $sourceDesc = htmlspecialchars(serialize($camera['monitor']));
|
||||||
$sourceDesc = base64_encode(serialize($camera['monitor']));
|
$sourceDesc = base64_encode(serialize($camera['monitor']));
|
||||||
$sourceString = $camera['model'].' @ '.$host;
|
$sourceString = $camera['model'].' @ '.$host . ' using version ' . $camera['monitor']['SOAP'] ;
|
||||||
$cameras[$sourceDesc] = $sourceString;
|
$cameras[$sourceDesc] = $sourceString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ xhtmlHeaders(__FILE__, translate('LoggingIn') );
|
||||||
<body>
|
<body>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<h1>ZoneMinder <?php echo translate('Login') ?></h1>
|
<h1><?php echo ZM_WEB_TITLE . ' ' . translate('Login') ?></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<h2><?php echo translate('LoggingIn') ?></h2>
|
<h2><?php echo translate('LoggingIn') ?></h2>
|
||||||
|
|
|
@ -32,6 +32,9 @@ if ( $_REQUEST['id'] ) {
|
||||||
$newServer = array();
|
$newServer = array();
|
||||||
$newServer['Name'] = translate('NewServer');
|
$newServer['Name'] = translate('NewServer');
|
||||||
$newServer['Hostname'] = '';
|
$newServer['Hostname'] = '';
|
||||||
|
$newServer['zmstats'] = '';
|
||||||
|
$newServer['zmaudit'] = '';
|
||||||
|
$newServer['zmtrigger'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
|
|
@ -36,6 +36,7 @@ if ( $_REQUEST['id'] ) {
|
||||||
$newStorage['Type'] = 'local';
|
$newStorage['Type'] = 'local';
|
||||||
$newStorage['Scheme'] = 'Medium';
|
$newStorage['Scheme'] = 'Medium';
|
||||||
$newStorage['StorageId'] = '';
|
$newStorage['StorageId'] = '';
|
||||||
|
$newStorage['ServerId'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') );
|
$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') );
|
||||||
|
|
|
@ -18,45 +18,44 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
if ( !canView( 'Events' ) )
|
if ( !canView( 'Events' ) ) {
|
||||||
{
|
$view = 'error';
|
||||||
$view = "error";
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$archivetype = $_REQUEST['type'];
|
$archivetype = $_REQUEST['type'];
|
||||||
|
|
||||||
if ( $archivetype ) {
|
if ( $archivetype ) {
|
||||||
switch ($archivetype) {
|
switch ($archivetype) {
|
||||||
case "tar":
|
case 'tar':
|
||||||
$mimetype = "gzip";
|
$mimetype = 'gzip';
|
||||||
$file_ext = "tar.gz";
|
$file_ext = 'tar.gz';
|
||||||
break;
|
break;
|
||||||
case "zip":
|
case 'zip':
|
||||||
$mimetype = "zip";
|
$mimetype = 'zip';
|
||||||
$file_ext = "zip";
|
$file_ext = 'zip';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$mimetype = NULL;
|
$mimetype = NULL;
|
||||||
$file_ext = NULL;
|
$file_ext = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $mimetype ) {
|
if ( $mimetype ) {
|
||||||
$filename = "zmExport.$file_ext";
|
$filename = "zmExport.$file_ext";
|
||||||
$filename_path = ZM_DIR_TEMP."/".$filename;
|
$filename_path = ZM_DIR_EXPORTS.'/'.$filename;
|
||||||
if ( is_readable($filename_path) ) {
|
if ( is_readable($filename_path) ) {
|
||||||
header( "Content-type: application/$mimetype" );
|
header( "Content-type: application/$mimetype" );
|
||||||
header( "Content-Disposition: attachment; filename=$filename");
|
header( "Content-Disposition: attachment; filename=$filename");
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
readfile( $filename_path );
|
readfile( $filename_path );
|
||||||
} else {
|
|
||||||
Error("$filename_path does not exist or is not readable.");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Error("Unsupported archive type specified. Supported archives are tar and zip");
|
Error("$filename_path does not exist or is not readable.");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Error("Unsupported archive type specified. Supported archives are tar and zip");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Error("No archive type given to archive.php. Please specify a tar or zip archive.");
|
Error("No archive type given to archive.php. Please specify a tar or zip archive.");
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,25 +1,37 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# The purpose of this file is to create the symlinks in the web folder to the content folder. It can use an existing content folder or create a new one.
|
# This tool is used to verify folders critical to ZoneMinder exist and have the right permissions.
|
||||||
|
# It will also create symlinks when necessary. It can use an existing content folder or create a new one.
|
||||||
|
|
||||||
# Set the content dir default to be the one supplied to cmake
|
# Set the content dir default to be the one supplied to cmake
|
||||||
ZM_PATH_CONTENT="@ZM_CONTENTDIR@"
|
ZM_PATH_CONTENT="@ZM_CONTENTDIR@"
|
||||||
|
|
||||||
|
# Set the zoneminder log dir default to be the one supplied to cmake
|
||||||
|
ZM_LOGDIR="@ZM_LOGDIR@"
|
||||||
|
|
||||||
|
# Set the zoneminder temp dir default to be the one supplied to cmake
|
||||||
|
ZM_TMPDIR="@ZM_TMPDIR@"
|
||||||
|
|
||||||
echo "*** This bash script creates the nessecary symlinks for the zoneminder content"
|
echo "*** This bash script creates the nessecary symlinks for the zoneminder content"
|
||||||
echo "*** It can use an existing content folder or create a new one"
|
echo "*** It can use an existing content folder or create a new one"
|
||||||
echo "*** For usage: use -h"
|
echo "*** For usage: use -h"
|
||||||
echo "*** The default content directory is: $ZM_PATH_CONTENT"
|
echo "*** The default content directory is: $ZM_PATH_CONTENT"
|
||||||
|
echo "*** The default log directory is: $ZM_LOGDIR"
|
||||||
|
echo "*** The default temp directory is: $ZM_TMPDIR"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
usage()
|
usage()
|
||||||
{
|
{
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $0 [-q] [-z zm.conf] [-w WEB DIRECTORY] [CONTENT DIRECTORY]
|
Usage: $0 [-q] [-o] [-z zm.conf] [-w WEB DIRECTORY] [-l LOG DIRECTORY] [-t TMP DIRECTORY] [CONTENT DIRECTORY]
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
-h Show this message and quit
|
-h Show this message and quit
|
||||||
-z ZoneMinder configuration file
|
-z ZoneMinder configuration file
|
||||||
-w Override the web directory from zm.conf
|
-w Override the web directory from zm.conf
|
||||||
-q Quick mode. Do not change ownership recursively.
|
-q Quick mode. Do not change ownership recursively.
|
||||||
|
-l Override the zm log folder location
|
||||||
|
-t Override the zm temp folder location
|
||||||
|
-o Enable old legacy symlinks inside ZoneMinder's webroot folder
|
||||||
|
|
||||||
If the -w option is not used to specify the path to the web directory,
|
If the -w option is not used to specify the path to the web directory,
|
||||||
the script will use the path from zoneminder's configuration file.
|
the script will use the path from zoneminder's configuration file.
|
||||||
|
@ -27,10 +39,14 @@ If the -z option is used, the argument will be used instead of zm.conf
|
||||||
Otherwise, it will attempt to read zm.conf from the local directory.
|
Otherwise, it will attempt to read zm.conf from the local directory.
|
||||||
If that fails, it will try from /etc/zm.conf
|
If that fails, it will try from /etc/zm.conf
|
||||||
|
|
||||||
|
Newer versions of ZoneMinder no longer require symlinks to the events and
|
||||||
|
images folders inside the zm webroot. Indeed this is a security risk, and
|
||||||
|
$0 will no longer create these unless the -o option is specified.
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
while getopts "hz:w:q" OPTION
|
while getopts "hz:w:q:l:t:o" OPTION
|
||||||
do
|
do
|
||||||
case $OPTION in
|
case $OPTION in
|
||||||
h)
|
h)
|
||||||
|
@ -46,6 +62,15 @@ do
|
||||||
q)
|
q)
|
||||||
QUICK=1
|
QUICK=1
|
||||||
;;
|
;;
|
||||||
|
l)
|
||||||
|
ZM_LOGDIR_FORCE=$OPTARG
|
||||||
|
;;
|
||||||
|
t)
|
||||||
|
ZM_TMPDIR_FORCE=$OPTARG
|
||||||
|
;;
|
||||||
|
o)
|
||||||
|
LEGACY=1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
shift $(( OPTIND - 1 ))
|
shift $(( OPTIND - 1 ))
|
||||||
|
@ -73,7 +98,7 @@ elif [ -f "/etc/zm.conf" ]; then
|
||||||
echo "Using system zm.conf"
|
echo "Using system zm.conf"
|
||||||
source "/etc/zm.conf"
|
source "/etc/zm.conf"
|
||||||
else
|
else
|
||||||
echo "Failed locating zoneminder configuration file (zm.conf)\nUse the -z option to specify the full path to the zoneminder configuration file"
|
echo -e "Failed locating zoneminder configuration file (zm.conf)\nUse the -z option to specify the full path to the zoneminder configuration file"
|
||||||
exit 45
|
exit 45
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -82,6 +107,16 @@ if [ -n "$ZM_PATH_WEB_FORCE" ]; then
|
||||||
ZM_PATH_WEB="$(readlink -f $ZM_PATH_WEB_FORCE)"
|
ZM_PATH_WEB="$(readlink -f $ZM_PATH_WEB_FORCE)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Override the log directory path
|
||||||
|
if [ -n "$ZM_LOGDIR_FORCE" ]; then
|
||||||
|
ZM_LOGDIR="$(readlink -f $ZM_LOGDIR_FORCE)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Override the tmp directory path
|
||||||
|
if [ -n "$ZM_TMPDIR_FORCE" ]; then
|
||||||
|
ZM_TMPDIR="$(readlink -f $ZM_TMPDIR_FORCE)"
|
||||||
|
fi
|
||||||
|
|
||||||
# Override the default content path
|
# Override the default content path
|
||||||
if [[ -n "$@" ]]; then
|
if [[ -n "$@" ]]; then
|
||||||
ZM_PATH_CONTENT="$(readlink -f $@)"
|
ZM_PATH_CONTENT="$(readlink -f $@)"
|
||||||
|
@ -90,6 +125,8 @@ fi
|
||||||
# Print some information
|
# Print some information
|
||||||
echo "Web folder : $ZM_PATH_WEB"
|
echo "Web folder : $ZM_PATH_WEB"
|
||||||
echo "Content folder : $ZM_PATH_CONTENT"
|
echo "Content folder : $ZM_PATH_CONTENT"
|
||||||
|
echo "Log folder : $ZM_LOGDIR"
|
||||||
|
echo "Temp folder : $ZM_TMPDIR"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Verify the web folder is a real directory
|
# Verify the web folder is a real directory
|
||||||
|
@ -98,7 +135,7 @@ if [ -d "$ZM_PATH_WEB" ]; then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "Failed"
|
echo "Failed"
|
||||||
exit 3
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if the content folder exists, and if not, create it
|
# Check if the content folder exists, and if not, create it
|
||||||
|
@ -109,6 +146,22 @@ else
|
||||||
echo "No"
|
echo "No"
|
||||||
echo -n "Creating the content folder... "
|
echo -n "Creating the content folder... "
|
||||||
mkdir "$ZM_PATH_CONTENT"
|
mkdir "$ZM_PATH_CONTENT"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the log folder exists, and if not, create the entire folder including its parents
|
||||||
|
echo -n "Checking if the log folder exists... "
|
||||||
|
if [ -d "$ZM_LOGDIR" ]; then
|
||||||
|
echo "Yes"
|
||||||
|
else
|
||||||
|
echo "No"
|
||||||
|
echo -n "Creating the log folder... "
|
||||||
|
mkdir -p "$ZM_LOGDIR"
|
||||||
if [ "$?" = "0" ]; then
|
if [ "$?" = "0" ]; then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
|
@ -116,6 +169,23 @@ else
|
||||||
exit 4
|
exit 4
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if the temp folder exists, and if not, create the entire folder including its parents
|
||||||
|
echo -n "Checking if the temp folder exists... "
|
||||||
|
if [ -d "$ZM_TMPDIR" ]; then
|
||||||
|
echo "Yes"
|
||||||
|
else
|
||||||
|
echo "No"
|
||||||
|
echo -n "Creating the temp folder... "
|
||||||
|
mkdir -p "$ZM_TMPDIR"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 5
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Check if the content/images folder exists, and if not, create it
|
# Check if the content/images folder exists, and if not, create it
|
||||||
echo -n "Checking if the images folder exists inside the content folder... "
|
echo -n "Checking if the images folder exists inside the content folder... "
|
||||||
if [ -d "$ZM_PATH_CONTENT/images" ]; then
|
if [ -d "$ZM_PATH_CONTENT/images" ]; then
|
||||||
|
@ -131,6 +201,7 @@ else
|
||||||
exit 6
|
exit 6
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if the content/events folder exists, and if not, create it
|
# Check if the content/events folder exists, and if not, create it
|
||||||
echo -n "Checking if the events folder exists inside the content folder... "
|
echo -n "Checking if the events folder exists inside the content folder... "
|
||||||
if [ -d "$ZM_PATH_CONTENT/events" ]; then
|
if [ -d "$ZM_PATH_CONTENT/events" ]; then
|
||||||
|
@ -179,24 +250,26 @@ if [ -d "$ZM_PATH_WEB/events" ]; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create the symlink for the images folder
|
if [ -n "$LEGACY" ]; then
|
||||||
echo -n "Creating the symlink for the images folder... "
|
# Create the symlink for the images folder
|
||||||
ln -s -f "$ZM_PATH_CONTENT/images" "$ZM_PATH_WEB/images"
|
echo -n "Creating the symlink for the images folder... "
|
||||||
if [ "$?" = "0" ]; then
|
ln -s -f "$ZM_PATH_CONTENT/images" "$ZM_PATH_WEB/images"
|
||||||
echo "OK"
|
if [ "$?" = "0" ]; then
|
||||||
else
|
echo "OK"
|
||||||
echo "Failed"
|
else
|
||||||
exit 15
|
echo "Failed"
|
||||||
fi
|
exit 15
|
||||||
|
fi
|
||||||
# Create the symlink for the events folder
|
|
||||||
echo -n "Creating the symlink for the events folder... "
|
# Create the symlink for the events folder
|
||||||
ln -s -f "$ZM_PATH_CONTENT/events" "$ZM_PATH_WEB/events"
|
echo -n "Creating the symlink for the events folder... "
|
||||||
if [ "$?" = "0" ]; then
|
ln -s -f "$ZM_PATH_CONTENT/events" "$ZM_PATH_WEB/events"
|
||||||
echo "OK"
|
if [ "$?" = "0" ]; then
|
||||||
else
|
echo "OK"
|
||||||
echo "Failed"
|
else
|
||||||
exit 16
|
echo "Failed"
|
||||||
|
exit 16
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# change ownership for the images folder. do it recursively unless -q is used
|
# change ownership for the images folder. do it recursively unless -q is used
|
||||||
|
@ -228,11 +301,32 @@ if [ -n "$QUICK" ]; then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "Failed"
|
echo "Failed"
|
||||||
exit 25
|
exit 23
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -n "Changing ownership of the events folder recursively to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
|
echo -n "Changing ownership of the events folder recursively to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
|
||||||
chown -R ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_PATH_CONTENT/events"
|
chown -R ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_PATH_CONTENT/events"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 24
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# change ownership for the log folder. do it recursively unless -q is used
|
||||||
|
if [ -n "$QUICK" ]; then
|
||||||
|
echo -n "Changing ownership of the log folder to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
|
||||||
|
chown ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_LOGDIR"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 25
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -n "Changing ownership of the log folder recursively to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
|
||||||
|
chown -R ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_LOGDIR"
|
||||||
if [ "$?" = "0" ]; then
|
if [ "$?" = "0" ]; then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
|
@ -241,6 +335,27 @@ else
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# change ownership for the temp folder. do it recursively unless -q is used
|
||||||
|
if [ -n "$QUICK" ]; then
|
||||||
|
echo -n "Changing ownership of the temp folder to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
|
||||||
|
chown ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_TMPDIR"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 27
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -n "Changing ownership of the temp folder recursively to ${ZM_WEB_USER} ${ZM_WEB_GROUP}... "
|
||||||
|
chown -R ${ZM_WEB_USER}:${ZM_WEB_GROUP} "$ZM_TMPDIR"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 28
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Change directory permissions for the images folder
|
# Change directory permissions for the images folder
|
||||||
echo -n "Changing permissions of the images folder to 775... "
|
echo -n "Changing permissions of the images folder to 775... "
|
||||||
chmod 775 "$ZM_PATH_CONTENT/images"
|
chmod 775 "$ZM_PATH_CONTENT/images"
|
||||||
|
@ -251,7 +366,6 @@ else
|
||||||
exit 30
|
exit 30
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Change directory permissions for the events folder
|
# Change directory permissions for the events folder
|
||||||
echo -n "Changing permissions of the events folder to 775... "
|
echo -n "Changing permissions of the events folder to 775... "
|
||||||
chmod 775 "$ZM_PATH_CONTENT/events"
|
chmod 775 "$ZM_PATH_CONTENT/events"
|
||||||
|
@ -262,5 +376,35 @@ else
|
||||||
exit 31
|
exit 31
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Change directory permissions for the log folder
|
||||||
|
echo -n "Changing permissions of the log folder to 775... "
|
||||||
|
chmod 775 "$ZM_LOGDIR"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 32
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Change directory permissions for the temp folder
|
||||||
|
echo -n "Changing permissions of the temp folder to 775... "
|
||||||
|
chmod 775 "$ZM_TMPDIR"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 33
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Link the CakePHP tmp folder to the zoneminder temp folder
|
||||||
|
echo -n "Linking CakePHP tmp folder to ${ZM_TMPDIR}... "
|
||||||
|
ln -sfT "$ZM_TMPDIR" "$ZM_PATH_WEB/api/app/tmp"
|
||||||
|
if [ "$?" = "0" ]; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Failed"
|
||||||
|
exit 40
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "All done"
|
echo "All done"
|
||||||
|
|
Loading…
Reference in New Issue