SkeVSS国标视频汇聚云服务使用Onvif、GB28181协议对监控ye摄像机设备进行PTZ云台控制

SkeyeVSS平台可在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等。平台可支持多协议、多类型设备接入,包括国标GB28181、RTMP、RTSP/Onvif、海康SDK、大华SDK、海康Ehome等;

SkeyeVSS视频融合云平台具备丰富的视频能力,包括视频监控直播、云台控制、录像、云存储、检索与回看、告警、集群、级联、共享等能力,在很多实际场景中均有落地项目应用,如:智慧工地、智慧校园、智慧社区、智慧楼宇等。感兴趣的用户可以前往演示平台进行体验与测试部署。

今天我们讲解一下,如何通过SkeyeVSS平台实现对网络摄像机或者云台的PTZ控制,云台控制的方式主要通过两个途径:

1. Onvif协议接入设备云台控制

网络摄像机或者硬盘录像机等设备通过Onvif接入SkeyeVSS平台后,即可以对设备进行云台控制,如下图所示:

SkeyeVSS平台PTZ云台控制,分三步操作实现:

第一步:调用云台控制http api接口,将前端页面请求发送给SkeyeVSS后台,云台控制接口如下:

http://[ip]:[port]/api/v1/ptzcontrol

接口调用详情可以通过后台接口文档/apidoc查看,云台控制接口文档说明如下:

以向右转动云台为例,通道号为1的相机,设置云台速度是50(范围:0-100),接口调用示例:

代码语言:txt
复制
http://192.168.0.13:8888/api/v1/ptzcontrol?channel=1&speed=50&command=right
第二步:SkeyeVSS后台处理ptz云台控制http请求,golang层实现代码如下:
代码语言:txt
复制
/**
代码语言:txt
复制
* @api {get} /api/v1/ptzcontrol 云台控制
* @apiGroup channel
* @apiParam {Number} channel 指定通道号
* @apiParam {String=stop,up,down,left,right,zoomin,zoomout,focusin,focusout,aperturein,apertureout} command 动作命令
* @apiParam {Number} [speed] 动作速度, 例如5
*
* @apiUse ack
 */
func (h *APIHandler) PTZControl(c *gin.Context) {
	params := make(map[string]string)
	for k, v := range c.Request.URL.Query() {
		params[strings.ToLower(k)] = strings.Join(v, ",")
	}
	id, _ := strconv.Atoi(params["channel"])
	ack := NewMsgAck()
	ack.SkeyeVAR.Header.MessageType = MSG_SC_PTZ_CONTROL_ACK
	channel := channels.GetChannel(uint(id))
	if channel == nil || channel.Online == 0 {
		ack.SkeyeVAR.Header.ErrorNum = fmt.Sprintf("%d", http.StatusBadRequest)
		ack.SkeyeVAR.Header.ErrorString = fmt.Sprintf("Channel Offline")
		c.IndentedJSON(http.StatusOK, ack)
		return
	}
	if channel.GetDeviceType() != "ONVIF" {
		ack.SkeyeVAR.Header.ErrorNum = fmt.Sprintf("%d", http.StatusBadRequest)
		ack.SkeyeVAR.Header.ErrorString = fmt.Sprintf("Channel PTZ Control Not Support")
		c.IndentedJSON(http.StatusOK, ack)
		return
	}
	host, username, password, deviceUrl, err := channel.GetONVIFInfo()
	if err != nil {
		ack.SkeyeVAR.Header.ErrorNum = fmt.Sprintf("%d", http.StatusBadRequest)
		ack.SkeyeVAR.Header.ErrorString = err.Error()
		c.IndentedJSON(http.StatusOK, ack)
		return
	}
	cmd := strings.ToLower(params["command"])
	switch cmd {
	case "stop":
		err = onvif.StopPTZ(host, username, password, deviceUrl)
	default:
		speed, _ := strconv.Atoi(params["speed"])
		if speed == 0 {
			speed = 5
		}
		err = onvif.StartPTZ(cmd, uint(speed), host, username, password, deviceUrl)
	}
	if err != nil {
		ack.SkeyeVAR.Header.ErrorNum = fmt.Sprintf("%d", http.StatusBadRequest)
		ack.SkeyeVAR.Header.ErrorString = err.Error()
	}
	c.IndentedJSON(http.StatusOK, ack)
}
第三步:SkeyeVSS后台通过onvif协议向设备端发送云台控制命令,后台golang层代码实现如下:
代码语言:txt
复制
func StartPTZ(cmd string, speed uint, host, username, password, deviceUrl string) (err error) {
代码语言:txt
复制
	ptz := fmt.Sprintf("start ptz cmd[%s] speed[%d] host[%s] username[%s] password[%s] deviceUrl[%s]", cmd, speed, host, username, password, deviceUrl)
代码语言:txt
复制
	global.OperationLogger.Info(ptz)
代码语言:txt
复制
	if dll == nil {
代码语言:txt
复制
		err = fmt.Errorf("onvif dll not init")
代码语言:txt
复制
		return
代码语言:txt
复制
	}
代码语言:txt
复制
	utils.Logf("start ptz cmd[%s] speed[%d] host[%s]", cmd, speed, host)
代码语言:txt
复制
	_cmd := uintptr(C.SKEYE_PTZ_CMD_TYPE_UP)
代码语言:txt
复制
	switch cmd {
代码语言:txt
复制
	case "up":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_UP)
代码语言:txt
复制
	case "down":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_DOWN)
