diff --git a/web/skins/classic/views/monitorprobe.php b/web/skins/classic/views/monitorprobe.php
index 3b38df6ed..0717d1fca 100644
--- a/web/skins/classic/views/monitorprobe.php
+++ b/web/skins/classic/views/monitorprobe.php
@@ -23,93 +23,94 @@ if ( !canEdit('Monitors') ) {
return;
}
-$cameras = array();
-$cameras[0] = translate('ChooseDetectedCamera');
+// Probe Local Cameras
+function probeV4L() {
-if ( ZM_HAS_V4L2 ) {
- // Probe Local Cameras
+ $cameras = array();
$command = getZmuCommand(' --query --device');
if ( !empty($_REQUEST['device']) )
$command .= '='.escapeshellarg($_REQUEST['device']);
$result = exec(escapeshellcmd($command), $output, $status);
- if ( $status )
- Fatal("Unable to probe local cameras, status is '$status'");
+ if ( $status ) {
+ Error("Unable to probe local cameras, status is '$status'");
+ return $cameras;
+ }
- $monitors = array();
- foreach ( dbFetchAll("SELECT Id, Name, Device,Channel FROM Monitors WHERE Type = 'Local' ORDER BY Device, Channel" ) as $monitor )
- $monitors[$monitor['Device'].':'.$monitor['Channel']] = $monitor;
+ $monitors = array();
+ foreach ( dbFetchAll("SELECT Id, Name, Device,Channel FROM Monitors WHERE Type = 'Local' ORDER BY Device, Channel" ) as $monitor )
+ $monitors[$monitor['Device'].':'.$monitor['Channel']] = $monitor;
- $devices = array();
- $preferredStandards = array('PAL', 'NTSC');
- $preferredFormats = array('BGR3', 'RGB3', 'YUYV', 'UYVY', 'JPEG', 'MJPG', '422P', 'YU12', 'GREY');
- foreach ( $output as $line ) {
- if ( !preg_match('/^d:([^|]+).*S:([^|]*).*F:([^|]+).*I:(\d+)\|(.+)$/', $line, $deviceMatches) )
- Fatal("Can't parse command output '$line'");
- $standards = explode('/',$deviceMatches[2]);
- $preferredStandard = false;
- foreach ( $preferredStandards as $standard ) {
- if ( in_array( $standard, $standards ) ) {
- $preferredStandard = $standard;
- break;
- }
- }
- $formats = explode('/',$deviceMatches[3]);
- $preferredFormat = false;
- foreach ( $preferredFormats as $format ) {
- if ( in_array($format, $formats) ) {
- $preferredFormat = $format;
- break;
- }
- }
- $device = array(
- 'device' => $deviceMatches[1],
- 'standards' => $standard,
- 'preferredStandard' => $preferredStandard,
- 'formats' => $formats,
- 'preferredFormat' => $preferredFormat,
- );
- $inputs = array();
- for ( $i = 0; $i < $deviceMatches[4]; $i++ ) {
- if ( !preg_match('/i'.$i.':([^|]+)\|i'.$i.'T:([^|]+)\|/', $deviceMatches[5], $inputMatches) )
- Fatal("Can't parse input '".$deviceMatches[5]."'");
- if ( $inputMatches[2] == 'Camera' ) {
- $input = array(
- 'index' => $i,
- 'id' => $deviceMatches[1].':'.$i,
- 'name' => $inputMatches[1],
- 'free' => empty($monitors[$deviceMatches[1].':'.$i]),
- );
- $inputMonitor = array(
- 'Type' => 'Local',
- 'Device' => $deviceMatches[1],
- 'Channel' => $i,
- 'Colours' => 3,
- 'Format' => $preferredStandard,
- 'Palette' => $preferredFormat,
- );
- if ( $preferredStandard == 'NTSC' ) {
- $inputMonitor['Width'] = 320;
- $inputMonitor['Height'] = 240;
- } else {
- $inputMonitor['Width'] = 384;
- $inputMonitor['Height'] = 288;
- }
- if ( $preferredFormat == 'GREY' ) {
- $inputMonitor['Colours'] = 1;
- $inputMonitor['SignalCheckColour'] = '#000023';
- }
- $inputDesc = base64_encode(serialize($inputMonitor));
- $inputString = $deviceMatches[1].', chan '.$i.($input['free']?(' - '.translate('Available')):(' ('.$monitors[$input['id']]['Name'].')'));
- $inputs[] = $input;
- $cameras[$inputDesc] = $inputString;
- }
- }
- $device['inputs'] = $inputs;
- $devices[] = $device;
- } # end foreach output line
-} # end if has v4l2
+ $devices = array();
+ $preferredStandards = array('PAL', 'NTSC');
+ $preferredFormats = array('BGR3', 'RGB3', 'YUYV', 'UYVY', 'JPEG', 'MJPG', '422P', 'YU12', 'GREY');
+ foreach ( $output as $line ) {
+ if ( !preg_match('/^d:([^|]+).*S:([^|]*).*F:([^|]+).*I:(\d+)\|(.+)$/', $line, $deviceMatches) )
+ Fatal("Can't parse command output '$line'");
+ $standards = explode('/',$deviceMatches[2]);
+ $preferredStandard = false;
+ foreach ( $preferredStandards as $standard ) {
+ if ( in_array( $standard, $standards ) ) {
+ $preferredStandard = $standard;
+ break;
+ }
+ }
+ $formats = explode('/',$deviceMatches[3]);
+ $preferredFormat = false;
+ foreach ( $preferredFormats as $format ) {
+ if ( in_array($format, $formats) ) {
+ $preferredFormat = $format;
+ break;
+ }
+ }
+ $device = array(
+ 'device' => $deviceMatches[1],
+ 'standards' => $standard,
+ 'preferredStandard' => $preferredStandard,
+ 'formats' => $formats,
+ 'preferredFormat' => $preferredFormat,
+ );
+ $inputs = array();
+ for ( $i = 0; $i < $deviceMatches[4]; $i++ ) {
+ if ( !preg_match('/i'.$i.':([^|]+)\|i'.$i.'T:([^|]+)\|/', $deviceMatches[5], $inputMatches) )
+ Fatal("Can't parse input '".$deviceMatches[5]."'");
+ if ( $inputMatches[2] == 'Camera' ) {
+ $input = array(
+ 'index' => $i,
+ 'id' => $deviceMatches[1].':'.$i,
+ 'name' => $inputMatches[1],
+ 'free' => empty($monitors[$deviceMatches[1].':'.$i]),
+ );
+ $inputMonitor = array(
+ 'Type' => 'Local',
+ 'Device' => $deviceMatches[1],
+ 'Channel' => $i,
+ 'Colours' => 3,
+ 'Format' => $preferredStandard,
+ 'Palette' => $preferredFormat,
+ );
+ if ( $preferredStandard == 'NTSC' ) {
+ $inputMonitor['Width'] = 320;
+ $inputMonitor['Height'] = 240;
+ } else {
+ $inputMonitor['Width'] = 384;
+ $inputMonitor['Height'] = 288;
+ }
+ if ( $preferredFormat == 'GREY' ) {
+ $inputMonitor['Colours'] = 1;
+ $inputMonitor['SignalCheckColour'] = '#000023';
+ }
+ $inputDesc = base64_encode(serialize($inputMonitor));
+ $inputString = $deviceMatches[1].', chan '.$i.($input['free']?(' - '.translate('Available')):(' ('.$monitors[$input['id']]['Name'].')'));
+ $inputs[] = $input;
+ $cameras[$inputDesc] = $inputString;
+ }
+ }
+ $device['inputs'] = $inputs;
+ $devices[] = $device;
+ } # end foreach output line
+} # end function probeV4L
// Probe Network Cameras
//
@@ -240,82 +241,95 @@ function probeWansview($ip) {
return $camera;
}
-$monitors = array();
-foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type = 'Remote' ORDER BY Host") as $monitor ) {
- if ( preg_match('/^(.+)@(.+)$/', $monitor['Host'], $matches) ) {
- //echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."
";
- $monitors[gethostbyname($matches[2])] = $monitor;
- } else {
- //echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."
";
- $monitors[gethostbyname($monitor['Host'])] = $monitor;
- }
-}
-$macBases = array(
- '00:40:8c' => array('type'=>'Axis', 'probeFunc'=>'probeAxis'),
- '00:80:f0' => array('type'=>'Panasonic','probeFunc'=>'probePana'),
- '00:0f:7c' => array('type'=>'ACTi','probeFunc'=>'probeACTi'),
- '00:02:d1' => array('type'=>'Vivotek','probeFunc'=>'probeVivotek'),
- '7c:dd:90' => array('type'=>'Wansview','probeFunc'=>'probeWansview'),
- '78:a5:dd' => array('type'=>'Wansview','probeFunc'=>'probeWansview')
-);
+function probeNetwork() {
+ // Calling arp without the full path was reported to fail on some systems
+ // Use the builtin unix command "type" to tell us where the command is
+ $arp_command = '';
+ $result = explode(' ', ZM_PATH_ARP);
+ if ( !is_executable($result[0]) ) {
+ if ( ZM_PATH_ARP ) {
+ Warning("User assigned ARP tool not found. Verify ZM_PATH_ARP points to a valid arp tool and is executable by the web user account.");
+ }
+ $result = exec('type -p arp', $output, $status);
+ if ( $status ) {
+ Warning("Unable to determine path for arp command, type -p arp returned '$status' output is: " . implode("\n", $output));
+ unset($output);
+ $result = exec('which arp', $output, $status);
+ if ( $status ) {
+ Warning("Unable to determine path for arp command, which arp returned '$status'");
+ if ( file_exists('/usr/sbin/arp') ) {
+ $arp_command = '/usr/sbin/arp -a';
+ }
+ } else {
+ $arp_command = $output[0].' -a';
+ }
+ } else {
+ $arp_command = $output[0].' -a';
+ }
+ } else {
+ $arp_command = ZM_PATH_ARP;
+ }
+ // Now that we know where arp is, call it using the full path
+ unset($output);
+ $result = exec(escapeshellcmd($arp_command), $output, $status);
+ if ( $status ) {
+ Error("Unable to probe network cameras, status is '$status'");
+ return;
+ }
-unset($output);
-// Calling arp without the full path was reported to fail on some systems
-// Use the builtin unix command "type" to tell us where the command is
-$arp_command = '';
-$result = explode(' ', ZM_PATH_ARP);
-if ( !is_executable($result[0]) ) {
- if ( ZM_PATH_ARP ) {
- Warning("User assigned ARP tool not found. Verify ZM_PATH_ARP points to a valid arp tool and is executable by the web user account.");
- }
- $result = exec('type -p arp', $output, $status);
- if ( $status ) {
- Warning("Unable to determine path for arp command, type -p arp returned '$status' output is: " . implode("\n", $output));
- unset($output);
- $result = exec('which arp', $output, $status);
- if ( $status ) {
- Warning("Unable to determine path for arp command, which arp returned '$status'");
- if ( file_exists('/usr/sbin/arp') ) {
- $arp_command = '/usr/sbin/arp -a';
- }
- } else {
- $arp_command = $output[0].' -a';
- }
- } else {
- $arp_command = $output[0].' -a';
- }
-} else {
- $arp_command = ZM_PATH_ARP;
-}
-// Now that we know where arp is, call it using the full path
-unset($output);
-$result = exec(escapeshellcmd($arp_command), $output, $status);
-if ( $status )
- Fatal("Unable to probe network cameras, status is '$status'");
-foreach ( $output as $line ) {
- if ( !preg_match('/(\d+\.\d+\.\d+\.\d+).*(([0-9a-f]{2}:){5})/', $line, $matches) )
- continue;
- $ip = $matches[1];
- $host = $ip;
- $mac = $matches[2];
- //echo "I:$ip, H:$host, M:$mac
";
- $macRoot = substr($mac,0,8);
- if ( isset($macBases[$macRoot]) ) {
- $macBase = $macBases[$macRoot];
- $camera = call_user_func( $macBase['probeFunc'], $ip );
- $sourceDesc = htmlspecialchars(serialize($camera['monitor']));
- $sourceString = $camera['model'].' @ '.$host;
- if ( isset($monitors[$ip]) ) {
- $monitor = $monitors[$ip];
- $sourceString .= ' ('.$monitor['Name'].')';
- } else {
- $sourceString .= " - ".translate('Available');
- }
- $cameras[$sourceDesc] = $sourceString;
- }
-} # end foreach output line
+ $monitors = array();
+ foreach ( dbFetchAll("SELECT Id, Name, Host FROM Monitors WHERE Type = 'Remote' ORDER BY Host") as $monitor ) {
+ if ( preg_match('/^(.+)@(.+)$/', $monitor['Host'], $matches) ) {
+ //echo "1: ".$matches[2]." = ".gethostbyname($matches[2])."
";
+ $monitors[gethostbyname($matches[2])] = $monitor;
+ } else {
+ //echo "2: ".$monitor['Host']." = ".gethostbyname($monitor['Host'])."
";
+ $monitors[gethostbyname($monitor['Host'])] = $monitor;
+ }
+ }
-if ( count($cameras) <= 0 )
+ $macBases = array(
+ '00:40:8c' => array('type'=>'Axis', 'probeFunc'=>'probeAxis'),
+ '00:80:f0' => array('type'=>'Panasonic','probeFunc'=>'probePana'),
+ '00:0f:7c' => array('type'=>'ACTi','probeFunc'=>'probeACTi'),
+ '00:02:d1' => array('type'=>'Vivotek','probeFunc'=>'probeVivotek'),
+ '7c:dd:90' => array('type'=>'Wansview','probeFunc'=>'probeWansview'),
+ '78:a5:dd' => array('type'=>'Wansview','probeFunc'=>'probeWansview')
+ );
+
+ foreach ( $output as $line ) {
+ if ( !preg_match('/(\d+\.\d+\.\d+\.\d+).*(([0-9a-f]{2}:){5})/', $line, $matches) )
+ continue;
+ $ip = $matches[1];
+ $host = $ip;
+ $mac = $matches[2];
+ //echo "I:$ip, H:$host, M:$mac
";
+ $macRoot = substr($mac,0,8);
+ if ( isset($macBases[$macRoot]) ) {
+ $macBase = $macBases[$macRoot];
+ $camera = call_user_func($macBase['probeFunc'], $ip);
+ $sourceDesc = htmlspecialchars(serialize($camera['monitor']));
+ $sourceString = $camera['model'].' @ '.$host;
+ if ( isset($monitors[$ip]) ) {
+ $monitor = $monitors[$ip];
+ $sourceString .= ' ('.$monitor['Name'].')';
+ } else {
+ $sourceString .= ' - '.translate('Available');
+ }
+ $cameras[$sourceDesc] = $sourceString;
+ }
+ } # end foreach output line
+ return $cameras;
+} # end function probeNetwork()
+
+$cameras = array();
+$cameras[0] = translate('ChooseDetectedCamera');
+
+if ( ZM_HAS_V4L2 )
+ $cameras += probeV4L();
+$cameras += probeNetwork();
+
+if ( count($cameras) <= 1 )
$cameras[0] = translate('NoDetectedCameras');
$focusWindow = true;
@@ -335,10 +349,13 @@ xhtmlHeaders(__FILE__, translate('MonitorProbe') );
- + +