Merge remote-tracking branch 'upstream/feature-h264-videostorage' into monitor_packetqueue
This commit is contained in:
commit
0425c68d59
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
project (zoneminder)
|
||||
set(zoneminder_VERSION "1.29.2")
|
||||
file (STRINGS "version" zoneminder_VERSION)
|
||||
# make API version a minor of ZM version
|
||||
set(zoneminder_API_VERSION "${zoneminder_VERSION}.1")
|
||||
|
||||
|
@ -147,10 +147,10 @@ set(ZM_PERL_SEARCH_PATH "" CACHE PATH
|
|||
where ZM_PERL_MM_PARMS has been modified such that ZoneMinder's Perl modules are
|
||||
installed outside Perl's default search path.")
|
||||
set(ZM_TARGET_DISTRO "" CACHE STRING
|
||||
"Build ZoneMinder for a specific distribution. Currently, valid names are: f22, f23, el6, el7, OS13")
|
||||
"Build ZoneMinder for a specific distribution. Currently, valid names are: f23, f24, el6, el7, OS13, FreeBSD")
|
||||
|
||||
# Reassign some variables if a target distro has been specified
|
||||
if((ZM_TARGET_DISTRO STREQUAL "f22") OR (ZM_TARGET_DISTRO STREQUAL "f23"))
|
||||
if((ZM_TARGET_DISTRO STREQUAL "f23") OR (ZM_TARGET_DISTRO STREQUAL "f24"))
|
||||
set(ZM_RUNDIR "/var/run/zoneminder")
|
||||
set(ZM_SOCKDIR "/var/lib/zoneminder/sock")
|
||||
set(ZM_TMPDIR "/var/lib/zoneminder/temp")
|
||||
|
@ -193,7 +193,7 @@ elseif(ZM_TARGET_DISTRO STREQUAL "FreeBSD")
|
|||
set(ZM_WEBDIR "/usr/local/share/zoneminder/www")
|
||||
set(ZM_CGIDIR "/usr/local/libexec/zoneminder/cgi-bin")
|
||||
set(ZM_PERL_MM_PARMS "INSTALLDIRS=site")
|
||||
endif((ZM_TARGET_DISTRO STREQUAL "f22") OR (ZM_TARGET_DISTRO STREQUAL "f23"))
|
||||
endif((ZM_TARGET_DISTRO STREQUAL "f23") OR (ZM_TARGET_DISTRO STREQUAL "f24"))
|
||||
|
||||
# Required for certain checks to work
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES
|
||||
|
@ -768,13 +768,13 @@ if(ZM_ONVIF)
|
|||
endif(ZM_ONVIF)
|
||||
|
||||
# Process distro subdirectories
|
||||
if((ZM_TARGET_DISTRO STREQUAL "f22") OR (ZM_TARGET_DISTRO STREQUAL "f23"))
|
||||
if((ZM_TARGET_DISTRO STREQUAL "f23") OR (ZM_TARGET_DISTRO STREQUAL "f24"))
|
||||
add_subdirectory(distros/fedora)
|
||||
elseif((ZM_TARGET_DISTRO STREQUAL "el6") OR (ZM_TARGET_DISTRO STREQUAL "el7"))
|
||||
add_subdirectory(distros/redhat)
|
||||
elseif(ZM_TARGET_DISTRO STREQUAL "OS13")
|
||||
add_subdirectory(distros/opensuse)
|
||||
endif((ZM_TARGET_DISTRO STREQUAL "f22") OR (ZM_TARGET_DISTRO STREQUAL "f23"))
|
||||
endif((ZM_TARGET_DISTRO STREQUAL "f23") OR (ZM_TARGET_DISTRO STREQUAL "f24"))
|
||||
|
||||
# Print optional libraries detection status
|
||||
message(STATUS "Optional libraries found:${optlibsfound}")
|
||||
|
|
|
@ -373,7 +373,7 @@ UPDATE States SET IsActive = '1' WHERE Name = 'default';
|
|||
-- If duplicate states existed while upgrading, that is
|
||||
-- very likely an error that ZM allowed earlier, so
|
||||
-- we are picking up the first one and deleting the others
|
||||
ALTER IGNORE TABLE States ADD UNIQUE (Name);
|
||||
ALTER TABLE States ADD UNIQUE (Name);
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
--
|
||||
-- This updates a 1.29.1 database to 1.30.0
|
||||
--
|
||||
-- No changes required
|
||||
--
|
|
@ -1,7 +1,6 @@
|
|||
Alias /zm /usr/share/zoneminder/www
|
||||
|
||||
<Directory /usr/share/zoneminder/www>
|
||||
php_flag register_globals off
|
||||
Options Indexes FollowSymLinks
|
||||
<IfModule mod_dir.c>
|
||||
DirectoryIndex index.php
|
||||
|
|
|
@ -17,6 +17,14 @@ Build-Depends: debhelper (>= 9), cmake
|
|||
, libvlccore-dev, libvlc-dev
|
||||
, libcurl4-gnutls-dev | libcurl4-nss-dev | libcurl4-openssl-dev
|
||||
, libgcrypt11-dev, libpolkit-gobject-1-dev
|
||||
, libphp-serialization-perl
|
||||
, libdate-manip-perl, libmime-lite-perl, libmime-tools-perl, libdbd-mysql-perl
|
||||
, libwww-perl, libarchive-tar-perl, libarchive-zip-perl, libdevice-serialport-perl
|
||||
, libmodule-load-perl, libsys-mmap-perl, libjson-any-perl
|
||||
, libnet-sftp-foreign-perl, libio-pty-perl, libexpect-perl
|
||||
, libdata-dump-perl, libclass-std-fast-perl, libsoap-wsdl-perl, libio-socket-multicast-perl, libdigest-sha-perl
|
||||
, libsys-cpu-perl, libsys-meminfo-perl
|
||||
, libdata-uuid-perl
|
||||
Standards-Version: 3.9.4
|
||||
|
||||
Package: zoneminder
|
||||
|
@ -32,6 +40,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
|
|||
, libnet-sftp-foreign-perl, libio-pty-perl, libexpect-perl
|
||||
, libdata-dump-perl, libclass-std-fast-perl, libsoap-wsdl-perl, libio-socket-multicast-perl, libdigest-sha-perl
|
||||
, libsys-cpu-perl, libsys-meminfo-perl
|
||||
, libdata-uuid-perl
|
||||
, libpcre3
|
||||
, libav-tools, libavdevice53
|
||||
, rsyslog | system-log-daemon
|
||||
|
|
|
@ -9,15 +9,17 @@ configure_file(zoneminder.conf.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.conf @O
|
|||
configure_file(zoneminder.tmpfiles.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.tmpfiles @ONLY)
|
||||
configure_file(zoneminder.logrotate.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.logrotate @ONLY)
|
||||
|
||||
# Download jscalendar & move files into position
|
||||
file(DOWNLOAD http://iweb.dl.sourceforge.net/project/jscalendar/jscalendar/1.0/jscalendar-1.0.zip ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar-1.0.zip STATUS download_jsc)
|
||||
if(download_jsc EQUAL 0)
|
||||
message(STATUS "Jscalander successfully downloaded. Installing...")
|
||||
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ERROR_VARIABLE unzip_jsc)
|
||||
message(STATUS "Status of jscalender script was: ${unzip_jsc}")
|
||||
else(download_jsc EQUAL 0)
|
||||
message(STATUS "Unable to download optional jscalander. Skipping...")
|
||||
endif(download_jsc EQUAL 0)
|
||||
# Unpack jscalendar & move files into position
|
||||
message(STATUS "Unpacking and Installing jscalendar...")
|
||||
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar.sh
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
ERROR_VARIABLE unzip_jsc
|
||||
)
|
||||
if("${unzip_jsc}" STREQUAL "")
|
||||
message(STATUS "jscalendar successfully installed.")
|
||||
else("${unzip_jsc}" STREQUAL "")
|
||||
message(FATAL_ERROR "\nAn error occured while jscalendar was being processed:\n${unzip_jsc}")
|
||||
endif("${unzip_jsc}" STREQUAL "")
|
||||
|
||||
# Create several empty folders
|
||||
file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events images temp)
|
||||
|
@ -45,8 +47,5 @@ install(FILES zoneminder.logrotate DESTINATION /etc/logrotate.d RENAME zoneminde
|
|||
install(FILES ../../misc/zoneminder-tmpfiles.conf DESTINATION /etc/tmpfiles.d RENAME zoneminder.conf PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||
install(FILES redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(FILES zoneminder.service DESTINATION /usr/lib/systemd/system PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||
|
||||
# Install jscalendar
|
||||
if(unzip_jsc STREQUAL "")
|
||||
install(DIRECTORY jscalendar-1.0/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/tools/jscalendar)
|
||||
endif(unzip_jsc STREQUAL "")
|
||||
|
||||
|
|
|
@ -49,10 +49,9 @@ New installs
|
|||
Change ZM_DB_USER and ZM_DB_PASS to the values you created in the previous
|
||||
step.
|
||||
|
||||
Additionally, you must also edit
|
||||
/usr/share/zoneminder/www/api/app/Config/database.php in a similar manner.
|
||||
Scroll down and change login and password to the values you created in the
|
||||
previous step.
|
||||
This version of zoneminder no longer requires you to make a similar change
|
||||
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php
|
||||
This now happens dynamically. Do *not* make any changes to this file.
|
||||
|
||||
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local
|
||||
timezone. PHP will complain loudly if this is not set, or if it is set
|
||||
|
@ -113,10 +112,9 @@ Upgrades
|
|||
Compare /etc/zm/zm.conf to /etc/zm/zm.conf.rpmnew. Verify that zm.conf
|
||||
contains any new config settings that may be in zm.conf.rpmnew.
|
||||
|
||||
Additionally, you must also edit
|
||||
/usr/share/zoneminder/www/api/app/Config/database.php in a similar manner.
|
||||
Scroll down and change login and password to the values you used
|
||||
previsouly.
|
||||
This version of zoneminder no longer requires you to make a similar change
|
||||
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php
|
||||
This now happens dynamically. Do *not* make any changes to this file.
|
||||
|
||||
2. Verify permissions of the zmuser account.
|
||||
|
||||
|
|
|
@ -0,0 +1,429 @@
|
|||
%define zmuid $(id -un)
|
||||
%define zmgid $(id -gn)
|
||||
%define zmuid_final apache
|
||||
%define zmgid_final apache
|
||||
|
||||
%global _hardened_build 1
|
||||
|
||||
### Delete the lines below to build with ffmpeg and/or x10
|
||||
%define _without_ffmpeg 1
|
||||
%define _without_x10 1
|
||||
|
||||
Name: zoneminder
|
||||
Version: 1.30.0
|
||||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
# jscalendar is LGPL (any version): http://www.dynarch.com/projects/calendar/
|
||||
# Mootools is inder the MIT license: http://mootools.net/
|
||||
License: GPLv2+ and LGPLv2+ and MIT
|
||||
URL: http://www.zoneminder.com/
|
||||
|
||||
#Source: https://github.com/ZoneMinder/ZoneMinder/archive/v%{version}.tar.gz
|
||||
Source: ZoneMinder-%{version}.tar.gz
|
||||
|
||||
BuildRequires: cmake gnutls-devel systemd-units bzip2-devel
|
||||
BuildRequires: mariadb-devel pcre-devel libjpeg-turbo-devel
|
||||
BuildRequires: perl(Archive::Tar) perl(Archive::Zip) perl-podlators
|
||||
BuildRequires: perl(Date::Manip) perl(DBD::mysql)
|
||||
BuildRequires: perl(ExtUtils::MakeMaker) perl(LWP::UserAgent)
|
||||
BuildRequires: perl(MIME::Entity) perl(MIME::Lite)
|
||||
BuildRequires: perl(PHP::Serialization) perl(Sys::Mmap)
|
||||
BuildRequires: perl(Time::HiRes) perl(Net::SFTP::Foreign)
|
||||
BuildRequires: perl(Expect) perl(Sys::Syslog)
|
||||
BuildRequires: gcc gcc-c++ vlc-devel libcurl-devel libv4l-devel
|
||||
%{!?_without_ffmpeg:BuildRequires: ffmpeg-devel}
|
||||
%{!?_without_x10:BuildRequires: perl(X10::ActiveHome) perl(Astro::SunTime)}
|
||||
# cmake needs the following installed at build time due to the way it auto-detects certain parameters
|
||||
BuildRequires: httpd polkit-devel
|
||||
%{!?_without_ffmpeg:BuildRequires: ffmpeg}
|
||||
|
||||
Requires: httpd php php-gd php-mysql cambozola polkit net-tools psmisc
|
||||
Requires: libjpeg-turbo vlc-core libcurl
|
||||
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
|
||||
Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip)
|
||||
Requires: perl(MIME::Entity) perl(MIME::Lite) perl(Net::SMTP) perl(Net::FTP)
|
||||
Requires: perl(LWP::Protocol::https)
|
||||
%{!?_without_ffmpeg:Requires: ffmpeg}
|
||||
|
||||
Requires(post): systemd-units systemd-sysv
|
||||
Requires(post): /usr/bin/gpasswd
|
||||
Requires(post): /usr/bin/less
|
||||
Requires(preun): systemd-units
|
||||
Requires(postun): systemd-units
|
||||
|
||||
%description
|
||||
ZoneMinder is a set of applications which is intended to provide a complete
|
||||
solution allowing you to capture, analyse, record and monitor any cameras you
|
||||
have attached to a Linux based machine. It is designed to run on kernels which
|
||||
support the Video For Linux (V4L) interface and has been tested with cameras
|
||||
attached to BTTV cards, various USB cameras and IP network cameras. It is
|
||||
designed to support as many cameras as you can attach to your computer without
|
||||
too much degradation of performance.
|
||||
|
||||
%prep
|
||||
%setup -q -n ZoneMinder-%{version}
|
||||
|
||||
# Change the following default values
|
||||
./utils/zmeditconfigdata.sh ZM_PATH_ZMS /cgi-bin-zm/nph-zms
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes
|
||||
./utils/zmeditconfigdata.sh ZM_PATH_SWAP /dev/shm
|
||||
./utils/zmeditconfigdata.sh ZM_UPLOAD_FTP_LOC_DIR /var/spool/zoneminder-upload
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
|
||||
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
|
||||
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_FAST_DELETE no
|
||||
|
||||
%build
|
||||
%cmake \
|
||||
-DZM_TARGET_DISTRO="f23" \
|
||||
%{?_without_ffmpeg:-DZM_NO_FFMPEG=ON} \
|
||||
%{?_without_x10:-DZM_NO_X10=ON} \
|
||||
.
|
||||
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
export DESTDIR=%{buildroot}
|
||||
make install
|
||||
|
||||
%post
|
||||
|
||||
# Add any new PTZ control configurations to the database (will not overwrite)
|
||||
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
|
||||
|
||||
if [ $1 -eq 1 ] ; then
|
||||
# Initial installation
|
||||
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
# Allow zoneminder access to local video sources, serial ports, and x10
|
||||
/usr/bin/gpasswd -a %{zmuid_final} video
|
||||
/usr/bin/gpasswd -a %{zmuid_final} dialout
|
||||
|
||||
# Upgrade from a previous version of zoneminder
|
||||
if [ $1 -eq 2 ] ; then
|
||||
|
||||
# Add any new PTZ control configurations to the database (will not overwrite)
|
||||
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
|
||||
|
||||
# Freshen the database
|
||||
%{_bindir}/zmupdate.pl -f >/dev/null 2>&1 || :
|
||||
|
||||
# We can't run this automatically when new sql account permissions need to
|
||||
# be manually added first
|
||||
# Run zmupdate non-interactively
|
||||
#/usr/bin/zmupdate.pl --nointeractive
|
||||
fi
|
||||
|
||||
# Warn the end user to read the README file
|
||||
echo -e "\nVERY IMPORTANT: Before starting ZoneMinder, read README.Fedora to finish the\ninstallation or upgrade!\n"
|
||||
echo -e "\nThe README file is located here: %{_docdir}/%{name}\n"
|
||||
|
||||
%preun
|
||||
if [ $1 -eq 0 ] ; then
|
||||
# Package removal, not upgrade
|
||||
/bin/systemctl --no-reload disable zoneminder.service > /dev/null 2>&1 || :
|
||||
/bin/systemctl stop zoneminder.service > /dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%postun
|
||||
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
|
||||
if [ $1 -ge 1 ] ; then
|
||||
# Package upgrade, not uninstall
|
||||
/bin/systemctl try-restart zoneminder.service >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%triggerun -- zoneminder < 1.25.0-4
|
||||
# Save the current service runlevel info
|
||||
# User must manually run systemd-sysv-convert --apply zoneminder
|
||||
# to migrate them to systemd targets
|
||||
/usr/bin/systemd-sysv-convert --save zoneminder >/dev/null 2>&1 ||:
|
||||
|
||||
# Run these because the SysV package being removed won't do them
|
||||
/sbin/chkconfig --del zoneminder >/dev/null 2>&1 || :
|
||||
/bin/systemctl try-restart zoneminder.service >/dev/null 2>&1 || :
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc AUTHORS COPYING README.md distros/fedora/README.Fedora distros/fedora/README.https distros/fedora/jscalendar-doc
|
||||
%config %attr(640,root,%{zmgid_final}) /etc/zm/zm.conf
|
||||
%config(noreplace) %attr(644,root,root) /etc/httpd/conf.d/zoneminder.conf
|
||||
%config(noreplace) /etc/tmpfiles.d/zoneminder.conf
|
||||
%config(noreplace) /etc/logrotate.d/zoneminder
|
||||
|
||||
%{_unitdir}/zoneminder.service
|
||||
|
||||
%{_bindir}/zma
|
||||
%{_bindir}/zmaudit.pl
|
||||
%{_bindir}/zmc
|
||||
%{_bindir}/zmcontrol.pl
|
||||
%{_bindir}/zmdc.pl
|
||||
%{_bindir}/zmf
|
||||
%{_bindir}/zmfilter.pl
|
||||
%{_bindir}/zmpkg.pl
|
||||
%{_bindir}/zmtrack.pl
|
||||
%{_bindir}/zmtrigger.pl
|
||||
%{_bindir}/zmu
|
||||
%{_bindir}/zmupdate.pl
|
||||
%{_bindir}/zmvideo.pl
|
||||
%{_bindir}/zmwatch.pl
|
||||
%{_bindir}/zmcamtool.pl
|
||||
%{_bindir}/zmsystemctl.pl
|
||||
%{_bindir}/zmtelemetry.pl
|
||||
%{!?_without_x10:%{_bindir}/zmx10.pl}
|
||||
%{_bindir}/zmonvif-probe.pl
|
||||
|
||||
%{perl_vendorlib}/ZoneMinder*
|
||||
%{perl_vendorlib}/ONVIF*
|
||||
%{perl_vendorlib}/WSDiscovery*
|
||||
%{perl_vendorlib}/WSSecurity*
|
||||
%{perl_vendorlib}/WSNotification*
|
||||
%{_mandir}/man*/*
|
||||
%dir %{_libexecdir}/zoneminder
|
||||
%{_libexecdir}/zoneminder/cgi-bin
|
||||
%dir %{_datadir}/zoneminder
|
||||
%{_datadir}/zoneminder/db
|
||||
%{_datadir}/zoneminder/www
|
||||
|
||||
%{_datadir}/polkit-1/actions/com.zoneminder.systemctl.policy
|
||||
%{_datadir}/polkit-1/rules.d/com.zoneminder.systemctl.rules
|
||||
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/events
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/images
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/sock
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/swap
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/temp
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/log/zoneminder
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/spool/zoneminder-upload
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /run/zoneminder
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Mar 3 2016 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.30.0
|
||||
- Bump version fo 1.30.0 release.
|
||||
|
||||
* Sat Nov 21 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.29.0
|
||||
- Bump version for 1.29.0 release on Fedora 23.
|
||||
|
||||
* Sat Feb 14 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.1
|
||||
- Bump version for 1.28.1 release on Fedora 21.
|
||||
|
||||
* Sun Oct 5 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.0
|
||||
- Bump version for 1.28.0 release.
|
||||
|
||||
* Fri Mar 14 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.27
|
||||
- Tweak build requirements for cmake
|
||||
|
||||
* Sat Feb 01 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.27
|
||||
- Add zmcamtool.pl. Bump version for 1.27 release.
|
||||
|
||||
* Mon Dec 16 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.5
|
||||
- This is a bug fixe release
|
||||
- RTSP fixes, cmake enhancements, couple other misc fixes
|
||||
|
||||
* Mon Oct 07 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
|
||||
- Initial cmake build.
|
||||
|
||||
* Sat Oct 05 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
|
||||
- Fedora specific path changes have been moved to zoneminder-1.26.0-defaults.patch
|
||||
- All files are now part of the zoneminder source tree. Update specfile accordingly.
|
||||
|
||||
* Sat Sep 21 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.3
|
||||
- Initial rebuild for ZoneMinder 1.26.3 release.
|
||||
|
||||
* Fri Feb 15 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25.0-13
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||
|
||||
* Mon Jan 21 2013 Adam Tkac <atkac redhat com> - 1.25.0-12
|
||||
- rebuild due to "jpeg8-ABI" feature drop
|
||||
|
||||
* Mon Jan 7 2013 Remi Collet <rcollet@redhat.com> - 1.25.0-11
|
||||
- fix configuration file for httpd 2.4, #871502
|
||||
|
||||
* Fri Dec 21 2012 Adam Tkac <atkac redhat com> - 1.25.0-10
|
||||
- rebuild against new libjpeg
|
||||
|
||||
* Thu Aug 09 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-9
|
||||
- Add patch to work around v4l2 api breakage in 3.5 kernel.
|
||||
|
||||
* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25.0-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
|
||||
|
||||
* Sat Jun 23 2012 Petr Pisar <ppisar@redhat.com> - 1.25.0-7
|
||||
- Perl 5.16 rebuild
|
||||
|
||||
* Wed Mar 21 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-6
|
||||
- Fix stupid thinko in sql modifications.
|
||||
|
||||
* Sat Feb 25 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-5
|
||||
- Clean up macro usage.
|
||||
|
||||
* Sat Feb 25 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-4
|
||||
- Convert to systemd.
|
||||
- Add tmpfiles.d configuration since the initscript isn't around to create
|
||||
/run/zoneminder.
|
||||
- Remove some pointless executable permissions.
|
||||
- Add logrotate file.
|
||||
|
||||
* Wed Feb 22 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-3
|
||||
- Update README.Fedora to reference systemctl and mention timezone info in
|
||||
php.ini.
|
||||
- Add proper default for EYEZM_LOG_TO_FILE.
|
||||
|
||||
|
||||
* Thu Feb 09 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-2
|
||||
- Rebuild for new pcre.
|
||||
|
||||
* Thu Jan 19 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-1
|
||||
- Update to 1.25.0
|
||||
- Fix gcc4.7 build problems.
|
||||
- Drop gcc4.4 build fixes; for whatever reason they now break the build.
|
||||
- Clean up old patches.
|
||||
- Force setting of ZM_TMPDIR and ZM_RUNDIR.
|
||||
|
||||
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.4-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
|
||||
|
||||
* Thu Sep 15 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-3
|
||||
- Re-add the dist-tag that somehow got lost.
|
||||
|
||||
* Thu Sep 15 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-2
|
||||
- Add patch for bug 711780 - fix syntax issue in Mapped.pm.
|
||||
- Undo that patch, and undo another which was the cause of the whole mess.
|
||||
- Fix up other patches so ZM_PATH_BUILD is both defined and useful.
|
||||
- Make sure database creation mods actually take.
|
||||
- Update Fedora-specific docs with some additional info.
|
||||
- Use bundled mootools (javascript, so no guideline violation).
|
||||
- Update download location.
|
||||
- Update the gcrypt patch to actually work.
|
||||
- Upstream changed the tarball without changing the version to patch a
|
||||
vulnerability, so redownload.
|
||||
|
||||
* Sun Aug 14 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-1
|
||||
- Initial attempt to upgrade to 1.24.4.
|
||||
- Add patch from BZ 460310 to build against libgcrypt instead of requiring the
|
||||
gnutls openssl libs.
|
||||
|
||||
* Thu Jul 21 2011 Petr Sabata <contyk@redhat.com> - 1.24.3-7.20110324svn3310
|
||||
- Perl mass rebuild
|
||||
|
||||
* Wed Jul 20 2011 Petr Sabata <contyk@redhat.com> - 1.24.3-6.20110324svn3310
|
||||
- Perl mass rebuild
|
||||
|
||||
* Mon May 09 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-5.20110324svn3310
|
||||
- Bump for gnutls update.
|
||||
|
||||
* Thu Mar 24 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-4.20110324svn3310
|
||||
- Update to latest 1.24.3 subversion. Turns out that what upstream was calling
|
||||
1.24.3 is really just an occasionally updated devel snapshot.
|
||||
- Rebase various patches.
|
||||
|
||||
* Wed Mar 23 2011 Dan Horák <dan@danny.cz> - 1.24.3-3
|
||||
- rebuilt for mysql 5.5.10 (soname bump in libmysqlclient)
|
||||
|
||||
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
|
||||
|
||||
* Tue Jan 25 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-1
|
||||
- Update to latest upstream version.
|
||||
- Rebase patches.
|
||||
- Initial incomplete attempt to disable v4l1 support.
|
||||
|
||||
* Fri Jan 21 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-6
|
||||
- Unbundle cambozola; instead link to the separately pacakged copy.
|
||||
- Remove BuildRoot:, %%clean and buildroot cleaning in %%install.
|
||||
- Git rid of mixed space/tab usage by removing all tabs.
|
||||
- Remove unnecessary Conflicts: line.
|
||||
- Attempt to force short_open_tag on for the code directories.
|
||||
- Move default location of sockets, swaps, logfiles and some temporary files to
|
||||
make more sense and allow things to work better with a future selinux policy.
|
||||
- Fix errors in README.Fedora.
|
||||
|
||||
* Wed Jun 02 2010 Marcela Maslanova <mmaslano@redhat.com> - 1.24.2-5
|
||||
- Mass rebuild with perl-5.12.0
|
||||
|
||||
* Fri Dec 4 2009 Stepan Kasal <skasal@redhat.com> - 1.24.2-4
|
||||
- rebuild against perl 5.10.1
|
||||
- use Perl vendorarch and archlib variables correctly
|
||||
|
||||
* Mon Jul 27 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.2-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
|
||||
|
||||
* Wed Jul 22 2009 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-2
|
||||
- Bump release since 1.24.2-1 was mistakenly tagged a few months ago.
|
||||
|
||||
* Wed Jul 22 2009 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-1
|
||||
- Initial update to 1.24.2.
|
||||
- Rebase patches.
|
||||
- Update mootools download location.
|
||||
- Update to mootools 1.2.3.
|
||||
- Add additional dependencies for some optional features.
|
||||
|
||||
* Sat Apr 11 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-3
|
||||
- Remove unused Sys::Mmap perl dependency RPM is finding
|
||||
|
||||
* Sat Apr 11 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-2
|
||||
- Update gcc44 patch to disable -frepo, seems to be broken with gcc44
|
||||
- Added noffmpeg patch to make building outside mock easier
|
||||
|
||||
* Sat Mar 21 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-1
|
||||
- Patch for gcc 4.4 compilation errors
|
||||
- Upgrade to 1.24.1
|
||||
|
||||
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.23.3-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
|
||||
|
||||
* Sat Jan 24 2009 Caolán McNamara <caolanm@redhat.com> - 1.23.3-3
|
||||
- rebuild for dependencies
|
||||
|
||||
* Mon Dec 15 2008 Martin Ebourne <martin@zepler.org> - 1.23.3-2
|
||||
- Fix permissions on zm.conf
|
||||
|
||||
* Fri Jul 11 2008 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.23.3-1
|
||||
- Initial attempt at packaging 1.23.
|
||||
|
||||
* Tue Jul 1 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-15
|
||||
- Add perl module compat dependency, bz #453590
|
||||
|
||||
* Tue May 6 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-14
|
||||
- Remove default runlevel, bz #441315
|
||||
|
||||
* Mon Apr 28 2008 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.22.3-13
|
||||
- Backport patch for CVE-2008-1381 from 1.23.3 to 1.22.3.
|
||||
|
||||
* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 1.22.3-12
|
||||
- Autorebuild for GCC 4.3
|
||||
|
||||
* Thu Jan 3 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-11
|
||||
- Fix compilation on gcc 4.3
|
||||
|
||||
* Thu Dec 6 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-10
|
||||
- Rebuild for new openssl
|
||||
|
||||
* Thu Aug 2 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-8
|
||||
- Fix licence tag
|
||||
|
||||
* Thu Jul 12 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-7
|
||||
- Fixes from testing by Jitz including missing dependencies and database creation
|
||||
|
||||
* Sat Jun 30 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-6
|
||||
- Disable crashtrace on ppc
|
||||
|
||||
* Sat Jun 30 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-5
|
||||
- Fix uid for directories in /var/lib/zoneminder
|
||||
|
||||
* Tue Jun 26 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-4
|
||||
- Added perl Archive::Tar dependency
|
||||
- Disabled web interface due to lack of access control on the event images
|
||||
|
||||
* Sun Jun 10 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-3
|
||||
- Changes recommended in review by Jason Tibbitts
|
||||
|
||||
* Mon Apr 2 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-2
|
||||
- Standardised on package name of zoneminder
|
||||
|
||||
* Thu Dec 28 2006 Martin Ebourne <martin@zepler.org> - 1.22.3-1
|
||||
- First version. Uses some parts from zm-1.20.1 by Corey DeLasaux and Serg Oskin
|
|
@ -0,0 +1 @@
|
|||
../redhat/jscalendar-1.0.zip
|
|
@ -1 +0,0 @@
|
|||
zoneminder.f23.spec
|
|
@ -1,429 +0,0 @@
|
|||
%define zmuid $(id -un)
|
||||
%define zmgid $(id -gn)
|
||||
%define zmuid_final apache
|
||||
%define zmgid_final apache
|
||||
|
||||
%global _hardened_build 1
|
||||
|
||||
### Delete the lines below to build with ffmpeg and/or x10
|
||||
%define _without_ffmpeg 1
|
||||
%define _without_x10 1
|
||||
|
||||
Name: zoneminder
|
||||
Version: 1.30.0
|
||||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
# jscalendar is LGPL (any version): http://www.dynarch.com/projects/calendar/
|
||||
# Mootools is inder the MIT license: http://mootools.net/
|
||||
License: GPLv2+ and LGPLv2+ and MIT
|
||||
URL: http://www.zoneminder.com/
|
||||
|
||||
#Source: https://github.com/ZoneMinder/ZoneMinder/archive/v%{version}.tar.gz
|
||||
Source: ZoneMinder-%{version}.tar.gz
|
||||
|
||||
BuildRequires: cmake gnutls-devel systemd-units bzip2-devel
|
||||
BuildRequires: mariadb-devel pcre-devel libjpeg-turbo-devel
|
||||
BuildRequires: perl(Archive::Tar) perl(Archive::Zip) perl-podlators
|
||||
BuildRequires: perl(Date::Manip) perl(DBD::mysql)
|
||||
BuildRequires: perl(ExtUtils::MakeMaker) perl(LWP::UserAgent)
|
||||
BuildRequires: perl(MIME::Entity) perl(MIME::Lite)
|
||||
BuildRequires: perl(PHP::Serialization) perl(Sys::Mmap)
|
||||
BuildRequires: perl(Time::HiRes) perl(Net::SFTP::Foreign)
|
||||
BuildRequires: perl(Expect) perl(Sys::Syslog)
|
||||
BuildRequires: gcc gcc-c++ vlc-devel libcurl-devel libv4l-devel
|
||||
%{!?_without_ffmpeg:BuildRequires: ffmpeg-devel}
|
||||
%{!?_without_x10:BuildRequires: perl(X10::ActiveHome) perl(Astro::SunTime)}
|
||||
# cmake needs the following installed at build time due to the way it auto-detects certain parameters
|
||||
BuildRequires: httpd polkit-devel
|
||||
%{!?_without_ffmpeg:BuildRequires: ffmpeg}
|
||||
|
||||
Requires: httpd php php-gd php-mysql cambozola polkit net-tools psmisc
|
||||
Requires: libjpeg-turbo vlc-core libcurl
|
||||
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
|
||||
Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip)
|
||||
Requires: perl(MIME::Entity) perl(MIME::Lite) perl(Net::SMTP) perl(Net::FTP)
|
||||
Requires: perl(LWP::Protocol::https)
|
||||
%{!?_without_ffmpeg:Requires: ffmpeg}
|
||||
|
||||
Requires(post): systemd-units systemd-sysv
|
||||
Requires(post): /usr/bin/gpasswd
|
||||
Requires(post): /usr/bin/less
|
||||
Requires(preun): systemd-units
|
||||
Requires(postun): systemd-units
|
||||
|
||||
%description
|
||||
ZoneMinder is a set of applications which is intended to provide a complete
|
||||
solution allowing you to capture, analyse, record and monitor any cameras you
|
||||
have attached to a Linux based machine. It is designed to run on kernels which
|
||||
support the Video For Linux (V4L) interface and has been tested with cameras
|
||||
attached to BTTV cards, various USB cameras and IP network cameras. It is
|
||||
designed to support as many cameras as you can attach to your computer without
|
||||
too much degradation of performance.
|
||||
|
||||
%prep
|
||||
%setup -q -n ZoneMinder-%{version}
|
||||
|
||||
# Change the following default values
|
||||
./utils/zmeditconfigdata.sh ZM_PATH_ZMS /cgi-bin-zm/nph-zms
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes
|
||||
./utils/zmeditconfigdata.sh ZM_PATH_SWAP /dev/shm
|
||||
./utils/zmeditconfigdata.sh ZM_UPLOAD_FTP_LOC_DIR /var/spool/zoneminder-upload
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
|
||||
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
|
||||
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_FAST_DELETE no
|
||||
|
||||
%build
|
||||
%cmake \
|
||||
-DZM_TARGET_DISTRO="f23" \
|
||||
%{?_without_ffmpeg:-DZM_NO_FFMPEG=ON} \
|
||||
%{?_without_x10:-DZM_NO_X10=ON} \
|
||||
.
|
||||
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
export DESTDIR=%{buildroot}
|
||||
make install
|
||||
|
||||
%post
|
||||
|
||||
# Add any new PTZ control configurations to the database (will not overwrite)
|
||||
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
|
||||
|
||||
if [ $1 -eq 1 ] ; then
|
||||
# Initial installation
|
||||
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
# Allow zoneminder access to local video sources, serial ports, and x10
|
||||
/usr/bin/gpasswd -a %{zmuid_final} video
|
||||
/usr/bin/gpasswd -a %{zmuid_final} dialout
|
||||
|
||||
# Upgrade from a previous version of zoneminder
|
||||
if [ $1 -eq 2 ] ; then
|
||||
|
||||
# Add any new PTZ control configurations to the database (will not overwrite)
|
||||
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
|
||||
|
||||
# Freshen the database
|
||||
%{_bindir}/zmupdate.pl -f >/dev/null 2>&1 || :
|
||||
|
||||
# We can't run this automatically when new sql account permissions need to
|
||||
# be manually added first
|
||||
# Run zmupdate non-interactively
|
||||
#/usr/bin/zmupdate.pl --nointeractive
|
||||
fi
|
||||
|
||||
# Warn the end user to read the README file
|
||||
echo -e "\nVERY IMPORTANT: Before starting ZoneMinder, read README.Fedora to finish the\ninstallation or upgrade!\n"
|
||||
echo -e "\nThe README file is located here: %{_docdir}/%{name}\n"
|
||||
|
||||
%preun
|
||||
if [ $1 -eq 0 ] ; then
|
||||
# Package removal, not upgrade
|
||||
/bin/systemctl --no-reload disable zoneminder.service > /dev/null 2>&1 || :
|
||||
/bin/systemctl stop zoneminder.service > /dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%postun
|
||||
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
|
||||
if [ $1 -ge 1 ] ; then
|
||||
# Package upgrade, not uninstall
|
||||
/bin/systemctl try-restart zoneminder.service >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%triggerun -- zoneminder < 1.25.0-4
|
||||
# Save the current service runlevel info
|
||||
# User must manually run systemd-sysv-convert --apply zoneminder
|
||||
# to migrate them to systemd targets
|
||||
/usr/bin/systemd-sysv-convert --save zoneminder >/dev/null 2>&1 ||:
|
||||
|
||||
# Run these because the SysV package being removed won't do them
|
||||
/sbin/chkconfig --del zoneminder >/dev/null 2>&1 || :
|
||||
/bin/systemctl try-restart zoneminder.service >/dev/null 2>&1 || :
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc AUTHORS COPYING README.md distros/fedora/README.Fedora distros/fedora/README.https distros/fedora/jscalendar-doc
|
||||
%config %attr(640,root,%{zmgid_final}) /etc/zm/zm.conf
|
||||
%config(noreplace) %attr(644,root,root) /etc/httpd/conf.d/zoneminder.conf
|
||||
%config(noreplace) /etc/tmpfiles.d/zoneminder.conf
|
||||
%config(noreplace) /etc/logrotate.d/zoneminder
|
||||
|
||||
%{_unitdir}/zoneminder.service
|
||||
|
||||
%{_bindir}/zma
|
||||
%{_bindir}/zmaudit.pl
|
||||
%{_bindir}/zmc
|
||||
%{_bindir}/zmcontrol.pl
|
||||
%{_bindir}/zmdc.pl
|
||||
%{_bindir}/zmf
|
||||
%{_bindir}/zmfilter.pl
|
||||
%{_bindir}/zmpkg.pl
|
||||
%{_bindir}/zmtrack.pl
|
||||
%{_bindir}/zmtrigger.pl
|
||||
%{_bindir}/zmu
|
||||
%{_bindir}/zmupdate.pl
|
||||
%{_bindir}/zmvideo.pl
|
||||
%{_bindir}/zmwatch.pl
|
||||
%{_bindir}/zmcamtool.pl
|
||||
%{_bindir}/zmsystemctl.pl
|
||||
%{_bindir}/zmtelemetry.pl
|
||||
%{!?_without_x10:%{_bindir}/zmx10.pl}
|
||||
%{_bindir}/zmonvif-probe.pl
|
||||
|
||||
%{perl_vendorlib}/ZoneMinder*
|
||||
%{perl_vendorlib}/ONVIF*
|
||||
%{perl_vendorlib}/WSDiscovery*
|
||||
%{perl_vendorlib}/WSSecurity*
|
||||
%{perl_vendorlib}/WSNotification*
|
||||
%{_mandir}/man*/*
|
||||
%dir %{_libexecdir}/zoneminder
|
||||
%{_libexecdir}/zoneminder/cgi-bin
|
||||
%dir %{_datadir}/zoneminder
|
||||
%{_datadir}/zoneminder/db
|
||||
%{_datadir}/zoneminder/www
|
||||
|
||||
%{_datadir}/polkit-1/actions/com.zoneminder.systemctl.policy
|
||||
%{_datadir}/polkit-1/rules.d/com.zoneminder.systemctl.rules
|
||||
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/events
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/images
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/sock
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/swap
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/temp
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/log/zoneminder
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/spool/zoneminder-upload
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /run/zoneminder
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Mar 3 2016 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.30.0
|
||||
- Bump version fo 1.30.0 release.
|
||||
|
||||
* Sat Nov 21 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.29.0
|
||||
- Bump version for 1.29.0 release on Fedora 23.
|
||||
|
||||
* Sat Feb 14 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.1
|
||||
- Bump version for 1.28.1 release on Fedora 21.
|
||||
|
||||
* Sun Oct 5 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.0
|
||||
- Bump version for 1.28.0 release.
|
||||
|
||||
* Fri Mar 14 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.27
|
||||
- Tweak build requirements for cmake
|
||||
|
||||
* Sat Feb 01 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.27
|
||||
- Add zmcamtool.pl. Bump version for 1.27 release.
|
||||
|
||||
* Mon Dec 16 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.5
|
||||
- This is a bug fixe release
|
||||
- RTSP fixes, cmake enhancements, couple other misc fixes
|
||||
|
||||
* Mon Oct 07 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
|
||||
- Initial cmake build.
|
||||
|
||||
* Sat Oct 05 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
|
||||
- Fedora specific path changes have been moved to zoneminder-1.26.0-defaults.patch
|
||||
- All files are now part of the zoneminder source tree. Update specfile accordingly.
|
||||
|
||||
* Sat Sep 21 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.3
|
||||
- Initial rebuild for ZoneMinder 1.26.3 release.
|
||||
|
||||
* Fri Feb 15 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25.0-13
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||
|
||||
* Mon Jan 21 2013 Adam Tkac <atkac redhat com> - 1.25.0-12
|
||||
- rebuild due to "jpeg8-ABI" feature drop
|
||||
|
||||
* Mon Jan 7 2013 Remi Collet <rcollet@redhat.com> - 1.25.0-11
|
||||
- fix configuration file for httpd 2.4, #871502
|
||||
|
||||
* Fri Dec 21 2012 Adam Tkac <atkac redhat com> - 1.25.0-10
|
||||
- rebuild against new libjpeg
|
||||
|
||||
* Thu Aug 09 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-9
|
||||
- Add patch to work around v4l2 api breakage in 3.5 kernel.
|
||||
|
||||
* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25.0-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
|
||||
|
||||
* Sat Jun 23 2012 Petr Pisar <ppisar@redhat.com> - 1.25.0-7
|
||||
- Perl 5.16 rebuild
|
||||
|
||||
* Wed Mar 21 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-6
|
||||
- Fix stupid thinko in sql modifications.
|
||||
|
||||
* Sat Feb 25 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-5
|
||||
- Clean up macro usage.
|
||||
|
||||
* Sat Feb 25 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-4
|
||||
- Convert to systemd.
|
||||
- Add tmpfiles.d configuration since the initscript isn't around to create
|
||||
/run/zoneminder.
|
||||
- Remove some pointless executable permissions.
|
||||
- Add logrotate file.
|
||||
|
||||
* Wed Feb 22 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-3
|
||||
- Update README.Fedora to reference systemctl and mention timezone info in
|
||||
php.ini.
|
||||
- Add proper default for EYEZM_LOG_TO_FILE.
|
||||
|
||||
|
||||
* Thu Feb 09 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-2
|
||||
- Rebuild for new pcre.
|
||||
|
||||
* Thu Jan 19 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-1
|
||||
- Update to 1.25.0
|
||||
- Fix gcc4.7 build problems.
|
||||
- Drop gcc4.4 build fixes; for whatever reason they now break the build.
|
||||
- Clean up old patches.
|
||||
- Force setting of ZM_TMPDIR and ZM_RUNDIR.
|
||||
|
||||
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.4-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
|
||||
|
||||
* Thu Sep 15 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-3
|
||||
- Re-add the dist-tag that somehow got lost.
|
||||
|
||||
* Thu Sep 15 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-2
|
||||
- Add patch for bug 711780 - fix syntax issue in Mapped.pm.
|
||||
- Undo that patch, and undo another which was the cause of the whole mess.
|
||||
- Fix up other patches so ZM_PATH_BUILD is both defined and useful.
|
||||
- Make sure database creation mods actually take.
|
||||
- Update Fedora-specific docs with some additional info.
|
||||
- Use bundled mootools (javascript, so no guideline violation).
|
||||
- Update download location.
|
||||
- Update the gcrypt patch to actually work.
|
||||
- Upstream changed the tarball without changing the version to patch a
|
||||
vulnerability, so redownload.
|
||||
|
||||
* Sun Aug 14 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-1
|
||||
- Initial attempt to upgrade to 1.24.4.
|
||||
- Add patch from BZ 460310 to build against libgcrypt instead of requiring the
|
||||
gnutls openssl libs.
|
||||
|
||||
* Thu Jul 21 2011 Petr Sabata <contyk@redhat.com> - 1.24.3-7.20110324svn3310
|
||||
- Perl mass rebuild
|
||||
|
||||
* Wed Jul 20 2011 Petr Sabata <contyk@redhat.com> - 1.24.3-6.20110324svn3310
|
||||
- Perl mass rebuild
|
||||
|
||||
* Mon May 09 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-5.20110324svn3310
|
||||
- Bump for gnutls update.
|
||||
|
||||
* Thu Mar 24 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-4.20110324svn3310
|
||||
- Update to latest 1.24.3 subversion. Turns out that what upstream was calling
|
||||
1.24.3 is really just an occasionally updated devel snapshot.
|
||||
- Rebase various patches.
|
||||
|
||||
* Wed Mar 23 2011 Dan Horák <dan@danny.cz> - 1.24.3-3
|
||||
- rebuilt for mysql 5.5.10 (soname bump in libmysqlclient)
|
||||
|
||||
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
|
||||
|
||||
* Tue Jan 25 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-1
|
||||
- Update to latest upstream version.
|
||||
- Rebase patches.
|
||||
- Initial incomplete attempt to disable v4l1 support.
|
||||
|
||||
* Fri Jan 21 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-6
|
||||
- Unbundle cambozola; instead link to the separately pacakged copy.
|
||||
- Remove BuildRoot:, %%clean and buildroot cleaning in %%install.
|
||||
- Git rid of mixed space/tab usage by removing all tabs.
|
||||
- Remove unnecessary Conflicts: line.
|
||||
- Attempt to force short_open_tag on for the code directories.
|
||||
- Move default location of sockets, swaps, logfiles and some temporary files to
|
||||
make more sense and allow things to work better with a future selinux policy.
|
||||
- Fix errors in README.Fedora.
|
||||
|
||||
* Wed Jun 02 2010 Marcela Maslanova <mmaslano@redhat.com> - 1.24.2-5
|
||||
- Mass rebuild with perl-5.12.0
|
||||
|
||||
* Fri Dec 4 2009 Stepan Kasal <skasal@redhat.com> - 1.24.2-4
|
||||
- rebuild against perl 5.10.1
|
||||
- use Perl vendorarch and archlib variables correctly
|
||||
|
||||
* Mon Jul 27 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.2-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
|
||||
|
||||
* Wed Jul 22 2009 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-2
|
||||
- Bump release since 1.24.2-1 was mistakenly tagged a few months ago.
|
||||
|
||||
* Wed Jul 22 2009 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-1
|
||||
- Initial update to 1.24.2.
|
||||
- Rebase patches.
|
||||
- Update mootools download location.
|
||||
- Update to mootools 1.2.3.
|
||||
- Add additional dependencies for some optional features.
|
||||
|
||||
* Sat Apr 11 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-3
|
||||
- Remove unused Sys::Mmap perl dependency RPM is finding
|
||||
|
||||
* Sat Apr 11 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-2
|
||||
- Update gcc44 patch to disable -frepo, seems to be broken with gcc44
|
||||
- Added noffmpeg patch to make building outside mock easier
|
||||
|
||||
* Sat Mar 21 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-1
|
||||
- Patch for gcc 4.4 compilation errors
|
||||
- Upgrade to 1.24.1
|
||||
|
||||
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.23.3-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
|
||||
|
||||
* Sat Jan 24 2009 Caolán McNamara <caolanm@redhat.com> - 1.23.3-3
|
||||
- rebuild for dependencies
|
||||
|
||||
* Mon Dec 15 2008 Martin Ebourne <martin@zepler.org> - 1.23.3-2
|
||||
- Fix permissions on zm.conf
|
||||
|
||||
* Fri Jul 11 2008 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.23.3-1
|
||||
- Initial attempt at packaging 1.23.
|
||||
|
||||
* Tue Jul 1 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-15
|
||||
- Add perl module compat dependency, bz #453590
|
||||
|
||||
* Tue May 6 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-14
|
||||
- Remove default runlevel, bz #441315
|
||||
|
||||
* Mon Apr 28 2008 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.22.3-13
|
||||
- Backport patch for CVE-2008-1381 from 1.23.3 to 1.22.3.
|
||||
|
||||
* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 1.22.3-12
|
||||
- Autorebuild for GCC 4.3
|
||||
|
||||
* Thu Jan 3 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-11
|
||||
- Fix compilation on gcc 4.3
|
||||
|
||||
* Thu Dec 6 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-10
|
||||
- Rebuild for new openssl
|
||||
|
||||
* Thu Aug 2 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-8
|
||||
- Fix licence tag
|
||||
|
||||
* Thu Jul 12 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-7
|
||||
- Fixes from testing by Jitz including missing dependencies and database creation
|
||||
|
||||
* Sat Jun 30 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-6
|
||||
- Disable crashtrace on ppc
|
||||
|
||||
* Sat Jun 30 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-5
|
||||
- Fix uid for directories in /var/lib/zoneminder
|
||||
|
||||
* Tue Jun 26 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-4
|
||||
- Added perl Archive::Tar dependency
|
||||
- Disabled web interface due to lack of access control on the event images
|
||||
|
||||
* Sun Jun 10 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-3
|
||||
- Changes recommended in review by Jason Tibbitts
|
||||
|
||||
* Mon Apr 2 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-2
|
||||
- Standardised on package name of zoneminder
|
||||
|
||||
* Thu Dec 28 2006 Martin Ebourne <martin@zepler.org> - 1.22.3-1
|
||||
- First version. Uses some parts from zm-1.20.1 by Corey DeLasaux and Serg Oskin
|
|
@ -0,0 +1 @@
|
|||
zoneminder.f24.spec
|
|
@ -0,0 +1,429 @@
|
|||
%define zmuid $(id -un)
|
||||
%define zmgid $(id -gn)
|
||||
%define zmuid_final apache
|
||||
%define zmgid_final apache
|
||||
|
||||
%global _hardened_build 1
|
||||
|
||||
### Delete the lines below to build with ffmpeg and/or x10
|
||||
%define _without_ffmpeg 1
|
||||
%define _without_x10 1
|
||||
|
||||
Name: zoneminder
|
||||
Version: 1.30.0
|
||||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
# jscalendar is LGPL (any version): http://www.dynarch.com/projects/calendar/
|
||||
# Mootools is inder the MIT license: http://mootools.net/
|
||||
License: GPLv2+ and LGPLv2+ and MIT
|
||||
URL: http://www.zoneminder.com/
|
||||
|
||||
#Source: https://github.com/ZoneMinder/ZoneMinder/archive/v%{version}.tar.gz
|
||||
Source: ZoneMinder-%{version}.tar.gz
|
||||
|
||||
BuildRequires: cmake gnutls-devel systemd-units bzip2-devel
|
||||
BuildRequires: mariadb-devel pcre-devel libjpeg-turbo-devel
|
||||
BuildRequires: perl(Archive::Tar) perl(Archive::Zip) perl-podlators
|
||||
BuildRequires: perl(Date::Manip) perl(DBD::mysql)
|
||||
BuildRequires: perl(ExtUtils::MakeMaker) perl(LWP::UserAgent)
|
||||
BuildRequires: perl(MIME::Entity) perl(MIME::Lite)
|
||||
BuildRequires: perl(PHP::Serialization) perl(Sys::Mmap)
|
||||
BuildRequires: perl(Time::HiRes) perl(Net::SFTP::Foreign)
|
||||
BuildRequires: perl(Expect) perl(Sys::Syslog)
|
||||
BuildRequires: gcc gcc-c++ vlc-devel libcurl-devel libv4l-devel
|
||||
%{!?_without_ffmpeg:BuildRequires: ffmpeg-devel}
|
||||
%{!?_without_x10:BuildRequires: perl(X10::ActiveHome) perl(Astro::SunTime)}
|
||||
# cmake needs the following installed at build time due to the way it auto-detects certain parameters
|
||||
BuildRequires: httpd polkit-devel
|
||||
%{!?_without_ffmpeg:BuildRequires: ffmpeg}
|
||||
|
||||
Requires: httpd php php-gd php-mysql cambozola polkit net-tools psmisc
|
||||
Requires: libjpeg-turbo vlc-core libcurl
|
||||
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
|
||||
Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip)
|
||||
Requires: perl(MIME::Entity) perl(MIME::Lite) perl(Net::SMTP) perl(Net::FTP)
|
||||
Requires: perl(LWP::Protocol::https)
|
||||
%{!?_without_ffmpeg:Requires: ffmpeg}
|
||||
|
||||
Requires(post): systemd-units systemd-sysv
|
||||
Requires(post): /usr/bin/gpasswd
|
||||
Requires(post): /usr/bin/less
|
||||
Requires(preun): systemd-units
|
||||
Requires(postun): systemd-units
|
||||
|
||||
%description
|
||||
ZoneMinder is a set of applications which is intended to provide a complete
|
||||
solution allowing you to capture, analyse, record and monitor any cameras you
|
||||
have attached to a Linux based machine. It is designed to run on kernels which
|
||||
support the Video For Linux (V4L) interface and has been tested with cameras
|
||||
attached to BTTV cards, various USB cameras and IP network cameras. It is
|
||||
designed to support as many cameras as you can attach to your computer without
|
||||
too much degradation of performance.
|
||||
|
||||
%prep
|
||||
%setup -q -n ZoneMinder-%{version}
|
||||
|
||||
# Change the following default values
|
||||
./utils/zmeditconfigdata.sh ZM_PATH_ZMS /cgi-bin-zm/nph-zms
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes
|
||||
./utils/zmeditconfigdata.sh ZM_PATH_SWAP /dev/shm
|
||||
./utils/zmeditconfigdata.sh ZM_UPLOAD_FTP_LOC_DIR /var/spool/zoneminder-upload
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
|
||||
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
|
||||
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_FAST_DELETE no
|
||||
|
||||
%build
|
||||
%cmake \
|
||||
-DZM_TARGET_DISTRO="f23" \
|
||||
%{?_without_ffmpeg:-DZM_NO_FFMPEG=ON} \
|
||||
%{?_without_x10:-DZM_NO_X10=ON} \
|
||||
.
|
||||
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
export DESTDIR=%{buildroot}
|
||||
make install
|
||||
|
||||
%post
|
||||
|
||||
# Add any new PTZ control configurations to the database (will not overwrite)
|
||||
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
|
||||
|
||||
if [ $1 -eq 1 ] ; then
|
||||
# Initial installation
|
||||
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
# Allow zoneminder access to local video sources, serial ports, and x10
|
||||
/usr/bin/gpasswd -a %{zmuid_final} video
|
||||
/usr/bin/gpasswd -a %{zmuid_final} dialout
|
||||
|
||||
# Upgrade from a previous version of zoneminder
|
||||
if [ $1 -eq 2 ] ; then
|
||||
|
||||
# Add any new PTZ control configurations to the database (will not overwrite)
|
||||
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
|
||||
|
||||
# Freshen the database
|
||||
%{_bindir}/zmupdate.pl -f >/dev/null 2>&1 || :
|
||||
|
||||
# We can't run this automatically when new sql account permissions need to
|
||||
# be manually added first
|
||||
# Run zmupdate non-interactively
|
||||
#/usr/bin/zmupdate.pl --nointeractive
|
||||
fi
|
||||
|
||||
# Warn the end user to read the README file
|
||||
echo -e "\nVERY IMPORTANT: Before starting ZoneMinder, read README.Fedora to finish the\ninstallation or upgrade!\n"
|
||||
echo -e "\nThe README file is located here: %{_docdir}/%{name}\n"
|
||||
|
||||
%preun
|
||||
if [ $1 -eq 0 ] ; then
|
||||
# Package removal, not upgrade
|
||||
/bin/systemctl --no-reload disable zoneminder.service > /dev/null 2>&1 || :
|
||||
/bin/systemctl stop zoneminder.service > /dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%postun
|
||||
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
|
||||
if [ $1 -ge 1 ] ; then
|
||||
# Package upgrade, not uninstall
|
||||
/bin/systemctl try-restart zoneminder.service >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%triggerun -- zoneminder < 1.25.0-4
|
||||
# Save the current service runlevel info
|
||||
# User must manually run systemd-sysv-convert --apply zoneminder
|
||||
# to migrate them to systemd targets
|
||||
/usr/bin/systemd-sysv-convert --save zoneminder >/dev/null 2>&1 ||:
|
||||
|
||||
# Run these because the SysV package being removed won't do them
|
||||
/sbin/chkconfig --del zoneminder >/dev/null 2>&1 || :
|
||||
/bin/systemctl try-restart zoneminder.service >/dev/null 2>&1 || :
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc AUTHORS COPYING README.md distros/fedora/README.Fedora distros/fedora/README.https distros/fedora/jscalendar-doc
|
||||
%config %attr(640,root,%{zmgid_final}) /etc/zm/zm.conf
|
||||
%config(noreplace) %attr(644,root,root) /etc/httpd/conf.d/zoneminder.conf
|
||||
%config(noreplace) /etc/tmpfiles.d/zoneminder.conf
|
||||
%config(noreplace) /etc/logrotate.d/zoneminder
|
||||
|
||||
%{_unitdir}/zoneminder.service
|
||||
|
||||
%{_bindir}/zma
|
||||
%{_bindir}/zmaudit.pl
|
||||
%{_bindir}/zmc
|
||||
%{_bindir}/zmcontrol.pl
|
||||
%{_bindir}/zmdc.pl
|
||||
%{_bindir}/zmf
|
||||
%{_bindir}/zmfilter.pl
|
||||
%{_bindir}/zmpkg.pl
|
||||
%{_bindir}/zmtrack.pl
|
||||
%{_bindir}/zmtrigger.pl
|
||||
%{_bindir}/zmu
|
||||
%{_bindir}/zmupdate.pl
|
||||
%{_bindir}/zmvideo.pl
|
||||
%{_bindir}/zmwatch.pl
|
||||
%{_bindir}/zmcamtool.pl
|
||||
%{_bindir}/zmsystemctl.pl
|
||||
%{_bindir}/zmtelemetry.pl
|
||||
%{!?_without_x10:%{_bindir}/zmx10.pl}
|
||||
%{_bindir}/zmonvif-probe.pl
|
||||
|
||||
%{perl_vendorlib}/ZoneMinder*
|
||||
%{perl_vendorlib}/ONVIF*
|
||||
%{perl_vendorlib}/WSDiscovery*
|
||||
%{perl_vendorlib}/WSSecurity*
|
||||
%{perl_vendorlib}/WSNotification*
|
||||
%{_mandir}/man*/*
|
||||
%dir %{_libexecdir}/zoneminder
|
||||
%{_libexecdir}/zoneminder/cgi-bin
|
||||
%dir %{_datadir}/zoneminder
|
||||
%{_datadir}/zoneminder/db
|
||||
%{_datadir}/zoneminder/www
|
||||
|
||||
%{_datadir}/polkit-1/actions/com.zoneminder.systemctl.policy
|
||||
%{_datadir}/polkit-1/rules.d/com.zoneminder.systemctl.rules
|
||||
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/events
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/images
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/sock
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/swap
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/temp
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/log/zoneminder
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/spool/zoneminder-upload
|
||||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /run/zoneminder
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Mar 3 2016 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.30.0
|
||||
- Bump version fo 1.30.0 release.
|
||||
|
||||
* Sat Nov 21 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.29.0
|
||||
- Bump version for 1.29.0 release on Fedora 23.
|
||||
|
||||
* Sat Feb 14 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.1
|
||||
- Bump version for 1.28.1 release on Fedora 21.
|
||||
|
||||
* Sun Oct 5 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.0
|
||||
- Bump version for 1.28.0 release.
|
||||
|
||||
* Fri Mar 14 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.27
|
||||
- Tweak build requirements for cmake
|
||||
|
||||
* Sat Feb 01 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.27
|
||||
- Add zmcamtool.pl. Bump version for 1.27 release.
|
||||
|
||||
* Mon Dec 16 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.5
|
||||
- This is a bug fixe release
|
||||
- RTSP fixes, cmake enhancements, couple other misc fixes
|
||||
|
||||
* Mon Oct 07 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
|
||||
- Initial cmake build.
|
||||
|
||||
* Sat Oct 05 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
|
||||
- Fedora specific path changes have been moved to zoneminder-1.26.0-defaults.patch
|
||||
- All files are now part of the zoneminder source tree. Update specfile accordingly.
|
||||
|
||||
* Sat Sep 21 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.3
|
||||
- Initial rebuild for ZoneMinder 1.26.3 release.
|
||||
|
||||
* Fri Feb 15 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25.0-13
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||
|
||||
* Mon Jan 21 2013 Adam Tkac <atkac redhat com> - 1.25.0-12
|
||||
- rebuild due to "jpeg8-ABI" feature drop
|
||||
|
||||
* Mon Jan 7 2013 Remi Collet <rcollet@redhat.com> - 1.25.0-11
|
||||
- fix configuration file for httpd 2.4, #871502
|
||||
|
||||
* Fri Dec 21 2012 Adam Tkac <atkac redhat com> - 1.25.0-10
|
||||
- rebuild against new libjpeg
|
||||
|
||||
* Thu Aug 09 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-9
|
||||
- Add patch to work around v4l2 api breakage in 3.5 kernel.
|
||||
|
||||
* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25.0-8
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
|
||||
|
||||
* Sat Jun 23 2012 Petr Pisar <ppisar@redhat.com> - 1.25.0-7
|
||||
- Perl 5.16 rebuild
|
||||
|
||||
* Wed Mar 21 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-6
|
||||
- Fix stupid thinko in sql modifications.
|
||||
|
||||
* Sat Feb 25 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-5
|
||||
- Clean up macro usage.
|
||||
|
||||
* Sat Feb 25 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-4
|
||||
- Convert to systemd.
|
||||
- Add tmpfiles.d configuration since the initscript isn't around to create
|
||||
/run/zoneminder.
|
||||
- Remove some pointless executable permissions.
|
||||
- Add logrotate file.
|
||||
|
||||
* Wed Feb 22 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-3
|
||||
- Update README.Fedora to reference systemctl and mention timezone info in
|
||||
php.ini.
|
||||
- Add proper default for EYEZM_LOG_TO_FILE.
|
||||
|
||||
|
||||
* Thu Feb 09 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-2
|
||||
- Rebuild for new pcre.
|
||||
|
||||
* Thu Jan 19 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-1
|
||||
- Update to 1.25.0
|
||||
- Fix gcc4.7 build problems.
|
||||
- Drop gcc4.4 build fixes; for whatever reason they now break the build.
|
||||
- Clean up old patches.
|
||||
- Force setting of ZM_TMPDIR and ZM_RUNDIR.
|
||||
|
||||
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.4-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
|
||||
|
||||
* Thu Sep 15 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-3
|
||||
- Re-add the dist-tag that somehow got lost.
|
||||
|
||||
* Thu Sep 15 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-2
|
||||
- Add patch for bug 711780 - fix syntax issue in Mapped.pm.
|
||||
- Undo that patch, and undo another which was the cause of the whole mess.
|
||||
- Fix up other patches so ZM_PATH_BUILD is both defined and useful.
|
||||
- Make sure database creation mods actually take.
|
||||
- Update Fedora-specific docs with some additional info.
|
||||
- Use bundled mootools (javascript, so no guideline violation).
|
||||
- Update download location.
|
||||
- Update the gcrypt patch to actually work.
|
||||
- Upstream changed the tarball without changing the version to patch a
|
||||
vulnerability, so redownload.
|
||||
|
||||
* Sun Aug 14 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-1
|
||||
- Initial attempt to upgrade to 1.24.4.
|
||||
- Add patch from BZ 460310 to build against libgcrypt instead of requiring the
|
||||
gnutls openssl libs.
|
||||
|
||||
* Thu Jul 21 2011 Petr Sabata <contyk@redhat.com> - 1.24.3-7.20110324svn3310
|
||||
- Perl mass rebuild
|
||||
|
||||
* Wed Jul 20 2011 Petr Sabata <contyk@redhat.com> - 1.24.3-6.20110324svn3310
|
||||
- Perl mass rebuild
|
||||
|
||||
* Mon May 09 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-5.20110324svn3310
|
||||
- Bump for gnutls update.
|
||||
|
||||
* Thu Mar 24 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-4.20110324svn3310
|
||||
- Update to latest 1.24.3 subversion. Turns out that what upstream was calling
|
||||
1.24.3 is really just an occasionally updated devel snapshot.
|
||||
- Rebase various patches.
|
||||
|
||||
* Wed Mar 23 2011 Dan Horák <dan@danny.cz> - 1.24.3-3
|
||||
- rebuilt for mysql 5.5.10 (soname bump in libmysqlclient)
|
||||
|
||||
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
|
||||
|
||||
* Tue Jan 25 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-1
|
||||
- Update to latest upstream version.
|
||||
- Rebase patches.
|
||||
- Initial incomplete attempt to disable v4l1 support.
|
||||
|
||||
* Fri Jan 21 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-6
|
||||
- Unbundle cambozola; instead link to the separately pacakged copy.
|
||||
- Remove BuildRoot:, %%clean and buildroot cleaning in %%install.
|
||||
- Git rid of mixed space/tab usage by removing all tabs.
|
||||
- Remove unnecessary Conflicts: line.
|
||||
- Attempt to force short_open_tag on for the code directories.
|
||||
- Move default location of sockets, swaps, logfiles and some temporary files to
|
||||
make more sense and allow things to work better with a future selinux policy.
|
||||
- Fix errors in README.Fedora.
|
||||
|
||||
* Wed Jun 02 2010 Marcela Maslanova <mmaslano@redhat.com> - 1.24.2-5
|
||||
- Mass rebuild with perl-5.12.0
|
||||
|
||||
* Fri Dec 4 2009 Stepan Kasal <skasal@redhat.com> - 1.24.2-4
|
||||
- rebuild against perl 5.10.1
|
||||
- use Perl vendorarch and archlib variables correctly
|
||||
|
||||
* Mon Jul 27 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.2-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
|
||||
|
||||
* Wed Jul 22 2009 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-2
|
||||
- Bump release since 1.24.2-1 was mistakenly tagged a few months ago.
|
||||
|
||||
* Wed Jul 22 2009 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-1
|
||||
- Initial update to 1.24.2.
|
||||
- Rebase patches.
|
||||
- Update mootools download location.
|
||||
- Update to mootools 1.2.3.
|
||||
- Add additional dependencies for some optional features.
|
||||
|
||||
* Sat Apr 11 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-3
|
||||
- Remove unused Sys::Mmap perl dependency RPM is finding
|
||||
|
||||
* Sat Apr 11 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-2
|
||||
- Update gcc44 patch to disable -frepo, seems to be broken with gcc44
|
||||
- Added noffmpeg patch to make building outside mock easier
|
||||
|
||||
* Sat Mar 21 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-1
|
||||
- Patch for gcc 4.4 compilation errors
|
||||
- Upgrade to 1.24.1
|
||||
|
||||
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.23.3-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
|
||||
|
||||
* Sat Jan 24 2009 Caolán McNamara <caolanm@redhat.com> - 1.23.3-3
|
||||
- rebuild for dependencies
|
||||
|
||||
* Mon Dec 15 2008 Martin Ebourne <martin@zepler.org> - 1.23.3-2
|
||||
- Fix permissions on zm.conf
|
||||
|
||||
* Fri Jul 11 2008 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.23.3-1
|
||||
- Initial attempt at packaging 1.23.
|
||||
|
||||
* Tue Jul 1 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-15
|
||||
- Add perl module compat dependency, bz #453590
|
||||
|
||||
* Tue May 6 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-14
|
||||
- Remove default runlevel, bz #441315
|
||||
|
||||
* Mon Apr 28 2008 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.22.3-13
|
||||
- Backport patch for CVE-2008-1381 from 1.23.3 to 1.22.3.
|
||||
|
||||
* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 1.22.3-12
|
||||
- Autorebuild for GCC 4.3
|
||||
|
||||
* Thu Jan 3 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-11
|
||||
- Fix compilation on gcc 4.3
|
||||
|
||||
* Thu Dec 6 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-10
|
||||
- Rebuild for new openssl
|
||||
|
||||
* Thu Aug 2 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-8
|
||||
- Fix licence tag
|
||||
|
||||
* Thu Jul 12 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-7
|
||||
- Fixes from testing by Jitz including missing dependencies and database creation
|
||||
|
||||
* Sat Jun 30 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-6
|
||||
- Disable crashtrace on ppc
|
||||
|
||||
* Sat Jun 30 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-5
|
||||
- Fix uid for directories in /var/lib/zoneminder
|
||||
|
||||
* Tue Jun 26 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-4
|
||||
- Added perl Archive::Tar dependency
|
||||
- Disabled web interface due to lack of access control on the event images
|
||||
|
||||
* Sun Jun 10 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-3
|
||||
- Changes recommended in review by Jason Tibbitts
|
||||
|
||||
* Mon Apr 2 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-2
|
||||
- Standardised on package name of zoneminder
|
||||
|
||||
* Thu Dec 28 2006 Martin Ebourne <martin@zepler.org> - 1.22.3-1
|
||||
- First version. Uses some parts from zm-1.20.1 by Corey DeLasaux and Serg Oskin
|
|
@ -15,27 +15,17 @@ else(ZM_TARGET_DISTRO STREQUAL "el7")
|
|||
configure_file(zoneminder.el6.conf.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.el6.conf @ONLY)
|
||||
endif(ZM_TARGET_DISTRO STREQUAL "el7")
|
||||
|
||||
# Download jscalendar & move files into position
|
||||
file(DOWNLOAD http://iweb.dl.sourceforge.net/project/jscalendar/jscalendar/1.0/jscalendar-1.0.zip ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar-1.0.zip LOG jsc_log STATUS download_jsc)
|
||||
#message(STATUS "Log of jscalender script was: ${jsc_log}")
|
||||
if(download_jsc EQUAL 0)
|
||||
message(STATUS "Jscalander successfully downloaded. Installing...")
|
||||
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ERROR_VARIABLE unzip_jsc)
|
||||
message(STATUS "Status of jscalender script was: ${unzip_jsc}")
|
||||
else(download_jsc EQUAL 0)
|
||||
message(STATUS "Unable to download optional jscalander. Skipping...")
|
||||
endif(download_jsc EQUAL 0)
|
||||
|
||||
# Cambozola is now packaged in zmrepo
|
||||
# Download cambozola & move files into position
|
||||
#file(DOWNLOAD http://www.andywilcock.com/code/cambozola/cambozola-0.931.tar.gz ${CMAKE_CURRENT_SOURCE_DIR}/cambozola-0.931.tar.gz STATUS download_camb)
|
||||
#if(download_camb EQUAL 0)
|
||||
# message(STATUS "Cambozola successfully downloaded. Installing...")
|
||||
# execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cambozola.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ERROR_VARIABLE untar_camb)
|
||||
# message(STATUS "Status of cambozola script was: ${untar_camb}")
|
||||
#else(download_camb EQUAL 0)
|
||||
# message(STATUS "Unable to download optional Cambozola. Skipping...")
|
||||
#endif(download_camb EQUAL 0)
|
||||
# Unpack jscalendar & move files into position
|
||||
message(STATUS "Unpacking and Installing jscalendar...")
|
||||
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar.sh
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
ERROR_VARIABLE unzip_jsc
|
||||
)
|
||||
if("${unzip_jsc}" STREQUAL "")
|
||||
message(STATUS "jscalendar successfully installed.")
|
||||
else("${unzip_jsc}" STREQUAL "")
|
||||
message(FATAL_ERROR "\nAn error occured while jscalendar was being processed:\n${unzip_jsc}")
|
||||
endif("${unzip_jsc}" STREQUAL "")
|
||||
|
||||
# Create several empty folders
|
||||
file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events images temp)
|
||||
|
@ -59,6 +49,8 @@ install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DE
|
|||
|
||||
# Install auxiliary files required to run zoneminder on CentOS
|
||||
install(FILES redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
install(DIRECTORY jscalendar-1.0/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/tools/jscalendar)
|
||||
|
||||
if(ZM_TARGET_DISTRO STREQUAL "el7")
|
||||
install(FILES zoneminder.el7.conf DESTINATION /etc/httpd/conf.d RENAME zoneminder.conf PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||
install(FILES zoneminder.el7.logrotate DESTINATION /etc/logrotate.d RENAME zoneminder PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||
|
@ -70,12 +62,3 @@ else(ZM_TARGET_DISTRO STREQUAL "el7")
|
|||
install(FILES zoneminder.sysvinit DESTINATION /etc/rc.d/init.d RENAME zoneminder PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
|
||||
endif(ZM_TARGET_DISTRO STREQUAL "el7")
|
||||
|
||||
# Install jscalendar
|
||||
if(unzip_jsc STREQUAL "")
|
||||
install(DIRECTORY jscalendar-1.0/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/tools/jscalendar)
|
||||
endif(unzip_jsc STREQUAL "")
|
||||
|
||||
# Install cambozola
|
||||
if(untar_camb STREQUAL "")
|
||||
install(FILES cambozola-0.931/dist/cambozola.jar DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www)
|
||||
endif(untar_camb STREQUAL "")
|
||||
|
|
|
@ -40,11 +40,6 @@ New installs
|
|||
other than zmuser/zmpass then you must now edit /etc/zm.conf. Change
|
||||
ZM_DB_USER and ZM_DB_PASS to the values you created in the previous step.
|
||||
|
||||
Additionally, you must also edit
|
||||
/usr/share/zoneminder/www/api/app/Config/database.php in a similar manner.
|
||||
Scroll down and change login and password to the values you created in the
|
||||
previous step.
|
||||
|
||||
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local
|
||||
timezone. PHP will complain loudly if this is not set, or if it is set
|
||||
incorrectly, and these complaints will show up in the zoneminder logging
|
||||
|
@ -89,9 +84,8 @@ New installs
|
|||
|
||||
Then point your web browser to http://<machine name or ip>/zm
|
||||
|
||||
================================================================================
|
||||
UPGRADES
|
||||
================================================================================
|
||||
Upgrades
|
||||
========
|
||||
|
||||
1. Verify /etc/zm.conf.
|
||||
|
||||
|
@ -105,11 +99,6 @@ New installs
|
|||
Compare /etc/zm.conf to /etc/zm.conf.rpmnew. Verify that zm.conf
|
||||
contains any new config settings that may be in zm.conf.rpmnew.
|
||||
|
||||
Additionally, you must also edit
|
||||
/usr/share/zoneminder/www/api/app/Config/database.php in a similar manner.
|
||||
Scroll down and change login and password to the values you used
|
||||
previsouly.
|
||||
|
||||
2. Verify permissions of the zmuser account.
|
||||
|
||||
Over time, the database account permissions required for normal operation
|
||||
|
|
|
@ -47,10 +47,9 @@ New installs
|
|||
Change ZM_DB_USER and ZM_DB_PASS to the values you created in the previous
|
||||
step.
|
||||
|
||||
Additionally, you must also edit
|
||||
/usr/share/zoneminder/www/api/app/Config/database.php in a similar manner.
|
||||
Scroll down and change login and password to the values you created in the
|
||||
previous step.
|
||||
This version of zoneminder no longer requires you to make a similar change
|
||||
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php
|
||||
This now happens dynamically. Do *not* make any changes to this file.
|
||||
|
||||
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local
|
||||
timezone. PHP will complain loudly if this is not set, or if it is set
|
||||
|
@ -111,10 +110,9 @@ Upgrades
|
|||
Compare /etc/zm/zm.conf to /etc/zm/zm.conf.rpmnew. Verify that zm.conf
|
||||
contains any new config settings that may be in zm.conf.rpmnew.
|
||||
|
||||
Additionally, you must also edit
|
||||
/usr/share/zoneminder/www/api/app/Config/database.php in a similar manner.
|
||||
Scroll down and change login and password to the values you used
|
||||
previsouly.
|
||||
This version of zoneminder no longer requires you to make a similar change
|
||||
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php
|
||||
This now happens dynamically. Do *not* make any changes to this file.
|
||||
|
||||
2. Verify permissions of the zmuser account.
|
||||
|
||||
|
|
Binary file not shown.
|
@ -5,17 +5,23 @@ Maintainer: Dmitry Smirnov <onlyjob@debian.org>
|
|||
Uploaders: Vagrant Cascadian <vagrant@debian.org>
|
||||
Build-Depends: debhelper (>= 9), python-sphinx | python3-sphinx, apache2-dev, dh-linktree
|
||||
,cmake
|
||||
,libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libavdevice-dev
|
||||
,libavcodec-dev, libavformat-dev (>= 3:0.svn20090204), libswscale-dev (>= 3:0.svn20090204), libavutil-dev, libavdevice-dev
|
||||
,libbz2-dev
|
||||
,libgcrypt-dev
|
||||
,libcurl4-gnutls-dev
|
||||
,libgnutls-openssl-dev
|
||||
,libjpeg8-dev|libjpeg9-dev|libjpeg62-turbo-dev,
|
||||
,libjpeg8-dev|libjpeg9-dev|libjpeg62-turbo-dev,
|
||||
,libmysqlclient-dev
|
||||
,libpcre3-dev
|
||||
,libpolkit-gobject-1-dev
|
||||
,libv4l-dev (>= 0.8.3) [!hurd-any]
|
||||
,libvlc-dev
|
||||
,libdate-manip-perl
|
||||
,libdbd-mysql-perl
|
||||
,libphp-serialization-perl
|
||||
,libsys-mmap-perl [!hurd-any]
|
||||
,libwww-perl
|
||||
,libdata-uuid-perl
|
||||
# Unbundled (dh_linktree):
|
||||
,libjs-jquery
|
||||
,libjs-mootools
|
||||
|
@ -37,14 +43,15 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
|
|||
,libmodule-load-conditional-perl
|
||||
,libnet-sftp-foreign-perl
|
||||
# ,libzoneminder-perl (= ${source:Version})
|
||||
,libarchive-zip-perl
|
||||
,libdbd-mysql-perl
|
||||
,libdevice-serialport-perl
|
||||
,libimage-info-perl
|
||||
,libjson-any-perl
|
||||
,libsys-mmap-perl [!hurd-any]
|
||||
,liburi-encode-perl
|
||||
,libwww-perl
|
||||
,libarchive-zip-perl
|
||||
,libdbd-mysql-perl
|
||||
,libdevice-serialport-perl
|
||||
,libimage-info-perl
|
||||
,libjson-any-perl
|
||||
,libsys-mmap-perl [!hurd-any]
|
||||
,liburi-encode-perl
|
||||
,libwww-perl
|
||||
,libdata-uuid-perl
|
||||
,mysql-client | virtual-mysql-client
|
||||
,perl-modules
|
||||
,php5-mysql, php5-gd
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
Alias /zm /usr/share/zoneminder/www
|
||||
|
||||
<Directory /usr/share/zoneminder/www>
|
||||
php_flag register_globals off
|
||||
Options Indexes FollowSymLinks
|
||||
<IfModule mod_dir.c>
|
||||
DirectoryIndex index.php
|
||||
|
|
|
@ -1,9 +1,43 @@
|
|||
zoneminder (1.28.1+1-vivid-SNAPSHOT2015081701) vivid; urgency=medium
|
||||
zoneminder (1.29.0+dfsg-1) unstable; urgency=low
|
||||
|
||||
* include api, switch to cmake build
|
||||
* New upstream release [February 2016] (Closes: #788317, #770851).
|
||||
|
||||
-- Isaac Connor <iconnor@connortechnology.com> Mon, 17 Aug 2015 10:29:23 -0400
|
||||
[ Dmitry Smirnov <onlyjob@debian.org> ]
|
||||
* copyright/Files-Excluded += "onvif/*" due to licensing uncertainty.
|
||||
* Fixed FTBFS when built with dpkg-buildpackage -A (Closes: #806126).
|
||||
* FFmpeg 2.9 support. Thanks, Andreas Cadhalpun. (Closes: #803850).
|
||||
* Use "ffmpeg" instead of "avconv":
|
||||
+ "libav_path.patch" replaced with "default_ffmpeg_path.patch".
|
||||
* zoneminder/Depends:
|
||||
- perl-modules (package-relation-with-perl-modules)
|
||||
- libav-tools
|
||||
* zoneminder/Recommends:
|
||||
+ ffmpeg | libav-tools
|
||||
* Updated Vcs URLs.
|
||||
* Build/install new man pages.
|
||||
* Removed obsolete lintian-overrides.
|
||||
* README: grant "index" right to DB user.
|
||||
* systemd: start after MySQL but do not require the latter.
|
||||
* Added new patch with spelling corrections.
|
||||
* Removed obsolete patches:
|
||||
- 783.patch
|
||||
- 980-fix-image-size.patch
|
||||
- cmake-fix-confpath.patch
|
||||
- cmake.patch
|
||||
- cmake-gnutls.patch
|
||||
- fix-html-export.patch
|
||||
- format-hardening.patch
|
||||
- libv4l1-videodev.h.patch
|
||||
- pod_man_fixes.patch
|
||||
- pod_name_fixes.patch
|
||||
- pod_zmupdate-to-pod2usage.patch
|
||||
- respect-privacy.patch
|
||||
- zmtrigger-plus.patch
|
||||
|
||||
[ Vagrant Cascadian <vagrant@debian.org> ]
|
||||
* Remove myself from Uploaders.
|
||||
|
||||
-- Dmitry Smirnov <onlyjob@debian.org> Tue, 09 Feb 2016 15:40:32 +1100
|
||||
|
||||
zoneminder (1.28.1-8) unstable; urgency=medium
|
||||
|
|
@ -8,7 +8,6 @@ ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin"
|
|||
|
||||
Alias /zm /usr/share/zoneminder/www
|
||||
<Directory /usr/share/zoneminder/www>
|
||||
php_flag register_globals off
|
||||
Options Indexes FollowSymLinks
|
||||
<IfModule mod_dir.c>
|
||||
DirectoryIndex index.php
|
|
@ -5,7 +5,11 @@ Maintainer: Dmitry Smirnov <onlyjob@debian.org>
|
|||
Uploaders: Vagrant Cascadian <vagrant@debian.org>
|
||||
Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apache2-dev, dh-linktree
|
||||
,cmake
|
||||
,libavcodec-ffmpeg-dev, libavformat-ffmpeg-dev, libswscale-ffmpeg-dev, libavutil-ffmpeg-dev, libavdevice-ffmpeg-dev
|
||||
,libavdevice-dev (>= 6:10~)
|
||||
,libavcodec-dev (>= 6:10~)
|
||||
,libavformat-dev (>= 6:10~)
|
||||
,libavutil-dev (>= 6:10~)
|
||||
,libswscale-dev (>= 6:10~)
|
||||
,libbz2-dev
|
||||
,libgcrypt-dev
|
||||
,libcurl4-gnutls-dev
|
||||
|
@ -21,6 +25,9 @@ Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apa
|
|||
,libphp-serialization-perl
|
||||
,libsys-mmap-perl [!hurd-any]
|
||||
,libwww-perl
|
||||
,libdata-uuid-perl
|
||||
,libx264-dev
|
||||
,libmp4v2-dev
|
||||
# Unbundled (dh_linktree):
|
||||
,libjs-jquery
|
||||
,libjs-mootools
|
||||
|
@ -41,30 +48,32 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
|
|||
,libphp-serialization-perl
|
||||
,libmodule-load-conditional-perl
|
||||
,libnet-sftp-foreign-perl
|
||||
,libarchive-zip-perl
|
||||
,libdbd-mysql-perl
|
||||
,libdevice-serialport-perl
|
||||
,libimage-info-perl
|
||||
,libjson-any-perl
|
||||
,libsys-mmap-perl [!hurd-any]
|
||||
,liburi-encode-perl
|
||||
,libwww-perl
|
||||
,libdata-dump-perl
|
||||
,libclass-std-fast-perl
|
||||
,libsoap-wsdl-perl
|
||||
,libio-socket-multicast-perl
|
||||
,libdigest-sha-perl
|
||||
,libsys-cpu-perl, libsys-meminfo-perl
|
||||
,libarchive-zip-perl
|
||||
,libdbd-mysql-perl
|
||||
,libdevice-serialport-perl
|
||||
,libimage-info-perl
|
||||
,libjson-any-perl
|
||||
,libsys-mmap-perl [!hurd-any]
|
||||
,liburi-encode-perl
|
||||
,libwww-perl
|
||||
,libdata-dump-perl
|
||||
,libclass-std-fast-perl
|
||||
,libsoap-wsdl-perl
|
||||
,libio-socket-multicast-perl
|
||||
,libdigest-sha-perl
|
||||
,libsys-cpu-perl, libsys-meminfo-perl
|
||||
,libdata-uuid-perl
|
||||
,mysql-client | virtual-mysql-client
|
||||
,perl-modules
|
||||
,php5-mysql, php5-gd
|
||||
,php5-mysql | php-mysql, php5-gd | php-gd
|
||||
,policykit-1
|
||||
,rsyslog | system-log-daemon
|
||||
,zip
|
||||
Recommends: ${misc:Recommends}
|
||||
,libapache2-mod-php5 | php5-fpm
|
||||
,libapache2-mod-php5 | libapache2-mod-php | php5-fpm | php-fpm
|
||||
,mysql-server | virtual-mysql-server
|
||||
,zoneminder-doc (>= ${source:Version})
|
||||
,ffmpeg
|
||||
Suggests: fcgiwrap, logrotate
|
||||
Description: video camera security and surveillance solution
|
||||
ZoneMinder is intended for use in single or multi-camera video security
|
42
docs/api.rst
42
docs/api.rst
|
@ -130,6 +130,28 @@ depend on it.
|
|||
curl -XDELETE http://server/zm/api/monitors/1.json
|
||||
|
||||
|
||||
Arm/Disarm monitors
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This command will force an alarm on Monitor 1:
|
||||
|
||||
::
|
||||
|
||||
curl http://server/zm/api/monitors/alarm/id:1/command:on.json
|
||||
|
||||
This command will disable the alarm on Monitor 1:
|
||||
|
||||
::
|
||||
|
||||
curl http://server/zm/api/monitors/alarm/id:1/command:off.json
|
||||
|
||||
This command will report the status of the alarm Monitor 1:
|
||||
|
||||
::
|
||||
|
||||
curl http://server/zm/api/monitors/alarm/id:1/command:status.json
|
||||
|
||||
|
||||
Return a list of all events
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -216,6 +238,26 @@ Return a list of events for all monitors within a specified date/time range
|
|||
curl -XGET "http://server/zm/api/events/index/StartTime%20>=:2015-05-15%2018:43:56/EndTime%20<=:208:43:56.json"
|
||||
|
||||
|
||||
Return event count based on times and conditions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The API also supports a handy mechanism to return a count of events for a period of time.
|
||||
|
||||
This returns number of events per monitor that were recorded in the last one hour
|
||||
|
||||
::
|
||||
|
||||
curl "http://server/zm/api/events/consoleEvents/1%20hour.json"
|
||||
|
||||
This returns number of events per monitor that were recorded in the last day where there were atleast 10 frames that were alarms"
|
||||
|
||||
::
|
||||
|
||||
curl "http://server/zm/api/events/consoleEvents/1%20day.json/AlarmFrames >=: 10.json"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Configuration Apis
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -1,37 +1,154 @@
|
|||
Debian
|
||||
======
|
||||
|
||||
A fresh build based on master branch running Debian 7 (wheezy)\:
|
||||
.. contents::
|
||||
|
||||
Easy Way: Debian Jessie
|
||||
-----------------------
|
||||
|
||||
**Step 1:** Setup Sudo
|
||||
|
||||
By default Debian does not come with sudo. Log in as root or use su command.
|
||||
N.B. The instructions below are for setting up sudo for your current account, you can
|
||||
do this as root if you prefer.
|
||||
|
||||
::
|
||||
|
||||
root@host:~# aptitude install -y apache2 mysql-server php5 php5-mysql build-essential libmysqlclient-dev libssl-dev libbz2-dev libpcre3-dev libdbi-perl libarchive-zip-perl libdate-manip-perl libdevice-serialport-perl libmime-perl libpcre3 libwww-perl libdbd-mysql-perl libsys-mmap-perl yasm automake autoconf libjpeg8-dev libjpeg8 apache2-mpm-prefork libapache2-mod-php5 php5-cli libphp-serialization-perl libgnutls-dev libjpeg8-dev libavcodec-dev libavformat-dev libswscale-dev libavutil-dev libv4l-dev libtool ffmpeg libnetpbm10-dev libavdevice-dev libmime-lite-perl dh-autoreconf dpatch;
|
||||
apt-get update
|
||||
apt-get install sudo
|
||||
usermod -a -G sudo <username>
|
||||
exit
|
||||
|
||||
root@host:~# git clone https://github.com/ZoneMinder/ZoneMinder.git zoneminder;
|
||||
root@host:~# cd zoneminder;
|
||||
root@host:~# ln -s distros/debian;
|
||||
root@host:~# dpkg-checkbuilddeps;
|
||||
root@host:~# dpkg-buildpackage;
|
||||
Logout or try ``newgrp`` to reload user groups
|
||||
|
||||
One level above you'll now find a deb package matching the architecture of the build host:
|
||||
**Step 2:** Run sudo and update
|
||||
|
||||
Now run session using sudo and ensure system is updated.
|
||||
::
|
||||
|
||||
root@host:~# ls -1 ~/zoneminder*;
|
||||
/root/zoneminder_1.26.4-1_amd64.changes
|
||||
/root/zoneminder_1.26.4-1_amd64.deb
|
||||
/root/zoneminder_1.26.4-1.dsc
|
||||
/root/zoneminder_1.26.4-1.tar.gz
|
||||
sudo -i
|
||||
apt-get upgrade
|
||||
|
||||
The dpkg command itself does not resolve dependencies. That's what high-level interfaces like aptitude and apt-get are normally for. Unfortunately, unlike RPM, there's no easy way to install a separate deb package not contained with any repository.
|
||||
**Step 3:** Install Apache and MySQL
|
||||
|
||||
These are not dependencies for the package as they could
|
||||
be installed elsewhere.
|
||||
|
||||
To overcome this "limitation" we'll use dpkg only to install the zoneminder package and apt-get to fetch all needed dependencies afterwards. Running dpkg-reconfigure in the end will ensure that the setup scripts e.g. for database provisioning were executed.
|
||||
::
|
||||
|
||||
root@host:~# dpkg -i /root/zoneminder_1.26.4-1_amd64.deb; apt-get install -f;
|
||||
root@host:~# dpkg-reconfigure zoneminder;
|
||||
apt-get install apache2 mysql-server
|
||||
|
||||
**Step 4:** Edit sources.list to add jessie-backports
|
||||
|
||||
Alternatively you may also use gdebi to automatically resolve dependencies during installation:
|
||||
::
|
||||
|
||||
root@host:~# aptitude install -y gdebi;
|
||||
root@host:~# gdebi /root/zoneminder_1.26.4-1_amd64.deb;
|
||||
nano /etc/apt/sources.list
|
||||
|
||||
Add the following to the bottom of the file
|
||||
|
||||
::
|
||||
|
||||
# Backports repository
|
||||
deb http://httpredir.debian.org/debian jessie-backports main contrib non-free
|
||||
|
||||
CTRL+o and <Enter> to save
|
||||
CTRL+x to exit
|
||||
|
||||
**Step 5:** Install ZoneMinder
|
||||
|
||||
::
|
||||
|
||||
apt-get update
|
||||
apt-get install zoneminder
|
||||
|
||||
**Step 6:** Read the Readme
|
||||
|
||||
The rest of the install process is covered in the README.Debian, so feel free to have
|
||||
a read.
|
||||
|
||||
::
|
||||
|
||||
gunzip /usr/share/doc/zoneminder/README.Debian.gz
|
||||
cat /usr/share/doc/zoneminder/README.Debian
|
||||
|
||||
**Step 7:** Setup Database
|
||||
|
||||
Install the zm database and setup the user account. Refer to Hints in Ubuntu install
|
||||
should you choose to change default database user and password.
|
||||
|
||||
::
|
||||
|
||||
cat /usr/share/zoneminder/db/zm_create.sql | sudo mysql --defaults-file=/etc/mysql/debian.cnf
|
||||
echo 'grant lock tables,alter,create,select,insert,update,delete,index on zm.* to 'zmuser'@localhost identified by "zmpass";' | sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql
|
||||
|
||||
** Step 8:** zm.conf Permissions
|
||||
|
||||
Adjust permissions to the zm.conf file to allow web account to access it.
|
||||
|
||||
::
|
||||
|
||||
chgrp -c www-data /etc/zm/zm.conf
|
||||
|
||||
**Step 9:** Setup ZoneMinder service
|
||||
|
||||
::
|
||||
|
||||
systemctl enable zoneminder.service
|
||||
|
||||
**Step 10:** Configure Apache
|
||||
|
||||
The following commands will setup the default /zm virtual directory and configure
|
||||
required apache modules.
|
||||
|
||||
::
|
||||
|
||||
a2enconf zoneminder
|
||||
a2enmod cgi
|
||||
a2enmod rewrite
|
||||
|
||||
**Step 11:** Edit Timezone in PHP
|
||||
|
||||
::
|
||||
|
||||
nano /etc/php5/apache2/php.ini
|
||||
|
||||
Search for [Date] (Ctrl + w then type Date and press Enter) and change
|
||||
date.timezone for your time zone. **Don't forget to remove the ; from in front
|
||||
of date.timezone**
|
||||
|
||||
::
|
||||
|
||||
[Date]
|
||||
; Defines the default timezone used by the date functions
|
||||
; http://php.net/date.timezone
|
||||
date.timezone = America/New_York
|
||||
|
||||
CTRL+o then [Enter] to save
|
||||
|
||||
CTRL+x to exit
|
||||
|
||||
**Step 12:** Start ZoneMinder
|
||||
|
||||
Reload Apache to enable your changes and then start ZoneMinder.
|
||||
|
||||
::
|
||||
|
||||
systemctl reload apache2
|
||||
systemctl start zoneminder
|
||||
|
||||
**Step 13:** Making sure ZoneMinder works
|
||||
|
||||
1. Open up a browser and go to ``http://hostname_or_ip/zm`` - should bring up ZoneMinder Console
|
||||
|
||||
2. (Optional API Check)Open up a tab in the same browser and go to ``http://hostname_or_ip/zm/api/host/getVersion.json``
|
||||
|
||||
If it is working correctly you should get version information similar to the example below:
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"version": "1.29.0",
|
||||
"apiversion": "1.29.0.1"
|
||||
}
|
||||
|
||||
**Congratulations** Your installation is complete
|
||||
|
|
|
@ -1,289 +1,269 @@
|
|||
Ubuntu Instruction
|
||||
===================
|
||||
Ubuntu
|
||||
======
|
||||
|
||||
.. contents::
|
||||
|
||||
Easy Way: Install ZoneMinder from a package (Ubuntu 15.x+)
|
||||
-----------------------------------------------------------
|
||||
These instructions are for a brand new ubuntu 15.04 system which does not have ZM installed.
|
||||
Easy Way: Ubuntu 16.04
|
||||
----------------------
|
||||
These instructions are for a brand new ubuntu 16.04 system which does not have ZM
|
||||
installed.
|
||||
|
||||
**Step 1**: Make sure we add the correct packages
|
||||
|
||||
It is recommended that you use an Ubuntu Server install and select the LAMP option
|
||||
during install to install Apache, MySQL and PHP. If you failed to do this you can
|
||||
achieve the same result by running:
|
||||
|
||||
::
|
||||
|
||||
sudo add-apt-repository ppa:iconnor/zoneminder
|
||||
sudo apt-get update
|
||||
tasksel install lamp-server
|
||||
|
||||
if you don't have mysql already installed:
|
||||
During installation it will ask you to set up a master/root password for the MySQL.
|
||||
|
||||
**Step 1:** Either run commands in this install using sudo or use the below to become root
|
||||
::
|
||||
|
||||
sudo -i
|
||||
|
||||
**Step 2:** Update Repos
|
||||
|
||||
.. topic :: Latest Release
|
||||
|
||||
ZoneMinder 1.29.0 is now part of the current standard Ubuntu repository. But
|
||||
if you wish to install the later releases of ZoneMinder you will need
|
||||
to add the iconnor/zoneminder PPA.
|
||||
|
||||
::
|
||||
|
||||
add-apt-repository ppa:iconnor/zoneminder
|
||||
|
||||
Update repo and upgrade.
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install mysql-server
|
||||
apt-get update
|
||||
apt-get upgrade
|
||||
apt-get dist-upgrade
|
||||
|
||||
This will ask you to set up a master password for the DB (you are asked for the mysql root password when installing mysql server).
|
||||
**Step 3:** Configure MySQL
|
||||
|
||||
**Step 2**: Install ZoneMinder
|
||||
.. sidebar :: Note
|
||||
|
||||
The MySQL default configuration file (/etc/mysql/mysql.cnf)is read through
|
||||
several symbolic links beginning with /etc/mysql/my.cnf as follows:
|
||||
|
||||
| /etc/mysql/my.cnf -> /etc/alternatives/my.cnf
|
||||
| /etc/alternatives/my.cnf -> /etc/mysql/mysql.cnf
|
||||
| /etc/mysql/mysql.cnf is a basic file
|
||||
|
||||
Certain new defaults in MySQL 5.7 are currently causing some issues with ZoneMinder,
|
||||
the workaround is to modify the sql_mode setting of MySQL.
|
||||
|
||||
To better manage the MySQL server it is recommended to copy the sample config file and
|
||||
replace the default my.cnf symbolic link.
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install zoneminder
|
||||
rm /etc/mysql/my.cnf (this removes the current symbolic link)
|
||||
cp /etc/mysql/mysql.conf.d/mysqld.cnf /etc/mysql/my.cnf
|
||||
|
||||
**Step 3**: Configure the Database
|
||||
To change MySQL settings:
|
||||
|
||||
::
|
||||
|
||||
sudo mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
|
||||
nano /etc/mysql/my.cnf
|
||||
|
||||
In the [mysqld] section add the following
|
||||
|
||||
::
|
||||
|
||||
sql_mode = NO_ENGINE_SUBSTITUTION
|
||||
|
||||
CTRL+o then [Enter] to save
|
||||
|
||||
CTRL+x to exit
|
||||
|
||||
Restart MySQL
|
||||
|
||||
::
|
||||
|
||||
systemctl restart mysql
|
||||
|
||||
|
||||
**Step 4:** Install ZoneMinder
|
||||
|
||||
::
|
||||
|
||||
apt-get install zoneminder
|
||||
|
||||
**Step 5:** Configure the ZoneMinder Database
|
||||
|
||||
::
|
||||
|
||||
mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
|
||||
mysql -uroot -p -e "grant select,insert,update,delete,create,alter,index,lock tables on zm.* to 'zmuser'@localhost identified by 'zmpass';"
|
||||
|
||||
You don't really need this, but no harm (needed if you are upgrading)
|
||||
|
||||
**Step 6:** Set permissions
|
||||
|
||||
Set /etc/zm/zm.conf to root:www-data 740 and www-data access to content
|
||||
|
||||
::
|
||||
|
||||
sudo /usr/bin/zmupdate.pl
|
||||
chmod 740 /etc/zm/zm.conf
|
||||
chown root:www-data /etc/zm/zm.conf
|
||||
chown -R www-data:www-data /usr/share/zoneminder/
|
||||
|
||||
**Step 4**: Configure systemd to recognize ZoneMinder and configure Apache correctly:
|
||||
**Step 7:** Configure Apache correctly:
|
||||
|
||||
::
|
||||
|
||||
sudo systemctl enable zoneminder
|
||||
sudo a2enconf zoneminder
|
||||
sudo a2enmod cgi
|
||||
sudo chown -R www-data:www-data /usr/share/zoneminder/
|
||||
a2enconf zoneminder
|
||||
a2enmod cgi
|
||||
a2enmod rewrite
|
||||
|
||||
|
||||
We need this for API routing to work:
|
||||
**Step 8:** Enable and start Zoneminder
|
||||
|
||||
::
|
||||
|
||||
sudo a2enmod rewrite
|
||||
systemctl enable zoneminder
|
||||
systemctl start zoneminder
|
||||
|
||||
This is probably a bug with iconnor's PPA as of Oct 3, 2015 with package 1.28.107. After installing, ``zm.conf`` does not have the right read permissions, so we need to fix that. This may go away in future PPA releases:
|
||||
**Step 9:** Edit Timezone in PHP
|
||||
|
||||
::
|
||||
|
||||
sudo chown www-data:www-data /etc/zm/zm.conf
|
||||
nano /etc/php/7.0/apache2/php.ini
|
||||
|
||||
We also need to install php5-gd (as of 1.28.107, this is not installed)
|
||||
Search for [Date] (Ctrl + w then type Date and press Enter) and change
|
||||
date.timezone for your time zone, see [this](http://php.net/manual/en/timezones.php).
|
||||
**Don't forget to remove the ; from in front of date.timezone**
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install php5-gd
|
||||
[Date]
|
||||
; Defines the default timezone used by the date functions
|
||||
; http://php.net/date.timezone
|
||||
date.timezone = America/New_York
|
||||
|
||||
**Step 5**: Edit Timezone in PHP
|
||||
CTRL+o then [Enter] to save
|
||||
|
||||
CTRL+x to exit
|
||||
|
||||
**Step 10:** Reload Apache service
|
||||
|
||||
::
|
||||
|
||||
vi /etc/php5/apache2/php.ini
|
||||
systemctl reload apache2
|
||||
|
||||
Look for [Date] and inside it you will see a date.timezone
|
||||
that is commented. remove the comment and specific your timezone.
|
||||
Please make sure the timezone is valid (see this: http://php.net/manual/en/timezones.php)
|
||||
**Step 11:** Making sure ZoneMinder works
|
||||
|
||||
In my case:
|
||||
1. Open up a browser and go to ``http://hostname_or_ip/zm`` - should bring up ZoneMinder Console
|
||||
|
||||
::
|
||||
2. (Optional API Check)Open up a tab in the same browser and go to ``http://hostname_or_ip/zm/api/host/getVersion.json``
|
||||
|
||||
date.timezone = America/New_York
|
||||
If it is working correctly you should get version information similar to the example below:
|
||||
|
||||
**Step 6**: Restart services
|
||||
::
|
||||
|
||||
::
|
||||
{
|
||||
"version": "1.29.0",
|
||||
"apiversion": "1.29.0.1"
|
||||
}
|
||||
|
||||
sudo service apache2 reload
|
||||
sudo systemctl restart zoneminder
|
||||
**Congratulations** Your installation is complete
|
||||
|
||||
PPA install may need some tweaking of ZMS_PATH in ZoneMinder options. `Socket_sendto or no live streaming`_
|
||||
|
||||
**Step 7: make sure live streaming works**: Make sure you can view Monitor streams:
|
||||
|
||||
startup ZM console in your browser, go to ``Options->Path`` and make sure ``PATH_ZMS`` is set to ``/zm/cgi-bin/nph-zms`` and restart ZM (you should not need to do this for packages, as this should automatically work)
|
||||
|
||||
|
||||
**Step 8**: If you have changed your DB login/password from zmuser/zmpass, the API won't know about it
|
||||
|
||||
If you changed the DB password **after** installing ZM, the APIs will not be able to connect to the DB.
|
||||
|
||||
If you have, go to ``zoneminder/www/api/app/Config`` & Edit ``database.php``
|
||||
|
||||
There is a class there called ``DATABASE_CONFIG`` - change the ``$default`` array to reflect your new details. Example:
|
||||
|
||||
::
|
||||
|
||||
public $default = array(
|
||||
'datasource' => 'Database/Mysql',
|
||||
'persistent' => false,
|
||||
'host' => 'localhost',
|
||||
'login' => 'mynewDBusername',
|
||||
'password' => 'mynewDBpassword'
|
||||
'database' => 'zm',
|
||||
'prefix' => '',
|
||||
//'encoding' => 'utf8',
|
||||
);
|
||||
|
||||
|
||||
You are done. Lets proceed to make sure everything works:
|
||||
|
||||
Making sure ZM and APIs work:
|
||||
|
||||
1. open up a browser and go to ``http://localhost/zm`` - should bring up ZM
|
||||
2. (OPTIONAL - just for peace of mind) open up a tab and go to ``http://localhost/zm/api`` - should bring up a screen showing CakePHP version with some green color boxes. Green is good. If you see red, or you don't see green, there may be a problem (should not happen). Ignore any warnings in yellow saying "DebugKit" not installed. You don't need it
|
||||
3. open up a tab in the same browser and go to ``http://localhost/zm/api/host/getVersion.json``
|
||||
|
||||
If it responds with something like:
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"version": "1.28.107",
|
||||
"apiversion": "1.28.107.1"
|
||||
}
|
||||
|
||||
|
||||
**Then your APIs are working**
|
||||
|
||||
Make sure ZM and APIs work with security:
|
||||
1. Enable OPT_AUTH in ZM
|
||||
2. Log out of ZM in browser
|
||||
3. Open a NEW tab in the SAME BROWSER (important) and go to ``http://localhost/zm/api/host/getVersion.json`` - should give you "Unauthorized" along with a lot more of text
|
||||
4. Go to another tab in the SAME BROWSER (important) and log into ZM
|
||||
5. Repeat step 3 and it should give you the ZM and API version
|
||||
|
||||
**Congrats** your installation is complete
|
||||
|
||||
|
||||
Easy Way: Install ZoneMinder from a package (Ubuntu 14.x)
|
||||
-----------------------------------------------------------
|
||||
Easy Way: Ubuntu 14.x
|
||||
---------------------
|
||||
**These instructions are for a brand new ubuntu 14.x system which does not have ZM installed.**
|
||||
|
||||
**Step 1:** Install ZoneMinder
|
||||
**Step 1:** Either run commands in this install using sudo or use the below to become root
|
||||
|
||||
::
|
||||
|
||||
sudo add-apt-repository ppa:iconnor/zoneminder
|
||||
sudo apt-get update
|
||||
sudo apt-get install zoneminder
|
||||
sudo -i
|
||||
|
||||
**Step 2:** Install ZoneMinder
|
||||
|
||||
::
|
||||
|
||||
add-apt-repository ppa:iconnor/zoneminder
|
||||
apt-get update
|
||||
apt-get install zoneminder
|
||||
|
||||
(just press OK for the prompts you get)
|
||||
|
||||
**Step 2:** Set up DB
|
||||
**Step 3:** Set up DB
|
||||
|
||||
::
|
||||
|
||||
sudo mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
|
||||
mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
|
||||
mysql -uroot -p -e "grant select,insert,update,delete,create,alter,index,lock tables on zm.* to 'zmuser'@localhost identified by 'zmpass';"
|
||||
|
||||
**Step 3:** Set up Apache
|
||||
**Step 4:** Set up Apache
|
||||
|
||||
::
|
||||
|
||||
sudo a2enconf zoneminder
|
||||
sudo a2enmod rewrite
|
||||
sudo a2enmod cgi
|
||||
a2enconf zoneminder
|
||||
a2enmod rewrite
|
||||
a2enmod cgi
|
||||
|
||||
**Step 4:**:Some tweaks that will be needed:
|
||||
|
||||
Edit ``/etc/init.d/zoneminder``:
|
||||
|
||||
add a ``sleep 10`` right after line 25 that reads ``echo -n "Starting $prog:"``
|
||||
(The reason we need this sleep is to make sure ZM starts after mysqld starts)
|
||||
|
||||
As of Oct 3 2015, zm.conf is not readable by ZM. This is likely a bug and will go away in the next package
|
||||
**Step 5:** Make zm.conf readable by web user.
|
||||
|
||||
::
|
||||
|
||||
sudo chown www-data:www-data /etc/zm/zm.conf
|
||||
|
||||
|
||||
|
||||
**Step 5**: If you have changed your DB login/password
|
||||
|
||||
If you changed the DB password **after** installing ZM, the APIs will not be able to connect to the DB.
|
||||
|
||||
If you have, go to ``/usr/share/zoneminder/www/api/app/Config`` & Edit ``database.php``
|
||||
|
||||
There is a class there called ``DATABASE_CONFIG`` - change the ``$default`` array to reflect your new details. Example:
|
||||
**Step 6:** Edit Timezone in PHP
|
||||
|
||||
::
|
||||
|
||||
public $default = array(
|
||||
'datasource' => 'Database/Mysql',
|
||||
'persistent' => false,
|
||||
'host' => 'localhost',
|
||||
'login' => 'mynewDBusername',
|
||||
'password' => 'mynewDBpassword'
|
||||
'database' => 'zm',
|
||||
'prefix' => '',
|
||||
//'encoding' => 'utf8',`
|
||||
);
|
||||
nano /etc/php5/apache2/php.ini
|
||||
|
||||
We also need to install php5-gd (as of 1.28.107, this is not installed)
|
||||
Search for [Date] (Ctrl + w then type Date and press Enter) and change
|
||||
date.timezone for your time zone, see [this](http://php.net/manual/en/timezones.php).
|
||||
**Don't forget to remove the ; from in front of date.timezone**
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install php5-gd
|
||||
[Date]
|
||||
; Defines the default timezone used by the date functions
|
||||
; http://php.net/date.timezone
|
||||
date.timezone = America/New_York
|
||||
|
||||
CTRL+o then [Enter] to save
|
||||
|
||||
**Step 6**: Edit Timezone in PHP
|
||||
CTRL+x to exit
|
||||
|
||||
``sudo vi /etc/php5/apache2/php.ini``
|
||||
Look for [Date] and inside it you will see a date.timezone
|
||||
that is commented. remove the comment and specific your timezone.
|
||||
Please make sure the timezone is valid (see [this](http://php.net/manual/en/timezones.php))
|
||||
|
||||
In my case:
|
||||
**Step 7:** Restart Apache service and start ZoneMinder
|
||||
|
||||
::
|
||||
|
||||
date.timezone = America/New_York
|
||||
service apache2 reload
|
||||
service zoneminder start
|
||||
|
||||
|
||||
**Step 7: make sure live streaming works**: Make sure you can view Monitor streams:
|
||||
**Step 8:** Making sure ZoneMinder works
|
||||
|
||||
startup ZM console in your browser, go to ``Options->Path`` and make sure ``PATH_ZMS`` is set to ``/zm/cgi-bin/nph-zms`` and restart ZM (you should not need to do this for packages, as this should automatically work)
|
||||
1. Open up a browser and go to ``http://hostname_or_ip/zm`` - should bring up ZoneMinder Console
|
||||
|
||||
2. (Optional API Check)Open up a tab in the same browser and go to ``http://hostname_or_ip/zm/api/host/getVersion.json``
|
||||
|
||||
If it is working correctly you should get version information similar to the example below:
|
||||
|
||||
restart:
|
||||
|
||||
::
|
||||
|
||||
sudo service apache2 restart
|
||||
sudo service zoneminder restart
|
||||
|
||||
**Step 8**: Making sure ZM and APIs work: (optional - only if you need APIs)
|
||||
|
||||
1. open up a browser and go to ``http://localhost/zm`` - should bring up ZM
|
||||
2. (OPTIONAL - just for peace of mind) open up a tab and go to ``http://localhost/zm/api`` - should bring up a screen showing CakePHP version with some green color boxes. Green is good. If you see red, or you don't see green, there may be a problem (should not happen). Ignore any warnings in yellow saying "DebugKit" not installed. You don't need it
|
||||
3. open up a tab in the same browser and go to ``http://localhost/zm/api/host/getVersion.json``
|
||||
|
||||
If it responds with something like:
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"version": "1.28.107",
|
||||
"apiversion": "1.28.107.1"
|
||||
}
|
||||
|
||||
Then your APIs are working
|
||||
|
||||
Make sure you can view Monitor View:
|
||||
1. Open up ZM, configure your monitors and verify you can view Monitor feeds.
|
||||
2. If not, open up ZM console in your browser, go to ``Options->Path`` and make sure ``PATH_ZMS`` is set to ``/zm/cgi-bin/nph-zms`` and restart ZM (you should not need to do this for packages, as this should automatically work)
|
||||
|
||||
Make sure ZM and APIs work with security:
|
||||
1. Enable OPT_AUTH in ZM
|
||||
2. Log out of ZM in browser
|
||||
3. Open a NEW tab in the SAME BROWSER (important) and go to ``http://localhost/zm/api/host/getVersion.json`` - should give you "Unauthorized" along with a lot more of text
|
||||
4. Go to another tab in the SAME BROWSER (important) and log into ZM
|
||||
5. Repeat step 3 and it should give you the ZM and API version
|
||||
|
||||
**Congrats** Your installation is complete
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"version": "1.29.0",
|
||||
"apiversion": "1.29.0.1"
|
||||
}
|
||||
|
||||
**Congratulations** Your installation is complete
|
||||
|
||||
Harder Way: Build Package From Source
|
||||
-------------------------------------------
|
||||
-------------------------------------
|
||||
(These instructions assume installation from source on a ubuntu 15.x+ system)
|
||||
|
||||
**Step 1:** Grab the package installer script
|
||||
|
@ -314,12 +294,21 @@ To build the latest stable release:
|
|||
|
||||
::
|
||||
|
||||
./do_debian_package.sh `lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'` `date +%Y%m%d`01 local stable
|
||||
./do_debian_package.sh `lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'` `date +%Y%m%d`01 local stable
|
||||
|
||||
|
||||
Note that the ``lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'`` part simply extracts your distribution name - like "vivid", "trusty" etc. You can always replace it by your distro name if you know it. As far as the script goes, it checks if your distro is "trusty" in which case it pulls in pre-systemd release configurations and if its not "trusty" it assumes its based on systemd and pulls in systemd related config files.
|
||||
Note that the ``lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'``
|
||||
part simply extracts your distribution name - like "vivid", "trusty" etc. You
|
||||
can always replace it by your distro name if you know it. As far as the script
|
||||
goes, it checks if your distro is "trusty" in which case it pulls in pre-systemd
|
||||
release configurations and if its not "trusty" it assumes its based on systemd
|
||||
and pulls in systemd related config files.
|
||||
|
||||
(At the end the script will ask if you want to retain the checked out version of zoneminder. If you are a developer and are making local changes, make sure you select "y" so that the next time you do the build process mentioned here, it keeps your changes. Selecting any other value than "y" or "Y" will delete the checked out code and only retain the package)
|
||||
(At the end the script will ask if you want to retain the checked out version of
|
||||
ZoneMinder. If you are a developer and are making local changes, make sure you
|
||||
select "y" so that the next time you do the build process mentioned here, it
|
||||
keeps your changes. Selecting any other value than "y" or "Y" will delete the
|
||||
checked out code and only retain the package)
|
||||
|
||||
This should now create a bunch of .deb files
|
||||
|
||||
|
@ -335,57 +324,58 @@ This should now create a bunch of .deb files
|
|||
|
||||
**Step 5:** Post install configuration
|
||||
|
||||
::
|
||||
Now that you have installed from your own package you can resume following the
|
||||
standard install guide for your version, start at the step after Install Zoneminder.
|
||||
|
||||
sudo mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
|
||||
mysql -uroot -p -e "grant select,insert,update,delete,create,alter,index,lock tables on zm.* to 'zmuser'@localhost identified by 'zmpass';"
|
||||
Hints
|
||||
-----
|
||||
Make sure ZoneMinder and APIs work with security
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
sudo a2enmod cgi rewrite
|
||||
sudo a2enconf zoneminder
|
||||
1. Enable OPT_AUTH in ZoneMinder
|
||||
2. Log out of ZoneMinder in browser
|
||||
3. Open a new tab in the *same browser* (important) and go to
|
||||
``http://localhost/zm/api/host/getVersion.json`` - should give you "Unauthorized"
|
||||
along with a lot more of text
|
||||
4. Go to another tab in the SAME BROWSER (important) and log into ZM
|
||||
5. Repeat step 3 and it should give you the ZM and API version
|
||||
|
||||
Socket_sendto or no live streaming
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
After you have setup your camera make sure you can view Monitor streams, if not
|
||||
check some of the common causes:
|
||||
|
||||
* Check Apache cgi module is enabled.
|
||||
* Check Apache /etc/apache2/conf-enabled/zoneminder.conf ScriptAlias matches PATH_ZMS.
|
||||
|
||||
ScriptAlias **/zm/cgi-bin** /usr/lib/zoneminder/cgi-bin
|
||||
|
||||
From console go to ``Options->Path`` and make sure PATH_ZMS is set to **/zm/cgi-bin/**\ nph-zms.
|
||||
|
||||
|
||||
Changed Default DB User
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**Step 6:** Fix PHP TimeZone
|
||||
If you have changed your DB login/password from zmuser/zmpass, you need to
|
||||
update these values in zm.conf and the API's database.php file.
|
||||
|
||||
``sudo vi /etc/php5/apache2/php.ini``
|
||||
1. Edit zm.conf to change ZM_DB_USER and ZM_DB_PASS to the values you used.
|
||||
|
||||
Look for [Date] and inside it you will see a date.timezone that is commented. remove the comment and specific your timezone. Please make sure the timezone is valid (see http://php.net/manual/en/timezones.php)
|
||||
2. Edit databse.php which can be found in the web server folder zoneminder/www/api/app/Config
|
||||
|
||||
Example:
|
||||
|
||||
``date.timezone = America/New_York``
|
||||
|
||||
**Step 7:** Fix some key permission issues and make sure API works
|
||||
There is a class there called DATABASE_CONFIG -
|
||||
change the $default array to reflect your new details. Example:
|
||||
|
||||
::
|
||||
|
||||
sudo chown www-data /etc/zm/zm.conf
|
||||
sudo chown -R www-data /usr/share/zoneminder/www/api/
|
||||
|
||||
|
||||
**Step 8:** Restart all services
|
||||
|
||||
::
|
||||
|
||||
sudo service apache2 restart
|
||||
sudo service zoneminder restart
|
||||
|
||||
Check if ZM is running properly
|
||||
|
||||
::
|
||||
|
||||
sudo service zoneminder status
|
||||
|
||||
|
||||
**Step 9:** Make sure streaming works - set PATH_ZMS
|
||||
|
||||
open up ZM console in your browser, go to Options->Path and make sure ``PATH_ZMS`` is set to ``/zm/cgi-bin/nph-zms`` and restart ZM
|
||||
|
||||
|
||||
**Step 10:** Make sure everything works
|
||||
|
||||
* point your browser to http://yourzmip/zm - you should see ZM console running
|
||||
* point your browser to http://yourzmip/zm/api/host/getVersion.json - you should see an API version
|
||||
* Configure your monitors and make sure its all a-ok
|
||||
|
||||
|
||||
public $default = array(
|
||||
'datasource' => 'Database/Mysql',
|
||||
'persistent' => false,
|
||||
'host' => 'localhost',
|
||||
'login' => 'mynewDBusername',
|
||||
'password' => 'mynewDBpassword'
|
||||
'database' => 'zm',
|
||||
'prefix' => '',
|
||||
//'encoding' => 'utf8',
|
||||
);
|
|
@ -10,6 +10,7 @@ If you have changed the value of an option you should then ‘save’ it. A numb
|
|||
options/options_display
|
||||
options/options_system
|
||||
options/options_config
|
||||
options/options_servers
|
||||
options/options_paths
|
||||
options/options_web
|
||||
options/options_images
|
||||
|
|
|
@ -61,16 +61,19 @@ sub _notify_response
|
|||
}
|
||||
|
||||
sub send_multi() {
|
||||
my ($self, $address, $port, $data) = @_;
|
||||
my ($self, $address, $port, $utf8_string) = @_;
|
||||
|
||||
my $destination = $address . ':' . $port;
|
||||
my $socket = IO::Socket::Multicast->new(PROTO => 'udp',
|
||||
LocalPort=>$port, PeerAddr=>$destination, ReuseAddr=>1)
|
||||
|
||||
or die 'Cannot open multicast socket to ' . ${address} . ':' . ${port};
|
||||
|
||||
my $bytes = $utf8_string;
|
||||
utf8::encode($bytes);
|
||||
|
||||
$socket->mcast_ttl(1);
|
||||
$socket->send($data);
|
||||
$socket->send($bytes);
|
||||
}
|
||||
|
||||
sub receive_multi() {
|
||||
|
@ -142,17 +145,18 @@ sub send_receive {
|
|||
}
|
||||
|
||||
if($last_response) {
|
||||
$self->code();
|
||||
$self->message();
|
||||
$self->is_success(1);
|
||||
$self->status('OK');
|
||||
$self->set_code();
|
||||
$self->set_message("");
|
||||
$self->set_is_success(1);
|
||||
$self->set_status('OK');
|
||||
}
|
||||
else{
|
||||
$self->code();
|
||||
$self->message();
|
||||
$self->is_success(0);
|
||||
$self->status('TIMEOUT');
|
||||
$self->set_code();
|
||||
$self->set_message("Timed out waiting for response");
|
||||
$self->set_is_success(0);
|
||||
$self->set_status('TIMEOUT');
|
||||
}
|
||||
|
||||
return $last_response;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
package WSDiscovery10::Elements::Header;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
||||
__PACKAGE__->_set_element_form_qualified(0);
|
||||
|
||||
sub get_xmlns { 'http://schemas.xmlsoap.org/soap/envelope/' };
|
||||
|
||||
our $XML_ATTRIBUTE_CLASS;
|
||||
undef $XML_ATTRIBUTE_CLASS;
|
||||
|
||||
sub __get_attr_class {
|
||||
return $XML_ATTRIBUTE_CLASS;
|
||||
}
|
||||
|
||||
use Class::Std::Fast::Storable constructor => 'none';
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
|
||||
|
||||
Class::Std::initialize();
|
||||
|
||||
{ # BLOCK to scope variables
|
||||
|
||||
my %Action_of :ATTR(:get<Action>);
|
||||
my %MessageID_of :ATTR(:get<MessageID>);
|
||||
my %ReplyTo_of :ATTR(:get<ReplyTo>);
|
||||
my %To_of :ATTR(:get<To>);
|
||||
|
||||
__PACKAGE__->_factory(
|
||||
[ qw( Action MessageID ReplyTo To ) ],
|
||||
{
|
||||
'Action' => \%Action_of,
|
||||
'MessageID' => \%MessageID_of,
|
||||
'ReplyTo' => \%ReplyTo_of,
|
||||
'To' => \%To_of,
|
||||
},
|
||||
{
|
||||
'Action' => 'WSDiscovery10::Elements::Action',
|
||||
'MessageID' => 'WSDiscovery10::Elements::MessageID',
|
||||
'ReplyTo' => 'WSDiscovery10::Elements::ReplyTo',
|
||||
'To' => 'WSDiscovery10::Elements::To',
|
||||
},
|
||||
{
|
||||
'Action' => '',
|
||||
'MessageID' => '',
|
||||
'ReplyTo' => '',
|
||||
'To' => '',
|
||||
}
|
||||
);
|
||||
|
||||
} # end BLOCK
|
||||
|
||||
|
||||
1;
|
|
@ -34,7 +34,11 @@ sub ProbeOp {
|
|||
|
||||
},
|
||||
header => {
|
||||
|
||||
'use' => 'literal',
|
||||
namespace => 'http://schemas.xmlsoap.org/ws/2004/08/addressing',
|
||||
encodingStyle => '',
|
||||
parts => [qw( WSDiscovery10::Elements::Header )],
|
||||
|
||||
},
|
||||
headerfault => {
|
||||
|
||||
|
|
|
@ -23,7 +23,12 @@ our $typemap_1 = {
|
|||
'ProbeMatches/ProbeMatch/Types' => 'WSDiscovery10::Types::QNameListType',
|
||||
'ProbeMatches/ProbeMatch/EndpointReference' => 'WSDiscovery10::Types::EndpointReferenceType',
|
||||
'ProbeMatches/ProbeMatch/EndpointReference/ReferenceProperties' => 'WSDiscovery10::Types::ReferencePropertiesType',
|
||||
'ProbeMatches/ProbeMatch/EndpointReference/PortType' => 'WSDiscovery10::Types::AttributedQName'
|
||||
'ProbeMatches/ProbeMatch/EndpointReference/PortType' => 'WSDiscovery10::Types::AttributedQName',
|
||||
'MessageID' => '__SKIP__',
|
||||
'RelatesTo' => '__SKIP__',
|
||||
'To' => '__SKIP__',
|
||||
'Action' => '__SKIP__',
|
||||
'AppSequence' => '__SKIP__',
|
||||
};
|
||||
;
|
||||
|
||||
|
|
|
@ -7,8 +7,10 @@ __PACKAGE__->_set_element_form_qualified(0);
|
|||
|
||||
sub get_xmlns { 'http://schemas.xmlsoap.org/ws/2005/04/discovery' };
|
||||
|
||||
our $XML_ATTRIBUTE_CLASS;
|
||||
undef $XML_ATTRIBUTE_CLASS;
|
||||
our $XML_ATTRIBUTE_CLASS = 'WSDiscovery10::Types::ProbeType::_ProbeType::XmlAttr';
|
||||
|
||||
#our $XML_ATTRIBUTE_CLASS;
|
||||
#undef $XML_ATTRIBUTE_CLASS;
|
||||
|
||||
sub __get_attr_class {
|
||||
return $XML_ATTRIBUTE_CLASS;
|
||||
|
@ -49,11 +51,56 @@ __PACKAGE__->_factory(
|
|||
} # end BLOCK
|
||||
|
||||
|
||||
package WSDiscovery10::Types::ProbeType::_ProbeType::XmlAttr;
|
||||
#use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
|
||||
use Class::Std::Fast::Storable constructor => 'none', cache => 1;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
|
||||
{ # BLOCK to scope variables
|
||||
|
||||
my %Attribs_of :ATTR(:get<Attribs>);
|
||||
|
||||
sub new
|
||||
{
|
||||
my $self = pop @{ Class::Std::Fast::OBJECT_CACHE_REF()->{ $_[0] } };
|
||||
$self = bless \(my $o = Class::Std::Fast::ID()), $_[0]
|
||||
if not defined $self;
|
||||
|
||||
$self->BUILD(${$self}, $_[1]);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub BUILD
|
||||
{
|
||||
my ($self, $ident, $arg_ref) = @_;
|
||||
|
||||
$Attribs_of{$ident} = $arg_ref;
|
||||
}
|
||||
|
||||
# without this no attributes are serialized
|
||||
# SOAP::WSDL::XSD::Typelib::CompexType sub serialize_attr()
|
||||
|
||||
sub as_bool :BOOLIFY { 1 }
|
||||
|
||||
sub serialize()
|
||||
{
|
||||
my $ident = ${ $_[0] };
|
||||
my $option_ref = $_[1];
|
||||
my $attr_str = "";
|
||||
my %attr_hash = %{$Attribs_of{$ident}};
|
||||
|
||||
foreach my $attr (keys %attr_hash)
|
||||
{
|
||||
my $value = $attr_hash{$attr};
|
||||
$attr_str .= " $attr=\"$value\"";
|
||||
}
|
||||
|
||||
return $attr_str;
|
||||
}
|
||||
|
||||
} # end BLOCK
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
@ -25,13 +25,14 @@
|
|||
#
|
||||
|
||||
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 WSDiscovery10::Elements::To;
|
||||
|
||||
require WSDiscovery::TransportUDP;
|
||||
|
||||
|
@ -169,6 +170,8 @@ sub discover
|
|||
## try both soap versions
|
||||
my %services;
|
||||
|
||||
my $uuid_gen = Data::UUID->new();
|
||||
|
||||
if($verbose) {
|
||||
print "Probing for SOAP 1.1\n"
|
||||
}
|
||||
|
@ -177,12 +180,18 @@ sub discover
|
|||
});
|
||||
$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::To->new({ value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' })
|
||||
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";
|
||||
|
||||
|
@ -197,12 +206,22 @@ sub discover
|
|||
});
|
||||
$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.
|
||||
$uuid = $uuid_gen->create_str();
|
||||
|
||||
$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
|
||||
xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl',
|
||||
'xmlns:tds' => 'http://www.onvif.org/ver10/device/wsdl', },
|
||||
Types => 'dn:NetworkVideoTransmitter tds:Device', # QNameListType
|
||||
Scopes => { value => '' },
|
||||
},
|
||||
WSDiscovery10::Elements::To->new({ value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' })
|
||||
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";
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ use warnings;
|
|||
|
||||
require Exporter;
|
||||
require ZoneMinder::Base;
|
||||
use ZoneMinder::ConfigData qw(:all);
|
||||
|
||||
our @ISA = qw(Exporter ZoneMinder::Base);
|
||||
|
||||
|
@ -44,7 +45,12 @@ use vars qw( %Config );
|
|||
our @EXPORT_CONFIG = qw( %Config ); # Get populated by BEGIN
|
||||
|
||||
our %EXPORT_TAGS = (
|
||||
'constants' => [ qw(
|
||||
functions => [ qw(
|
||||
zmConfigLoad
|
||||
loadConfigFromDB
|
||||
saveConfigToDB
|
||||
) ],
|
||||
constants => [ qw(
|
||||
ZM_PID
|
||||
) ]
|
||||
);
|
||||
|
@ -96,20 +102,134 @@ BEGIN
|
|||
}
|
||||
$sth->finish();
|
||||
#$dbh->disconnect();
|
||||
if ( ! exists $Config{ZM_SERVER_ID} ) {
|
||||
$Config{ZM_SERVER_ID} = undef;
|
||||
$sth = $dbh->prepare_cached( 'SELECT * FROM Servers WHERE Name=?' );
|
||||
if ( $Config{ZM_SERVER_NAME} ) {
|
||||
$res = $sth->execute( $Config{ZM_SERVER_NAME} );
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
$Config{ZM_SERVER_ID} = $$result{Id};
|
||||
} elsif ( $Config{ZM_SERVER_HOST} ) {
|
||||
$res = $sth->execute( $Config{ZM_SERVER_HOST} );
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
$Config{ZM_SERVER_ID} = $$result{Id};
|
||||
}
|
||||
$sth->finish();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! exists $Config{ZM_SERVER_ID} ) {
|
||||
$Config{ZM_SERVER_ID} = undef;
|
||||
$sth = $dbh->prepare_cached( 'SELECT * FROM Servers WHERE Name=?' );
|
||||
if ( $Config{ZM_SERVER_NAME} ) {
|
||||
$res = $sth->execute( $Config{ZM_SERVER_NAME} );
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
$Config{ZM_SERVER_ID} = $$result{Id};
|
||||
} elsif ( $Config{ZM_SERVER_HOST} ) {
|
||||
$res = $sth->execute( $Config{ZM_SERVER_HOST} );
|
||||
my $result = $sth->fetchrow_hashref();
|
||||
$Config{ZM_SERVER_ID} = $$result{Id};
|
||||
}
|
||||
}
|
||||
sub loadConfigFromDB {
|
||||
print( "Loading config from DB\n" );
|
||||
my $dbh = ZoneMinder::Database::zmDbConnect();
|
||||
if ( !$dbh ) {
|
||||
print( "Error: unable to load options from database: $DBI::errstr\n" );
|
||||
return( 0 );
|
||||
}
|
||||
my $sql = "select * from Config";
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute()
|
||||
or croak( "Can't execute: ".$sth->errstr() );
|
||||
my $option_count = 0;
|
||||
while( my $config = $sth->fetchrow_hashref() ) {
|
||||
my ( $name, $value ) = ( $config->{Name}, $config->{Value} );
|
||||
#print( "Name = '$name'\n" );
|
||||
my $option = $options_hash{$name};
|
||||
if ( !$option ) {
|
||||
warn( "No option '$name' found, removing" );
|
||||
next;
|
||||
}
|
||||
#next if ( $option->{category} eq 'hidden' );
|
||||
if ( defined($value) ) {
|
||||
if ( $option->{type} == $types{boolean} ) {
|
||||
$option->{value} = $value?"yes":"no";
|
||||
} else {
|
||||
$option->{value} = $value;
|
||||
}
|
||||
}
|
||||
$option_count++;;
|
||||
}
|
||||
$sth->finish();
|
||||
return( $option_count );
|
||||
}
|
||||
|
||||
sub saveConfigToDB {
|
||||
print( "Saving config to DB\n" );
|
||||
my $dbh = ZoneMinder::Database::zmDbConnect();
|
||||
if ( !$dbh )
|
||||
{
|
||||
print( "Error: unable to save options to database: $DBI::errstr\n" );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
my $ac = $dbh->{AutoCommit};
|
||||
$dbh->{AutoCommit} = 0;
|
||||
|
||||
$dbh->do('LOCK TABLE Config WRITE')
|
||||
or croak( "Can't lock Config table: " . $dbh->errstr() );
|
||||
|
||||
my $sql = "delete from Config";
|
||||
my $res = $dbh->do( $sql )
|
||||
or croak( "Can't do '$sql': ".$dbh->errstr() );
|
||||
|
||||
$sql = "replace into Config set Id = ?, Name = ?, Value = ?, Type = ?, DefaultValue = ?, Hint = ?, Pattern = ?, Format = ?, Prompt = ?, Help = ?, Category = ?, Readonly = ?, Requires = ?";
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
foreach my $option ( @options )
|
||||
{
|
||||
#next if ( $option->{category} eq 'hidden' );
|
||||
#print( $option->{name}."\n" ) if ( !$option->{category} );
|
||||
$option->{db_type} = $option->{type}->{db_type};
|
||||
$option->{db_hint} = $option->{type}->{hint};
|
||||
$option->{db_pattern} = $option->{type}->{pattern};
|
||||
$option->{db_format} = $option->{type}->{format};
|
||||
if ( $option->{db_type} eq "boolean" )
|
||||
{
|
||||
$option->{db_value} = ($option->{value} eq "yes")
|
||||
? "1"
|
||||
: "0"
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
$option->{db_value} = $option->{value};
|
||||
}
|
||||
if ( my $requires = $option->{requires} )
|
||||
{
|
||||
$option->{db_requires} = join( ";",
|
||||
map {
|
||||
my $value = $_->{value};
|
||||
$value = ($value eq "yes")
|
||||
? 1
|
||||
: 0
|
||||
if ( $options_hash{$_->{name}}->{db_type} eq "boolean" )
|
||||
; ( "$_->{name}=$value" )
|
||||
} @$requires
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
my $res = $sth->execute(
|
||||
$option->{id},
|
||||
$option->{name},
|
||||
$option->{db_value},
|
||||
$option->{db_type},
|
||||
$option->{default},
|
||||
$option->{db_hint},
|
||||
$option->{db_pattern},
|
||||
$option->{db_format},
|
||||
$option->{description},
|
||||
$option->{help},
|
||||
$option->{category},
|
||||
$option->{readonly} ? 1 : 0,
|
||||
$option->{db_requires}
|
||||
) or croak( "Can't execute: ".$sth->errstr() );
|
||||
}
|
||||
$sth->finish();
|
||||
|
||||
$dbh->do('UNLOCK TABLES');
|
||||
$dbh->{AutoCommit} = $ac;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -121,7 +241,7 @@ ZoneMinder::Config - ZoneMinder configuration module.
|
|||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use ZoneMinder::Config qw(:all);
|
||||
use ZoneMinder::Config qw(:all);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
@ -136,7 +256,25 @@ namespace of the calling program or module.
|
|||
Once the configuration has been imported then configuration variables are
|
||||
defined as constants and can be accessed directory by name, e.g.
|
||||
|
||||
$lang = $Config{ZM_LANG_DEFAULT};
|
||||
$lang = $Config{ZM_LANG_DEFAULT};
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=over 4
|
||||
|
||||
=item loadConfigFromDB ();
|
||||
|
||||
Loads existing configuration from the database (if any) and merges it with
|
||||
the definitions held in this module. This results in the merging of any new
|
||||
configuration and the removal of any deprecated configuration while
|
||||
preserving the existing values of every else.
|
||||
|
||||
=item saveConfigToDB ();
|
||||
|
||||
Saves configuration held in memory to the database. The act of loading and
|
||||
saving configuration is a convenient way to ensure that the configuration
|
||||
held in the database corresponds with the most recent definitions and that
|
||||
all components are using the same set of configuration.
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
|
@ -159,7 +297,7 @@ Copyright (C) 2001-2008 Philip Coombes
|
|||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
|
||||
=cut
|
||||
=cut
|
||||
|
|
|
@ -1,276 +0,0 @@
|
|||
# ==========================================================================
|
||||
#
|
||||
# ZoneMinder Config Admin Module, $Date$, $Revision$
|
||||
# Copyright (C) 2001-2008 Philip Coombes
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ==========================================================================
|
||||
#
|
||||
# This module contains the debug definitions and functions used by the rest
|
||||
# of the ZoneMinder scripts
|
||||
#
|
||||
package ZoneMinder::ConfigAdmin;
|
||||
|
||||
use 5.006;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require Exporter;
|
||||
require ZoneMinder::Base;
|
||||
|
||||
our @ISA = qw(Exporter ZoneMinder::Base);
|
||||
|
||||
# Items to export into callers namespace by default. Note: do not export
|
||||
# names by default without a very good reason. Use EXPORT_OK instead.
|
||||
# Do not simply export all your public functions/methods/constants.
|
||||
|
||||
# This allows declaration use ZoneMinder ':all';
|
||||
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
|
||||
# will save memory.
|
||||
our %EXPORT_TAGS = (
|
||||
'functions' => [ qw(
|
||||
loadConfigFromDB
|
||||
saveConfigToDB
|
||||
) ]
|
||||
);
|
||||
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
|
||||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'functions'} } );
|
||||
|
||||
our @EXPORT = qw();
|
||||
|
||||
our $VERSION = $ZoneMinder::Base::VERSION;
|
||||
|
||||
# ==========================================================================
|
||||
#
|
||||
# Configuration Administration
|
||||
#
|
||||
# ==========================================================================
|
||||
|
||||
use ZoneMinder::Config qw(:all);
|
||||
use ZoneMinder::ConfigData qw(:all);
|
||||
|
||||
use Carp;
|
||||
|
||||
sub loadConfigFromDB
|
||||
{
|
||||
print( "Loading config from DB\n" );
|
||||
my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
.";host=".$Config{ZM_DB_HOST}
|
||||
,$Config{ZM_DB_USER}
|
||||
,$Config{ZM_DB_PASS}
|
||||
);
|
||||
|
||||
if ( !$dbh )
|
||||
{
|
||||
print( "Error: unable to load options from database: $DBI::errstr\n" );
|
||||
return( 0 );
|
||||
}
|
||||
my $sql = "select * from Config";
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute()
|
||||
or croak( "Can't execute: ".$sth->errstr() );
|
||||
my $option_count = 0;
|
||||
while( my $config = $sth->fetchrow_hashref() )
|
||||
{
|
||||
my ( $name, $value ) = ( $config->{Name}, $config->{Value} );
|
||||
#print( "Name = '$name'\n" );
|
||||
my $option = $options_hash{$name};
|
||||
if ( !$option )
|
||||
{
|
||||
warn( "No option '$name' found, removing" );
|
||||
next;
|
||||
}
|
||||
#next if ( $option->{category} eq 'hidden' );
|
||||
if ( defined($value) )
|
||||
{
|
||||
if ( $option->{type} == $types{boolean} )
|
||||
{
|
||||
$option->{value} = $value?"yes":"no";
|
||||
}
|
||||
else
|
||||
{
|
||||
$option->{value} = $value;
|
||||
}
|
||||
}
|
||||
$option_count++;;
|
||||
}
|
||||
$sth->finish();
|
||||
$dbh->disconnect();
|
||||
return( $option_count );
|
||||
}
|
||||
|
||||
sub saveConfigToDB
|
||||
{
|
||||
print( "Saving config to DB\n" );
|
||||
my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}
|
||||
.";host=".$Config{ZM_DB_HOST}
|
||||
,$Config{ZM_DB_USER}
|
||||
,$Config{ZM_DB_PASS}
|
||||
);
|
||||
|
||||
if ( !$dbh )
|
||||
{
|
||||
print( "Error: unable to save options to database: $DBI::errstr\n" );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
my $ac = $dbh->{AutoCommit};
|
||||
$dbh->{AutoCommit} = 0;
|
||||
|
||||
$dbh->do('LOCK TABLE Config WRITE')
|
||||
or croak( "Can't lock Config table: " . $dbh->errstr() );
|
||||
|
||||
my $sql = "delete from Config";
|
||||
my $res = $dbh->do( $sql )
|
||||
or croak( "Can't do '$sql': ".$dbh->errstr() );
|
||||
|
||||
$sql = "replace into Config set Id = ?, Name = ?, Value = ?, Type = ?, DefaultValue = ?, Hint = ?, Pattern = ?, Format = ?, Prompt = ?, Help = ?, Category = ?, Readonly = ?, Requires = ?";
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or croak( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
foreach my $option ( @options )
|
||||
{
|
||||
#next if ( $option->{category} eq 'hidden' );
|
||||
#print( $option->{name}."\n" ) if ( !$option->{category} );
|
||||
$option->{db_type} = $option->{type}->{db_type};
|
||||
$option->{db_hint} = $option->{type}->{hint};
|
||||
$option->{db_pattern} = $option->{type}->{pattern};
|
||||
$option->{db_format} = $option->{type}->{format};
|
||||
if ( $option->{db_type} eq "boolean" )
|
||||
{
|
||||
$option->{db_value} = ($option->{value} eq "yes")
|
||||
? "1"
|
||||
: "0"
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
$option->{db_value} = $option->{value};
|
||||
}
|
||||
if ( my $requires = $option->{requires} )
|
||||
{
|
||||
$option->{db_requires} = join( ";",
|
||||
map {
|
||||
my $value = $_->{value};
|
||||
$value = ($value eq "yes")
|
||||
? 1
|
||||
: 0
|
||||
if ( $options_hash{$_->{name}}->{db_type} eq "boolean" )
|
||||
; ( "$_->{name}=$value" )
|
||||
} @$requires
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
my $res = $sth->execute(
|
||||
$option->{id},
|
||||
$option->{name},
|
||||
$option->{db_value},
|
||||
$option->{db_type},
|
||||
$option->{default},
|
||||
$option->{db_hint},
|
||||
$option->{db_pattern},
|
||||
$option->{db_format},
|
||||
$option->{description},
|
||||
$option->{help},
|
||||
$option->{category},
|
||||
$option->{readonly} ? 1 : 0,
|
||||
$option->{db_requires}
|
||||
) or croak( "Can't execute: ".$sth->errstr() );
|
||||
}
|
||||
$sth->finish();
|
||||
|
||||
$dbh->do('UNLOCK TABLES');
|
||||
$dbh->{AutoCommit} = $ac;
|
||||
|
||||
$dbh->disconnect();
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ZoneMinder::ConfigAdmin - ZoneMinder Configuration Administration module
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use ZoneMinder::ConfigAdmin;
|
||||
use ZoneMinder::ConfigAdmin qw(:all);
|
||||
|
||||
loadConfigFromDB();
|
||||
saveConfigToDB();
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The ZoneMinder:ConfigAdmin module contains the master definition of the
|
||||
ZoneMinder configuration options as well as helper methods. This module is
|
||||
intended for specialist confguration management and would not normally be
|
||||
used by end users.
|
||||
|
||||
The configuration held in this module, which was previously in zmconfig.pl,
|
||||
includes the name, default value, description, help text, type and category
|
||||
for each option, as well as a number of additional fields in a small number
|
||||
of cases.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=over 4
|
||||
|
||||
=item loadConfigFromDB ();
|
||||
|
||||
Loads existing configuration from the database (if any) and merges it with
|
||||
the definitions held in this module. This results in the merging of any new
|
||||
configuration and the removal of any deprecated configuration while
|
||||
preserving the existing values of every else.
|
||||
|
||||
=item saveConfigToDB ();
|
||||
|
||||
Saves configuration held in memory to the database. The act of loading and
|
||||
saving configuration is a convenient way to ensure that the configuration
|
||||
held in the database corresponds with the most recent definitions and that
|
||||
all components are using the same set of configuration.
|
||||
|
||||
=back
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
None by default.
|
||||
The :data tag will export the various configuration data structures
|
||||
The :functions tag will export the helper functions.
|
||||
The :all tag will export all above symbols.
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
http://www.zoneminder.com
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Philip Coombes, E<lt>philip.coombes@zoneminder.comE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2001-2008 Philip Coombes
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
|
||||
=cut
|
|
@ -1709,6 +1709,17 @@ our @options =
|
|||
type => $types{boolean},
|
||||
category => "config",
|
||||
},
|
||||
{
|
||||
name => 'ZM_LD_PRELOAD',
|
||||
default => '',
|
||||
description => "Path to library to preload before launching daemons",
|
||||
help => qqq("Some older cameras require the use of the v4l1 compat
|
||||
library. This setting allows the setting of the path
|
||||
to the library, so that it can be loaded by zmdc.pl
|
||||
before launching zmc."),
|
||||
type => $types{abs_path},
|
||||
category => 'config',
|
||||
},
|
||||
{
|
||||
name => "ZM_SIGNAL_CHECK_POINTS",
|
||||
default => "10",
|
||||
|
|
|
@ -75,6 +75,10 @@ $| = 1;
|
|||
|
||||
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
|
||||
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
|
||||
if ( $Config{ZM_LD_PRELOAD} ) {
|
||||
Debug("Adding ENV{LD_PRELOAD} = $Config{ZM_LD_PRELOAD}");
|
||||
$ENV{LD_PRELOAD} = $Config{ZM_LD_PRELOAD};
|
||||
}
|
||||
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
|
||||
|
||||
my @daemons = (
|
||||
|
@ -88,7 +92,7 @@ my @daemons = (
|
|||
'zmwatch.pl',
|
||||
'zmupdate.pl',
|
||||
'zmtrack.pl',
|
||||
'zmtelemetry.pl',
|
||||
'zmtelemetry.pl'
|
||||
);
|
||||
|
||||
my $command = shift @ARGV;
|
||||
|
@ -258,7 +262,7 @@ sub run
|
|||
killAll( 1 );
|
||||
|
||||
socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
|
||||
unlink( main::SOCK_FILE ) or Error( "Unable to unlink " . main::SOCK_FILE );
|
||||
unlink( main::SOCK_FILE ) or Error( "Unable to unlink " . main::SOCK_FILE .". Error message was: $!" ) if ( -e main::SOCK_FILE );
|
||||
bind( SERVER, $saddr ) or Fatal( "Can't bind to " . main::SOCK_FILE . ": $!" );
|
||||
listen( SERVER, SOMAXCONN ) or Fatal( "Can't listen: $!" );
|
||||
|
||||
|
@ -370,8 +374,8 @@ sub run
|
|||
.strftime( '%y/%m/%d %H:%M:%S', localtime() )
|
||||
."\n"
|
||||
);
|
||||
unlink( main::SOCK_FILE );
|
||||
unlink( ZM_PID );
|
||||
unlink( main::SOCK_FILE ) or Error( "Unable to unlink " . main::SOCK_FILE .". Error message was: $!" ) if ( -e main::SOCK_FILE );
|
||||
unlink( ZM_PID ) or Error( "Unable to unlink " . ZM_PID .". Error message was: $!" ) if ( -e ZM_PID );
|
||||
exit();
|
||||
}
|
||||
|
||||
|
@ -756,8 +760,8 @@ sub shutdownAll
|
|||
.strftime( '%y/%m/%d %H:%M:%S', localtime() )
|
||||
."\n"
|
||||
);
|
||||
unlink( main::SOCK_FILE );
|
||||
unlink( ZM_PID );
|
||||
unlink( main::SOCK_FILE ) or Error( "Unable to unlink " . main::SOCK_FILE .". Error message was: $!" ) if ( -e main::SOCK_FILE );
|
||||
unlink( ZM_PID ) or Error( "Unable to unlink " . ZM_PID .". Error message was: $!" ) if ( -e ZM_PID );
|
||||
close( CLIENT );
|
||||
close( SERVER );
|
||||
exit();
|
||||
|
|
|
@ -226,7 +226,12 @@ if ( $command =~ /^(?:start|restart)$/ )
|
|||
zmMemTidy();
|
||||
runCommand( "zmdc.pl startup" );
|
||||
|
||||
Info( "Starting up services" . ( $Config{ZM_SERVER_ID} ? " for server $Config{ZM_SERVER_ID}\n" : "\n" ) );
|
||||
if ( $Config{ZM_SERVER_ID} ) {
|
||||
Info( "Multi-server configuration detected. Starting up services for server $Config{ZM_SERVER_ID}\n");
|
||||
} else {
|
||||
Info( "Single server configuration detected. Starting up services." );
|
||||
}
|
||||
|
||||
my $sql = $Config{ZM_SERVER_ID} ? 'SELECT * FROM Monitors WHERE ServerId=?' : 'SELECT * FROM Monitors';
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
|
|
|
@ -71,7 +71,7 @@ if ( $Config{ZM_TELEMETRY_DATA} )
|
|||
{
|
||||
print( "Update agent starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
|
||||
|
||||
my $lastCheck = $Config{ZM_TELEMETRY_LAST_CHECK};
|
||||
my $lastCheck = $Config{ZM_TELEMETRY_LAST_UPLOAD};
|
||||
|
||||
while( 1 ) {
|
||||
my $now = time();
|
||||
|
|
|
@ -72,7 +72,6 @@ use ZoneMinder::Config qw(:all);
|
|||
use ZoneMinder::Logger qw(:all);
|
||||
use ZoneMinder::General qw(:all);
|
||||
use ZoneMinder::Database qw(:all);
|
||||
use ZoneMinder::ConfigAdmin qw( :functions );
|
||||
use POSIX;
|
||||
use DBI;
|
||||
use Getopt::Long;
|
||||
|
@ -155,6 +154,7 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} )
|
|||
my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'";
|
||||
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute( "$currVersion" ) or die( "Can't execute: ".$sth->errstr() );
|
||||
$sth->finish();
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
|
@ -184,10 +184,12 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} )
|
|||
my $lv_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_VERSION'";
|
||||
my $lv_sth = $dbh->prepare_cached( $lv_sql ) or die( "Can't prepare '$lv_sql': ".$dbh->errstr() );
|
||||
my $lv_res = $lv_sth->execute( $lastVersion ) or die( "Can't execute: ".$lv_sth->errstr() );
|
||||
$lv_sth->finish();
|
||||
|
||||
my $lc_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_CHECK'";
|
||||
my $lc_sth = $dbh->prepare_cached( $lc_sql ) or die( "Can't prepare '$lc_sql': ".$dbh->errstr() );
|
||||
my $lc_res = $lc_sth->execute( $lastCheck ) or die( "Can't execute: ".$lc_sth->errstr() );
|
||||
$lc_sth->finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -239,14 +241,14 @@ if ( $zoneFix )
|
|||
}
|
||||
$sth->finish();
|
||||
|
||||
$sql = "update Zones set MinAlarmPixels = ?, MaxAlarmPixels = ?, MinFilterPixels = ?, MaxFilterPixels = ?, MinBlobPixels = ?, MaxBlobPixels = ? where Id = ?";
|
||||
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
foreach my $zone ( @zones )
|
||||
{
|
||||
my $zone_width = (($zone->{HiX}*$zone->{MonitorWidth})-($zone->{LoX}*$zone->{MonitorWidth}))/100;
|
||||
my $zone_height = (($zone->{HiY}*$zone->{MonitorHeight})-($zone->{LoY}*$zone->{MonitorHeight}))/100;
|
||||
my $zone_area = $zone_width * $zone_height;
|
||||
my $monitor_area = $zone->{MonitorWidth} * $zone->{MonitorHeight};
|
||||
my $sql = "update Zones set MinAlarmPixels = ?, MaxAlarmPixels = ?, MinFilterPixels = ?, MaxFilterPixels = ?, MinBlobPixels = ?, MaxBlobPixels = ? where Id = ?";
|
||||
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute(
|
||||
($zone->{MinAlarmPixels}*$monitor_area)/$zone_area,
|
||||
($zone->{MaxAlarmPixels}*$monitor_area)/$zone_area,
|
||||
|
@ -257,6 +259,7 @@ if ( $zoneFix )
|
|||
$zone->{Id}
|
||||
) or die( "Can't execute: ".$sth->errstr() );
|
||||
}
|
||||
$sth->finish();
|
||||
}
|
||||
if ( $migrateEvents )
|
||||
{
|
||||
|
@ -318,11 +321,13 @@ if ( $migrateEvents )
|
|||
symlink( $newTimePath, $idLink ) or die( "Can't symlink $newTimePath -> $idLink: $!" );
|
||||
rename( $oldEventPath, $newEventPath ) or die( "Can't move $oldEventPath -> $newEventPath: $!" );
|
||||
}
|
||||
$sth->finish();
|
||||
|
||||
print( "Updating configuration.\n" );
|
||||
$sql = "update Config set Value = ? where Name = 'ZM_USE_DEEP_STORAGE'";
|
||||
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
$res = $sth->execute( 1 ) or die( "Can't execute: ".$sth->errstr() );
|
||||
$sth->finish();
|
||||
|
||||
print( "All events converted.\n\n" );
|
||||
}
|
||||
|
@ -334,8 +339,8 @@ if ( $migrateEvents )
|
|||
if ( $freshen )
|
||||
{
|
||||
print( "\nFreshening configuration in database\n" );
|
||||
loadConfigFromDB();
|
||||
saveConfigToDB();
|
||||
ZoneMinder::Config::loadConfigFromDB();
|
||||
ZoneMinder::Config::saveConfigToDB();
|
||||
}
|
||||
|
||||
# Don't do innoDB upgrade if not interactive
|
||||
|
@ -360,10 +365,10 @@ if ( $interactive ) {
|
|||
$dbh->do(q|SET sql_mode='traditional'|); # Elevate warnings to errors
|
||||
print "\nConverting MyISAM tables to InnoDB. Please wait.\n";
|
||||
foreach (@MyISAM_Tables) {
|
||||
my $sql = "ALTER TABLE $_ ENGINE = InnoDB";
|
||||
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $sql = "ALTER TABLE $_ ENGINE = InnoDB";
|
||||
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
|
||||
$sth->finish();
|
||||
$sth->finish();
|
||||
}
|
||||
$dbh->do(q|SET sql_mode=''|); # Set mode back to default
|
||||
}
|
||||
|
@ -494,8 +499,8 @@ if ( $version )
|
|||
print( "\nUpgrading database to version ".ZM_VERSION."\n" );
|
||||
|
||||
# Update config first of all
|
||||
loadConfigFromDB();
|
||||
saveConfigToDB();
|
||||
ZoneMinder::Config::loadConfigFromDB();
|
||||
ZoneMinder::Config::saveConfigToDB();
|
||||
|
||||
my $cascade = undef;
|
||||
if ( $cascade || $version eq "1.19.0" )
|
||||
|
@ -1064,6 +1069,7 @@ if ( $version )
|
|||
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
my $res = $sth->execute( "$installed_version", "ZM_DYN_DB_VERSION" ) or die( "Can't execute: ".$sth->errstr() );
|
||||
$res = $sth->execute( "$installed_version", "ZM_DYN_CURR_VERSION" ) or die( "Can't execute: ".$sth->errstr() );
|
||||
$sth->finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
162
src/zm_comms.cpp
162
src/zm_comms.cpp
|
@ -35,6 +35,8 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h> // for debug output
|
||||
#include <stdio.h> // for snprintf
|
||||
|
||||
#ifdef SOLARIS
|
||||
#include <sys/filio.h> // define FIONREAD
|
||||
|
@ -516,6 +518,166 @@ bool Socket::setNoDelay( bool nodelay )
|
|||
return( true );
|
||||
}
|
||||
|
||||
bool InetSocket::connect( const char *host, const char *serv )
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result, *rp;
|
||||
int s;
|
||||
char buf[255];
|
||||
|
||||
mAddressFamily = AF_UNSPEC;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||
hints.ai_socktype = getType();
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_protocol = 0; /* Any protocol */
|
||||
|
||||
s = getaddrinfo(host, serv, &hints, &result);
|
||||
if (s != 0) {
|
||||
Error( "connect(): getaddrinfo: %s", gai_strerror(s) );
|
||||
return( false );
|
||||
}
|
||||
|
||||
/* getaddrinfo() returns a list of address structures.
|
||||
* Try each address until we successfully connect(2).
|
||||
* If socket(2) (or connect(2)) fails, we (close the socket
|
||||
* and) try the next address. */
|
||||
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
if (mSd != -1) {
|
||||
if (::connect(mSd, rp->ai_addr, rp->ai_addrlen) != -1)
|
||||
break; /* Success */
|
||||
continue;
|
||||
}
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (rp->ai_family == AF_INET) {
|
||||
inet_ntop(AF_INET, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, sizeof(buf)-1);
|
||||
}
|
||||
else if (rp->ai_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, buf, sizeof(buf)-1);
|
||||
}
|
||||
else {
|
||||
strncpy(buf, "n/a", sizeof(buf)-1);
|
||||
}
|
||||
Debug( 1, "connect(): Trying '%s', family '%d', proto '%d'", buf, rp->ai_family, rp->ai_protocol);
|
||||
mSd = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (mSd == -1)
|
||||
continue;
|
||||
|
||||
int val = 1;
|
||||
|
||||
(void)::setsockopt( mSd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val) );
|
||||
(void)::setsockopt( mSd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val) );
|
||||
mAddressFamily = rp->ai_family; /* save AF_ for ctrl and data connections */
|
||||
|
||||
if (::connect(mSd, rp->ai_addr, rp->ai_addrlen) != -1)
|
||||
break; /* Success */
|
||||
|
||||
::close(mSd);
|
||||
}
|
||||
|
||||
if (rp == NULL) { /* No address succeeded */
|
||||
Error( "connect(), Could not connect" );
|
||||
mAddressFamily = AF_UNSPEC;
|
||||
return( false );
|
||||
}
|
||||
|
||||
freeaddrinfo(result); /* No longer needed */
|
||||
|
||||
mState = CONNECTED;
|
||||
|
||||
return( true );
|
||||
}
|
||||
|
||||
bool InetSocket::connect( const char *host, int port )
|
||||
{
|
||||
char serv[8];
|
||||
snprintf(serv, sizeof(serv), "%d", port);
|
||||
|
||||
return connect( host, serv );
|
||||
}
|
||||
|
||||
bool InetSocket::bind( const char * host, const char * serv )
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result, *rp;
|
||||
int s;
|
||||
char buf[255];
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||
hints.ai_socktype = getType();
|
||||
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
||||
hints.ai_protocol = 0; /* Any protocol */
|
||||
hints.ai_canonname = NULL;
|
||||
hints.ai_addr = NULL;
|
||||
hints.ai_next = NULL;
|
||||
|
||||
s = getaddrinfo(host, serv, &hints, &result);
|
||||
if (s != 0) {
|
||||
Error( "bind(): getaddrinfo: %s", gai_strerror(s) );
|
||||
return( false );
|
||||
}
|
||||
|
||||
/* getaddrinfo() returns a list of address structures.
|
||||
* Try each address until we successfully bind(2).
|
||||
* If socket(2) (or bind(2)) fails, we (close the socket
|
||||
* and) try the next address. */
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (rp->ai_family == AF_INET) {
|
||||
inet_ntop(AF_INET, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, sizeof(buf)-1);
|
||||
}
|
||||
else if (rp->ai_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr, buf, sizeof(buf)-1);
|
||||
}
|
||||
else {
|
||||
strncpy(buf, "n/a", sizeof(buf)-1);
|
||||
}
|
||||
Debug( 1, "bind(): Trying '%s', family '%d', proto '%d'", buf, rp->ai_family, rp->ai_protocol);
|
||||
mSd = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (mSd == -1)
|
||||
continue;
|
||||
|
||||
mState = DISCONNECTED;
|
||||
if (::bind(mSd, rp->ai_addr, rp->ai_addrlen) == 0)
|
||||
break; /* Success */
|
||||
|
||||
::close(mSd);
|
||||
mSd = -1;
|
||||
}
|
||||
|
||||
if (rp == NULL) { /* No address succeeded */
|
||||
Error( "bind(), Could not bind" );
|
||||
return( false );
|
||||
}
|
||||
|
||||
freeaddrinfo(result); /* No longer needed */
|
||||
|
||||
return( true );
|
||||
}
|
||||
|
||||
bool InetSocket::bind( const char * serv )
|
||||
{
|
||||
return bind( NULL, serv);
|
||||
}
|
||||
|
||||
bool InetSocket::bind( const char * host, int port )
|
||||
{
|
||||
char serv[8];
|
||||
snprintf(serv, sizeof(serv), "%d", port);
|
||||
|
||||
return bind( host, serv );
|
||||
}
|
||||
|
||||
bool InetSocket::bind( int port )
|
||||
{
|
||||
char serv[8];
|
||||
snprintf(serv, sizeof(serv), "%d", port);
|
||||
|
||||
return bind( NULL, serv );
|
||||
}
|
||||
|
||||
bool TcpInetServer::listen()
|
||||
{
|
||||
return( Socket::listen() );
|
||||
|
|
160
src/zm_comms.h
160
src/zm_comms.h
|
@ -399,103 +399,27 @@ public:
|
|||
|
||||
class InetSocket : virtual public Socket
|
||||
{
|
||||
protected:
|
||||
int mAddressFamily;
|
||||
|
||||
public:
|
||||
int getDomain() const
|
||||
{
|
||||
return( AF_INET );
|
||||
}
|
||||
virtual socklen_t getAddrSize() const
|
||||
{
|
||||
return( SockAddrInet::addrSize() );
|
||||
}
|
||||
int getDomain() const
|
||||
{
|
||||
return( mAddressFamily );
|
||||
}
|
||||
virtual socklen_t getAddrSize() const
|
||||
{
|
||||
return( SockAddrInet::addrSize() );
|
||||
}
|
||||
|
||||
protected:
|
||||
bool resolveLocal( const char *host, const char *serv, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mLocalAddr = addr;
|
||||
return( addr->resolve( host, serv, proto ) );
|
||||
}
|
||||
bool resolveLocal( const char *host, int port, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mLocalAddr = addr;
|
||||
return( addr->resolve( host, port, proto ) );
|
||||
}
|
||||
bool resolveLocal( const char *serv, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mLocalAddr = addr;
|
||||
return( addr->resolve( serv, proto ) );
|
||||
}
|
||||
bool resolveLocal( int port, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mLocalAddr = addr;
|
||||
return( addr->resolve( port, proto ) );
|
||||
}
|
||||
bool connect( const char *host, const char *serv );
|
||||
bool connect( const char *host, int port );
|
||||
|
||||
bool resolveRemote( const char *host, const char *serv, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mRemoteAddr = addr;
|
||||
return( addr->resolve( host, serv, proto ) );
|
||||
}
|
||||
bool resolveRemote( const char *host, int port, const char *proto )
|
||||
{
|
||||
SockAddrInet *addr = new SockAddrInet;
|
||||
mRemoteAddr = addr;
|
||||
return( addr->resolve( host, port, proto ) );
|
||||
}
|
||||
|
||||
protected:
|
||||
bool bind( const SockAddrInet &addr )
|
||||
{
|
||||
mLocalAddr = new SockAddrInet( addr );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
if ( !resolveLocal( host, serv, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
bool bind( const char *host, int port )
|
||||
{
|
||||
if ( !resolveLocal( host, port, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
bool bind( const char *serv )
|
||||
{
|
||||
if ( !resolveLocal( serv, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
bool bind( int port )
|
||||
{
|
||||
if ( !resolveLocal( port, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::bind() );
|
||||
}
|
||||
|
||||
bool connect( const SockAddrInet &addr )
|
||||
{
|
||||
mRemoteAddr = new SockAddrInet( addr );
|
||||
return( Socket::connect() );
|
||||
}
|
||||
bool connect( const char *host, const char *serv )
|
||||
{
|
||||
if ( !resolveRemote( host, serv, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::connect() );
|
||||
}
|
||||
bool connect( const char *host, int port )
|
||||
{
|
||||
if ( !resolveRemote( host, port, getProtocol() ) )
|
||||
return( false );
|
||||
return( Socket::connect() );
|
||||
}
|
||||
bool bind( const char *host, const char *serv );
|
||||
bool bind( const char *host, int port );
|
||||
bool bind( const char *serv );
|
||||
bool bind( int port );
|
||||
};
|
||||
|
||||
class UnixSocket : virtual public Socket
|
||||
|
@ -591,10 +515,6 @@ public:
|
|||
class UdpInetSocket : virtual public UdpSocket, virtual public InetSocket
|
||||
{
|
||||
public:
|
||||
bool bind( const SockAddrInet &addr )
|
||||
{
|
||||
return( InetSocket::bind( addr ) );
|
||||
}
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
return( InetSocket::bind( host, serv ) );
|
||||
|
@ -612,10 +532,6 @@ public:
|
|||
return( InetSocket::bind( port ) );
|
||||
}
|
||||
|
||||
bool connect( const SockAddrInet &addr )
|
||||
{
|
||||
return( InetSocket::connect( addr ) );
|
||||
}
|
||||
bool connect( const char *host, const char *serv )
|
||||
{
|
||||
return( InetSocket::connect( host, serv ) );
|
||||
|
@ -642,33 +558,7 @@ public:
|
|||
|
||||
class UdpInetClient : public UdpInetSocket
|
||||
{
|
||||
protected:
|
||||
bool bind( const SockAddrInet &addr )
|
||||
{
|
||||
return( UdpInetSocket::bind( addr ) );
|
||||
}
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
return( UdpInetSocket::bind( host, serv ) );
|
||||
}
|
||||
bool bind( const char *host, int port )
|
||||
{
|
||||
return( UdpInetSocket::bind( host, port ) );
|
||||
}
|
||||
bool bind( const char *serv )
|
||||
{
|
||||
return( UdpInetSocket::bind( serv ) );
|
||||
}
|
||||
bool bind( int port )
|
||||
{
|
||||
return( UdpInetSocket::bind( port ) );
|
||||
}
|
||||
|
||||
public:
|
||||
bool connect( const SockAddrInet &addr )
|
||||
{
|
||||
return( UdpInetSocket::connect( addr ) );
|
||||
}
|
||||
bool connect( const char *host, const char *serv )
|
||||
{
|
||||
return( UdpInetSocket::connect( host, serv ) );
|
||||
|
@ -697,10 +587,6 @@ public:
|
|||
class UdpInetServer : public UdpInetSocket
|
||||
{
|
||||
public:
|
||||
bool bind( const SockAddrInet &addr )
|
||||
{
|
||||
return( UdpInetSocket::bind( addr ) );
|
||||
}
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
return( UdpInetSocket::bind( host, serv ) );
|
||||
|
@ -812,18 +698,6 @@ public:
|
|||
class TcpInetServer : public TcpInetSocket
|
||||
{
|
||||
public:
|
||||
bool bind( const char *host, const char *serv )
|
||||
{
|
||||
return( TcpInetSocket::bind( host, serv ) );
|
||||
}
|
||||
bool bind( const char *host, int port )
|
||||
{
|
||||
return( TcpInetSocket::bind( host, port ) );
|
||||
}
|
||||
bool bind( const char *serv )
|
||||
{
|
||||
return( TcpInetSocket::bind( serv ) );
|
||||
}
|
||||
bool bind( int port )
|
||||
{
|
||||
return( TcpInetSocket::bind( port ) );
|
||||
|
|
|
@ -133,12 +133,11 @@ void zmLoadConfig()
|
|||
} else {
|
||||
Fatal("Can't get ServerName for Server ID %d", staticConfig.SERVER_ID );
|
||||
}
|
||||
|
||||
}
|
||||
if ( ! staticConfig.SERVER_ID ) {
|
||||
Debug( 1, "No Server ID or Name specified in config. Not using Multi-Server Mode." );
|
||||
} else {
|
||||
Debug( 1, "Server is %d: using Multi-Server Mode.", staticConfig.SERVER_ID );
|
||||
if ( staticConfig.SERVER_ID ) {
|
||||
Debug( 3, "Multi-server configuration detected. Server is %d.", staticConfig.SERVER_ID );
|
||||
} else {
|
||||
Debug( 3, "Single server configuration assumed because no Server ID or Name was specified." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -333,7 +333,7 @@ bool Event::OpenFrameSocket( int monitor_id )
|
|||
strncpy( addr.sun_path, sock_path, sizeof(addr.sun_path) );
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
if ( connect( sd, (struct sockaddr *)&addr, strlen(addr.sun_path)+sizeof(addr.sun_family)) < 0 )
|
||||
if ( connect( sd, (struct sockaddr *)&addr, strlen(addr.sun_path)+sizeof(addr.sun_family)+1) < 0 )
|
||||
{
|
||||
Warning( "Can't connect to frame server: %s", strerror(errno) );
|
||||
close( sd );
|
||||
|
|
|
@ -150,11 +150,11 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
|||
Error("NULL Input or output buffer");
|
||||
return -1;
|
||||
}
|
||||
if(in_pf == 0 || out_pf == 0) {
|
||||
Error("Invalid input or output pixel formats");
|
||||
return -2;
|
||||
}
|
||||
if(!width || !height) {
|
||||
// if(in_pf == 0 || out_pf == 0) {
|
||||
// Error("Invalid input or output pixel formats");
|
||||
// return -2;
|
||||
// }
|
||||
if (!width || !height) {
|
||||
Error("Invalid width or height");
|
||||
return -3;
|
||||
}
|
||||
|
@ -170,30 +170,50 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint
|
|||
#endif
|
||||
|
||||
/* Check the buffer sizes */
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
size_t insize = av_image_get_buffer_size(in_pf, width, height,1);
|
||||
#else
|
||||
size_t insize = avpicture_get_size(in_pf, width, height);
|
||||
#endif
|
||||
if(insize != in_buffer_size) {
|
||||
Error("The input buffer size does not match the expected size for the input format. Required: %d Available: %d", insize, in_buffer_size);
|
||||
return -4;
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
size_t outsize = av_image_get_buffer_size(out_pf, width, height,1);
|
||||
#else
|
||||
size_t outsize = avpicture_get_size(out_pf, width, height);
|
||||
#endif
|
||||
if(outsize < out_buffer_size) {
|
||||
Error("The output buffer is undersized for the output format. Required: %d Available: %d", outsize, out_buffer_size);
|
||||
return -5;
|
||||
}
|
||||
|
||||
/* Get the context */
|
||||
swscale_ctx = sws_getCachedContext( NULL, width, height, in_pf, width, height, out_pf, 0, NULL, NULL, NULL );
|
||||
swscale_ctx = sws_getCachedContext(swscale_ctx, width, height, in_pf, width, height, out_pf, 0, NULL, NULL, NULL);
|
||||
if(swscale_ctx == NULL) {
|
||||
Error("Failed getting swscale context");
|
||||
return -6;
|
||||
}
|
||||
|
||||
/* Fill in the buffers */
|
||||
if(!avpicture_fill( (AVPicture*)input_avframe, (uint8_t*)in_buffer, in_pf, width, height ) ) {
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
if (av_image_fill_arrays(input_avframe->data, input_avframe->linesize,
|
||||
(uint8_t*) in_buffer, in_pf, width, height, 1) <= 0) {
|
||||
#else
|
||||
if (avpicture_fill((AVPicture*) input_avframe, (uint8_t*) in_buffer,
|
||||
in_pf, width, height) <= 0) {
|
||||
#endif
|
||||
Error("Failed filling input frame with input buffer");
|
||||
return -7;
|
||||
}
|
||||
if(!avpicture_fill( (AVPicture*)output_avframe, out_buffer, out_pf, width, height ) ) {
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
if (av_image_fill_arrays(output_avframe->data, output_avframe->linesize,
|
||||
out_buffer, out_pf, width, height, 1) <= 0) {
|
||||
#else
|
||||
if (avpicture_fill((AVPicture*) output_avframe, out_buffer, out_pf, width,
|
||||
height) <= 0) {
|
||||
#endif
|
||||
Error("Failed filling output frame with output buffer");
|
||||
return -8;
|
||||
}
|
||||
|
@ -322,8 +342,7 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat
|
|||
}
|
||||
}
|
||||
|
||||
static void zm_log_fps(double d, const char *postfix)
|
||||
{
|
||||
static void zm_log_fps(double d, const char *postfix) {
|
||||
uint64_t v = lrintf(d * 100);
|
||||
if (!v) {
|
||||
Debug(3, "%1.4f %s", d, postfix);
|
||||
|
@ -341,15 +360,8 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
|
|||
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
|
||||
AVStream *st = ic->streams[i];
|
||||
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
||||
unsigned char *separator = ic->dump_separator;
|
||||
char **codec_separator = (char **)av_opt_ptr(st->codec->av_class, st->codec, "dump_separator");
|
||||
int use_format_separator = !*codec_separator;
|
||||
|
||||
if (use_format_separator)
|
||||
*codec_separator = av_strdup((const char *)separator);
|
||||
avcodec_string(buf, sizeof(buf), st->codec, is_output);
|
||||
if (use_format_separator)
|
||||
av_freep(codec_separator);
|
||||
Debug(3, " Stream #%d:%d", index, i);
|
||||
|
||||
/* the pid is an important information, so we display it */
|
||||
|
@ -381,7 +393,7 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
|
|||
int tbc = st->codec->time_base.den && st->codec->time_base.num;
|
||||
|
||||
if (fps || tbr || tbn || tbc)
|
||||
Debug(3, "%s", separator);
|
||||
Debug(3, "\n" );
|
||||
|
||||
if (fps)
|
||||
zm_log_fps(av_q2d(st->avg_frame_rate), tbr || tbn || tbc ? "fps, " : "fps");
|
||||
|
|
|
@ -48,6 +48,10 @@ extern "C" {
|
|||
#else
|
||||
#include <libavcodec/opt.h>
|
||||
#endif
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
#include <libavutil/imgutils.h>
|
||||
#endif
|
||||
#elif HAVE_FFMPEG_AVUTIL_H
|
||||
#include <ffmpeg/avutil.h>
|
||||
#include <ffmpeg/base64.h>
|
||||
|
|
|
@ -192,9 +192,14 @@ int FfmpegCamera::Capture( Image &image )
|
|||
if ( frameComplete )
|
||||
{
|
||||
Debug( 3, "Got frame %d", frameCount );
|
||||
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height);
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(mFrame->data, mFrame->linesize,
|
||||
directbuffer, imagePixFormat, width, height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer,
|
||||
imagePixFormat, width, height);
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if(mConvertContext == NULL) {
|
||||
mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
|
@ -392,8 +397,13 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
Fatal( "Unable to allocate frame for %s", mPath.c_str() );
|
||||
|
||||
Debug ( 1, "Allocated frames" );
|
||||
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 );
|
||||
#else
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
#endif
|
||||
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
|
@ -510,8 +520,7 @@ void *FfmpegCamera::ReopenFfmpegThreadCallback(void *ctx){
|
|||
}
|
||||
|
||||
//Function to handle capture and store
|
||||
|
||||
int FfmpegCamera::CaptureAndRecord(Image &image, bool recording, char* event_file, zm_packetqueue* packetqueue) {
|
||||
int FfmpegCamera::CaptureAndRecord( Image &image, bool recording, char* event_file, zm_packetqueue* packetqueue ){
|
||||
if (!mCanCapture){
|
||||
return -1;
|
||||
}
|
||||
|
@ -580,51 +589,90 @@ int FfmpegCamera::CaptureAndRecord(Image &image, bool recording, char* event_fil
|
|||
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height);
|
||||
|
||||
|
||||
//Buffer video packets
|
||||
if (!recording) {
|
||||
if(packet.flags & AV_PKT_FLAG_KEY) {
|
||||
packetqueue->clearQueues();
|
||||
}
|
||||
packetqueue->queueVideoPacket(&packet);
|
||||
}
|
||||
|
||||
//Video recording
|
||||
if (recording && !wasRecording) {
|
||||
//Instantiate the video storage module
|
||||
|
||||
videoStore = new VideoStore((const char *) event_file, "mp4", mFormatContext->streams[mVideoStreamId], mAudioStreamId == -1 ? NULL : mFormatContext->streams[mAudioStreamId], startTime);
|
||||
wasRecording = true;
|
||||
strcpy(oldDirectory, event_file);
|
||||
while (packetqueue->popVideoPacket(&queuedpacket)) {
|
||||
int ret = videoStore->writeVideoFramePacket(&packet, mFormatContext->streams[mVideoStreamId]); //, &lastKeyframePkt);
|
||||
if (ret < 0) {//Less than zero and we skipped a frame
|
||||
av_free_packet(&packet);
|
||||
return 0;
|
||||
//Buffer video packets
|
||||
if (!recording) {
|
||||
if(packet.flags & AV_PKT_FLAG_KEY) {
|
||||
packetqueue->clearQueues();
|
||||
}
|
||||
packetqueue->queueVideoPacket(&packet);
|
||||
}
|
||||
|
||||
} else if (!recording && wasRecording && videoStore) {
|
||||
Info("Deleting videoStore instance");
|
||||
delete videoStore;
|
||||
videoStore = NULL;
|
||||
}
|
||||
//Video recording
|
||||
if ( recording && !wasRecording ) {
|
||||
//Instantiate the video storage module
|
||||
|
||||
//The directory we are recording to is no longer tied to the current event. Need to re-init the videostore with the correct directory and start recording again
|
||||
if (recording && wasRecording && (strcmp(oldDirectory, event_file) != 0) && (packet.flags & AV_PKT_FLAG_KEY)) { //don't open new videostore until we're on a key frame..would this require an offset adjustment for the event as a result?...if we store our key frame location with the event will that be enough?
|
||||
Info("Re-starting video storage module");
|
||||
if (videoStore) {
|
||||
if (record_audio) {
|
||||
if (mAudioStreamId == -1) {
|
||||
Debug(3, "Record Audio on but no audio stream found");
|
||||
videoStore = new VideoStore((const char *) event_file, "mp4",
|
||||
mFormatContext->streams[mVideoStreamId],
|
||||
NULL, startTime);
|
||||
} else {
|
||||
Debug(3, "Video module initiated with audio stream");
|
||||
videoStore = new VideoStore((const char *) event_file, "mp4",
|
||||
mFormatContext->streams[mVideoStreamId],
|
||||
mFormatContext->streams[mAudioStreamId],
|
||||
startTime);
|
||||
}
|
||||
} else {
|
||||
Debug(3, "Record_audio is false so exclude audio stream");
|
||||
videoStore = new VideoStore((const char *) event_file, "mp4",
|
||||
mFormatContext->streams[mVideoStreamId],
|
||||
NULL, startTime);
|
||||
}
|
||||
wasRecording = true;
|
||||
strcpy(oldDirectory, event_file);
|
||||
while (packetqueue->popVideoPacket(&queuedpacket)) {
|
||||
int ret = videoStore->writeVideoFramePacket(&packet, mFormatContext->streams[mVideoStreamId]); //, &lastKeyframePkt);
|
||||
if (ret < 0) {//Less than zero and we skipped a frame
|
||||
av_free_packet(&packet);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ( ( ! recording ) && wasRecording && videoStore ) {
|
||||
Info("Deleting videoStore instance");
|
||||
delete videoStore;
|
||||
videoStore = NULL;
|
||||
}
|
||||
|
||||
videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime);
|
||||
// The directory we are recording to is no longer tied to the current
|
||||
// event. Need to re-init the videostore with the correct directory and
|
||||
// start recording again
|
||||
if (recording && wasRecording && (strcmp(oldDirectory, event_file) != 0)
|
||||
&& (packet.flags & AV_PKT_FLAG_KEY)) {
|
||||
Info("Re-starting video storage module");
|
||||
if(videoStore){
|
||||
delete videoStore;
|
||||
videoStore = NULL;
|
||||
}
|
||||
|
||||
if (record_audio) {
|
||||
if (mAudioStreamId == -1) {
|
||||
Debug(3, "Record Audio on but no audio stream found");
|
||||
videoStore = new VideoStore((const char *) event_file, "mp4",
|
||||
mFormatContext->streams[mVideoStreamId],
|
||||
NULL, startTime);
|
||||
} else {
|
||||
Debug(3, "Video module initiated with audio stream");
|
||||
videoStore = new VideoStore((const char *) event_file, "mp4",
|
||||
mFormatContext->streams[mVideoStreamId],
|
||||
mFormatContext->streams[mAudioStreamId],
|
||||
startTime);
|
||||
}
|
||||
} else {
|
||||
Debug(3, "Record_audio is false so exclude audio stream");
|
||||
videoStore = new VideoStore((const char *) event_file, "mp4",
|
||||
mFormatContext->streams[mVideoStreamId],
|
||||
NULL, startTime);
|
||||
}
|
||||
strcpy(oldDirectory, event_file);
|
||||
}
|
||||
|
||||
if ( videoStore && recording ) {
|
||||
//Write the packet to our video store
|
||||
int ret = videoStore->writeVideoFramePacket(&packet, mFormatContext->streams[mVideoStreamId]);//, &lastKeyframePkt);
|
||||
int ret = videoStore->writeVideoFramePacket(&packet,
|
||||
mFormatContext->streams[mVideoStreamId]); //, &lastKeyframePkt);
|
||||
if(ret<0){//Less than zero and we skipped a frame
|
||||
av_free_packet( &packet );
|
||||
return 0;
|
||||
|
@ -633,13 +681,20 @@ int FfmpegCamera::CaptureAndRecord(Image &image, bool recording, char* event_fil
|
|||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( mConvertContext == NULL ) {
|
||||
mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
mConvertContext = sws_getContext(mCodecContext->width,
|
||||
mCodecContext->height,
|
||||
mCodecContext->pix_fmt,
|
||||
width, height,
|
||||
imagePixFormat, SWS_BICUBIC, NULL,
|
||||
NULL, NULL);
|
||||
if ( mConvertContext == NULL )
|
||||
Fatal( "Unable to create conversion context for %s", mPath.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 )
|
||||
Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount );
|
||||
if (sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize,
|
||||
0, mCodecContext->height, mFrame->data, mFrame->linesize) < 0)
|
||||
Fatal("Unable to convert raw format %u to target format %u at frame %d",
|
||||
mCodecContext->pix_fmt, imagePixFormat, frameCount);
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" );
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
|
@ -651,7 +706,8 @@ int FfmpegCamera::CaptureAndRecord(Image &image, bool recording, char* event_fil
|
|||
if ( record_audio ) {
|
||||
Debug(4, "Recording audio packet" );
|
||||
//Write the packet to our video store
|
||||
int ret = videoStore->writeAudioFramePacket(&packet, mFormatContext->streams[packet.stream_index]); //FIXME no relevance of last key frame
|
||||
int ret = videoStore->writeAudioFramePacket(&packet,
|
||||
mFormatContext->streams[packet.stream_index]); //FIXME no relevance of last key frame
|
||||
if ( ret < 0 ) {//Less than zero and we skipped a frame
|
||||
av_free_packet( &packet );
|
||||
return 0;
|
||||
|
|
|
@ -35,8 +35,10 @@ static short *g_u_table;
|
|||
static short *b_u_table;
|
||||
__attribute__((aligned(16))) static const uint8_t movemask[16] = {0,4,8,12,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
|
||||
|
||||
jpeg_compress_struct *Image::jpg_ccinfo[101] = { 0 };
|
||||
jpeg_decompress_struct *Image::jpg_dcinfo = 0;
|
||||
jpeg_compress_struct *Image::writejpg_ccinfo[101] = { 0 };
|
||||
jpeg_compress_struct *Image::encodejpg_ccinfo[101] = { 0 };
|
||||
jpeg_decompress_struct *Image::readjpg_dcinfo = 0;
|
||||
jpeg_decompress_struct *Image::decodejpg_dcinfo = 0;
|
||||
struct zm_error_mgr Image::jpg_err;
|
||||
|
||||
/* Pointer to blend function. */
|
||||
|
@ -151,11 +153,17 @@ Image::~Image()
|
|||
delete[] b_u_table;
|
||||
initialised = false;
|
||||
}
|
||||
if ( jpg_dcinfo )
|
||||
if ( readjpg_dcinfo )
|
||||
{
|
||||
jpeg_destroy_decompress( jpg_dcinfo );
|
||||
delete jpg_dcinfo;
|
||||
jpg_dcinfo = 0;
|
||||
jpeg_destroy_decompress( readjpg_dcinfo );
|
||||
delete readjpg_dcinfo;
|
||||
readjpg_dcinfo = 0;
|
||||
}
|
||||
if ( decodejpg_dcinfo )
|
||||
{
|
||||
jpeg_destroy_decompress( decodejpg_dcinfo );
|
||||
delete decodejpg_dcinfo;
|
||||
decodejpg_dcinfo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -653,11 +661,11 @@ bool Image::WriteRaw( const char *filename ) const
|
|||
bool Image::ReadJpeg( const char *filename, unsigned int p_colours, unsigned int p_subpixelorder)
|
||||
{
|
||||
unsigned int new_width, new_height, new_colours, new_subpixelorder;
|
||||
struct jpeg_decompress_struct *cinfo = jpg_dcinfo;
|
||||
struct jpeg_decompress_struct *cinfo = readjpg_dcinfo;
|
||||
|
||||
if ( !cinfo )
|
||||
{
|
||||
cinfo = jpg_dcinfo = new jpeg_decompress_struct;
|
||||
cinfo = readjpg_dcinfo = new jpeg_decompress_struct;
|
||||
cinfo->err = jpeg_std_error( &jpg_err.pub );
|
||||
jpg_err.pub.error_exit = zm_jpeg_error_exit;
|
||||
jpg_err.pub.emit_message = zm_jpeg_emit_message;
|
||||
|
@ -814,11 +822,11 @@ bool Image::WriteJpeg( const char *filename, int quality_override, struct timeva
|
|||
}
|
||||
int quality = quality_override?quality_override:config.jpeg_file_quality;
|
||||
|
||||
struct jpeg_compress_struct *cinfo = jpg_ccinfo[quality];
|
||||
struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality];
|
||||
|
||||
if ( !cinfo )
|
||||
{
|
||||
cinfo = jpg_ccinfo[quality] = new jpeg_compress_struct;
|
||||
cinfo = writejpg_ccinfo[quality] = new jpeg_compress_struct;
|
||||
cinfo->err = jpeg_std_error( &jpg_err.pub );
|
||||
jpg_err.pub.error_exit = zm_jpeg_error_exit;
|
||||
jpg_err.pub.emit_message = zm_jpeg_emit_message;
|
||||
|
@ -945,11 +953,11 @@ bool Image::WriteJpeg( const char *filename, int quality_override, struct timeva
|
|||
bool Image::DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder)
|
||||
{
|
||||
unsigned int new_width, new_height, new_colours, new_subpixelorder;
|
||||
struct jpeg_decompress_struct *cinfo = jpg_dcinfo;
|
||||
struct jpeg_decompress_struct *cinfo = decodejpg_dcinfo;
|
||||
|
||||
if ( !cinfo )
|
||||
{
|
||||
cinfo = jpg_dcinfo = new jpeg_decompress_struct;
|
||||
cinfo = decodejpg_dcinfo = new jpeg_decompress_struct;
|
||||
cinfo->err = jpeg_std_error( &jpg_err.pub );
|
||||
jpg_err.pub.error_exit = zm_jpeg_error_exit;
|
||||
jpg_err.pub.emit_message = zm_jpeg_emit_message;
|
||||
|
@ -1079,11 +1087,11 @@ bool Image::EncodeJpeg( JOCTET *outbuffer, int *outbuffer_size, int quality_over
|
|||
|
||||
int quality = quality_override?quality_override:config.jpeg_stream_quality;
|
||||
|
||||
struct jpeg_compress_struct *cinfo = jpg_ccinfo[quality];
|
||||
struct jpeg_compress_struct *cinfo = encodejpg_ccinfo[quality];
|
||||
|
||||
if ( !cinfo )
|
||||
{
|
||||
cinfo = jpg_ccinfo[quality] = new jpeg_compress_struct;
|
||||
cinfo = encodejpg_ccinfo[quality] = new jpeg_compress_struct;
|
||||
cinfo->err = jpeg_std_error( &jpg_err.pub );
|
||||
jpg_err.pub.error_exit = zm_jpeg_error_exit;
|
||||
jpg_err.pub.emit_message = zm_jpeg_emit_message;
|
||||
|
|
|
@ -131,8 +131,10 @@ protected:
|
|||
static unsigned char *y_r_table;
|
||||
static unsigned char *y_g_table;
|
||||
static unsigned char *y_b_table;
|
||||
static jpeg_compress_struct *jpg_ccinfo[101];
|
||||
static jpeg_decompress_struct *jpg_dcinfo;
|
||||
static jpeg_compress_struct *writejpg_ccinfo[101];
|
||||
static jpeg_compress_struct *encodejpg_ccinfo[101];
|
||||
static jpeg_decompress_struct *readjpg_dcinfo;
|
||||
static jpeg_decompress_struct *decodejpg_dcinfo;
|
||||
static struct zm_error_mgr jpg_err;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -643,8 +643,12 @@ LocalCamera::LocalCamera(
|
|||
#endif
|
||||
if ( !tmpPicture )
|
||||
Fatal( "Could not allocate temporary picture" );
|
||||
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 );
|
||||
#else
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
#endif
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
|
@ -877,7 +881,18 @@ void LocalCamera::Initialise()
|
|||
#endif
|
||||
if ( !capturePictures[i] )
|
||||
Fatal( "Could not allocate picture" );
|
||||
avpicture_fill( (AVPicture *)capturePictures[i], (uint8_t*)v4l2_data.buffers[i].start, capturePixFormat, v4l2_data.fmt.fmt.pix.width, v4l2_data.fmt.fmt.pix.height );
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(capturePictures[i]->data,
|
||||
capturePictures[i]->linesize,
|
||||
(uint8_t*)v4l2_data.buffers[i].start,capturePixFormat,
|
||||
v4l2_data.fmt.fmt.pix.width,
|
||||
v4l2_data.fmt.fmt.pix.height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)capturePictures[i],
|
||||
(uint8_t*)v4l2_data.buffers[i].start, capturePixFormat,
|
||||
v4l2_data.fmt.fmt.pix.width,
|
||||
v4l2_data.fmt.fmt.pix.height );
|
||||
#endif
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
}
|
||||
|
||||
|
@ -1035,7 +1050,16 @@ void LocalCamera::Initialise()
|
|||
#endif
|
||||
if ( !capturePictures[i] )
|
||||
Fatal( "Could not allocate picture" );
|
||||
avpicture_fill( (AVPicture *)capturePictures[i], (unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i], capturePixFormat, width, height );
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(capturePictures[i]->data,
|
||||
capturePictures[i]->linesize,
|
||||
(unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i],
|
||||
capturePixFormat, width, height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)capturePictures[i],
|
||||
(unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i],
|
||||
capturePixFormat, width, height );
|
||||
#endif
|
||||
}
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
|
||||
|
@ -2128,10 +2152,17 @@ int LocalCamera::Capture( Image &image )
|
|||
}
|
||||
#if HAVE_LIBSWSCALE
|
||||
if(conversion_type == 1) {
|
||||
|
||||
|
||||
Debug( 9, "Calling sws_scale to perform the conversion" );
|
||||
/* Use swscale to convert the image directly into the shared memory */
|
||||
avpicture_fill( (AVPicture *)tmpPicture, directbuffer, imagePixFormat, width, height );
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(tmpPicture->data,
|
||||
tmpPicture->linesize, directbuffer,
|
||||
imagePixFormat, width, height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)tmpPicture, directbuffer,
|
||||
imagePixFormat, width, height );
|
||||
#endif
|
||||
sws_scale( imgConversionContext, capturePictures[capture_frame]->data, capturePictures[capture_frame]->linesize, 0, height, tmpPicture->data, tmpPicture->linesize );
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
#include <linux/videodev2.h>
|
||||
#endif // HAVE_LINUX_VIDEODEV2_H
|
||||
|
||||
// Required on systems with v4l1 but without v4l2 headers
|
||||
#ifndef VIDEO_MAX_FRAME
|
||||
#define VIDEO_MAX_FRAME 32
|
||||
#endif
|
||||
|
||||
#include "zm_ffmpeg.h"
|
||||
|
||||
//
|
||||
|
|
|
@ -332,8 +332,14 @@ void VideoStream::OpenStream( )
|
|||
{
|
||||
Panic( "Could not allocate opicture" );
|
||||
}
|
||||
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int size = av_image_get_buffer_size( c->pix_fmt, c->width,
|
||||
c->height, 1 );
|
||||
#else
|
||||
int size = avpicture_get_size( c->pix_fmt, c->width, c->height );
|
||||
#endif
|
||||
|
||||
uint8_t *opicture_buf = (uint8_t *)av_malloc( size );
|
||||
if ( !opicture_buf )
|
||||
{
|
||||
|
@ -344,7 +350,13 @@ void VideoStream::OpenStream( )
|
|||
#endif
|
||||
Panic( "Could not allocate opicture_buf" );
|
||||
}
|
||||
avpicture_fill( (AVPicture *)opicture, opicture_buf, c->pix_fmt, c->width, c->height );
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(opicture->data, opicture->linesize,
|
||||
opicture_buf, c->pix_fmt, c->width, c->height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)opicture, opicture_buf, c->pix_fmt,
|
||||
c->width, c->height );
|
||||
#endif
|
||||
|
||||
/* if the output format is not identical to the input format, then a temporary
|
||||
picture is needed too. It is then converted to the required
|
||||
|
@ -361,7 +373,12 @@ void VideoStream::OpenStream( )
|
|||
{
|
||||
Panic( "Could not allocate tmp_opicture" );
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int size = av_image_get_buffer_size( pf, c->width,
|
||||
c->height,1 );
|
||||
#else
|
||||
int size = avpicture_get_size( pf, c->width, c->height );
|
||||
#endif
|
||||
uint8_t *tmp_opicture_buf = (uint8_t *)av_malloc( size );
|
||||
if ( !tmp_opicture_buf )
|
||||
{
|
||||
|
@ -372,7 +389,14 @@ void VideoStream::OpenStream( )
|
|||
#endif
|
||||
Panic( "Could not allocate tmp_opicture_buf" );
|
||||
}
|
||||
avpicture_fill( (AVPicture *)tmp_opicture, tmp_opicture_buf, pf, c->width, c->height );
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(tmp_opicture->data,
|
||||
tmp_opicture->linesize, tmp_opicture_buf, pf,
|
||||
c->width, c->height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)tmp_opicture,
|
||||
tmp_opicture_buf, pf, c->width, c->height );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -678,14 +702,14 @@ double VideoStream::ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size,
|
|||
#endif
|
||||
if ( got_packet )
|
||||
{
|
||||
if ( c->coded_frame->key_frame )
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_CHECK(52, 30, 2, 30, 2)
|
||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
#else
|
||||
pkt->flags |= PKT_FLAG_KEY;
|
||||
#endif
|
||||
}
|
||||
// if ( c->coded_frame->key_frame )
|
||||
// {
|
||||
//#if LIBAVCODEC_VERSION_CHECK(52, 30, 2, 30, 2)
|
||||
// pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
//#else
|
||||
// pkt->flags |= PKT_FLAG_KEY;
|
||||
//#endif
|
||||
// }
|
||||
|
||||
if ( pkt->pts != (int64_t)AV_NOPTS_VALUE )
|
||||
{
|
||||
|
|
|
@ -220,8 +220,13 @@ int RemoteCameraRtsp::PrimeCapture()
|
|||
|
||||
if(mRawFrame == NULL || mFrame == NULL)
|
||||
Fatal( "Unable to allocate frame(s)");
|
||||
|
||||
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
int pSize = av_image_get_buffer_size( imagePixFormat, width, height, 1 );
|
||||
#else
|
||||
int pSize = avpicture_get_size( imagePixFormat, width, height );
|
||||
#endif
|
||||
|
||||
if( (unsigned int)pSize != imagesize) {
|
||||
Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize);
|
||||
}
|
||||
|
@ -423,91 +428,95 @@ int RemoteCameraRtsp::CaptureAndRecord( Image &image, bool recording, char* even
|
|||
// Why are we checking for it being the video stream
|
||||
if ( packet.stream_index == mVideoStreamId ) {
|
||||
|
||||
while ( !frameComplete && buffer.size() > 0 )
|
||||
{
|
||||
packet.data = buffer.head();
|
||||
packet.size = buffer.size();
|
||||
while ( !frameComplete && buffer.size() > 0 ) {
|
||||
packet.data = buffer.head();
|
||||
packet.size = buffer.size();
|
||||
|
||||
// So this does the decode
|
||||
// So this does the decode
|
||||
#if LIBAVCODEC_VERSION_CHECK(52, 23, 0, 23, 0)
|
||||
int len = avcodec_decode_video2( mCodecContext, mRawFrame, &frameComplete, &packet );
|
||||
int len = avcodec_decode_video2( mCodecContext, mRawFrame, &frameComplete, &packet );
|
||||
#else
|
||||
int len = avcodec_decode_video( mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size );
|
||||
int len = avcodec_decode_video( mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size );
|
||||
#endif
|
||||
if ( len < 0 )
|
||||
{
|
||||
Error( "Error while decoding frame %d", frameCount );
|
||||
Hexdump( Logger::ERROR, buffer.head(), buffer.size()>256?256:buffer.size() );
|
||||
buffer.clear();
|
||||
continue;
|
||||
}
|
||||
Debug( 2, "Frame: %d - %d/%d", frameCount, len, buffer.size() );
|
||||
//if ( buffer.size() < 400 )
|
||||
//Hexdump( 0, buffer.head(), buffer.size() );
|
||||
|
||||
buffer -= len;
|
||||
} // end while get & decode a frame
|
||||
if ( len < 0 ) {
|
||||
Error( "Error while decoding frame %d", frameCount );
|
||||
Hexdump( Logger::ERROR, buffer.head(), buffer.size()>256?256:buffer.size() );
|
||||
buffer.clear();
|
||||
continue;
|
||||
}
|
||||
Debug( 2, "Frame: %d - %d/%d", frameCount, len, buffer.size() );
|
||||
//if ( buffer.size() < 400 )
|
||||
//Hexdump( 0, buffer.head(), buffer.size() );
|
||||
|
||||
if ( frameComplete ) {
|
||||
|
||||
Debug( 3, "Got frame %d", frameCount );
|
||||
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height);
|
||||
|
||||
//Video recording
|
||||
if ( recording && !wasRecording ) {
|
||||
//Instantiate the video storage module
|
||||
buffer -= len;
|
||||
} // end while get & decode a frame
|
||||
|
||||
videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime);
|
||||
wasRecording = true;
|
||||
strcpy(oldDirectory, event_file);
|
||||
if ( frameComplete ) {
|
||||
|
||||
} else if ( !recording && wasRecording && videoStore ) {
|
||||
// Why are we deleting the videostore? Becase for soem reason we are no longer recording? How does that happen?
|
||||
Info("Deleting videoStore instance");
|
||||
delete videoStore;
|
||||
videoStore = NULL;
|
||||
}
|
||||
Debug( 3, "Got frame %d", frameCount );
|
||||
|
||||
//The directory we are recording to is no longer tied to the current event. Need to re-init the videostore with the correct directory and start recording again
|
||||
if ( recording && wasRecording && (strcmp(oldDirectory, event_file)!=0) && (packet.flags & AV_PKT_FLAG_KEY) ) {
|
||||
//don't open new videostore until we're on a key frame..would this require an offset adjustment for the event as a result?...if we store our key frame location with the event will that be enough?
|
||||
Info("Re-starting video storage module");
|
||||
if ( videoStore ) {
|
||||
delete videoStore;
|
||||
videoStore = NULL;
|
||||
}
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
|
||||
av_image_fill_arrays(mFrame->data, mFrame->linesize,
|
||||
directbuffer, imagePixFormat, width, height, 1);
|
||||
#else
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer,
|
||||
imagePixFormat, width, height);
|
||||
#endif
|
||||
|
||||
videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime);
|
||||
strcpy( oldDirectory, event_file );
|
||||
}
|
||||
//Video recording
|
||||
if ( recording && !wasRecording ) {
|
||||
//Instantiate the video storage module
|
||||
|
||||
if ( videoStore && recording ) {
|
||||
//Write the packet to our video store
|
||||
int ret = videoStore->writeVideoFramePacket(&packet, mFormatContext->streams[mVideoStreamId]);//, &lastKeyframePkt);
|
||||
if ( ret < 0 ) {//Less than zero and we skipped a frame
|
||||
av_free_packet( &packet );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime);
|
||||
wasRecording = true;
|
||||
strcpy(oldDirectory, event_file);
|
||||
|
||||
} else if ( !recording && wasRecording && videoStore ) {
|
||||
// Why are we deleting the videostore? Becase for soem reason we are no longer recording? How does that happen?
|
||||
Info("Deleting videoStore instance");
|
||||
delete videoStore;
|
||||
videoStore = NULL;
|
||||
}
|
||||
|
||||
//The directory we are recording to is no longer tied to the current event. Need to re-init the videostore with the correct directory and start recording again
|
||||
if ( recording && wasRecording && (strcmp(oldDirectory, event_file)!=0) && (packet.flags & AV_PKT_FLAG_KEY) ) {
|
||||
//don't open new videostore until we're on a key frame..would this require an offset adjustment for the event as a result?...if we store our key frame location with the event will that be enough?
|
||||
Info("Re-starting video storage module");
|
||||
if ( videoStore ) {
|
||||
delete videoStore;
|
||||
videoStore = NULL;
|
||||
}
|
||||
|
||||
videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime);
|
||||
strcpy( oldDirectory, event_file );
|
||||
}
|
||||
|
||||
if ( videoStore && recording ) {
|
||||
//Write the packet to our video store
|
||||
int ret = videoStore->writeVideoFramePacket(&packet, mFormatContext->streams[mVideoStreamId]);//, &lastKeyframePkt);
|
||||
if ( ret < 0 ) {//Less than zero and we skipped a frame
|
||||
av_free_packet( &packet );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if(mConvertContext == NULL) {
|
||||
mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
if(mConvertContext == NULL) {
|
||||
mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
|
||||
if(mConvertContext == NULL)
|
||||
Fatal( "Unable to create conversion context");
|
||||
}
|
||||
|
||||
if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 )
|
||||
Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount );
|
||||
if(mConvertContext == NULL)
|
||||
Fatal( "Unable to create conversion context");
|
||||
}
|
||||
|
||||
if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 )
|
||||
Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount );
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use RTSP cameras" );
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use RTSP cameras" );
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
|
||||
frameCount++;
|
||||
|
||||
} /* frame complete */
|
||||
frameCount++;
|
||||
|
||||
} /* frame complete */
|
||||
} else if ( packet.stream_index == mAudioStreamId ) {
|
||||
Debug( 4, "Got audio packet" );
|
||||
if ( videoStore && recording ) {
|
||||
|
@ -523,8 +532,6 @@ int RemoteCameraRtsp::CaptureAndRecord( Image &image, bool recording, char* even
|
|||
#endif
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
Debug( 4, "Not storing audio" );
|
||||
}
|
||||
}
|
||||
} // end if video or audio packet
|
||||
|
|
|
@ -279,20 +279,17 @@ int RtpCtrlThread::run()
|
|||
UdpInetSocket rtpCtrlServer;
|
||||
if ( mRtpSource.getLocalHost() != "" )
|
||||
{
|
||||
localAddr.resolve( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort(), "udp" );
|
||||
if ( !rtpCtrlServer.bind( localAddr ) )
|
||||
if ( !rtpCtrlServer.bind( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() ) )
|
||||
Fatal( "Failed to bind RTCP server" );
|
||||
sendReports = false;
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() );
|
||||
}
|
||||
else
|
||||
{
|
||||
localAddr.resolve( mRtpSource.getLocalCtrlPort(), "udp" );
|
||||
if ( !rtpCtrlServer.bind( localAddr ) )
|
||||
if ( !rtpCtrlServer.bind( mRtspThread.getAddressFamily() == AF_INET6 ? "::" : "0.0.0.0", mRtpSource.getLocalCtrlPort() ) )
|
||||
Fatal( "Failed to bind RTCP server" );
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() );
|
||||
remoteAddr.resolve( mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort(), "udp" );
|
||||
if ( !rtpCtrlServer.connect( remoteAddr ) )
|
||||
if ( !rtpCtrlServer.connect( mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort() ) )
|
||||
Fatal( "Failed to connect RTCP server" );
|
||||
Debug( 3, "Connected to %s:%d", mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort() );
|
||||
sendReports = true;
|
||||
|
|
|
@ -123,7 +123,7 @@ private:
|
|||
} sdes;
|
||||
|
||||
// BYE
|
||||
struct Bye
|
||||
struct
|
||||
{
|
||||
uint32_t srcN[]; // list of sources
|
||||
// can't express trailing text for reason (what does this mean? it's not even english!)
|
||||
|
|
|
@ -67,13 +67,17 @@ int RtpDataThread::run()
|
|||
|
||||
SockAddrInet localAddr;
|
||||
UdpInetServer rtpDataSocket;
|
||||
if ( mRtpSource.getLocalHost() != "" )
|
||||
localAddr.resolve( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort(), "udp" );
|
||||
if ( mRtpSource.getLocalHost() != "" ) {
|
||||
if ( !rtpDataSocket.bind( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() ) )
|
||||
Fatal( "Failed to bind RTP server" );
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() );
|
||||
}
|
||||
else
|
||||
localAddr.resolve( mRtpSource.getLocalDataPort(), "udp" );
|
||||
if ( !rtpDataSocket.bind( localAddr ) )
|
||||
Fatal( "Failed to bind RTP server" );
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() );
|
||||
{
|
||||
if ( !rtpDataSocket.bind( mRtspThread.getAddressFamily() == AF_INET6 ? "::" : "0.0.0.0", mRtpSource.getLocalDataPort() ) )
|
||||
Fatal( "Failed to bind RTP server" );
|
||||
Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() );
|
||||
}
|
||||
|
||||
Select select( 3 );
|
||||
select.addReader( &rtpDataSocket );
|
||||
|
|
|
@ -234,7 +234,7 @@ int RtspThread::run()
|
|||
|
||||
response.reserve( ZM_NETWORK_BUFSIZ );
|
||||
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) )
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), mPort.c_str() ) )
|
||||
Fatal( "Unable to connect RTSP socket" );
|
||||
//Select select( 0.25 );
|
||||
//select.addReader( &mRtspSocket );
|
||||
|
@ -248,7 +248,7 @@ int RtspThread::run()
|
|||
bool authTried = false;
|
||||
if ( mMethod == RTP_RTSP_HTTP )
|
||||
{
|
||||
if ( !mRtspSocket2.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) )
|
||||
if ( !mRtspSocket2.connect( mHost.c_str(), mPort.c_str() ) )
|
||||
Fatal( "Unable to connect auxiliary RTSP/HTTP socket" );
|
||||
//Select select( 0.25 );
|
||||
//select.addReader( &mRtspSocket2 );
|
||||
|
@ -289,13 +289,13 @@ int RtspThread::run()
|
|||
{
|
||||
if ( isalnum(response[0]) )
|
||||
{
|
||||
Error( "Response parse failure in '%s'", response.c_str() );
|
||||
Error( "Response parse failure in '%s'", response.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Error( "Response parse failure, %zd bytes follow", response.size() );
|
||||
if ( response.size() )
|
||||
Hexdump( Logger::ERROR, response.data(), min(response.size(),16) );
|
||||
Error( "Response parse failure, %zd bytes follow", response.size() );
|
||||
if ( response.size() )
|
||||
Hexdump( Logger::ERROR, response.data(), min(response.size(),16) );
|
||||
}
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ int RtspThread::run()
|
|||
mAuthenticator->checkAuthResponse(response);
|
||||
Debug(2, "Processed 401 response");
|
||||
mRtspSocket.close();
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) )
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), mPort.c_str() ) )
|
||||
Fatal( "Unable to reconnect RTSP socket" );
|
||||
Debug(2, "connection should be reopened now");
|
||||
}
|
||||
|
|
|
@ -138,6 +138,10 @@ public:
|
|||
{
|
||||
return( mStop );
|
||||
}
|
||||
int getAddressFamily ()
|
||||
{
|
||||
return mRtspSocket.getDomain();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ZM_RTSP_H
|
||||
|
|
|
@ -112,7 +112,7 @@ SessionDescriptor::ConnInfo::ConnInfo( const std::string &connInfo ) :
|
|||
if ( mNetworkType != "IN" )
|
||||
throw Exception( "Invalid SDP network type '"+mNetworkType+"' in connection info '"+connInfo+"'" );
|
||||
mAddressType = tokens[1];
|
||||
if ( mAddressType != "IP4" )
|
||||
if ( mAddressType != "IP4" && mAddressType != "IP6" )
|
||||
throw Exception( "Invalid SDP address type '"+mAddressType+"' in connection info '"+connInfo+"'" );
|
||||
StringVector addressTokens = split( tokens[2], "/" );
|
||||
if ( addressTokens.size() < 1 )
|
||||
|
|
|
@ -291,18 +291,21 @@ void StreamBase::openComms()
|
|||
if ( connkey > 0 )
|
||||
{
|
||||
|
||||
snprintf( sock_path_lock, sizeof(sock_path_lock), "%s/zms-%06d.lock", config.path_socks, connkey);
|
||||
unsigned int length = snprintf( sock_path_lock, sizeof(sock_path_lock), "%s/zms-%06d.lock", config.path_socks, connkey);
|
||||
if ( length >= sizeof(sock_path_lock) ) {
|
||||
Warning("Socket lock path was truncated.");
|
||||
length = sizeof(sock_path_lock)-1;
|
||||
}
|
||||
|
||||
lock_fd = open(sock_path_lock, O_CREAT|O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
if ( lock_fd <= 0 )
|
||||
{
|
||||
{
|
||||
Error("Unable to open sock lock file %s: %s", sock_path_lock, strerror(errno) );
|
||||
lock_fd = 0;
|
||||
}
|
||||
else if ( flock(lock_fd, LOCK_EX) != 0 )
|
||||
}
|
||||
else if ( flock(lock_fd, LOCK_EX) != 0 )
|
||||
{
|
||||
Error("Unable to lock sock lock file %s: %s", sock_path_lock, strerror(errno) );
|
||||
|
||||
close(lock_fd);
|
||||
lock_fd = 0;
|
||||
}
|
||||
|
@ -311,19 +314,25 @@ void StreamBase::openComms()
|
|||
Debug( 1, "We have obtained a lock on %s fd: %d", sock_path_lock, lock_fd);
|
||||
}
|
||||
|
||||
|
||||
sd = socket( AF_UNIX, SOCK_DGRAM, 0 );
|
||||
if ( sd < 0 )
|
||||
{
|
||||
Fatal( "Can't create socket: %s", strerror(errno) );
|
||||
}
|
||||
|
||||
snprintf( loc_sock_path, sizeof(loc_sock_path), "%s/zms-%06ds.sock", config.path_socks, connkey );
|
||||
length = snprintf( loc_sock_path, sizeof(loc_sock_path), "%s/zms-%06ds.sock", config.path_socks, connkey );
|
||||
if ( length >= sizeof(loc_sock_path) ) {
|
||||
Warning("Socket path was truncated.");
|
||||
length = sizeof(loc_sock_path)-1;
|
||||
}
|
||||
unlink( loc_sock_path );
|
||||
if ( sizeof(loc_addr.sun_path) < length ) {
|
||||
Error("Not enough space %d in loc_addr.sun_path for socket file %s", sizeof(loc_addr.sun_path), loc_sock_path );
|
||||
}
|
||||
|
||||
strncpy( loc_addr.sun_path, loc_sock_path, sizeof(loc_addr.sun_path) );
|
||||
loc_addr.sun_family = AF_UNIX;
|
||||
if ( bind( sd, (struct sockaddr *)&loc_addr, strlen(loc_addr.sun_path)+sizeof(loc_addr.sun_family)) < 0 )
|
||||
if ( bind( sd, (struct sockaddr *)&loc_addr, strlen(loc_addr.sun_path)+sizeof(loc_addr.sun_family)+1 ) < 0 )
|
||||
{
|
||||
Fatal( "Can't bind: %s", strerror(errno) );
|
||||
}
|
||||
|
@ -331,7 +340,7 @@ void StreamBase::openComms()
|
|||
snprintf( rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", config.path_socks, connkey );
|
||||
strncpy( rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path) );
|
||||
rem_addr.sun_family = AF_UNIX;
|
||||
}
|
||||
} // end if connKey > 0
|
||||
}
|
||||
|
||||
void StreamBase::closeComms()
|
||||
|
|
|
@ -33,315 +33,314 @@ extern "C"{
|
|||
}
|
||||
|
||||
VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||
AVStream *input_st,
|
||||
AVStream *inpaud_st,
|
||||
int64_t nStartTime) {
|
||||
|
||||
AVDictionary *pmetadata = NULL;
|
||||
int dsr;
|
||||
AVStream *input_st,
|
||||
AVStream *inpaud_st,
|
||||
int64_t nStartTime
|
||||
) {
|
||||
|
||||
//store inputs in variables local to class
|
||||
filename = filename_in;
|
||||
format = format_in;
|
||||
|
||||
keyframeMessage = false;
|
||||
keyframeSkipNumber = 0;
|
||||
AVDictionary *pmetadata = NULL;
|
||||
int dsr;
|
||||
|
||||
Info("Opening video storage stream %s format: %d\n", filename, format);
|
||||
//store inputs in variables local to class
|
||||
filename = filename_in;
|
||||
format = format_in;
|
||||
|
||||
//Init everything we need
|
||||
int ret;
|
||||
av_register_all();
|
||||
keyframeMessage = false;
|
||||
keyframeSkipNumber = 0;
|
||||
|
||||
ret = avformat_alloc_output_context2(&oc, NULL, NULL, filename);
|
||||
if ( ret < 0 ) {
|
||||
Warning("Could not create video storage stream %s as no output context"
|
||||
" could be assigned based on filename: %s",
|
||||
filename,
|
||||
av_make_error_string(ret).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
//Couldn't deduce format from filename, trying from format name
|
||||
Info("Opening video storage stream %s format: %d\n", filename, format);
|
||||
|
||||
//Init everything we need
|
||||
int ret;
|
||||
av_register_all();
|
||||
|
||||
ret = avformat_alloc_output_context2(&oc, NULL, NULL, filename);
|
||||
if ( ret < 0 ) {
|
||||
Warning("Could not create video storage stream %s as no output context"
|
||||
" could be assigned based on filename: %s",
|
||||
filename,
|
||||
av_make_error_string(ret).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
//Couldn't deduce format from filename, trying from format name
|
||||
if (!oc) {
|
||||
avformat_alloc_output_context2(&oc, NULL, format, filename);
|
||||
if (!oc) {
|
||||
avformat_alloc_output_context2(&oc, NULL, format, filename);
|
||||
if (!oc) {
|
||||
Fatal("Could not create video storage stream %s as no output context"
|
||||
" could not be assigned based on filename or format %s",
|
||||
filename, format);
|
||||
}
|
||||
Fatal("Could not create video storage stream %s as no output context"
|
||||
" could not be assigned based on filename or format %s",
|
||||
filename, format);
|
||||
}
|
||||
}
|
||||
|
||||
dsr = av_dict_set(&pmetadata, "title", "Zoneminder Security Recording", 0);
|
||||
if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__ );
|
||||
dsr = av_dict_set(&pmetadata, "title", "Zoneminder Security Recording", 0);
|
||||
if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__ );
|
||||
|
||||
oc->metadata = pmetadata;
|
||||
|
||||
fmt = oc->oformat;
|
||||
|
||||
video_st = avformat_new_stream(oc, input_st->codec->codec);
|
||||
if (!video_st) {
|
||||
Fatal("Unable to create video out stream\n");
|
||||
}
|
||||
|
||||
ret = avcodec_copy_context(video_st->codec, input_st->codec);
|
||||
if (ret < 0) {
|
||||
Fatal("Unable to copy input video context to output video context "
|
||||
"%s\n", av_make_error_string(ret).c_str());
|
||||
}
|
||||
oc->metadata = pmetadata;
|
||||
|
||||
video_st->codec->codec_tag = 0;
|
||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
|
||||
video_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
|
||||
if (inpaud_st) {
|
||||
audio_st = avformat_new_stream(oc, inpaud_st->codec->codec);
|
||||
if (!audio_st) {
|
||||
Error("Unable to create audio out stream\n");
|
||||
audio_st = NULL;
|
||||
} else {
|
||||
ret=avcodec_copy_context(audio_st->codec, inpaud_st->codec);
|
||||
if (ret < 0) {
|
||||
Fatal("Unable to copy audio context %s\n", av_make_error_string(ret).c_str());
|
||||
}
|
||||
audio_st->codec->codec_tag = 0;
|
||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
|
||||
audio_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
}
|
||||
fmt = oc->oformat;
|
||||
|
||||
video_st = avformat_new_stream(oc, input_st->codec->codec);
|
||||
if (!video_st) {
|
||||
Fatal("Unable to create video out stream\n");
|
||||
}
|
||||
|
||||
ret = avcodec_copy_context(video_st->codec, input_st->codec);
|
||||
if (ret < 0) {
|
||||
Fatal("Unable to copy input video context to output video context "
|
||||
"%s\n", av_make_error_string(ret).c_str());
|
||||
}
|
||||
|
||||
video_st->codec->codec_tag = 0;
|
||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
|
||||
video_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
|
||||
if (inpaud_st) {
|
||||
audio_st = avformat_new_stream(oc, inpaud_st->codec->codec);
|
||||
if (!audio_st) {
|
||||
Error("Unable to create audio out stream\n");
|
||||
audio_st = NULL;
|
||||
} else {
|
||||
Debug(3, "No Audio output stream");
|
||||
audio_st = NULL;
|
||||
}
|
||||
|
||||
/* open the output file, if needed */
|
||||
if (!(fmt->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,NULL,NULL);
|
||||
if (ret < 0) {
|
||||
Fatal("Could not open output file '%s': %s\n", filename,
|
||||
av_make_error_string(ret).c_str());
|
||||
}
|
||||
ret=avcodec_copy_context(audio_st->codec, inpaud_st->codec);
|
||||
if (ret < 0) {
|
||||
Fatal("Unable to copy audio context %s\n", av_make_error_string(ret).c_str());
|
||||
}
|
||||
audio_st->codec->codec_tag = 0;
|
||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
|
||||
audio_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Debug(3, "No Audio output stream");
|
||||
audio_st = NULL;
|
||||
}
|
||||
|
||||
//av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
|
||||
//if ((ret = avformat_write_header(ctx, &opts)) < 0) {
|
||||
//}
|
||||
//os->ctx_inited = 1;
|
||||
//avio_flush(ctx->pb);
|
||||
//av_dict_free(&opts);
|
||||
|
||||
/* Write the stream header, if any. */
|
||||
ret = avformat_write_header(oc, NULL);
|
||||
/* open the output file, if needed */
|
||||
if (!(fmt->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,NULL,NULL);
|
||||
if (ret < 0) {
|
||||
zm_dump_stream_format( oc, 0, 0, 1 );
|
||||
Fatal("Error occurred when writing output file header to %s: %s\n",
|
||||
filename,
|
||||
av_make_error_string(ret).c_str());
|
||||
Fatal("Could not open output file '%s': %s\n", filename,
|
||||
av_make_error_string(ret).c_str());
|
||||
}
|
||||
|
||||
prevDts = 0;
|
||||
startPts = 0;
|
||||
startDts = 0;
|
||||
filter_in_rescale_delta_last = AV_NOPTS_VALUE;
|
||||
}
|
||||
|
||||
startTime=av_gettime()-nStartTime;//oc->start_time;
|
||||
Info("VideoStore startTime=%d\n",startTime);
|
||||
//av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0);
|
||||
//if ((ret = avformat_write_header(ctx, &opts)) < 0) {
|
||||
//}
|
||||
//os->ctx_inited = 1;
|
||||
//avio_flush(ctx->pb);
|
||||
//av_dict_free(&opts);
|
||||
|
||||
/* Write the stream header, if any. */
|
||||
ret = avformat_write_header(oc, NULL);
|
||||
if (ret < 0) {
|
||||
zm_dump_stream_format( oc, 0, 0, 1 );
|
||||
Fatal("Error occurred when writing output file header to %s: %s\n",
|
||||
filename,
|
||||
av_make_error_string(ret).c_str());
|
||||
}
|
||||
|
||||
prevDts = 0;
|
||||
startPts = 0;
|
||||
startDts = 0;
|
||||
filter_in_rescale_delta_last = AV_NOPTS_VALUE;
|
||||
|
||||
startTime=av_gettime()-nStartTime;//oc->start_time;
|
||||
Info("VideoStore startTime=%d\n",startTime);
|
||||
} // VideoStore::VideoStore
|
||||
|
||||
|
||||
VideoStore::~VideoStore(){
|
||||
/* Write the trailer before close */
|
||||
if ( int rc = av_write_trailer(oc) ) {
|
||||
Error("Error writing trailer %s", av_err2str( rc ) );
|
||||
} else {
|
||||
Debug(3, "Sucess Writing trailer");
|
||||
}
|
||||
|
||||
// I wonder if we should be closing the file first.
|
||||
// I also wonder if we really need to be doing all the context allocation/de-allocation constantly, or whether we can just re-use it. Just do a file open/close/writeheader/etc.
|
||||
// What if we were only doing audio recording?
|
||||
if ( video_st ) {
|
||||
avcodec_close(video_st->codec);
|
||||
}
|
||||
if (audio_st) {
|
||||
avcodec_close(audio_st->codec);
|
||||
}
|
||||
|
||||
// WHen will be not using a file ?
|
||||
if (!(fmt->flags & AVFMT_NOFILE)) {
|
||||
/* Close the output file. */
|
||||
if ( int rc = avio_close(oc->pb) ) {
|
||||
Error("Error closing avio %s", av_err2str( rc ) );
|
||||
}
|
||||
} else {
|
||||
Debug(3, "Not closing avio because we are not writing to a file.");
|
||||
}
|
||||
/* Write the trailer before close */
|
||||
if ( int rc = av_write_trailer(oc) ) {
|
||||
Error("Error writing trailer %s", av_err2str( rc ) );
|
||||
} else {
|
||||
Debug(3, "Sucess Writing trailer");
|
||||
}
|
||||
|
||||
/* free the stream */
|
||||
avformat_free_context(oc);
|
||||
// I wonder if we should be closing the file first.
|
||||
// I also wonder if we really need to be doing all the context allocation/de-allocation constantly, or whether we can just re-use it. Just do a file open/close/writeheader/etc.
|
||||
// What if we were only doing audio recording?
|
||||
if ( video_st ) {
|
||||
avcodec_close(video_st->codec);
|
||||
}
|
||||
if (audio_st) {
|
||||
avcodec_close(audio_st->codec);
|
||||
}
|
||||
|
||||
// WHen will be not using a file ?
|
||||
if (!(fmt->flags & AVFMT_NOFILE)) {
|
||||
/* Close the output file. */
|
||||
if ( int rc = avio_close(oc->pb) ) {
|
||||
Error("Error closing avio %s", av_err2str( rc ) );
|
||||
}
|
||||
} else {
|
||||
Debug(3, "Not closing avio because we are not writing to a file.");
|
||||
}
|
||||
|
||||
/* free the stream */
|
||||
avformat_free_context(oc);
|
||||
}
|
||||
|
||||
|
||||
void VideoStore::dumpPacket( AVPacket *pkt ){
|
||||
char b[10240];
|
||||
char b[10240];
|
||||
|
||||
snprintf(b, sizeof(b), " pts: %" PRId64 ", dts: %" PRId64 ", data: %p, size: %d, sindex: %d, dflags: %04x, s-pos: %" PRId64 ", c-duration: %" PRId64 "\n"
|
||||
, pkt->pts
|
||||
, pkt->dts
|
||||
, pkt->data
|
||||
, pkt->size
|
||||
, pkt->stream_index
|
||||
, pkt->flags
|
||||
, pkt->pos
|
||||
, pkt->convergence_duration
|
||||
);
|
||||
Info("%s:%d:DEBUG: %s", __FILE__, __LINE__, b);
|
||||
snprintf(b, sizeof(b), " pts: %" PRId64 ", dts: %" PRId64 ", data: %p, size: %d, sindex: %d, dflags: %04x, s-pos: %" PRId64 ", c-duration: %" PRId64 "\n"
|
||||
, pkt->pts
|
||||
, pkt->dts
|
||||
, pkt->data
|
||||
, pkt->size
|
||||
, pkt->stream_index
|
||||
, pkt->flags
|
||||
, pkt->pos
|
||||
, pkt->convergence_duration
|
||||
);
|
||||
Info("%s:%d:DEBUG: %s", __FILE__, __LINE__, b);
|
||||
}
|
||||
|
||||
int VideoStore::writeVideoFramePacket(AVPacket *ipkt, AVStream *input_st){//, AVPacket *lastKeyframePkt){
|
||||
|
||||
Debug(3, "before ost_tbcket %d", startTime );
|
||||
zm_dump_stream_format( oc, ipkt->stream_index, 0, 1 );
|
||||
Debug(3, "before ost_tbcket %d", startTime );
|
||||
int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, video_st->time_base);
|
||||
|
||||
AVPacket opkt, safepkt;
|
||||
AVPicture pict;
|
||||
|
||||
av_init_packet(&opkt);
|
||||
Debug(3, "before ost_tbcket %d", startTime );
|
||||
zm_dump_stream_format( oc, ipkt->stream_index, 0, 1 );
|
||||
Debug(3, "before ost_tbcket %d", startTime );
|
||||
int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, video_st->time_base);
|
||||
|
||||
//Scale the PTS of the outgoing packet to be the correct time base
|
||||
if (ipkt->pts != AV_NOPTS_VALUE) {
|
||||
opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, video_st->time_base) - ost_tb_start_time;
|
||||
} else {
|
||||
opkt.pts = AV_NOPTS_VALUE;
|
||||
}
|
||||
|
||||
//Scale the DTS of the outgoing packet to be the correct time base
|
||||
if(ipkt->dts == AV_NOPTS_VALUE) {
|
||||
opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, video_st->time_base);
|
||||
} else {
|
||||
opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, video_st->time_base);
|
||||
}
|
||||
AVPacket opkt, safepkt;
|
||||
AVPicture pict;
|
||||
|
||||
opkt.dts -= ost_tb_start_time;
|
||||
av_init_packet(&opkt);
|
||||
|
||||
opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, video_st->time_base);
|
||||
opkt.flags = ipkt->flags;
|
||||
opkt.pos=-1;
|
||||
//Scale the PTS of the outgoing packet to be the correct time base
|
||||
if (ipkt->pts != AV_NOPTS_VALUE) {
|
||||
opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, video_st->time_base) - ost_tb_start_time;
|
||||
} else {
|
||||
opkt.pts = AV_NOPTS_VALUE;
|
||||
}
|
||||
|
||||
opkt.data = ipkt->data;
|
||||
opkt.size = ipkt->size;
|
||||
opkt.stream_index = ipkt->stream_index;
|
||||
/*opkt.flags |= AV_PKT_FLAG_KEY;*/
|
||||
|
||||
if (video_st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (fmt->flags & AVFMT_RAWPICTURE)) {
|
||||
/* store AVPicture in AVPacket, as expected by the output format */
|
||||
avpicture_fill(&pict, opkt.data, video_st->codec->pix_fmt, video_st->codec->width, video_st->codec->height);
|
||||
opkt.data = (uint8_t *)&pict;
|
||||
opkt.size = sizeof(AVPicture);
|
||||
opkt.flags |= AV_PKT_FLAG_KEY;
|
||||
//Scale the DTS of the outgoing packet to be the correct time base
|
||||
if(ipkt->dts == AV_NOPTS_VALUE) {
|
||||
opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, video_st->time_base);
|
||||
} else {
|
||||
opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, video_st->time_base);
|
||||
}
|
||||
|
||||
opkt.dts -= ost_tb_start_time;
|
||||
|
||||
opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, video_st->time_base);
|
||||
opkt.flags = ipkt->flags;
|
||||
opkt.pos=-1;
|
||||
|
||||
opkt.data = ipkt->data;
|
||||
opkt.size = ipkt->size;
|
||||
opkt.stream_index = ipkt->stream_index;
|
||||
/*opkt.flags |= AV_PKT_FLAG_KEY;*/
|
||||
|
||||
if (video_st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (fmt->flags & AVFMT_RAWPICTURE)) {
|
||||
/* store AVPicture in AVPacket, as expected by the output format */
|
||||
avpicture_fill(&pict, opkt.data, video_st->codec->pix_fmt, video_st->codec->width, video_st->codec->height);
|
||||
opkt.data = (uint8_t *)&pict;
|
||||
opkt.size = sizeof(AVPicture);
|
||||
opkt.flags |= AV_PKT_FLAG_KEY;
|
||||
}
|
||||
|
||||
memcpy(&safepkt, &opkt, sizeof(AVPacket));
|
||||
|
||||
if ((opkt.data == NULL)||(opkt.size < 1)) {
|
||||
Warning("%s:%d: Mangled AVPacket: discarding frame", __FILE__, __LINE__ );
|
||||
dumpPacket(&opkt);
|
||||
|
||||
} else if ((prevDts > 0) && (prevDts >= opkt.dts)) {
|
||||
Warning("%s:%d: DTS out of order: %lld \u226E %lld; discarding frame", __FILE__, __LINE__, prevDts, opkt.dts);
|
||||
prevDts = opkt.dts;
|
||||
dumpPacket(&opkt);
|
||||
|
||||
} else {
|
||||
int ret;
|
||||
|
||||
prevDts = opkt.dts; // Unsure if av_interleaved_write_frame() clobbers opkt.dts when out of order, so storing in advance
|
||||
ret = av_interleaved_write_frame(oc, &opkt);
|
||||
if(ret<0){
|
||||
// There's nothing we can really do if the frame is rejected, just drop it and get on with the next
|
||||
Warning("%s:%d: Writing frame [av_interleaved_write_frame()] failed: %s(%d) ", __FILE__, __LINE__, av_make_error_string(ret).c_str(), (ret));
|
||||
dumpPacket(&safepkt);
|
||||
}
|
||||
|
||||
memcpy(&safepkt, &opkt, sizeof(AVPacket));
|
||||
|
||||
if ((opkt.data == NULL)||(opkt.size < 1)) {
|
||||
Warning("%s:%d: Mangled AVPacket: discarding frame", __FILE__, __LINE__ );
|
||||
dumpPacket(&opkt);
|
||||
}
|
||||
|
||||
} else if ((prevDts > 0) && (prevDts >= opkt.dts)) {
|
||||
Warning("%s:%d: DTS out of order: %lld \u226E %lld; discarding frame", __FILE__, __LINE__, prevDts, opkt.dts);
|
||||
prevDts = opkt.dts;
|
||||
dumpPacket(&opkt);
|
||||
av_free_packet(&opkt);
|
||||
|
||||
} else {
|
||||
int ret;
|
||||
|
||||
prevDts = opkt.dts; // Unsure if av_interleaved_write_frame() clobbers opkt.dts when out of order, so storing in advance
|
||||
ret = av_interleaved_write_frame(oc, &opkt);
|
||||
if(ret<0){
|
||||
// There's nothing we can really do if the frame is rejected, just drop it and get on with the next
|
||||
Warning("%s:%d: Writing frame [av_interleaved_write_frame()] failed: %s(%d) ", __FILE__, __LINE__, av_make_error_string(ret).c_str(), (ret));
|
||||
dumpPacket(&safepkt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
av_free_packet(&opkt);
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VideoStore::writeAudioFramePacket(AVPacket *ipkt, AVStream *input_st){
|
||||
|
||||
if(!audio_st) {
|
||||
Error("Called writeAudioFramePacket when no audio_st");
|
||||
return -1;//FIXME -ve return codes do not free packet in ffmpeg_camera at the moment
|
||||
}
|
||||
/*if(!keyframeMessage)
|
||||
return -1;*/
|
||||
//zm_dump_stream_format( oc, ipkt->stream_index, 0, 1 );
|
||||
|
||||
// What is this doing? Getting the time of the start of this video chunk? Does that actually make sense?
|
||||
int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, audio_st->time_base);
|
||||
|
||||
AVPacket opkt;
|
||||
|
||||
av_init_packet(&opkt);
|
||||
Debug(3, "after init packet" );
|
||||
if(!audio_st) {
|
||||
Error("Called writeAudioFramePacket when no audio_st");
|
||||
return -1;//FIXME -ve return codes do not free packet in ffmpeg_camera at the moment
|
||||
}
|
||||
/*if(!keyframeMessage)
|
||||
return -1;*/
|
||||
//zm_dump_stream_format( oc, ipkt->stream_index, 0, 1 );
|
||||
|
||||
|
||||
//Scale the PTS of the outgoing packet to be the correct time base
|
||||
if (ipkt->pts != AV_NOPTS_VALUE) {
|
||||
Debug(3, "Rescaling output pts");
|
||||
opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, audio_st->time_base) - ost_tb_start_time;
|
||||
} else {
|
||||
Debug(3, "Setting output pts to AV_NOPTS_VALUE");
|
||||
opkt.pts = AV_NOPTS_VALUE;
|
||||
}
|
||||
|
||||
//Scale the DTS of the outgoing packet to be the correct time base
|
||||
if(ipkt->dts == AV_NOPTS_VALUE) {
|
||||
Debug(4, "ipkt->dts == AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts );
|
||||
opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, audio_st->time_base);
|
||||
Debug(4, "ipkt->dts == AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts );
|
||||
} else {
|
||||
Debug(4, "ipkt->dts != AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts );
|
||||
opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, audio_st->time_base);
|
||||
Debug(4, "ipkt->dts != AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts );
|
||||
}
|
||||
opkt.dts -= ost_tb_start_time;
|
||||
|
||||
// Seems like it would be really weird for the codec type to NOT be audiu
|
||||
if (audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && ipkt->dts != AV_NOPTS_VALUE) {
|
||||
Debug( 4, "code is audio, dts != AV_NOPTS_VALUE " );
|
||||
int duration = av_get_audio_frame_duration(input_st->codec, ipkt->size);
|
||||
if(!duration)
|
||||
duration = input_st->codec->frame_size;
|
||||
|
||||
//FIXME where to get filter_in_rescale_delta_last
|
||||
//FIXME av_rescale_delta doesn't exist in ubuntu vivid libavtools
|
||||
opkt.dts = opkt.pts = av_rescale_delta(input_st->time_base, ipkt->dts,
|
||||
(AVRational){1, input_st->codec->sample_rate}, duration, &filter_in_rescale_delta_last,
|
||||
audio_st->time_base) - ost_tb_start_time;
|
||||
}
|
||||
|
||||
opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, audio_st->time_base);
|
||||
opkt.pos=-1;
|
||||
opkt.flags = ipkt->flags;
|
||||
|
||||
opkt.data = ipkt->data;
|
||||
opkt.size = ipkt->size;
|
||||
opkt.stream_index = ipkt->stream_index;
|
||||
|
||||
int ret;
|
||||
ret = av_interleaved_write_frame(oc, &opkt);
|
||||
if(ret!=0){
|
||||
Fatal("Error encoding audio frame packet: %s\n", av_make_error_string(ret).c_str());
|
||||
}
|
||||
Debug(4,"Success writing audio frame" );
|
||||
av_free_packet(&opkt);
|
||||
return 0;
|
||||
// What is this doing? Getting the time of the start of this video chunk? Does that actually make sense?
|
||||
int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, audio_st->time_base);
|
||||
|
||||
AVPacket opkt;
|
||||
|
||||
av_init_packet(&opkt);
|
||||
Debug(3, "after init packet" );
|
||||
|
||||
|
||||
//Scale the PTS of the outgoing packet to be the correct time base
|
||||
if (ipkt->pts != AV_NOPTS_VALUE) {
|
||||
Debug(3, "Rescaling output pts");
|
||||
opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, audio_st->time_base) - ost_tb_start_time;
|
||||
} else {
|
||||
Debug(3, "Setting output pts to AV_NOPTS_VALUE");
|
||||
opkt.pts = AV_NOPTS_VALUE;
|
||||
}
|
||||
|
||||
//Scale the DTS of the outgoing packet to be the correct time base
|
||||
if(ipkt->dts == AV_NOPTS_VALUE) {
|
||||
Debug(4, "ipkt->dts == AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts );
|
||||
opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, audio_st->time_base);
|
||||
Debug(4, "ipkt->dts == AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts );
|
||||
} else {
|
||||
Debug(4, "ipkt->dts != AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts );
|
||||
opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, audio_st->time_base);
|
||||
Debug(4, "ipkt->dts != AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts );
|
||||
}
|
||||
opkt.dts -= ost_tb_start_time;
|
||||
|
||||
// Seems like it would be really weird for the codec type to NOT be audiu
|
||||
if (audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && ipkt->dts != AV_NOPTS_VALUE) {
|
||||
Debug( 4, "code is audio, dts != AV_NOPTS_VALUE " );
|
||||
int duration = av_get_audio_frame_duration(input_st->codec, ipkt->size);
|
||||
if(!duration)
|
||||
duration = input_st->codec->frame_size;
|
||||
|
||||
//FIXME where to get filter_in_rescale_delta_last
|
||||
//FIXME av_rescale_delta doesn't exist in ubuntu vivid libavtools
|
||||
opkt.dts = opkt.pts = av_rescale_delta(input_st->time_base, ipkt->dts,
|
||||
(AVRational){1, input_st->codec->sample_rate}, duration, &filter_in_rescale_delta_last,
|
||||
audio_st->time_base) - ost_tb_start_time;
|
||||
}
|
||||
|
||||
opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, audio_st->time_base);
|
||||
opkt.pos=-1;
|
||||
opkt.flags = ipkt->flags;
|
||||
|
||||
opkt.data = ipkt->data;
|
||||
opkt.size = ipkt->size;
|
||||
opkt.stream_index = ipkt->stream_index;
|
||||
|
||||
int ret;
|
||||
ret = av_interleaved_write_frame(oc, &opkt);
|
||||
if(ret!=0){
|
||||
Fatal("Error encoding audio frame packet: %s\n", av_make_error_string(ret).c_str());
|
||||
}
|
||||
Debug(4,"Success writing audio frame" );
|
||||
av_free_packet(&opkt);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ git submodule update --init --recursive
|
|||
if [ $DISTRO == "trusty" ]; then
|
||||
ln -sf distros/ubuntu1204 debian
|
||||
else
|
||||
ln -sf distros/ubuntu1504 debian
|
||||
ln -sf distros/ubuntu1604 debian
|
||||
fi;
|
||||
|
||||
# Auto-install all ZoneMinder's depedencies using the Debian control file
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue