zoneminder/web/skins/classic/views/monitor.php

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1299 lines
55 KiB
PHP
Raw Normal View History

<?php
//
// ZoneMinder web monitor view file, $Date$, $Revision$
2014-05-18 04:05:57 +08:00
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
2018-04-04 01:38:38 +08:00
require_once('includes/Server.php');
require_once('includes/Storage.php');
if ( !canEdit('Monitors', empty($_REQUEST['mid'])?0:$_REQUEST['mid']) ) {
2017-05-31 01:14:27 +08:00
$view = 'error';
2017-05-19 03:16:59 +08:00
return;
}
2017-05-31 01:14:27 +08:00
$Server = null;
if ( defined('ZM_SERVER_ID') ) {
$Server = dbFetchOne('SELECT * FROM Servers WHERE Id=?', NULL, array(ZM_SERVER_ID));
2017-05-31 01:14:27 +08:00
}
if ( !$Server ) {
$Server = array('Id' => '');
2017-05-19 03:16:59 +08:00
}
$mid = null;
2017-10-04 04:28:56 +08:00
$monitor = null;
2019-09-20 02:56:16 +08:00
if ( !empty($_REQUEST['mid']) ) {
$mid = validInt($_REQUEST['mid']);
$monitor = new ZM\Monitor($mid);
2017-10-04 04:28:56 +08:00
if ( $monitor and ZM_OPT_X10 )
$x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($mid));
}
if ( !$monitor ) {
$monitor = new ZM\Monitor();
$monitor->Name(translate('Monitor').'-'.getTableAutoInc('Monitors'));
$monitor->WebColour(random_colour());
2017-05-19 03:16:59 +08:00
} # end if $_REQUEST['mid']
if ( isset($_REQUEST['dupId']) ) {
$monitor = new ZM\Monitor($_REQUEST['dupId']);
$monitor->GroupIds(); // have to load before we change the Id
if ( ZM_OPT_X10 )
$x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['dupId']));
$clonedName = $monitor->Name();
$monitor->Name('Clone of '.$monitor->Name());
$monitor->Id($mid);
}
2017-05-19 03:16:59 +08:00
if ( ZM_OPT_X10 && empty($x10Monitor) ) {
$x10Monitor = array(
'Activation' => '',
'AlarmInput' => '',
'AlarmOutput' => '',
2017-05-19 03:16:59 +08:00
);
}
function fourcc($a, $b, $c, $d) {
return ord($a) | (ord($b) << 8) | (ord($c) << 16) | (ord($d) << 24);
}
if ( isset($_REQUEST['newMonitor']) ) {
# Update the monitor object with whatever has been set so far.
$monitor->set($_REQUEST['newMonitor']);
2017-06-15 03:35:35 +08:00
2017-05-19 03:16:59 +08:00
if ( ZM_OPT_X10 )
$newX10Monitor = $_REQUEST['newX10Monitor'];
} else {
if ( ZM_OPT_X10 )
$newX10Monitor = $x10Monitor;
}
2017-05-19 03:16:59 +08:00
# What if it has less zeros? This is not robust code.
2017-10-25 08:34:32 +08:00
if ( $monitor->AnalysisFPSLimit() == '0.00' )
$monitor->AnalysisFPSLimit('');
2017-06-15 03:35:35 +08:00
if ( $monitor->MaxFPS() == '0.00' )
$monitor->MaxFPS('');
2017-06-15 03:35:35 +08:00
if ( $monitor->AlarmMaxFPS() == '0.00' )
$monitor->AlarmMaxFPS('');
2017-05-19 03:16:59 +08:00
if ( !empty($_REQUEST['preset']) ) {
$preset = dbFetchOne( 'SELECT Type, Device, Channel, Format, Protocol, Method, Host, Port, Path, Width, Height, Palette, MaxFPS, Controllable, ControlId, ControlDevice, ControlAddress, DefaultRate, DefaultScale FROM MonitorPresets WHERE Id = ?', NULL, array($_REQUEST['preset']) );
foreach ( $preset as $name=>$value ) {
# Does isset handle NULL's? I don't think this code is correct.
2019-09-20 02:56:16 +08:00
# Icon: It does, but this means we can't set a null value.
2017-05-19 03:16:59 +08:00
if ( isset($value) ) {
2019-09-20 02:56:16 +08:00
$monitor->$name($value);
}
2017-05-19 03:16:59 +08:00
}
} # end if preset
2017-05-19 03:16:59 +08:00
if ( !empty($_REQUEST['probe']) ) {
$probe = json_decode(base64_decode($_REQUEST['probe']));
2017-05-19 03:16:59 +08:00
foreach ( $probe as $name=>$value ) {
if ( isset($value) ) {
# Does isset handle NULL's? I don't think this code is correct.
2018-09-20 23:30:23 +08:00
$monitor->$name = urldecode($value);
}
2017-05-19 03:16:59 +08:00
}
if ( ZM_HAS_V4L && $monitor->Type() == 'Local' ) {
$monitor->Palette( fourCC( substr($monitor->Palette,0,1), substr($monitor->Palette,1,1), substr($monitor->Palette,2,1), substr($monitor->Palette,3,1) ) );
if ( $monitor->Format() == 'PAL' )
$monitor->Format( 0x000000ff );
elseif ( $monitor->Format() == 'NTSC' )
$monitor->Format( 0x0000b000 );
}
} # end if apply probe settings
$sourceTypes = array(
2015-05-10 21:10:30 +08:00
'Local' => translate('Local'),
'Remote' => translate('Remote'),
'File' => translate('File'),
'Ffmpeg' => translate('Ffmpeg'),
'Libvlc' => translate('Libvlc'),
2017-10-04 04:28:56 +08:00
'cURL' => 'cURL (HTTP(S) only)',
'WebSite'=> 'Web Site',
2020-03-26 14:21:34 +08:00
'NVSocket' => translate('NVSocket'),
'VNC' => translate('VNC'),
2017-05-31 01:14:27 +08:00
);
if ( !ZM_HAS_V4L )
unset($sourceTypes['Local']);
$localMethods = array(
'v4l2' => 'Video For Linux version 2',
'v4l1' => 'Video For Linux version 1',
2017-05-19 03:16:59 +08:00
);
if ( !ZM_HAS_V4L2 )
2017-05-19 03:16:59 +08:00
unset($localMethods['v4l2']);
if ( !ZM_HAS_V4L1 )
2017-05-19 03:16:59 +08:00
unset($localMethods['v4l1']);
2017-05-31 07:53:02 +08:00
$remoteProtocols = array(
'http' => 'HTTP',
'rtsp' => 'RTSP'
);
2017-05-19 03:16:59 +08:00
2017-05-31 07:53:02 +08:00
$rtspMethods = array(
'rtpUni' => 'RTP/Unicast',
'rtpMulti' => 'RTP/Multicast',
'rtpRtsp' => 'RTP/RTSP',
'rtpRtspHttp' => 'RTP/RTSP/HTTP'
);
$rtspFFMpegMethods = array(
'rtpRtsp' => 'TCP',
'rtpUni' => 'UDP',
'rtpMulti' => 'UDP Multicast',
'rtpRtspHttp' => 'HTTP Tunnel'
2017-06-15 03:35:35 +08:00
);
2017-05-31 07:53:02 +08:00
$httpMethods = array(
'simple' => 'Simple',
'regexp' => 'Regexp',
'jpegTags' => 'JPEG Tags'
);
2017-05-19 03:16:59 +08:00
if ( !ZM_PCRE )
2017-05-19 03:16:59 +08:00
unset($httpMethods['regexp']);
// Currently unsupported
2017-05-31 07:53:02 +08:00
unset($httpMethods['jpegTags']);
if ( ZM_HAS_V4L1 ) {
$v4l1DeviceFormats = array(
0 => 'PAL',
1 => 'NTSC',
2 => 'SECAM',
3 => 'AUTO',
4 => 'FMT4',
5 => 'FMT5',
6 => 'FMT6',
7 => 'FMT7'
2017-05-31 07:53:02 +08:00
);
2017-05-31 07:53:02 +08:00
$v4l1MaxChannels = 15;
$v4l1DeviceChannels = array();
for ( $i = 0; $i <= $v4l1MaxChannels; $i++ )
2017-06-15 03:35:35 +08:00
$v4l1DeviceChannels[$i] = $i;
2017-05-31 07:53:02 +08:00
$v4l1LocalPalettes = array(
1 => translate('Grey'),
5 => 'BGR32',
4 => 'BGR24',
8 => '*YUYV',
3 => '*RGB565',
6 => '*RGB555',
7 => '*YUV422',
13 => '*YUV422P',
15 => '*YUV420P',
2017-05-31 07:53:02 +08:00
);
}
if ( ZM_HAS_V4L2 ) {
2017-05-19 03:16:59 +08:00
$v4l2DeviceFormats = array(
0x000000ff => 'PAL',
0x0000b000 => 'NTSC',
0x00000001 => 'PAL B',
0x00000002 => 'PAL B1',
0x00000004 => 'PAL G',
0x00000008 => 'PAL H',
0x00000010 => 'PAL I',
0x00000020 => 'PAL D',
0x00000040 => 'PAL D1',
0x00000080 => 'PAL K',
0x00000100 => 'PAL M',
0x00000200 => 'PAL N',
0x00000400 => 'PAL Nc',
0x00000800 => 'PAL 60',
0x00001000 => 'NTSC M',
0x00002000 => 'NTSC M JP',
0x00004000 => 'NTSC 443',
0x00008000 => 'NTSC M KR',
0x00010000 => 'SECAM B',
0x00020000 => 'SECAM D',
0x00040000 => 'SECAM G',
0x00080000 => 'SECAM H',
0x00100000 => 'SECAM K',
0x00200000 => 'SECAM K1',
0x00400000 => 'SECAM L',
0x00800000 => 'SECAM LC',
0x01000000 => 'ATSC 8 VSB',
0x02000000 => 'ATSC 16 VSB',
2017-05-19 03:16:59 +08:00
);
$v4l2MaxChannels = 31;
$v4l2DeviceChannels = array();
for ( $i = 0; $i <= $v4l2MaxChannels; $i++ )
2017-06-01 09:30:19 +08:00
$v4l2DeviceChannels[$i] = $i;
2017-05-19 03:16:59 +08:00
$v4l2LocalPalettes = array(
0 => 'Auto', /* Automatic palette selection */
2017-05-19 03:16:59 +08:00
/* FOURCC => Pixel format depth Description */
fourcc('G','R','E','Y') => translate('Grey'), /* 8 Greyscale */
fourcc('B','G','R','4') => 'BGR32', /* 32 BGR-8-8-8-8 */
fourcc('R','G','B','4') => 'RGB32', /* 32 RGB-8-8-8-8 */
fourcc('B','G','R','3') => 'BGR24', /* 24 BGR-8-8-8 */
fourcc('R','G','B','3') => 'RGB24', /* 24 RGB-8-8-8 */
fourcc('Y','U','Y','V') => '*YUYV', /* 16 YUV 4:2:2 */
2017-05-19 03:16:59 +08:00
/* compressed formats */
fourcc('J','P','E','G') => '*JPEG', /* JFIF JPEG */
fourcc('M','J','P','G') => '*MJPEG', /* Motion-JPEG */
// fourcc('d','v','s','d') => 'DV', /* 1394 */
// fourcc('M','P','E','G') => 'MPEG', /* MPEG-1/2/4 */
2017-05-31 01:14:27 +08:00
//
fourcc('R','G','B','1') => 'RGB332', /* 8 RGB-3-3-2 */
fourcc('R','4','4','4') => '*RGB444', /* 16 xxxxrrrr ggggbbbb */
fourcc('R','G','B','O') => '*RGB555', /* 16 RGB-5-5-5 */
fourcc('R','G','B','P') => '*RGB565', /* 16 RGB-5-6-5 */
// fourcc('R','G','B','Q') => 'RGB555X', /* 16 RGB-5-5-5 BE */
// fourcc('R','G','B','R') => 'RGB565X', /* 16 RGB-5-6-5 BE */
// fourcc('Y','1','6','') => 'Y16', /* 16 Greyscale */
// fourcc('P','A','L','8') => 'PAL8', /* 8 8-bit palette */
// fourcc('Y','V','U','9') => 'YVU410', /* 9 YVU 4:1:0 */
// fourcc('Y','V','1','2') => 'YVU420', /* 12 YVU 4:2:0 */
2017-05-31 01:14:27 +08:00
fourcc('U','Y','V','Y') => '*UYVY', /* 16 YUV 4:2:2 */
fourcc('4','2','2','P') => '*YUV422P', /* 16 YVU422 planar */
fourcc('4','1','1','P') => '*YUV411P', /* 16 YVU411 planar */
// fourcc('Y','4','1','P') => 'Y41P', /* 12 YUV 4:1:1 */
fourcc('Y','4','4','4') => '*YUV444', /* 16 xxxxyyyy uuuuvvvv */
// fourcc('Y','U','V','O') => 'YUV555', /* 16 YUV-5-5-5 */
// fourcc('Y','U','V','P') => 'YUV565', /* 16 YUV-5-6-5 */
// fourcc('Y','U','V','4') => 'YUV32', /* 32 YUV-8-8-8-8 */
2017-05-19 03:16:59 +08:00
/* two planes -- one Y, one Cr + Cb interleaved */
fourcc('N','V','1','2') => 'NV12', /* 12 Y/CbCr 4:2:0 */
// fourcc('N','V','2','1') => 'NV21', /* 12 Y/CrCb 4:2:0 */
2017-05-19 03:16:59 +08:00
/* The following formats are not defined in the V4L2 specification */
fourcc('Y','U','V','9') => '*YUV410', /* 9 YUV 4:1:0 */
fourcc('Y','U','1','2') => '*YUV420', /* 12 YUV 4:2:0 */
// fourcc('Y','Y','U','V') => 'YYUV', /* 16 YUV 4:2:2 */
// fourcc('H','I','2','4') => 'HI240', /* 8 8-bit color */
// fourcc('H','M','1','2') => 'HM12', /* 8 YUV 4:2:0 16x16 macroblocks */
2017-05-19 03:16:59 +08:00
/* see http://www.siliconimaging.com/RGB%20Bayer.htm */
// fourcc('B','A','8','1') => 'SBGGR8', /* 8 BGBG.. GRGR.. */
// fourcc('G','B','R','G') => 'SGBRG8', /* 8 GBGB.. RGRG.. */
// fourcc('B','Y','R','2') => 'SBGGR16', /* 16 BGBG.. GRGR.. */
2017-05-19 03:16:59 +08:00
/* Vendor-specific formats */
2017-05-31 01:14:27 +08:00
//'WNVA' => fourcc('W','N','V','A'), /* Winnov hw compress */
//'SN9C10X' => fourcc('S','9','1','0'), /* SN9C10x compression */
//'PWC1' => fourcc('P','W','C','1'), /* pwc older webcam */
//'PWC2' => fourcc('P','W','C','2'), /* pwc newer webcam */
//'ET61X251' => fourcc('E','6','2','5'), /* ET61X251 compression */
//'SPCA501' => fourcc('S','5','0','1'), /* YUYV per line */
//'SPCA505' => fourcc('S','5','0','5'), /* YYUV per line */
//'SPCA508' => fourcc('S','5','0','8'), /* YUVY per line */
//'SPCA561' => fourcc('S','5','6','1'), /* compressed GBRG bayer */
//'PAC207' => fourcc('P','2','0','7'), /* compressed BGGR bayer */
//'PJPG' => fourcc('P','J','P','G'), /* Pixart 73xx JPEG */
//'YVYU' => fourcc('Y','V','Y','U'), /* 16 YVU 4:2:2 */
2017-05-19 03:16:59 +08:00
);
}
$Colours = array(
2017-11-10 03:53:04 +08:00
'1' => translate('8BitGrey'),
'3' => translate('24BitColour'),
'4' => translate('32BitColour')
2017-05-19 03:16:59 +08:00
);
$orientations = array(
'ROTATE_0' => translate('Normal'),
'ROTATE_90' => translate('RotateRight'),
'ROTATE_180' => translate('Inverted'),
'ROTATE_270' => translate('RotateLeft'),
'FLIP_HORI' => translate('FlippedHori'),
'FLIP_VERT' => translate('FlippedVert')
2017-05-19 03:16:59 +08:00
);
$deinterlaceopts = array(
0x00000000 => 'Disabled',
0x00001E04 => 'Four field motion adaptive - Soft', /* 30 change */
0x00001404 => 'Four field motion adaptive - Medium', /* 20 change */
0x00000A04 => 'Four field motion adaptive - Hard', /* 10 change */
0x00000001 => 'Discard',
0x00000002 => 'Linear',
0x00000003 => 'Blend',
0x00000205 => 'Blend (25%)',
);
$deinterlaceopts_v4l2 = array(
0x00000000 => 'Disabled',
0x00001E04 => 'Four field motion adaptive - Soft', /* 30 change */
0x00001404 => 'Four field motion adaptive - Medium', /* 20 change */
0x00000A04 => 'Four field motion adaptive - Hard', /* 10 change */
0x00000001 => 'Discard',
0x00000002 => 'Linear',
0x00000003 => 'Blend',
0x00000205 => 'Blend (25%)',
0x02000000 => 'V4L2: Capture top field only',
0x03000000 => 'V4L2: Capture bottom field only',
0x07000000 => 'V4L2: Alternate fields (Bob)',
0x01000000 => 'V4L2: Progressive',
0x04000000 => 'V4L2: Interlaced',
);
$fastblendopts = array(
0 => 'No blending',
1 => '1.5625%',
3 => '3.125%',
6 => '6.25% (Indoor)',
12 => '12.5% (Outdoor)',
25 => '25%',
50 => '50%',
2017-05-19 03:16:59 +08:00
);
$fastblendopts_alarm = array(
0 => 'No blending (Alarm lasts forever)',
1 => '1.5625%',
3 => '3.125%',
6 => '6.25%',
12 => '12.5%',
25 => '25%',
50 => '50% (Alarm lasts a moment)',
2017-05-19 03:16:59 +08:00
);
$label_size = array(
1 => translate('Small'),
2 => translate('Default'),
3 => translate('Large'),
4 => translate('Extra Large'),
2017-05-19 03:16:59 +08:00
);
$codecs = array(
'auto' => translate('Auto'),
'MP4' => translate('MP4'),
'MJPEG' => translate('MJPEG'),
);
Feature h264 videostorage (#1882) * Moved writing of configure options from Controller to Model. Fixes #191. * Initial commit for saving events as videos :) * Add zm_video.cpp to autotools * Add zm_video.h to autotools * Search for MP4V2 header file 3 times: mp4v2/mp4v2.h, mp4v2.h, mp4.h * Fix serve memory leak * Few minor code improvements * Added the ability to override preset, tune, profile and few other improvements * Correctly write SPS & PPS from x264 encoder headers * Remove unnessecary SPS & PPS writing code * Imported missing files from master to feature-h264-videostorage * Audio support including fixes for dts/pts, split on keyframe and update to mkv extension to prevent ffmpeg problems writing rtsp audio to mp4 containter (header problem) * Updates to make gcc happy * Add html5 video control to timeline and event to support mkv playback * Add zm_videostore.cpp to CMakeLists.txt * Remove Modern Branch for now * Fix minor bug * Option handled added in master, removing duplicate declaration * Add CaptureandRecord from zm_camera.h * Putting placeholder in for CaptureAndRecord function * Removed duplicate code and brackets * add digest auth file for cmake Conflicts: src/CMakeLists.txt * Add web dir back into Makefile.am Revert "Removed web from SUBDIRS in Makefile.am" This reverts commit d9bbcdf3a94cba4d8955fcd03bd965ed2772f34d. * Add CaptureAndRecord to vlc, still need to make it record * Resolve SegFault on videostore * Swap to mp4 container * mp4 changes * spaces to tabs, hide video stuff if video writer is turned off * Make timeline open event.mp4 instead of mkv * Missed mkv in timeline.js * Fix some issues from the merge conflict * Resolve post merge build issues with braces * Fix whitespace * Update Jpeg and Video options for passthrough options * Whitespace fix zm_camera.h * Fix array mkssing comma * Add support for Jpeg save options for h264 branch snapshot. Might remove altogether if snapshots not needed * Update VideoStoreData memory size comment * Change from config.use_mkv_storage to per monitor option VideoWriter from video branch * Fix bracket issues post merge * Clean up comments and add av_free_packet * Convert from event_directory to event file as per Video branch * Testing videojs for video playback * Fixed a missing bracket post merge and also SQL_values now used for EventID and Monitors * bring recent improvements in ffmpeg capture function into captureandrecord * Remove pict from writeAudioFramePacket as not used * Add translate options for h264 Storage options in Monitor and update en_gb file * Cherry-Pick from iconnor - make it compile on ubuntu 15.04. Which is libav 56.1.0 Conflicts: src/zm_ffmpeg.cpp src/zm_remote_camera_rtsp.cpp Conflicts: distros/ubuntu1204/changelog * Clean up videostore code and remove lots of unused code * proof of concept for dynamic/automatic video rotation using video-js plugin zoomrotate Conflicts: web/skins/classic/views/event.php * removed redundant field in sql query Conflicts: web/skins/classic/views/event.php * local storage of video js plugin * Beautify! Make the code somewhat readable. * added missing videojs.zoomrotate.js file added missing videojs.zoomrotate.js file * Typo added missing " * Added missing brackets * fix to display thumbnails when only storing snapshot.jpg * added control for video playback rate Conflicts: web/skins/classic/views/event.php * dynamically create jpegs from video file for viewing in browser * fix timeline view for SaveJPEGs monitors (without enabled VideoWriter) * only expose monitor info which are being used in client * fix segmentation fault in zma with ubuntu 14.04 and ffmpeg 2.5.8 (gcc 4.8) when libx264 is not installed * better way of detecting showing image or video in timeline and event view instead of Monitor.VideoWriter, Event.DefaultVideo is used, so even if VideoWriter/SaveJPEG option is changed, a valid image or video will always be displayed for historical events in both timeline and event view this also fixes loading videos in timeline view * Fixes problem of crashing zmc when bad packet arrives causing av_interleaved_write_frame() to return non-zero (-22). Prefilters common packet issues. Add metadata title to generated video file * Remove syslog.h * fixed SaveJPEGs are not working which is caused in errors introduced when merging with master * Update README.md * Fix build warnings specific to h264 branch, unused FrameImg, unused ret and int64_t snprintf issues * Fix PRId64 issue in travis, builds locally fine, but I can see a gcc version issue here * Fix PRId64 issue in travis, another try * Try "STDC_FORMAT_MACROS" to see if that helps Travis on gcc 4.6.3 * Revert space removal around PRId64 * video branch ffmpeg 2.9 fixes ffmpeg 2.9 patched removed SSE2 CPU * Add FFMPEGInit back * use webvvt to overlay timestamp (honoring Monitor.LabelFormat) to videos in timeline and event also fixed bug which prevented seeking in timeline video preview * ffmpeg 3.0 API build failure fixes * Update README.md * merge all the commits from the messed up iconnor_video branch * fix whitespace * revert * whitespace fixes * spelling fix * put back some text * add these back * fix spelling mistake * Steal some packet dumping routines from ffmpeg. Convert them to use our logging routines * add a test and error message if the codec is not h264 * these have been removed in master * add a view to check auth and just send the video * add some comments, and dump filename and AVFormatContext on failure to write header * add the toggle for RecordAudio so that the checkbox works to turn off Audio * Must init videoStore in constuctor * more debug and comments, return checking * Fix dropped part of sql query. * fix extra else and some whitespace * Fix missing } from merge that was preventing building. * fix tabs * get rid of use of separator, just use \n * Restore lost fixes for deprecation * Why are these failing * Respect record_audio flag when setting up video file so dont try and initiliase mp4 with unsupported audio * Forgot that I was trying to solve case of stream is true and record_audio is false. * Pass swscale_ctx back in to getCachedContext or it will create new context every frame and leak memory like a mofo. * Add libx264-dev and libmp4v2-dev to build requires to save hassle of ensuring they are installed before build. * Merge my Rotation/Orientation work and fixes for bad h264 streams * need arpa/inet for reverse lookups * pull in the new byte range code for viewing videos * Move our recording flag deeper into closeevent * add braces and only call closeEvent if there is an event * deprecate the z_frame_rate stuff which is deprecated in ffmpeg * remark out some debugging * fix for video on stream 1 * fix audio_stream to audio_st * Ignore bad decodes * fix problems with content-length causing viewing to not work in chrome/android * change logic of sending file contents to handle an off by one and be more readable * Some fixes pointed out by Maxim Romanov. Also simply the loading of events to not join the Monitors table * fix to sql for timeline * added RecordAudio to sql in README * Use sub queries instead of joins to fix errors when using new mysql defaults. * fix sql queries * Dockerfile to build feature-h264-videostorage * Must cast codec * add php-acpu as a dependency * require php5-acpu * fix typo * remove extra / * Add a line for out-of-tree builds to do api/lib/Cake/bootstrap.php * delete merge conflict files * delete merge conflict files
2017-05-16 10:02:48 +08:00
2020-09-05 20:46:18 +08:00
$controls = ZM\Control::find(null, array('order'=>'lower(Name)'));
xhtmlHeaders(__FILE__, translate('Monitor').' - '.validHtmlStr($monitor->Name()));
getBodyTopHTML();
2020-08-28 04:53:24 +08:00
echo getNavBarHTML();
?>
2020-08-29 02:09:49 +08:00
<div id="page" class="container-fluid">
2020-09-03 05:32:24 +08:00
<div class="row flex-nowrap">
<nav> <!-- BEGIN PILL LIST -->
2021-01-30 09:37:55 +08:00
<ul class="nav nav-pills flex-column h-100" id="pills-tab" role="tablist" aria-orientation="vertical">
2017-05-31 07:53:02 +08:00
<?php
$tabs = array();
$tabs['general'] = translate('General');
$tabs['source'] = translate('Source');
2020-05-14 03:30:56 +08:00
$tabs['onvif'] = translate('ONVIF');
if ( $monitor->Type() != 'WebSite' ) {
$tabs['storage'] = translate('Storage');
$tabs['timestamp'] = translate('Timestamp');
$tabs['buffers'] = translate('Buffers');
if ( ZM_OPT_CONTROL && canView('Control') )
$tabs['control'] = translate('Control');
if ( ZM_OPT_X10 )
$tabs['x10'] = translate('X10');
$tabs['misc'] = translate('Misc');
$tabs['location'] = translate('Location');
}
if ( isset($_REQUEST['tab']) )
$tab = validHtmlStr($_REQUEST['tab']);
else
$tab = 'general';
2017-05-19 03:16:59 +08:00
foreach ( $tabs as $name=>$value ) {
2017-05-31 07:53:02 +08:00
?>
<li class="nav-item form-control-sm my-1">
<a
id="<?php echo $name?>-tab"
role="tab"
data-toggle="pill"
class="nav-link<?php echo $tab == $name ? ' active' : '' ?>"
href="#pills-<?php echo $name?>"
aria-controls="pills-<?php echo $name?>"
aria-selected="<?php echo $tab == $name ? 'true':'false'?>"
><?php echo $value ?></a></li>
2017-05-31 07:53:02 +08:00
<?php
}
2017-06-15 03:35:35 +08:00
?>
2017-05-31 07:53:02 +08:00
</ul>
</nav> <!-- END PILL LIST -->
<div class="d-flex flex-column col-sm-offset-2 container-fluid">
<!-- BEGIN MINI HEADER -->
2020-08-28 05:30:49 +08:00
<div class="d-flex flex-row justify-content-between px-3 py-1">
<div class="" id="toolbar" >
<button id="backBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Back') ?>" disabled><i class="fa fa-arrow-left"></i></button>
<button id="refreshBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Refresh') ?>" ><i class="fa fa-refresh"></i></button>
</div>
<h2><?php echo translate('Monitor') ?> - <?php echo validHtmlStr($monitor->Name()) ?><?php if ( $monitor->Id() ) { ?> (<?php echo $monitor->Id()?>)<?php } ?></h2>
2017-06-15 03:35:35 +08:00
<?php
if ( canEdit('Monitors') ) {
if ( isset($_REQUEST['dupId']) ) {
2017-05-31 07:53:02 +08:00
?>
2017-05-19 03:16:59 +08:00
<div class="alert alert-info">
Configuration cloned from Monitor: <?php echo validHtmlStr($clonedName) ?>
2017-05-19 03:16:59 +08:00
</div>
2017-05-31 07:53:02 +08:00
<?php
}
?>
2020-09-03 05:32:24 +08:00
<div>
<button id="probeBtn" class="btn btn-normal" data-mid="<?php echo $monitor->Id() ?>" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Probe') ?>" ><i class="fa fa-rss-square"></i></button>
<button id="onvifBtn" class="btn btn-normal" data-mid="<?php echo $monitor->Id() ?>" data-toggle="tooltip" data-placement="top" title="<?php echo translate('OnvifProbe') ?>" ><i class="fa fa-rss"></i></button>
<button id="presetBtn" class="btn btn-normal" data-mid="<?php echo $monitor->Id() ?>" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Presets') ?>" ><i class="fa fa-list-ol"></i></button>
2017-05-19 03:16:59 +08:00
</div>
2017-05-31 07:53:02 +08:00
<?php
} // end if canEdit('Monitors')
?>
</div>
2016-04-15 01:53:10 +08:00
<!-- BEGIN ITEM LIST -->
<div class="d-flex flex-row container-fluid pr-0">
<form name="contentForm" id="contentForm" method="post" action="?view=monitor">
<input type="hidden" name="tab" value="<?php echo $tab?>"/>
<input type="hidden" name="mid" value="<?php echo $monitor->Id() ? $monitor->Id() : $mid ?>"/>
<input type="hidden" name="origMethod" value="<?php echo (null !== $monitor->Method())?validHtmlStr($monitor->Method()):'' ?>"/>
<div class="tab-content" id="pills-tabContent">
2017-05-31 07:53:02 +08:00
<?php
foreach ( $tabs as $name=>$value ) {
2020-12-11 03:32:17 +08:00
echo '<div id="pills-'.$name.'" class="tab-pane fade'.($name==$tab ? ' show active' : '').'" role="tabpanel" aria-labelledby="'.$name.'-tab">';
?>
<table class="major">
2017-05-31 07:53:02 +08:00
<tbody>
<?php
switch ( $name ) {
2017-05-19 03:16:59 +08:00
case 'general' :
{
2017-05-31 07:53:02 +08:00
?>
2019-09-20 02:56:16 +08:00
<tr class="Name">
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Name') ?></td>
2019-09-20 02:56:16 +08:00
<td><input type="text" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/></td>
</tr>
<tr class="Notes">
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Notes') ?></td>
<td><textarea name="newMonitor[Notes]" rows="4"><?php echo validHtmlStr($monitor->Notes()) ?></textarea></td>
</tr>
2019-09-20 02:56:16 +08:00
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Server') ?></td><td>
<?php
2018-01-26 00:41:54 +08:00
$servers = array(''=>'None','auto'=>'Auto');
foreach ( ZM\Server::find(NULL, array('order'=>'lower(Name)')) as $Server ) {
$servers[$Server->Id()] = $Server->Name();
2017-06-15 03:35:35 +08:00
}
echo htmlSelect( 'newMonitor[ServerId]', $servers, $monitor->ServerId() );
?>
2019-09-20 02:56:16 +08:00
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('SourceType') ?></td>
2019-09-20 02:56:16 +08:00
<td><?php echo htmlSelect('newMonitor[Type]', $sourceTypes, $monitor->Type()); ?></td>
</tr>
2020-12-11 04:14:37 +08:00
<?php
if ( $monitor->Type() != 'WebSite' ) {
?>
2019-09-20 02:56:16 +08:00
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Function') ?></td>
2019-09-20 02:56:16 +08:00
<td>
2017-06-15 03:35:35 +08:00
<?php
2019-09-20 02:56:16 +08:00
$function_options = array();
foreach ( getEnumValues('Monitors', 'Function') as $f ) {
$function_options[$f] = translate("Fn$f");
2017-06-15 03:35:35 +08:00
}
2019-09-20 02:56:16 +08:00
echo htmlSelect('newMonitor[Function]', $function_options, $monitor->Function());
2017-06-15 03:35:35 +08:00
?>
2020-12-11 03:32:17 +08:00
<div id="function_help">
<?php
foreach ( ZM\getMonitorFunctionTypes() as $fn => $translated ) {
if ( isset($OLANG['FUNCTION_'.strtoupper($fn)]) ) {
echo '<div class="form-text" id="'.$fn.'Help">'.$OLANG['FUNCTION_'.strtoupper($fn)]['Help'].'</div>';
}
}
?>
</div>
2019-09-20 02:56:16 +08:00
</td>
</tr>
2020-12-11 03:32:17 +08:00
<tr id="FunctionEnabled">
2020-12-11 04:14:37 +08:00
<td class="text-right pr-3"><?php echo translate('Analysis Enabled') ?></td>
2020-12-11 03:32:17 +08:00
<td><input type="checkbox" name="newMonitor[Enabled]" value="1"<?php echo $monitor->Enabled() ? ' checked="checked"' : '' ?>/>
<?php
if ( isset($OLANG['FUNCTION_ANALYSIS_ENABLED']) ) {
echo '<div class="form-text">'.$OLANG['FUNCTION_ANALYSIS_ENABLED']['Help'].'</div>';
}
?>
</td>
2019-09-20 02:56:16 +08:00
</tr>
2020-12-11 04:14:37 +08:00
<tr id="FunctionDecodingEnabled">
<td class="text-right pr-3"><?php echo translate('Decoding Enabled') ?></td>
2020-12-11 05:24:45 +08:00
<td><input type="checkbox" name="newMonitor[DecodingEnabled]" value="1"<?php echo $monitor->DecodingEnabled() ? ' checked="checked"' : '' ?>/>
<?php
2020-12-11 04:14:37 +08:00
if ( isset($OLANG['FUNCTION_DECODING_ENABLED']) ) {
echo '<div class="form-text">'.$OLANG['FUNCTION_DECODING_ENABLED']['Help'].'</div>';
}
?>
2020-12-11 05:24:45 +08:00
</td>
2020-12-11 04:14:37 +08:00
</tr>
2017-05-19 03:16:59 +08:00
<tr>
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3"><?php echo translate('LinkedMonitors'); echo makeHelpLink('OPTIONS_LINKED_MONITORS') ?></td>
<td>
2017-06-15 03:35:35 +08:00
<?php
$monitors = dbFetchAll('SELECT Id, Name FROM Monitors ORDER BY Name,Sequence ASC');
$monitor_options = array();
foreach ( $monitors as $linked_monitor ) {
if ( (!$monitor->Id() || ($monitor->Id()!= $linked_monitor['Id'])) && visibleMonitor($linked_monitor['Id']) ) {
$monitor_options[$linked_monitor['Id']] = validHtmlStr($linked_monitor['Name']);
}
}
2019-09-20 02:56:16 +08:00
echo htmlSelect(
'newMonitor[LinkedMonitors][]',
2019-09-20 02:56:16 +08:00
$monitor_options,
( $monitor->LinkedMonitors() ? explode(',', $monitor->LinkedMonitors()) : array() ),
array('class'=>'chosen','multiple'=>'multiple')
);
2017-06-15 03:35:35 +08:00
?>
</td>
2017-05-19 03:16:59 +08:00
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Groups'); ?></td>
<td><select name="newMonitor[GroupIds][]" multiple="multiple" class="chosen"><?php
echo htmlOptions(ZM\Group::get_dropdown_options(), $monitor->GroupIds());
2019-12-03 04:49:42 +08:00
?></select></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('AnalysisFPS') ?></td>
<td><input type="number" name="newMonitor[AnalysisFPSLimit]" value="<?php echo validHtmlStr($monitor->AnalysisFPSLimit()) ?>" min="0" step="any"/></td>
</tr>
2017-06-15 03:35:35 +08:00
<?php
2017-10-04 04:28:56 +08:00
if ( $monitor->Type() != 'Local' && $monitor->Type() != 'File' && $monitor->Type() != 'NVSocket' ) {
2017-06-15 03:35:35 +08:00
?>
2017-05-19 03:16:59 +08:00
<tr>
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3"><?php echo translate('MaximumFPS'); echo makeHelpLink('OPTIONS_MAXFPS') ?></td>
<td>
<input type="number" name="newMonitor[MaxFPS]" value="<?php echo validHtmlStr($monitor->MaxFPS()) ?>" min="0" step="any"/>
<span id="newMonitor[MaxFPS]" style="color:red;<?php echo $monitor->MaxFPS() ? '' : 'display:none;' ?>">CAUTION: See the help text</span>
</td>
</tr>
2017-05-19 03:16:59 +08:00
<tr>
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3"><?php echo translate('AlarmMaximumFPS'); echo makeHelpLink('OPTIONS_MAXFPS') ?></td>
<td>
<input type="number" name="newMonitor[AlarmMaxFPS]" value="<?php echo validHtmlStr($monitor->AlarmMaxFPS()) ?>" min="0" step="any"/>
<span id="newMonitor[AlarmMaxFPS]" style="color:red;<?php echo $monitor->AlarmMaxFPS() ? '' : 'display:none;' ?>">CAUTION: See the help text</span>
</td>
2017-05-19 03:16:59 +08:00
</tr>
2017-06-15 03:35:35 +08:00
<?php
} else {
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('MaximumFPS') ?></td>
<td><input type="number" name="newMonitor[MaxFPS]" value="<?php echo validHtmlStr($monitor->MaxFPS()) ?>" min="0" step="any"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('AlarmMaximumFPS') ?></td>
<td><input type="number" name="newMonitor[AlarmMaxFPS]" value="<?php echo validHtmlStr($monitor->AlarmMaxFPS()) ?>" min="0" step="any"/></td>
</tr>
2017-06-15 03:35:35 +08:00
<?php
}
if ( ZM_FAST_IMAGE_BLENDS ) {
?>
2017-05-19 03:16:59 +08:00
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('RefImageBlendPct') ?></td>
<td><?php echo htmlSelect('newMonitor[RefBlendPerc]', $fastblendopts, $monitor->RefBlendPerc()); ?></td>
2017-05-19 03:16:59 +08:00
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('AlarmRefImageBlendPct') ?></td>
<td><?php echo htmlSelect('newMonitor[AlarmRefBlendPerc]', $fastblendopts_alarm, $monitor->AlarmRefBlendPerc()); ?></td>
</tr>
2017-05-19 03:16:59 +08:00
<?php
} else {
2017-05-31 01:47:30 +08:00
?>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo translate('RefImageBlendPct') ?></td><td><input type="text" name="newMonitor[RefBlendPerc]" value="<?php echo validHtmlStr($monitor->RefBlendPerc()) ?>" size="4"/></td></tr>
<tr><td class="text-right pr-3"><?php echo translate('AlarmRefImageBlendPct') ?></td><td><input type="text" name="newMonitor[AlarmRefBlendPerc]" value="<?php echo validHtmlStr($monitor->AlarmRefBlendPerc()) ?>" size="4"/></td></tr>
2017-05-31 01:47:30 +08:00
<?php
2017-05-19 03:16:59 +08:00
}
2017-05-31 01:47:30 +08:00
?>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo translate('Triggers') ?></td><td>
2017-05-31 01:47:30 +08:00
<?php
2019-09-20 02:56:16 +08:00
$optTriggers = getSetValues('Monitors', 'Triggers');
2017-06-01 10:01:35 +08:00
$breakCount = (int)(ceil(count($optTriggers)));
2019-09-20 02:56:16 +08:00
$breakCount = min(3, $breakCount);
2017-06-01 10:01:35 +08:00
$optCount = 0;
foreach ( $optTriggers as $optTrigger ) {
if ( $optTrigger == 'X10' and !ZM_OPT_X10 )
2017-06-01 10:01:35 +08:00
continue;
if ( $optCount && ($optCount%$breakCount == 0) )
echo '</br>';
echo '<input type="checkbox" name="newMonitor[Triggers][]" value="'.$optTrigger.'"'.
(( ('' !== $monitor->Triggers()) && in_array($optTrigger, $monitor->Triggers()) ) ? ' checked="checked"' : ''). '/> '. $optTrigger;
$optCount ++;
} # end foreach trigger option
if ( !$optCount ) {
echo '<em>'.translate('NoneAvailable').'</em>';
}
2017-05-31 01:47:30 +08:00
?>
2017-05-19 03:16:59 +08:00
</td></tr>
<?php
}
break;
2017-05-31 01:14:27 +08:00
}
2020-05-13 03:46:07 +08:00
case 'onvif' :
{
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('ONVIF_URL') ?></td>
2020-05-13 03:46:07 +08:00
<td><input type="text" name="newMonitor[ONVIF_URL]" value="<?php echo validHtmlStr($monitor->ONVIF_URL()) ?>"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Username') ?></td>
2020-05-13 03:46:07 +08:00
<td><input type="text" name="newMonitor[ONVIF_Username]" value="<?php echo validHtmlStr($monitor->ONVIF_Username()) ?>"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Password') ?></td>
2020-05-13 03:46:07 +08:00
<td><input type="text" name="newMonitor[ONVIF_Password]" value="<?php echo validHtmlStr($monitor->ONVIF_Password()) ?>"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('ONVIF_Options') ?></td>
2020-05-13 03:46:07 +08:00
<td><input type="text" name="newMonitor[ONVIF_Options]" value="<?php echo validHtmlStr($monitor->ONVIF_Options()) ?>"/></td>
</tr>
<?php
break;
}
case 'source' :
2017-05-31 01:14:27 +08:00
{
2017-06-15 03:35:35 +08:00
if ( ZM_HAS_V4L && $monitor->Type() == 'Local' ) {
?>
2019-08-14 21:44:28 +08:00
<tr>
<td class="text-right pr-3"><?php echo translate('DevicePath') ?></td>
<td><input type="text" name="newMonitor[Device]" value="<?php echo validHtmlStr($monitor->Device()) ?>"/></td>
</tr>
<tr>
<td><?php echo translate('CaptureMethod') ?></td>
<td><?php echo htmlSelect('newMonitor[Method]', $localMethods, $monitor->Method(), array('onchange'=>'submitTab', 'data-tab-name'=>$tab) ); ?></td>
</tr>
2017-06-15 03:35:35 +08:00
<?php
if ( ZM_HAS_V4L1 && $monitor->Method() == 'v4l1' ) {
?>
2017-11-10 03:53:04 +08:00
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('DeviceChannel') ?></td>
<td><?php echo htmlSelect('newMonitor[Channel]', $v4l1DeviceChannels, $monitor->Channel()); ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('DeviceFormat') ?></td>
<td><?php echo htmlSelect('newMonitor[Format]', $v4l1DeviceFormats, $monitor->Format()); ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('CapturePalette') ?></td>
<td><?php echo htmlSelect('newMonitor[Palette]', $v4l1LocalPalettes, $monitor->Palette()); ?></td>
2017-11-10 03:53:04 +08:00
</tr>
2017-06-15 03:35:35 +08:00
<?php
} else {
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('DeviceChannel') ?></td>
<td><?php echo htmlSelect('newMonitor[Channel]', $v4l2DeviceChannels, $monitor->Channel()); ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('DeviceFormat') ?></td>
<td><?php echo htmlSelect('newMonitor[Format]', $v4l2DeviceFormats, $monitor->Format()); ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('CapturePalette') ?></td>
<td><?php echo htmlSelect('newMonitor[Palette]', $v4l2LocalPalettes, $monitor->Palette()); ?></td>
</tr>
2017-06-15 03:35:35 +08:00
<?php
}
2017-06-15 03:35:35 +08:00
?>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo translate('V4LMultiBuffer') ?></td><td>
<input type="radio" name="newMonitor[V4LMultiBuffer]" id="newMonitor[V4LMultiBuffer]1" value="1" <?php echo ( $monitor->V4LMultiBuffer() == '1' ? 'checked="checked"' : '' ) ?>/>
<label for="newMonitor[V4LMultiBuffer]1">Yes</label>
<input type="radio" name="newMonitor[V4LMultiBuffer]" id="newMonitor[V4LMultiBuffer]0" value="0" <?php echo ( $monitor->V4LMultiBuffer() == '0' ? 'checked="checked"' : '' ) ?>/>
<label for="newMonitor[V4LMultiBuffer]0">No</label>
<input type="radio" name="newMonitor[V4LMultiBuffer]" id="newMonitor[V4LMultiBuffer]" value="" <?php echo ( $monitor->V4LMultiBuffer() == '' ? 'checked="checked"' : '' ) ?>/>
<label for="newMonitor[V4LMultiBuffer]">Use Config Value</label>
2017-05-19 03:16:59 +08:00
</td></tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('V4LCapturesPerFrame') ?></td>
<td><input type="number" name="newMonitor[V4LCapturesPerFrame]" value="<?php echo validHtmlStr($monitor->V4LCapturesPerFrame()); ?>" min="1"/></td>
</tr>
2017-06-15 03:35:35 +08:00
<?php
2017-10-04 04:28:56 +08:00
} else if ( $monitor->Type() == 'NVSocket' ) {
2017-11-14 06:25:19 +08:00
include('_monitor_source_nvsocket.php');
2020-03-26 14:21:34 +08:00
} else if ( $monitor->Type() == 'VNC' ) {
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('RemoteHostName') ?></td>
<td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('RemoteHostPort') ?></td>
<td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" size="6"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Username') ?></td>
<td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Password') ?></td>
<td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>"/></td>
</tr>
2017-06-15 03:35:35 +08:00
<?php
2017-10-04 04:28:56 +08:00
} else if ( $monitor->Type() == 'Remote' ) {
2017-06-15 03:35:35 +08:00
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('RemoteProtocol') ?></td>
<td><?php echo htmlSelect('newMonitor[Protocol]', $remoteProtocols, $monitor->Protocol(), "updateMethods( this );if(this.value=='rtsp'){\$('RTSPDescribe').setStyle('display','table-row');}else{\$('RTSPDescribe').hide();}" ); ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('RemoteMethod') ?></td>
<td>
<?php
if ( !$monitor->Protocol() || $monitor->Protocol() == 'http' ) {
echo htmlSelect('newMonitor[Method]', $httpMethods, $monitor->Method());
} else {
echo htmlSelect('newMonitor[Method]', $rtspMethods, $monitor->Method());
}
2017-05-31 01:47:30 +08:00
?>
</td>
</tr>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo translate('RemoteHostName') ?></td><td><input type="text" name="newMonitor[Host]" value="<?php echo validHtmlStr($monitor->Host()) ?>"/></td></tr>
<tr><td><?php echo translate('RemoteHostPort') ?></td><td><input type="number" name="newMonitor[Port]" value="<?php echo validHtmlStr($monitor->Port()) ?>" min="0" max="65535"/></td></tr>
<tr><td><?php echo translate('RemoteHostPath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
2017-05-31 01:47:30 +08:00
<?php
2017-06-15 03:35:35 +08:00
} else if ( $monitor->Type() == 'File' ) {
2017-05-31 01:47:30 +08:00
?>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo translate('SourcePath') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
2017-05-31 01:47:30 +08:00
<?php
2017-06-15 03:35:35 +08:00
} elseif ( $monitor->Type() == 'cURL' ) {
2017-05-31 01:47:30 +08:00
?>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo 'URL' ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td></tr>
<tr><td class="text-right pr-3"><?php echo 'Username' ?></td><td><input type="text" name="newMonitor[User]" value="<?php echo validHtmlStr($monitor->User()) ?>"/></td></tr>
<tr><td class="text-right pr-3"><?php echo 'Password' ?></td><td><input type="text" name="newMonitor[Pass]" value="<?php echo validHtmlStr($monitor->Pass()) ?>"/></td></tr>
<?php
} elseif ( $monitor->Type() == 'WebSite' ) {
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('WebSiteUrl') ?></td>
<td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>"/></td>
</tr>
<tr>
<td><?php echo translate('Width') ?> (<?php echo translate('Pixels') ?>)</td>
<td><input type="number" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" min="1"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Height') ?> (<?php echo translate('Pixels') ?>)</td>
<td><input type="number" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" min="1"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"<?php echo 'Web Site Refresh (Optional)' ?></td>
<td><input type="number" name="newMonitor[Refresh]" value="<?php echo validHtmlStr($monitor->Refresh()) ?>" min="1"/></td>
</tr>
2017-05-31 01:47:30 +08:00
<?php
} else if ( $monitor->Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) {
2017-05-31 01:47:30 +08:00
?>
<tr class="SourcePath">
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('SourcePath') ?></td>
<td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" /></td>
</tr>
<tr>
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3">
<?php echo translate('RemoteMethod'); echo makeHelpLink('OPTIONS_RTSPTrans') ?></td>
<td><?php echo htmlSelect('newMonitor[Method]', $rtspFFMpegMethods, $monitor->Method()) ?></td>
</tr>
<tr class="SourceOptions">
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3"><?php echo translate('Options'); echo makeHelpLink('OPTIONS_'.strtoupper($monitor->Type())) ?></td>
<td><input type="text" name="newMonitor[Options]" value="<?php echo validHtmlStr($monitor->Options()) ?>"/></td>
</tr>
2019-06-26 03:34:45 +08:00
<?php
}
if ( $monitor->Type() == 'Ffmpeg' ) {
?>
2019-08-14 21:44:28 +08:00
<tr class="SourceSecondPath">
2021-03-03 22:55:23 +08:00
<td class="text-right pr-3"><?php echo translate('SourceSecondPath') ?></td>
2019-08-14 21:44:28 +08:00
<td><input type="text" name="newMonitor[SecondPath]" value="<?php echo validHtmlStr($monitor->SecondPath()) ?>" /></td>
</tr>
2019-06-26 03:34:45 +08:00
<tr class="DecoderHWAccelName">
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3">
<?php echo translate('DecoderHWAccelName'); echo makeHelpLink('OPTIONS_DECODERHWACCELNAME') ?>
2019-06-26 03:34:45 +08:00
</td>
<td><input type="text" name="newMonitor[DecoderHWAccelName]" value="<?php echo validHtmlStr($monitor->DecoderHWAccelName()) ?>"/></td>
</tr>
<tr class="DecoderHWAccelDevice">
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('DecoderHWAccelDevice') ?>
2020-09-12 02:10:18 +08:00
<?php echo makeHelpLink('OPTIONS_DECODERHWACCELDEVICE') ?>
2019-06-26 03:34:45 +08:00
</td>
<td><input type="text" name="newMonitor[DecoderHWAccelDevice]" value="<?php echo validHtmlStr($monitor->DecoderHWAccelDevice()) ?>"/></td>
</tr>
2017-05-31 01:47:30 +08:00
<?php
2017-06-01 10:01:35 +08:00
}
if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
2017-05-31 01:47:30 +08:00
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('TargetColorspace') ?></td>
<td><?php echo htmlSelect('newMonitor[Colours]', $Colours, $monitor->Colours()) ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('CaptureResolution') ?> (<?php echo translate('Pixels') ?>)</td>
<td>
<input type="number" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" min="1"/>
<input type="number" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" min="1"/>
2021-01-30 09:37:55 +08:00
<?php
$resolutions =
array(
''=>translate('Custom'),
'176x120'=>'176x120 QCIF',
'176x144'=>'176x14',
'320x240'=>'320x240',
'320x200'=>'320x200',
'352x240'=>'352x240 CIF',
'352x480'=>'352x480',
'640x360'=>'640x360',
'640x400'=>'640x400',
'640x480'=>'640x480',
'704x240'=>'704x240 2CIF',
'704x480'=>'704x480 4CIF',
'704x576'=>'704x576 D1 PAL',
'720x480'=>'720x480 Full D1 NTSC',
'720x576'=>'720x576 Full D1 PAL',
'1280x720'=>'1280x720 720p',
'1280x800'=>'1280x800',
'1280x960'=>'1280x960 960p',
'1280x1024'=>'1280x1024 1MP',
'1600x1200'=>'1600x1200 2MP',
'1920x1080'=>'1920x1080 1080p',
'2048x1536'=>'2048x1536 3MP',
'2560x1440'=>'2560x1440 1440p QHD WQHD',
'2592x1944'=>'2592x1944 5MP',
2021-02-25 04:03:11 +08:00
'2688x1520'=>'2688x1520 4MP',
'3072x2048'=>'3072x2048 6MP',
2021-01-30 09:37:55 +08:00
'3840x2160'=>'3840x2160 4K UHD',
);
$selected = '';
if ( $monitor->Width() and $monitor->Height() ) {
$selected = $monitor->Width().'x'.$monitor->Height();
if ( ! isset($resolutions[$selected]) ) {
$resolutions[$selected] = $selected;
}
2021-01-30 09:37:55 +08:00
}
echo htmlselect('dimensions_select', $resolutions, $selected);
?>
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('PreserveAspect') ?></td>
<td><input type="checkbox" name="preserveAspectRatio" value="1"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Orientation') ?></td>
<td><?php echo htmlselect('newMonitor[Orientation]', $orientations, $monitor->Orientation());?></td>
</tr>
2017-05-31 01:47:30 +08:00
<?php
}
if ( $monitor->Type() == 'Local' ) {
2017-05-31 01:47:30 +08:00
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Deinterlacing') ?></td>
<td><?php echo htmlselect('newMonitor[Deinterlacing]', $deinterlaceopts_v4l2, $monitor->Deinterlacing())?></td>
</tr>
<?php
} else if ( $monitor->Type() != 'WebSite' ) {
2017-05-31 01:47:30 +08:00
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Deinterlacing') ?></td>
<td><?php echo htmlselect('newMonitor[Deinterlacing]', $deinterlaceopts, $monitor->Deinterlacing())?></td>
</tr>
2017-05-31 01:47:30 +08:00
<?php
2017-06-15 03:35:35 +08:00
}
if ( $monitor->Type() == 'Remote' ) {
?>
2020-03-04 23:46:59 +08:00
<tr id="RTSPDescribe"<?php if ( $monitor->Protocol()!= 'rtsp' ) { echo ' style="display:none;"'; } ?>>
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3"><?php echo translate('RTSPDescribe'); echo makeHelpLink('OPTIONS_RTSPDESCRIBE') ?></td>
2020-03-04 23:46:59 +08:00
<td><input type="checkbox" name="newMonitor[RTSPDescribe]" value="1"<?php if ( $monitor->RTSPDescribe() ) { ?> checked="checked"<?php } ?>/></td>
</tr>
2017-05-31 01:47:30 +08:00
<?php
2020-03-04 23:46:59 +08:00
} # end if monitor->Type() == 'Remote'
2017-06-01 10:01:35 +08:00
break;
}
2017-06-01 10:01:35 +08:00
case 'storage' :
2017-05-31 01:47:30 +08:00
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('StorageArea') ?></td>
<td>
<?php
$storage_areas = array(0=>'Default');
2020-03-04 23:46:59 +08:00
foreach ( ZM\Storage::find(array('Enabled'=>true), array('order'=>'lower(Name)')) as $Storage ) {
$storage_areas[$Storage->Id()] = $Storage->Name();
}
echo htmlSelect('newMonitor[StorageId]', $storage_areas, $monitor->StorageId());
?>
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('SaveJPEGs') ?></td>
<td>
<?php
$savejpegopts = array(
0 => 'Disabled',
1 => 'Frames only',
2 => 'Analysis images only (if available)',
3 => 'Frames + Analysis images (if available)',
);
echo htmlSelect('newMonitor[SaveJPEGs]', $savejpegopts, $monitor->SaveJPEGs());
?>
</td>
</tr>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo translate('VideoWriter') ?></td><td>
<?php
$videowriteropts = array(
0 => 'Disabled',
);
2018-10-01 21:17:22 +08:00
$videowriteropts[1] = 'X264 Encode';
2018-10-01 21:17:22 +08:00
if ( $monitor->Type() == 'Ffmpeg' )
2018-10-01 21:17:22 +08:00
$videowriteropts[2] = 'H264 Camera Passthrough';
else
$videowriteropts[2] = array('text'=>'H264 Camera Passthrough - only for FFMPEG','disabled'=>1);
echo htmlSelect('newMonitor[VideoWriter]', $videowriteropts, $monitor->VideoWriter());
?>
</td>
</tr>
<tr>
<td><?php echo translate('OutputCodec') ?></td>
<td>
<?php
$videowriter_codecs = array(
'0' => translate('Auto'),
2020-12-16 05:56:27 +08:00
'27' => 'h264',
'173' => 'h265/hevc',
'8' => 'mjpeg',
'1' => 'mpeg1',
'2' => 'mpeg2',
);
echo htmlSelect('newMonitor[OutputCodec]', $videowriter_codecs, $monitor->OutputCodec());
?>
</td>
</tr>
<tr>
<td><?php echo translate('Encoder') ?></td>
<td>
<?php
$videowriter_encoders = array(
'auto' => translate('Auto'),
'h264_omx' => 'h264_omx',
'libx264' => 'libx264',
'h264_vaapi' => 'h264_vaapi',
'h264' => 'h264',
'mjpeg' => 'mjpeg',
'mpeg1' => 'mpeg1',
'mpeg2' => 'mpeg2',
);
echo htmlSelect('newMonitor[Encoder]', $videowriter_encoders, $monitor->Encoder());?></td></tr>
<tr>
<td><?php echo translate('OutputContainer') ?></td>
<td>
<?php
$videowriter_containers = array(
'' => translate('Auto'),
'mp4' => 'mp4',
'mkv' => 'mkv',
);
echo htmlSelect('newMonitor[OutputContainer]', $videowriter_containers, $monitor->OutputContainer());
?>
</td>
</tr>
<tr>
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3"><?php echo translate('OptionalEncoderParam'); echo makeHelpLink('OPTIONS_ENCODER_PARAMETERS') ?></td>
<td>
<textarea name="newMonitor[EncoderParameters]" rows="<?php echo count(explode("\n", $monitor->EncoderParameters())); ?>"><?php echo validHtmlStr($monitor->EncoderParameters()) ?></textarea>
</td>
</tr>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo translate('RecordAudio') ?></td><td>
<?php if ( $monitor->Type() == 'Ffmpeg' ) { ?>
<input type="checkbox" name="newMonitor[RecordAudio]" value="1"<?php if ( $monitor->RecordAudio() ) { ?> checked="checked"<?php } ?>/>
<?php } else { ?>
Audio recording only available with FFMPEG
<input type="hidden" name="newMonitor[RecordAudio]" value="<?php echo $monitor->RecordAudio() ? 1 : 0 ?>"/>
<?php } ?>
</td></tr>
2017-05-31 01:47:30 +08:00
<?php
2017-05-19 03:16:59 +08:00
break;
case 'timestamp' :
{
2017-05-31 01:47:30 +08:00
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('TimestampLabelFormat') ?></td>
<td><input type="text" name="newMonitor[LabelFormat]" value="<?php echo validHtmlStr($monitor->LabelFormat()) ?>"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('TimestampLabelX') ?></td>
<td><input type="number" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX()) ?>" min="0"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('TimestampLabelY') ?></td>
<td><input type="number" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY()) ?>" min="0"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('TimestampLabelSize') ?></td>
<td><?php echo htmlselect('newMonitor[LabelSize]', $label_size, $monitor->LabelSize()) ?></td>
</tr>
2017-05-31 01:47:30 +08:00
<?php
2017-06-01 10:01:35 +08:00
break;
}
2017-05-19 03:16:59 +08:00
case 'buffers' :
{
2017-05-31 01:47:30 +08:00
?>
<tr>
2021-03-27 05:02:17 +08:00
<td class="text-right pr-3"><?php echo translate('ImageBufferSize'); echo makeHelpLink('ImageBufferCount'); ?></td>
<td><input type="number" name="newMonitor[ImageBufferCount]" value="<?php echo validHtmlStr($monitor->ImageBufferCount()) ?>" min="1"/></td>
</tr>
<tr>
2021-03-27 05:02:17 +08:00
<td class="text-right pr-3"><?php echo translate('MaxImageBufferCount'); echo makeHelpLink('MaxImageBufferCount'); ?></td>
<td><input type="number" name="newMonitor[MaxImageBufferCount]" value="<?php echo validHtmlStr($monitor->MaxImageBufferCount()) ?>" min="0"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('WarmupFrames') ?></td>
<td><input type="number" name="newMonitor[WarmupCount]" value="<?php echo validHtmlStr($monitor->WarmupCount()) ?>" min="0"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('PreEventImageBuffer') ?></td>
<td><input type="number" name="newMonitor[PreEventCount]" value="<?php echo validHtmlStr($monitor->PreEventCount()) ?>" min="0"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('PostEventImageBuffer') ?></td>
<td><input type="number" name="newMonitor[PostEventCount]" value="<?php echo validHtmlStr($monitor->PostEventCount()) ?>" min="0"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('StreamReplayBuffer') ?></td>
<td><input type="number" name="newMonitor[StreamReplayBuffer]" value="<?php echo validHtmlStr($monitor->StreamReplayBuffer()) ?>" min="0"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('AlarmFrameCount') ?></td>
<td><input type="number" name="newMonitor[AlarmFrameCount]" value="<?php echo validHtmlStr($monitor->AlarmFrameCount()) ?>" min="1"/></td>
</tr>
2017-05-31 01:47:30 +08:00
<?php
2017-06-01 10:01:35 +08:00
break;
}
2017-05-19 03:16:59 +08:00
case 'control' :
{
2017-05-31 01:47:30 +08:00
?>
2019-09-20 02:56:16 +08:00
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Controllable') ?></td>
<td><input type="checkbox" name="newMonitor[Controllable]" value="1"<?php if ( $monitor->Controllable() ) { ?> checked="checked"<?php } ?>/></td>
</tr>
2019-09-20 02:56:16 +08:00
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('ControlType') ?></td>
2020-09-05 20:46:18 +08:00
<td>
<?php
$controlTypes = array(''=>translate('None'));
foreach ( $controls as $control ) {
$controlTypes[$control->Id()] = $control->Name();
}
echo htmlSelect('newMonitor[ControlId]', $controlTypes, $monitor->ControlId());
if ( canEdit('Control') ) {
2020-09-26 05:18:44 +08:00
echo '&nbsp;'.makeLink('?view=controlcaps', translate('Edit'));
2020-09-05 20:46:18 +08:00
}
?>
</td>
2019-09-20 02:56:16 +08:00
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('ControlDevice') ?></td>
2019-09-20 02:56:16 +08:00
<td><input type="text" name="newMonitor[ControlDevice]" value="<?php echo validHtmlStr($monitor->ControlDevice()) ?>"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('ControlAddress') ?></td>
2020-07-28 23:37:10 +08:00
<td><input type="text" name="newMonitor[ControlAddress]" value="<?php echo validHtmlStr($monitor->ControlAddress()) ? : 'user:port@ip' ?>"/></td>
2019-09-20 02:56:16 +08:00
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('AutoStopTimeout') ?></td>
<td><input type="number" name="newMonitor[AutoStopTimeout]" value="<?php echo validHtmlStr($monitor->AutoStopTimeout()) ?>" min="0" step="any"/></td>
2019-09-20 02:56:16 +08:00
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('TrackMotion') ?></td>
2019-09-20 02:56:16 +08:00
<td><input type="checkbox" name="newMonitor[TrackMotion]" value="1"<?php if ( $monitor->TrackMotion() ) { ?> checked="checked"<?php } ?>/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('TrackDelay') ?></td>
<td><input type="number" name="newMonitor[TrackDelay]" value="<?php echo validHtmlStr($monitor->TrackDelay()) ?>" min="0" step="any"/></td>
2019-09-20 02:56:16 +08:00
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('ReturnLocation') ?></td>
<td><?php
$return_options = array(
'-1' => translate('None'),
'0' => translate('Home'),
'1' => translate('Preset').' 1',
);
echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnLocation()); ?></td>
2019-09-20 02:56:16 +08:00
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('ReturnDelay') ?></td>
<td><input type="number" name="newMonitor[ReturnDelay]" value="<?php echo validHtmlStr($monitor->ReturnDelay()) ?>" min="0" step="any"/></td>
2019-09-20 02:56:16 +08:00
</tr>
2017-05-31 01:47:30 +08:00
<?php
2017-06-01 10:01:35 +08:00
break;
}
2017-05-19 03:16:59 +08:00
case 'x10' :
{
2017-05-31 01:47:30 +08:00
?>
2020-08-29 02:18:01 +08:00
<tr><td class="text-right pr-3"><?php echo translate('X10ActivationString') ?></td><td><input type="text" name="newX10Monitor[Activation]" value="<?php echo validHtmlStr($newX10Monitor['Activation']) ?>" size="20"/></td></tr>
<tr><td class="text-right pr-3"><?php echo translate('X10InputAlarmString') ?></td><td><input type="text" name="newX10Monitor[AlarmInput]" value="<?php echo validHtmlStr($newX10Monitor['AlarmInput']) ?>" size="20"/></td></tr>
<tr><td class="text-right pr-3"><?php echo translate('X10OutputAlarmString') ?></td><td><input type="text" name="newX10Monitor[AlarmOutput]" value="<?php echo validHtmlStr($newX10Monitor['AlarmOutput']) ?>" size="20"/></td></tr>
2017-05-31 01:47:30 +08:00
<?php
2017-06-01 10:01:35 +08:00
break;
}
2017-05-19 03:16:59 +08:00
case 'misc' :
{
2017-06-15 03:35:35 +08:00
?>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('EventPrefix') ?></td>
<td><input type="text" name="newMonitor[EventPrefix]" value="<?php echo validHtmlStr($monitor->EventPrefix()) ?>"/></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('Sectionlength') ?></td>
<td>
<input type="number" name="newMonitor[SectionLength]" value="<?php echo validHtmlStr($monitor->SectionLength()) ?>" min="0"/>
<?php echo translate('seconds')?>
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('MinSectionlength') ?></td>
<td>
<input type="number" name="newMonitor[MinSectionLength]" value="<?php echo validHtmlStr($monitor->MinSectionLength()) ?>" min="0"/>
<?php echo translate('seconds')?>
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('FrameSkip') ?></td>
<td>
<input type="number" name="newMonitor[FrameSkip]" value="<?php echo validHtmlStr($monitor->FrameSkip()) ?>" min="0"/>
<?php echo translate('frames')?>
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('MotionFrameSkip') ?></td>
<td>
<input type="number" name="newMonitor[MotionFrameSkip]" value="<?php echo validHtmlStr($monitor->MotionFrameSkip()) ?>" min="0"/>
<?php echo translate('frames')?>
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('AnalysisUpdateDelay') ?></td>
<td>
<input type="number" name="newMonitor[AnalysisUpdateDelay]" value="<?php echo validHtmlStr($monitor->AnalysisUpdateDelay()) ?>" min="0"/>
<?php echo translate('seconds')?>
</td></tr>
<tr>
2020-09-23 03:51:44 +08:00
<td class="text-right pr-3"><?php echo translate('FPSReportInterval') ?></td>
<td>
<input type="number" name="newMonitor[FPSReportInterval]" value="<?php echo validHtmlStr($monitor->FPSReportInterval()) ?>" min="0"/>
<?php echo translate('frames')?>
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('DefaultRate') ?></td>
<td><?php echo htmlSelect('newMonitor[DefaultRate]', $rates, $monitor->DefaultRate()); ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('DefaultScale') ?></td>
<td><?php echo htmlSelect('newMonitor[DefaultScale]', $scales, $monitor->DefaultScale()); ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('DefaultCodec') ?></td>
<td><?php echo htmlSelect('newMonitor[DefaultCodec]', $codecs, $monitor->DefaultCodec()); ?></td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('SignalCheckPoints') ?></td>
<td>
<input type="number" name="newMonitor[SignalCheckPoints]" value="<?php echo validInt($monitor->SignalCheckPoints()) ?>" min="0"/>
</td>
</tr>
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('SignalCheckColour') ?></td>
<td>
<input type="color" name="newMonitor[SignalCheckColour]" value="<?php echo validHtmlStr($monitor->SignalCheckColour()) ?>"/>
<span id="SignalCheckSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->SignalCheckColour()); ?>;">&nbsp;&nbsp;&nbsp;&nbsp;</span>
</td>
</tr>
2017-06-15 03:35:35 +08:00
<tr>
2020-08-29 02:18:01 +08:00
<td class="text-right pr-3"><?php echo translate('WebColour') ?></td>
<td>
<input type="color" name="newMonitor[WebColour]" value="<?php echo validHtmlStr($monitor->WebColour()) ?>"/>
<span id="WebSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->WebColour()) ?>;">&nbsp;&nbsp;&nbsp;&nbsp;</span>
<i class="material-icons" data-on-click="random_WebColour">sync</i>
</td>
</tr>
2017-06-15 03:35:35 +08:00
<tr>
2020-09-12 02:10:18 +08:00
<td class="text-right pr-3"><?php echo translate('Exif'); echo makeHelpLink('OPTIONS_EXIF') ?></td>
2021-02-03 03:24:23 +08:00
<td><input type="checkbox" name="newMonitor[Exif]" value="1"<?php echo $monitor->Exif() ? ' checked="checked"' : '' ?>/></td>
</tr>
<tr>
<td class="text-right pr-3"><?php echo translate('RTSPServer'); echo makeHelpLink('OPTIONS_RTSPSERVER') ?></td>
<td><input type="checkbox" name="newMonitor[RTSPServer]" value="1"<?php echo $monitor->RTSPServer() ? ' checked="checked"' : '' ?>/></td>
</tr>
2021-02-28 01:28:59 +08:00
<tr>
<td class="text-right pr-3"><?php echo translate('RTSPStreamName'); echo makeHelpLink('OPTIONS_RTSPSTREAMNAME') ?></td>
<td><input type="text" name="newMonitor[RTSPStreamName]" value="<?php echo validHtmlStr($monitor->RTSPStreamName()) ?>"/></td>
</tr>
2017-06-15 03:35:35 +08:00
<?php
break;
}
case 'location':
?>
<tr>
<td class="text-right pr-3"><?php echo translate('Latitude') ?></td>
<td><input type="number" name="newMonitor[Latitude]" step="any" value="<?php echo $monitor->Latitude() ?>" min="-90" max="90"/></td>
</tr>
<tr>
<td class="text-right pr-3"><?php echo translate('Longitude') ?></td>
<td><input type="number" name="newMonitor[Longitude]" step="any" value="<?php echo $monitor->Longitude() ?>" min="-180" max="180"/></td>
</tr>
<tr>
<td class="text-right pr-3"><?php echo translate('Longitude') ?></td>
<td><button type="button" data-on-click="getLocation"><?php echo translate('GetCurrentLocation') ?></button></td>
2020-09-25 08:31:22 +08:00
</tr>
<tr>
<td colspan="2"><div id="LocationMap" style="height: 500px; width: 500px;"></div></td>
</tr>
<?php
break;
default :
ZM\Error("Unknown tab $tab");
2017-06-01 00:55:27 +08:00
} // end switch tab
?>
</tbody>
</table>
</div>
<?php
} # end foreach tab
?>
</div><!--tab-content-->
<div id="contentButtons" class="pr-3">
<button type="submit" name="action" value="save"<?php echo canEdit('Monitors') ? '' : ' disabled="disabled"' ?>><?php echo translate('Save') ?></button>
2020-08-28 23:56:09 +08:00
<button type="button" id="cancelBtn"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
2016-04-15 01:53:10 +08:00
</div>
2020-08-29 02:09:49 +08:00
</div>
</div>
<?php xhtmlFooter() ?>