代码语言:txt
复制
	case "left":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_LEFT)
代码语言:txt
复制
	case "right":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_RIGHT)
代码语言:txt
复制
	case "zoomin":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_ZOOMIN)
代码语言:txt
复制
	case "zoomout":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_ZOOMOUT)
代码语言:txt
复制
	case "focusin":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_FOCUSIN)
代码语言:txt
复制
	case "focusout":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_FOCUSOUT)
代码语言:txt
复制
	case "aperturein":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_APERTUREIN)
代码语言:txt
复制
	case "apertureout":
代码语言:txt
复制
		_cmd = uintptr(C.SKEYE_PTZ_CMD_TYPE_APERTUREOUT)
代码语言:txt
复制
	}
代码语言:txt
复制
	_speed := uintptr(speed)
代码语言:txt
复制
	_host := uintptr(unsafe.Pointer(syscall.StringBytePtr(host)))
代码语言:txt
复制
	_username := uintptr(unsafe.Pointer(syscall.StringBytePtr(username)))
代码语言:txt
复制
	_password := uintptr(unsafe.Pointer(syscall.StringBytePtr(password)))
代码语言:txt
复制
	_deviceUrl := uintptr(unsafe.Pointer(syscall.StringBytePtr(deviceUrl)))
代码语言:txt
复制
	r1, _, _ := procStartPtz.Call(_cmd, _speed, _host, _username, _password, _deviceUrl)
代码语言:txt
复制
	if r1 != 0 {
代码语言:txt
复制
		err = fmt.Errorf("SkeyeOnvifClient_StartPtz ret[%d]", r1)
代码语言:txt
复制
		return
代码语言:txt
复制
	}
代码语言:txt
复制
	return
代码语言:txt
复制
}

2. GB/T28181协议接入设备云台控制

网络摄像机或者硬盘录像机等设备通过GB28181国标协议接入SkeyeVSS平台后,即可以对设备进行云台控制,云台控制和Onvif协议方式类似,只是网页调用的接口有所区别,通过国标协议接入的设备都有一个统一的20位的国标ID,接口调用通过设备ID-通道ID来标识某一路摄像机,从而对其进行控制:

如上图所示,我们通过http api接口发送云台控制名,其参数serial标识设备ID,code标识通道ID,发送向左云台相对位置移动命令,云台控制速度设置为129,国标协议规定的云台速度范围(1-255)

代码语言:txt
复制
http://114.116.122.72:8000/api/v1/ptz/control?serial=34020000001320000011&code=34020000001320000011&speed=129&command=left

SkeyeVSS后台收到国标云台控制请求后,和onvif处理类似,不过是通过sip协议向设备端发送云台控制命令,其sip请求如下:

代码语言:txt
复制
MESSAGE sip:34020000001320000011@111.20.116.14:34524;transport=udp SIP/2.0
代码语言:txt
复制
Via: SIP/2.0/UDP 192.168.0.161:55060;rport=55060;branch=z9hG4bK322219540
代码语言:txt
复制
From: <sip:34020000002000000001@3402000000>;tag=541219540
代码语言:txt
复制
To: <sip:34020000001320000011@3402000000>
代码语言:txt
复制
Call-ID: 588219540
代码语言:txt
复制
CSeq: 2974 MESSAGE
代码语言:txt
复制
Max-Forwards: 70
代码语言:txt
复制
User-Agent: SkeyeVSS SIP Server
代码语言:txt
复制
Content-Length: 272
代码语言:txt
复制
Content-Type: Application/MANSCDP+xml
代码语言:txt
复制
<?xml version="1.0" encoding="UTF-8"?>
代码语言:txt
复制
<Control>
代码语言:txt
复制
    <CmdType>DeviceControl</CmdType>
代码语言:txt
复制
    <SN>493219540</SN>
代码语言:txt
复制
    <DeviceID>34020000001320000011</DeviceID>
代码语言:txt
复制
    <PTZCmd>A50F0100000000B5</PTZCmd>
代码语言:txt
复制
    <Info>
代码语言:txt
复制
        <ControlPriority>5</ControlPriority>
代码语言:txt
复制
    </Info>
代码语言:txt
复制
</Control>

设备端收到请求,sip应答200 ok,表示云台控制命令执行正常,如下:

代码语言:txt
复制
SIP/2.0 200 OK
代码语言:txt
复制
Call-ID: 588219540
代码语言:txt
复制
Content-Length: 0
代码语言:txt
复制
CSeq: 2974 MESSAGE
代码语言:txt
复制
From: <sip:34020000002000000001@3402000000>;tag=541219540
代码语言:txt
复制
To: <sip:34020000001320000011@3402000000>;tag=a0caa8705b5a99be472077e6d7c4b377
代码语言:txt
复制
User-Agent: SIP UAS V.2016.xxxx
代码语言:txt
复制
Via: SIP/2.0/UDP 192.168.0.161:55060;rport=55060;received=114.116.122.72;branch=z9hG4bK322219540

SkeyeVSS国标视频融合云平部署轻松、视频能力丰富,平台可支持市面上绝大多数的视频源设备接入,具有视频汇聚管理、转码分发、告警上报、智能分析等功能。基于端-边-云的计算及资源汇聚与调度能力,平台可以实现海量资源的接入、汇聚、计算、存储、处理等,解决视频监控场景中海量设备接入、边端资源异构、网络通信不稳定、统一运维管理复杂等难题。