''); } $mid = null; $monitor = null; if (!empty($_REQUEST['mid'])) { $mid = validInt($_REQUEST['mid']); $monitor = new ZM\Monitor($mid); if ($monitor->Id()) { if (ZM_OPT_X10) { $x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($mid)); } } else { $monitor->Name(translate('Monitor').'-'.$mid); $monitor->WebColour(random_colour()); } } if (!$monitor) { $monitor = new ZM\Monitor(); $monitor->Name(translate('Monitor').'-'.getTableAutoInc('Monitors')); $monitor->WebColour(random_colour()); } # 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); } if (ZM_OPT_X10 && empty($x10Monitor)) { $x10Monitor = array( 'Activation' => '', 'AlarmInput' => '', 'AlarmOutput' => '', ); } 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']); if (ZM_OPT_X10) $newX10Monitor = $_REQUEST['newX10Monitor']; } else { if (ZM_OPT_X10) $newX10Monitor = $x10Monitor; } # What if it has less zeros? This is not robust code. if ( $monitor->AnalysisFPSLimit() == '0.00' ) $monitor->AnalysisFPSLimit(''); if ( $monitor->MaxFPS() == '0.00' ) $monitor->MaxFPS(''); if ( $monitor->AlarmMaxFPS() == '0.00' ) $monitor->AlarmMaxFPS(''); 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. # Icon: It does, but this means we can't set a null value. if ( isset($value) ) { $monitor->$name($value); } } } # end if preset if ( !empty($_REQUEST['probe']) ) { $probe = json_decode(base64_decode($_REQUEST['probe'])); foreach ( $probe as $name=>$value ) { if ( isset($value) ) { # Does isset handle NULL's? I don't think this code is correct. $monitor->$name = urldecode($value); } } if ( ZM_HAS_V4L2 && $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( 'Local' => translate('Local'), 'Remote' => translate('Remote'), 'File' => translate('File'), 'Ffmpeg' => translate('Ffmpeg'), 'Libvlc' => translate('Libvlc'), 'cURL' => 'cURL (HTTP(S) only)', 'WebSite'=> 'Web Site', 'NVSocket' => translate('NVSocket'), 'VNC' => translate('VNC'), ); if ( !ZM_HAS_V4L2 ) unset($sourceTypes['Local']); $localMethods = array( 'v4l2' => 'Video For Linux version 2', ); if ( !ZM_HAS_V4L2 ) unset($localMethods['v4l2']); $remoteProtocols = array( 'http' => 'HTTP', 'rtsp' => 'RTSP' ); $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' ); $httpMethods = array( 'simple' => 'Simple', 'regexp' => 'Regexp', 'jpegTags' => 'JPEG Tags' ); if ( !ZM_PCRE ) unset($httpMethods['regexp']); // Currently unsupported unset($httpMethods['jpegTags']); if ( ZM_HAS_V4L2 ) { $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', ); $v4l2MaxChannels = 31; $v4l2DeviceChannels = array(); for ( $i = 0; $i <= $v4l2MaxChannels; $i++ ) $v4l2DeviceChannels[$i] = $i; $v4l2LocalPalettes = array( 0 => 'Auto', /* Automatic palette selection */ /* 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 */ /* 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 */ // 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 */ 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 */ /* 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 */ /* 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 */ /* 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.. */ /* Vendor-specific formats */ //'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 */ ); } $Colours = array( '1' => translate('8BitGrey'), '3' => translate('24BitColour'), '4' => translate('32BitColour') ); $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') ); $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%', ); $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)', ); $label_size = array( 1 => translate('Small'), 2 => translate('Default'), 3 => translate('Large'), 4 => translate('Extra Large'), ); $codecs = array( 'auto' => translate('Auto'), 'MP4' => translate('MP4'), 'MJPEG' => translate('MJPEG'), ); $monitors = dbFetchAll('SELECT Id, Name FROM Monitors ORDER BY Name,Sequence ASC'); $controls = ZM\Control::find(null, array('order'=>'lower(Name)')); xhtmlHeaders(__FILE__, translate('Monitor').' - '.validHtmlStr($monitor->Name())); getBodyTopHTML(); echo getNavBarHTML(); ?>

