EasyDarwin开源流媒体云平台之云台ptz控制设计与实现
2016-07-14 21:47
399 查看
本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/51912692
近日,EasyDarwin云平台加入云台控制功能,完善了云平台的功能,提升了用户体验。具体设计以及实现如下。
流程设计
客户端通过RESTful接口向云平台发送控制命令;
云平台组织控制报文向设备发送;
设备执行后向云平台返回控制响应报文;
云平台接收响应报文后将控制结果返回给客户端。
接口设计
首先我们设计云台控制的接口,接口为RESTful方式接口。
device: 设备序列号;
channel: 通道;
protocol: 控制模式, 包括 Onvif、 SDK;
actiontype: ptz 控制模式, 分为连续( Continuous)、 单步( Single);
command: ptz 控制命令包括转动、 变焦等,
stop/up/down/left/right/zoomin/zoomout/focusin/focusout/aperturein/apertureout;
speed: ptz 控制速度。
通讯报文设计
格式说明:
Serial:设备序列号;
Channel: 摄像机通道号;
Protocol: 指定 ptz 控制方式, ONVIF 协议或者设备 SDK;
ActionType: ptz 控制类型, 包括连续或者单步;
Command: ptz 控制命令, 包括停止, 上下左右旋转, 变焦等等;
Speed: ptz 控制速度;
From: EasyCMS 接收 Client 访问的 SessionID;
To: EasyCMS 向 Device 发送报文的 SessionID;
Via: EasyCMS 的 ServiceID;
实现
邮件:support@easydarwin.org
WEB:www.EasyDarwin.org
Copyright © EasyDarwin.org 2012-2016
近日,EasyDarwin云平台加入云台控制功能,完善了云平台的功能,提升了用户体验。具体设计以及实现如下。
流程设计
客户端通过RESTful接口向云平台发送控制命令;
云平台组织控制报文向设备发送;
设备执行后向云平台返回控制响应报文;
云平台接收响应报文后将控制结果返回给客户端。
接口设计
首先我们设计云台控制的接口,接口为RESTful方式接口。
http://[ip]:[port]/api/ptzcontrol?device=001001000058&channel=0&actiontype=single&c ommand=down&speed=5&protocol=onvif
device: 设备序列号;
channel: 通道;
protocol: 控制模式, 包括 Onvif、 SDK;
actiontype: ptz 控制模式, 分为连续( Continuous)、 单步( Single);
command: ptz 控制命令包括转动、 变焦等,
stop/up/down/left/right/zoomin/zoomout/focusin/focusout/aperturein/apertureout;
speed: ptz 控制速度。
通讯报文设计
//云平台响应客户端控制 { "EasyDarwin" : { "Body" : { "Channel" : "0", "Protocol" : "ONVIF", "Reserve" : "1", "Serial" : "001001000058" }, "Header" : { "CSeq" : "2", "ErrorNum" : "200", "ErrorString" : "Success OK", "MessageType" : "MSG_SC_PTZ_CONTROL_ACK", "Version" : "1.0" } } }
//云平台向设备发送控制报文 { "EasyDarwin" : { "Body" : { "ActionType" : "SINGLE", "Channel" : "0", "Command" : "DOWN", "From" : "f6a221eec46b47dea8ae1a2bd11f8d02", "Protocol" : "ONVIF", "Reserve" : "1", "Serial" : "001001000058", "Speed" : "5", "To" : "245d6ec33cd247b7b7524219552db4d8", "Via" : "27823d2e8b6b4032b453d435a16b7be8" }, "Header" : { "CSeq" : "1", "MessageType" : "MSG_SD_CONTROL_PTZ_REQ", "Version" : "1.0" } } }
//设备响应云平台控制 { "EasyDarwin" : { "Body" : { "Channel" : "0", "From" : "245d6ec33cd247b7b7524219552db4d8", "Protocol" : "ONVIF", "Reserve" : "1", "Serial" : "001001000058", "To" : "f6a221eec46b47dea8ae1a2bd11f8d02", "Via" : "27823d2e8b6b4032b453d435a16b7be8" }, "Header" : { "CSeq" : "1", "ErrorNum" : "200", "ErrorString" : "Success OK", "MessageType" : "MSG_DS_CONTROL_PTZ_ACK", "Version" : "1.0" } } }
格式说明:
Serial:设备序列号;
Channel: 摄像机通道号;
Protocol: 指定 ptz 控制方式, ONVIF 协议或者设备 SDK;
ActionType: ptz 控制类型, 包括连续或者单步;
Command: ptz 控制命令, 包括停止, 上下左右旋转, 变焦等等;
Speed: ptz 控制速度;
From: EasyCMS 接收 Client 访问的 SessionID;
To: EasyCMS 向 Device 发送报文的 SessionID;
Via: EasyCMS 的 ServiceID;
实现
//EasyCMS HTTPSession.cpp //在session map中查找device session,组织控制报文,通过device session发送给设备 OSRefTableEx* deviceMap = QTSServerInterface::GetServer()->GetDeviceSessionMap(); OSRefTableEx::OSRefEx* theDevRef = deviceMap->Resolve(chSerial); if (theDevRef == NULL) return EASY_ERROR_DEVICE_NOT_FOUND; OSRefReleaserEx releaser(deviceMap, chSerial); HTTPSession* pDevSession = static_cast<HTTPSession *>(theDevRef->GetObjectPtr()); EasyProtocolACK reqreq(MSG_SD_CONTROL_PTZ_REQ); EasyJsonValue headerheader, bodybody; char chTemp[16] = { 0 }; UInt32 uDevCseq = pDevSession->GetCSeq(); sprintf(chTemp, "%d", uDevCseq); headerheader[EASY_TAG_CSEQ] = string(chTemp); headerheader[EASY_TAG_VERSION] = EASY_PROTOCOL_VERSION; string strProtocol(chProtocol); string strActionType(chActionType); string strCmd(chCmd); boost::to_upper(strProtocol); boost::to_upper(strActionType); boost::to_upper(strCmd); bodybody[EASY_TAG_SERIAL] = chSerial; bodybody[EASY_TAG_CHANNEL] = chChannel; bodybody[EASY_TAG_PROTOCOL] = strProtocol; bodybody[EASY_TAG_RESERVE] = chReserve; bodybody[EASY_TAG_ACTION_TYPE] = strActionType; bodybody[EASY_TAG_CMD] = strCmd; bodybody[EASY_TAG_SPEED] = chSpeed; bodybody[EASY_TAG_FROM] = fSessionID; bodybody[EASY_TAG_TO] = pDevSession->GetValue(EasyHTTPSessionID)->GetAsCString(); bodybody[EASY_TAG_VIA] = QTSServerInterface::GetServer()->GetCloudServiceNodeID(); reqreq.SetHead(headerheader); reqreq.SetBody(bodybody); string buffer = reqreq.GetMsg(); StrPtrLen theValue(const_cast<char*>(buffer.c_str()), buffer.size()); pDevSession->SendHTTPPacket(&theValue, false, false);
//EasyCamera EasyCMSSession.cpp processControlPTZReq //EasyCamera接收控制报文,调用EasyCameraSource的控制接口 QTSS_Error EasyCMSSession::processControlPTZReq() const { EasyMsgSDControlPTZREQ ctrlPTZReq(fContentBuffer); string serial = ctrlPTZReq.GetBodyValue(EASY_TAG_SERIAL); string protocol = ctrlPTZReq.GetBodyValue(EASY_TAG_PROTOCOL); string channel = ctrlPTZReq.GetBodyValue(EASY_TAG_CHANNEL); string reserve = ctrlPTZReq.GetBodyValue(EASY_TAG_RESERVE); string actionType = ctrlPTZReq.GetBodyValue(EASY_TAG_ACTION_TYPE); string command = ctrlPTZReq.GetBodyValue(EASY_TAG_CMD); string speed = ctrlPTZReq.GetBodyValue(EASY_TAG_SPEED); string from = ctrlPTZReq.GetBodyValue(EASY_TAG_FROM); string to = ctrlPTZReq.GetBodyValue(EASY_TAG_TO); string via = ctrlPTZReq.GetBodyValue(EASY_TAG_VIA); if (serial.empty() || channel.empty() || command.empty()) { return QTSS_ValueNotFound; } QTSS_RoleParams params; params.cameraPTZParams.inActionType = EasyProtocol::GetPTZActionType(actionType); params.cameraPTZParams.inCommand = EasyProtocol::GetPTZCMDType(command); params.cameraPTZParams.inSpeed = EasyUtil::String2Int(speed); QTSS_Error errCode = QTSS_NoErr; UInt32 fCurrentModule = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kControlPTZRole); for (; fCurrentModule < numModules; ++fCurrentModule) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kControlPTZRole, fCurrentModule); errCode = theModule->CallDispatch(Easy_ControlPTZ_Role, ¶ms); } EasyJsonValue body; body[EASY_TAG_SERIAL] = serial; body[EASY_TAG_CHANNEL] = channel; body[EASY_TAG_RESERVE] = reserve; body[EASY_TAG_PROTOCOL] = protocol; body[EASY_TAG_FROM] = to; body[EASY_TAG_TO] = from; body[EASY_TAG_VIA] = via; EasyMsgDSControlPTZACK rsp(body, ctrlPTZReq.GetMsgCSeq(), getStatusNo(errCode)); string msg = rsp.GetMsg(); StrPtrLen jsonContent(const_cast<char*>(msg.data())); HTTPRequest httpAck(&QTSServerInterface::GetServerHeader(), httpResponseType); if (httpAck.CreateResponseHeader()) { if (jsonContent.Len) httpAck.AppendContentLengthHeader(jsonContent.Len); //Push msg to OutputBuffer char respHeader[2048] = { 0 }; StrPtrLen* ackPtr = httpAck.GetCompleteHTTPHeader(); strncpy(respHeader, ackPtr->Ptr, ackPtr->Len); fOutputStream->Put(respHeader); if (jsonContent.Len > 0) fOutputStream->Put(jsonContent.Ptr, jsonContent.Len); } return errCode; }
//EasyCamera EasyCameraSource.cpp ControlPTZ QTSS_Error EasyCameraSource::ControlPTZ(Easy_CameraPTZ_Params* params) { QTSS_Error result = QTSS_RequestFailed; if (cameraLogin()) { HI_S32 error; if (params->inActionType == EASY_PTZ_ACTION_TYPE_CONTINUOUS) { error = HI_NET_DEV_PTZ_Ctrl_Standard(m_u32Handle, getPTZCMDFromCMDType(params->inCommand), params->inSpeed); } else if (params->inActionType == EASY_PTZ_ACTION_TYPE_SINGLE) { error = HI_NET_DEV_PTZ_Ctrl_StandardEx(m_u32Handle, getPTZCMDFromCMDType(params->inCommand)); } else { return QTSS_BadArgument; } if (error == HI_SUCCESS) { result = QTSS_NoErr; } else { result = QTSS_RequestFailed; } } return result; }
获取更多信息
Github:https://github.com/easydarwin邮件:support@easydarwin.org
WEB:www.EasyDarwin.org
Copyright © EasyDarwin.org 2012-2016
相关文章推荐
- EasyDarwin开源流媒体云平台之云台ptz控制设计与实现
- .Net 分布式云平台基础服务建设说明概要
- .Net 分布式云平台基础服务建设说明概要
- 详谈云计算五个应用趋势
- .Net 分布式云平台基础服务建设说明概要
- 详谈云计算五个应用趋势
- 参加云计算开源产业联盟成果发布会的一些照片
- 现在云战争(真的)开始了
- .Net 分布式云平台基础服务建设说明概要
- .Net 分布式云平台基础服务建设说明概要
- 技术解析 | 两台成云—大华微型云存储系统
- windows下spark开发环境配置
- 新浪云计算SAE部署代码过程
- 【案例】华为助力传统广播新媒体转型
- 首届华为开发者大赛沙龙牵手大连-与开发者共话赛事
- 初识云计算
- 计算范式
- MSML 云计算深度学习平台
- RabbitMQ(七):适用于云计算集群的远程调用(RPC)
- abas ERP和SAAS