本文将介绍如何使用ONVIF来同步NTP时间。
一、ONVIF 和 NTP
ONVIF(开放式网络视频接口)规范定义了一套电子视频设备与网络视频管理系统之间的通信接口。而NTP(网络时间协议)是一种用于同步计算机时钟的协议。
在使用ONVIF设备进行视频监控的过程中,确保设备的时间与管理系统的时间是同步的非常重要。为了实现这个目标,可以使用ONVIF提供的Web服务接口和NTP协议来同步时间。
二、使用ONVIF的GetSystemDateAndTime方法查询设备时间
首先,我们需要获取设备当前的系统时间。使用ONVIF的GetSystemDateAndTime方法可以得到设备的当前时间。
$endpoint = 'http://192.168.1.100/onvif/device_service'; $username = 'admin'; $password = '123456'; $soap = new SoapClient(null, array( 'location' => $endpoint, 'uri' => 'urn:dnvif-org:services', )); $auth = array( 'UsernameToken' => array( 'Username' => $username, 'Password' => $password, 'Nonce' => uniqid(), 'Created' => date('Y-m-dTH:i:sZ', time()) ) ); $header = new SoapHeader('http://www.onvif.org/ver10/device/wsdl', 'Security', $auth); $soap->__setSoapHeaders(array($header)); $params = array(); $result = $soap->__soapCall('GetSystemDateAndTime', array($params)); $dateTimeType = $result->{'SystemDateAndTime'}->{'DateTimeType'}; $date = $result->{'SystemDateAndTime'}->{'UTCDateTime'}->{'Date'}; $time = $result->{'SystemDateAndTime'}->{'UTCDateTime'}->{'Time'};
三、使用NTP同步系统时间
一旦我们已经获取了设备的当前时间,我们可以使用NTP协议来调整系统时间。以下是使用PHP进行NTP时间同步的代码。
function setSystemTime($date, $time) { $dateTime = "$date $time"; $ntpServer = 'time.windows.com'; // NTP服务器地址 $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); $data = " 10" . str_repeat(" ", 47); // 请求NTP时间 socket_sendto($socket, $data, strlen($data), 0, $ntpServer, 123); socket_recvfrom($socket, $data, 48, 0, $ntpServer, $port); socket_close($socket); $leap = (ord($data[0]) >> 6) & 3; $version = (ord($data[0]) >> 3) & 7; $mode = ord($data[0]) & 7; $stratum = ord($data[1]); $poll = ord($data[2]); $precision = pow(2, (ord($data[3]) - 256)); $delay = unpack("N", substr($data, 4, 4))[1] / 1000000; $dispersion = unpack("N", substr($data, 8, 4))[1] / 1000000; $reference = unpack("N", substr($data, 12, 4))[1] - 2208988800; $originate = unpack("N", substr($data, 16, 4))[1] - 2208988800; $receive = unpack("N", substr($data, 24, 4))[1] - 2208988800; $transmit = unpack("N", substr($data, 32, 4))[1] - 2208988800; $offset = ($receive - $originate + $transmit - time()) / 2; return date("Y-m-d H:i:s", $transmit + $offset); // 获取同步后的系统时间 } $systemTime = setSystemTime($date, $time); // 设置系统时间
四、完整代码示例
$endpoint = 'http://192.168.1.100/onvif/device_service'; $username = 'admin'; $password = '123456'; $soap = new SoapClient(null, array( 'location' => $endpoint, 'uri' => 'urn:dnvif-org:services', )); $auth = array( 'UsernameToken' => array( 'Username' => $username, 'Password' => $password, 'Nonce' => uniqid(), 'Created' => date('Y-m-dTH:i:sZ', time()) ) ); $header = new SoapHeader('http://www.onvif.org/ver10/device/wsdl', 'Security', $auth); $soap->__setSoapHeaders(array($header)); $params = array(); $result = $soap->__soapCall('GetSystemDateAndTime', array($params)); $dateTimeType = $result->{'SystemDateAndTime'}->{'DateTimeType'}; $date = $result->{'SystemDateAndTime'}->{'UTCDateTime'}->{'Date'}; $time = $result->{'SystemDateAndTime'}->{'UTCDateTime'}->{'Time'}; function setSystemTime($date, $time) { $dateTime = "$date $time"; $ntpServer = 'time.windows.com'; // NTP服务器地址 $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); $data = " 10" . str_repeat(" ", 47); // 请求NTP时间 socket_sendto($socket, $data, strlen($data), 0, $ntpServer, 123); socket_recvfrom($socket, $data, 48, 0, $ntpServer, $port); socket_close($socket); $leap = (ord($data[0]) >> 6) & 3; $version = (ord($data[0]) >> 3) & 7; $mode = ord($data[0]) & 7; $stratum = ord($data[1]); $poll = ord($data[2]); $precision = pow(2, (ord($data[3]) - 256)); $delay = unpack("N", substr($data, 4, 4))[1] / 1000000; $dispersion = unpack("N", substr($data, 8, 4))[1] / 1000000; $reference = unpack("N", substr($data, 12, 4))[1] - 2208988800; $originate = unpack("N", substr($data, 16, 4))[1] - 2208988800; $receive = unpack("N", substr($data, 24, 4))[1] - 2208988800; $transmit = unpack("N", substr($data, 32, 4))[1] - 2208988800; $offset = ($receive - $originate + $transmit - time()) / 2; return date("Y-m-d H:i:s", $transmit + $offset); // 获取同步后的系统时间 } $systemTime = setSystemTime($date, $time); // 设置系统时间