最近完成了GB28181的云台控制功能,记录下相关代码。
参考
要实现GB28181的云台控制,基本不用参考其他文档了,直接查看标准文档即可,当然COPY别人现成代码也是很爽的,不过百度相关代码其实也不多,是不是搞这块的人不多呢。这里主要要说的是,云台控制就是发送了消息,相机会一直执行,直到其他命令或者发送了停止命令,切记要考虑这个机制。
代码
其他不说了,具体格式参考文档,此次就不贴图了,直接上代码
std::string MakePtzCmd(int ucommand, int speed) { uint8_t buffer[8] = {0}; buffer[0] = 0xA5; buffer[1] = 0x0F; buffer[2] = 0x01;
switch (ucommand) { case PTZ_STOP: buffer[3] = 0; buffer[4] = 0; buffer[5] = 0; buffer[6] = 0; break; case PTZ_UP: buffer[3] = 8; buffer[4] = speed; buffer[5] = speed; buffer[6] = 0; break; case PTZ_DOWN: buffer[3] = 4; buffer[4] = speed; buffer[5] = speed; buffer[6] = 0; break; case PTZ_LEFT: buffer[3] = 2; buffer[4] = speed; buffer[5] = speed; buffer[6] = 0; break; case PTZ_RIGHT: buffer[3] = 1; buffer[4] = speed; buffer[5] = speed; buffer[6] = 0; break; case PTZ_RIGHTUP: buffer[3] = 9; buffer[4] = speed; buffer[5] = speed; buffer[6] = 0; break; case PTZ_RIGHTDOWN: buffer[3] = 5; buffer[4] = speed; buffer[5] = speed; buffer[6] = 0; break; case PTZ_LEFTUP: buffer[3] = 0xa; buffer[4] = speed; buffer[5] = speed; buffer[6] = 0; break; case PTZ_LEFTDOWN: buffer[3] = 6; buffer[4] = speed; buffer[5] = speed; buffer[6] = 0; break; case PTZ_ZOOM_IN: buffer[3] = 0x10; buffer[4] = 0; buffer[5] = 0; buffer[6] = speed << 4; break; case PTZ_ZOOM_OUT: buffer[3] = 0x20; buffer[4] = 0; buffer[5] = 0; buffer[6] = speed << 4; break; default: break; }
int check = 0; std::string result; char tmp[3] = {0}; for(size_t i = 0; i < 7; i++) { check += uint8_t(buffer[i]); sprintf(tmp, "%02x", uint8_t(buffer[i])); result.append(tmp, 2); } buffer[7] = check % 256; sprintf(tmp, "%02x", uint8_t(buffer[7])); result.append(tmp, 2); return result; }
|
上面是生成PTZ命令的方法,实际上最终是要通过SIP下发MESSAGE消息,MESSGAGE的消息格式为
char body[256] = {0}; sprintf(body, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" "<Control>" "<CmdType>DeviceControl</CmdType>" "<SN>%d</SN>" "<DeviceID>%s</DeviceID>" "<PTZCmd>%s</PTZCmd>" "</Control>", ++ptz_seq_no_, device_id.c_str(), GetPtzCmd(cmd,param).c_str());
|
当然也要设置 Content-Type 为 Application/MANSCDP+xml