GB28181学习(十八)——图像抓拍

前言

本文主要介绍图像抓拍功能,通过自研的sip库(mysipsdk.dll)对接真实设备,使用http方式实现图像数据传输,最终达到图像抓拍与保存的目的。

基本要求

  • 图像格式宜使用JPEG;
  • 图像分辨率宜采用与主码流相同的分辨率;
  • 抓拍图像文件命令宜遵循如下格式:

GB28181学习(十八)——图像抓拍_第1张图片

协议接口

  • MESSAGE消息头Content-type头域为Content-type:Application/MANSCDP+xml;
  • 图像传输方式宜使用http;
  • 图像抓拍传输完成中的SessionID应与图像抓拍配置中的SessionID一致;

流程图

GB28181学习(十八)——图像抓拍_第2张图片

流程说明:

  • SIP服务器(mysipsdk.dll)向设备端发送图像抓拍配置命令;
  • 设备端返回200 OK;
  • 设备端返回图像抓拍配置响应;
  • SIP服务器(mysipsdk.dll)返回200 OK;
  • 设备端将图像数据传输至图片存储服务器;
  • 设备端发送图像抓拍传输完成消息;
  • SIP服务器(mysipsdk.dll)返回200 OK;

设计

  1. SIP服务器(mysipsdk.dll)向设备端发送图像抓拍配置命令;

参数说明:

SnapNum:连拍张数,最多10张,当为手动抓拍时取值为1
Interval:单张抓拍间隔时间,单位:秒,最短为1秒
UploadURL:抓拍图像上传路径,例如:http://192.168.1.121/uploadsnapshot?token=xxx
SessionID:会话ID,由平台生成,用于关联抓拍的图像和平台请求,SessionID由大小写英文字母、数字、短划线组成,长度32~128字节

代码示例:

int CGBDeviceConfig::SnapShotConfig_(CMyGBDevice* device, const std::string& deviceID, const std::string& request)
{
	if (!device || deviceID.empty() || request.empty())
		return -1;

	Json::Value value;
	Json::Reader reader;
	if (!reader.parse(request.c_str(), value))
		return -1;

	std::string sn = GetConfigSN();
	std::string uploadURL = value["uploadURL"].asString();
	std::string sessionID = value["sessionID"].asString();
	int snapNum = value["snapNum"].asInt();
	int interval = value["interval"].asInt();

	char snapShotInfo[500] = { 0 };
	snprintf(snapShotInfo, 500,
		"\n"
		"\n"
		"DeviceConfig\n"
		"%s\n"
		"%s\n"
		"\n"
		"%d\n"
		"%d\n"
		"%s\n"
		"%s\n"
		"\n"
		"\n"
		, sn.c_str()
		, deviceID.c_str()
		, snapNum
		, interval
		, uploadURL.c_str()
		, sessionID.c_str()
	);

	return CMySipContext::GetInstance().SendSipMessage(device, snapShotInfo);
}
  1. 设备端发送图像抓拍传输完成消息,SIP服务器(mysipsdk.dll)做解析;

主要流程:

1) 接收响应消息;
2) xml解析;
3) 判断CmdType是否为"UploadSnapShotFinished";
4) 如果3)步骤为是,解析返回消息并回调至应用层;

图像抓拍返回字段说明:

CmdType:固定为字符串"UploadSnapShotFinished"
SessionID:会话ID,由平台生成,用于关联抓拍的图像和平台请求
SnapShotList:抓拍图像标识列表
SnapShotFileID:抓拍图像唯一标识,由前端抓拍设备生成

代码示例:

bool CDeviceConfigMethod::OnRecvMsg(pjsip_rx_data* rdata)
{
	if (PJSIP_OTHER_METHOD == rdata->msg_info.cseq->method.id)
	{
		CMyXmlParser xmlParser(CMySipContext::GetInstance().GetMessageBody(rdata));
		CMyDynamicStruct dynamicStruct;
		dynamicStruct.Set(xmlParser.GetXml());

		auto cmd = xmlParser.GetXml()->RootElement()->Value();
		auto cmdType = dynamicStruct.Get("CmdType");
		if ("UploadSnapShotFinished" == cmdType)
		{
			CSnapShotFinishInfo snapShotInfo;
			snapShotInfo.deviceID = dynamicStruct.Get("DeviceID");
			snapShotInfo.sessionID = dynamicStruct.Get("SessionID");
			std::string snapShotList = dynamicStruct.Get("SnapShotList");

			Json::Reader reader;
			Json::Value value;
			reader.parse(snapShotList, value);
			int size = value.size();
			for (int i = 0; i < size; i++)
			{
				Json::Value val = value[i];
				std::string snapShotfileID = val["SnapShotFileID"].asString();
				snapShotInfo.snapShotFileIDs.push_back(snapShotfileID);
			}

            // 回调至应用层,需注册
			if (m_dataCB)
				m_dataCB(m_handleType, m_user, &snapShotInfo);
		}
		else
		{
			return false;
		}

		Response(rdata, PJSIP_SC_OK, NoHead);
		return true;
	}

	return false;
}

你可能感兴趣的:(GB28181,学习,GB28181,c++)