- Name()) ?>Id() ) { ?> (Id()?>)

Configuration cloned from Monitor:
$value ) { echo '
'; ?> Id() and count($monitors)) { $monitor_ids = array(); foreach ($monitors as $m) { $monitor_ids[] = $m['Id']; } $available_monitor_ids = array_diff(range(min($monitor_ids),max($monitor_ids)), $monitor_ids); ?> Id() and count($monitors) ?> Type() != 'WebSite' ) { ?> Type() != 'Local' && $monitor->Type() != 'File' && $monitor->Type() != 'NVSocket' ) { ?> Type() == 'Local' ) { ?> Method() == 'v4l2' ) { ?> Type() == 'NVSocket' ) { include('_monitor_source_nvsocket.php'); } else if ( $monitor->Type() == 'VNC' ) { ?> Type() == 'Remote' ) { ?> Type() == 'File' ) { ?> Type() == 'cURL' ) { ?> Type() == 'WebSite' ) { ?> Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) { ?> Type() == 'Ffmpeg' ) { ?> Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) { ?> Type() == 'Local' ) { ?> Type() != 'WebSite' ) { ?> Type() == 'Remote' ) { ?> Protocol()!= 'rtsp' ) { echo ' style="display:none;"'; } ?>> Type() == 'Remote' break; } case 'storage' : ?>

translate('Unknown')); foreach ( ZM\Manufacturer::find( null, array('order'=>'lower(Name)')) as $Manufacturer ) { $manufacturers[$Manufacturer->Id()] = $Manufacturer->Name(); } echo htmlSelect('newMonitor[ManufacturerId]', $manufacturers, $monitor->ManufacturerId(), array('class'=>'chosen','data-on-change-this'=>'ManufacturerId_onchange')); ?> ManufacturerId() ? ' style="display:none"' : '' ?> data-on-input-this="Manufacturer_onchange" />
translate('Unknown')); foreach ( ZM\Model::find(array('ManufacturerId'=>$monitor->ManufacturerId()), array('order'=>'lower(Name)')) as $Model ) { $models[$Model->Id()] = $Model->Name(); } echo htmlSelect('newMonitor[ModelId]', $models, $monitor->ModelId(), array('class'=>'chosen', 'data-on-change-this'=>'ModelId_onchange')); ?> ModelId() ? ' style="display:none"':'' ?> data-on-input-this="Model_onchange" />
'None','auto'=>'Auto'); foreach ( ZM\Server::find(NULL, array('order'=>'lower(Name)')) as $Server ) { $servers[$Server->Id()] = $Server->Name(); } echo htmlSelect( 'newMonitor[ServerId]', $servers, $monitor->ServerId() ); ?>
Type()); ?>
Function()); ?>
$translated ) { if ( isset($OLANG['FUNCTION_'.strtoupper($fn)]) ) { echo '
'.$OLANG['FUNCTION_'.strtoupper($fn)]['Help'].'
'; } } ?>
Enabled() ? ' checked="checked"' : '' ?>/> '.$OLANG['FUNCTION_ANALYSIS_ENABLED']['Help'].''; } ?>
DecodingEnabled() ? ' checked="checked"' : '' ?>/> '.$OLANG['FUNCTION_DECODING_ENABLED']['Help'].''; } ?>
Id() || ($monitor->Id()!= $linked_monitor['Id'])) && visibleMonitor($linked_monitor['Id']) ) { $monitor_options[$linked_monitor['Id']] = validHtmlStr($linked_monitor['Name']); } } echo htmlSelect( 'newMonitor[LinkedMonitors][]', $monitor_options, ( $monitor->LinkedMonitors() ? explode(',', $monitor->LinkedMonitors()) : array() ), array('class'=>'chosen','multiple'=>'multiple') ); ?>
CAUTION: See the help text
CAUTION: See the help text
RefBlendPerc()); ?>
AlarmRefBlendPerc()); ?>
'; echo 'Triggers()) && in_array($optTrigger, $monitor->Triggers()) ) ? ' checked="checked"' : ''). '/> '. $optTrigger; $optCount ++; } # end foreach trigger option if ( !$optCount ) { echo ''.translate('NoneAvailable').''; } ?>
Method(), array('onchange'=>'submitTab', 'data-tab-name'=>$tab) ); ?>
Channel()); ?>
Format()); ?>
Palette()); ?>
V4LMultiBuffer() == '1' ? 'checked="checked"' : '' ) ?>/> V4LMultiBuffer() == '0' ? 'checked="checked"' : '' ) ?>/> V4LMultiBuffer() == '' ? 'checked="checked"' : '' ) ?>/>
Protocol(), "updateMethods( this );if(this.value=='rtsp'){\$('RTSPDescribe').setStyle('display','table-row');}else{\$('RTSPDescribe').hide();}" ); ?>
Protocol() || $monitor->Protocol() == 'http' ) { echo htmlSelect('newMonitor[Method]', $httpMethods, $monitor->Method()); } else { echo htmlSelect('newMonitor[Method]', $rtspMethods, $monitor->Method()); } ?>
()
()
Method()) ?>
Type())) ?>
Colours()) ?>
() 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', '2688x1520'=>'2688x1520 4MP', '3072x2048'=>'3072x2048 6MP', '3840x2160'=>'3840x2160 4K UHD', ); $selected = ''; if ( $monitor->Width() and $monitor->Height() ) { $selected = $monitor->Width().'x'.$monitor->Height(); if ( ! isset($resolutions[$selected]) ) { $resolutions[$selected] = $selected; } } echo htmlselect('dimensions_select', $resolutions, $selected); ?>
Orientation());?>
Deinterlacing())?>
Deinterlacing())?>
RTSPDescribe() ) { ?> checked="checked"/>
'Default'); 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()); ?>
'Disabled', 1 => 'Frames only', 2 => 'Analysis images only (if available)', 3 => 'Frames + Analysis images (if available)', ); echo htmlSelect('newMonitor[SaveJPEGs]', $savejpegopts, $monitor->SaveJPEGs()); ?>
'Disabled', ); $videowriteropts[1] = 'Encode'; if ( $monitor->Type() == 'Ffmpeg' ) $videowriteropts[2] = 'Camera Passthrough'; else $videowriteropts[2] = array('text'=>'Camera Passthrough - only for FFMPEG','disabled'=>1); echo htmlSelect('newMonitor[VideoWriter]', $videowriteropts, $monitor->VideoWriter()); ?>
translate('Auto'), '27' => 'h264', '173' => 'h265/hevc', ); echo htmlSelect('newMonitor[OutputCodec]', $videowriter_codecs, $monitor->OutputCodec()); ?>
translate('Auto'), 'libx264' => 'libx264', 'h264' => 'h264', 'h264_nvenc' => 'h264_nvenc', 'h264_omx' => 'h264_omx', 'h264_vaapi' => 'h264_vaapi', 'libx265' => 'libx265', 'hevc_nvenc' => 'hevc_nvenc', 'hevc_vaapi' => 'hevc_vaapi', ); echo htmlSelect('newMonitor[Encoder]', $videowriter_encoders, $monitor->Encoder());?>
translate('Auto'), 'mp4' => 'mp4', 'mkv' => 'mkv', ); echo htmlSelect('newMonitor[OutputContainer]', $videowriter_containers, $monitor->OutputContainer()); ?>
Type() == 'Ffmpeg' ) { ?> RecordAudio() ) { ?> checked="checked"/> Audio recording only available with FFMPEG
LabelSize()) ?>
Controllable() ) { ?> checked="checked"/>
translate('None')); foreach ( $controls as $control ) { $controlTypes[$control->Id()] = $control->Name(); } echo htmlSelect('newMonitor[ControlId]', $controlTypes, $monitor->ControlId()); if ( canEdit('Control') ) { echo ' '.makeLink('?view=controlcaps', translate('Edit')); } ?>
ModectDuringPTZ() ) { ?> checked="checked"/>
TrackMotion() ) { ?> checked="checked"/>
translate('None'), '0' => translate('Home'), '1' => translate('Preset').' 1', ); echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnLocation()); ?>
DefaultRate()); ?>
DefaultScale()); ?>
DefaultCodec()); ?>
    
     sync
Exif() ? ' checked="checked"' : '' ?>/>
RTSPServer() ? ' checked="checked"' : '' ?>/>
translate('Not important'), 'Less'=>translate('Less important'), 'Normal'=>translate('Normal') ), $monitor->Importance()); ?>