Commit 5c488cd03ba911224bca3a341b00455fbce2df09
Committed by
GitHub
Merge pull request #9 from lawrencehj/master
增加了PTZ控制指令码的实现
Showing
4 changed files
with
63 additions
and
14 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| ... | ... | @@ -59,10 +59,10 @@ public class SipLayer implements SipListener, Runnable { |
| 59 | 59 | |
| 60 | 60 | @PostConstruct |
| 61 | 61 | private void initSipServer() { |
| 62 | - Thread thread=new Thread(this); | |
| 63 | - thread.setDaemon(true); | |
| 64 | - thread.setName("sip server thread start"); | |
| 65 | - thread.start(); | |
| 62 | + Thread thread = new Thread(this); | |
| 63 | + thread.setDaemon(true); | |
| 64 | + thread.setName("sip server thread start"); | |
| 65 | + thread.start(); | |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | @Override |
| ... | ... | @@ -84,7 +84,7 @@ public class SipLayer implements SipListener, Runnable { |
| 84 | 84 | * 0; public static final int TRACE_MESSAGES = 16; public static final int |
| 85 | 85 | * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32; |
| 86 | 86 | */ |
| 87 | - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0"); | |
| 87 | + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32"); | |
| 88 | 88 | properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log"); |
| 89 | 89 | properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log"); |
| 90 | 90 | sipStack = (SipStackImpl) sipFactory.createSipStack(properties); |
| ... | ... | @@ -99,13 +99,15 @@ public class SipLayer implements SipListener, Runnable { |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | 101 | private void startTcpListener() throws Exception { |
| 102 | - ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "TCP"); | |
| 102 | + ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), | |
| 103 | + "TCP"); | |
| 103 | 104 | tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); |
| 104 | 105 | tcpSipProvider.addSipListener(this); |
| 105 | 106 | } |
| 106 | 107 | |
| 107 | 108 | private void startUdpListener() throws Exception { |
| 108 | - ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP"); | |
| 109 | + ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), | |
| 110 | + "UDP"); | |
| 109 | 111 | udpSipProvider = sipStack.createSipProvider(udpListeningPoint); |
| 110 | 112 | udpSipProvider.addSipListener(this); |
| 111 | 113 | } |
| ... | ... | @@ -127,13 +129,15 @@ public class SipLayer implements SipListener, Runnable { |
| 127 | 129 | if ((status >= 200) && (status < 300)) { // Success! |
| 128 | 130 | ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); |
| 129 | 131 | processor.process(evt, this, sipConfig); |
| 132 | + } else if (status == Response.TRYING) { | |
| 133 | + // trying不会回复 | |
| 130 | 134 | } else { |
| 131 | 135 | logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getContent().toString()); |
| 132 | 136 | } |
| 133 | 137 | // trying不会回复 |
| 134 | - if (status == Response.TRYING) { | |
| 138 | + // if (status == Response.TRYING) { | |
| 135 | 139 | |
| 136 | - } | |
| 140 | + // } | |
| 137 | 141 | } |
| 138 | 142 | |
| 139 | 143 | /** | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| ... | ... | @@ -94,6 +94,49 @@ public class SIPCommander implements ISIPCommander { |
| 94 | 94 | return ptzCmd(device, channelId, 0, 0, inOut, 0, zoomSpeed); |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | + /** | |
| 98 | + * 云台指令码计算 | |
| 99 | + * | |
| 100 | + * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 | |
| 101 | + * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 | |
| 102 | + * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 | |
| 103 | + * @param moveSpeed 镜头移动速度 默认 0XFF (0-255) | |
| 104 | + * @param zoomSpeed 镜头缩放速度 默认 0X1 (0-255) | |
| 105 | + */ | |
| 106 | + public static String cmdString(int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) { | |
| 107 | + int cmdCode = 0; | |
| 108 | + if (leftRight == 2) { | |
| 109 | + cmdCode|=0x01; // 右移 | |
| 110 | + } else if(leftRight == 1) { | |
| 111 | + cmdCode|=0x02; // 左移 | |
| 112 | + } | |
| 113 | + if (upDown == 2) { | |
| 114 | + cmdCode|=0x04; // 下移 | |
| 115 | + } else if(upDown == 1) { | |
| 116 | + cmdCode|=0x08; // 上移 | |
| 117 | + } | |
| 118 | + if (inOut == 2) { | |
| 119 | + cmdCode |= 0x10; // 放大 | |
| 120 | + } else if(inOut == 1) { | |
| 121 | + cmdCode |= 0x20; // 缩小 | |
| 122 | + } | |
| 123 | + StringBuilder builder = new StringBuilder("A50F01"); | |
| 124 | + String strTmp; | |
| 125 | + strTmp = String.format("%02X", cmdCode); | |
| 126 | + builder.append(strTmp, 0, 2); | |
| 127 | + strTmp = String.format("%02X", moveSpeed); | |
| 128 | + builder.append(strTmp, 0, 2); | |
| 129 | + builder.append(strTmp, 0, 2); | |
| 130 | + strTmp = String.format("%X", zoomSpeed); | |
| 131 | + builder.append(strTmp, 0, 1).append("0"); | |
| 132 | + //计算校验码 | |
| 133 | + int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + moveSpeed + moveSpeed + (zoomSpeed /*<< 4*/ & 0XF0)) % 0X100; | |
| 134 | + strTmp = String.format("%02X", checkCode); | |
| 135 | + builder.append(strTmp, 0, 2); | |
| 136 | + return builder.toString(); | |
| 137 | +} | |
| 138 | + | |
| 139 | + | |
| 97 | 140 | /** |
| 98 | 141 | * 云台控制,支持方向与缩放控制 |
| 99 | 142 | * |
| ... | ... | @@ -109,13 +152,14 @@ public class SIPCommander implements ISIPCommander { |
| 109 | 152 | public boolean ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed, |
| 110 | 153 | int zoomSpeed) { |
| 111 | 154 | try { |
| 155 | + String cmdStr= cmdString(leftRight, upDown, inOut, moveSpeed, zoomSpeed); | |
| 112 | 156 | StringBuffer ptzXml = new StringBuffer(200); |
| 113 | 157 | ptzXml.append("<?xml version=\"1.0\" ?>"); |
| 114 | 158 | ptzXml.append("<Control>"); |
| 115 | 159 | ptzXml.append("<CmdType>DeviceControl</CmdType>"); |
| 116 | 160 | ptzXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>"); |
| 117 | 161 | ptzXml.append("<DeviceID>" + channelId + "</DeviceID>"); |
| 118 | - ptzXml.append("<PTZCmd>" + "</PTZCmd>"); | |
| 162 | + ptzXml.append("<PTZCmd>" + cmdStr + "</PTZCmd>"); | |
| 119 | 163 | ptzXml.append("<Info>"); |
| 120 | 164 | ptzXml.append("</Info>"); |
| 121 | 165 | ptzXml.append("</Control>"); |
| ... | ... | @@ -123,7 +167,6 @@ public class SIPCommander implements ISIPCommander { |
| 123 | 167 | Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag"); |
| 124 | 168 | |
| 125 | 169 | transmitRequest(device, request); |
| 126 | - | |
| 127 | 170 | return true; |
| 128 | 171 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| 129 | 172 | e.printStackTrace(); | ... | ... |
src/main/resources/application.yml
| ... | ... | @@ -26,7 +26,8 @@ spring: |
| 26 | 26 | server: |
| 27 | 27 | port: 8080 |
| 28 | 28 | sip: |
| 29 | - ip: 10.200.64.63 | |
| 29 | +# ip: 10.200.64.63 | |
| 30 | + ip: 192.168.0.102 | |
| 30 | 31 | port: 5060 |
| 31 | 32 | # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) |
| 32 | 33 | # 后两位为行业编码,定义参照附录D.3 |
| ... | ... | @@ -34,7 +35,8 @@ sip: |
| 34 | 35 | domain: 3701020049 |
| 35 | 36 | id: 37010200492000000001 |
| 36 | 37 | # 默认设备认证密码,后续扩展使用设备单独密码 |
| 37 | - password: admin | |
| 38 | + password: admin123 | |
| 38 | 39 | media: |
| 39 | - ip: 10.200.64.88 | |
| 40 | +# ip: 10.200.64.88 | |
| 41 | + ip: 192.168.0.102 | |
| 40 | 42 | port: 10000 |
| 41 | 43 | \ No newline at end of file | ... | ... |
wikis/images/核心流程.png