Commit 2f165d595af3565bd17612ee0f5866ace8ab43f4

Authored by panlinlin
1 parent 418970ea

对级联点播信令进行处理

src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -30,6 +30,8 @@ public class VideoManagerConstants { @@ -30,6 +30,8 @@ public class VideoManagerConstants {
30 30
31 public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_platform_register_info_"; 31 public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_platform_register_info_";
32 32
  33 + public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_platform_send_rtp_info_";
  34 +
33 public static final String Pattern_Topic = "VMP_keeplive_platform_"; 35 public static final String Pattern_Topic = "VMP_keeplive_platform_";
34 36
35 public static final String EVENT_ONLINE_REGISTER = "1"; 37 public static final String EVENT_ONLINE_REGISTER = "1";
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +public class SendRtpItem {
  4 +
  5 + /**
  6 + * 推流ip
  7 + */
  8 + private String ip;
  9 +
  10 + /**
  11 + * 推流端口
  12 + */
  13 + private int port;
  14 +
  15 + /**
  16 + * 推流标识
  17 + */
  18 + private String ssrc;
  19 +
  20 + /**
  21 + * 平台id
  22 + */
  23 + private String platformId;
  24 +
  25 + /**
  26 + * 通道id
  27 + */
  28 + private String channelId;
  29 +
  30 + /**
  31 + * 推流状态
  32 + * 0 等待设备推流上来
  33 + * 1 等待上级平台回复ack
  34 + * 2 推流中
  35 + */
  36 + private int status = 0;
  37 +
  38 + /**
  39 + * 设备推流的app
  40 + */
  41 + private String app = "rtp";
  42 +
  43 + /**
  44 + * 设备推流的streamId
  45 + */
  46 + private String streamId;
  47 +
  48 + /**
  49 + * 是否为tcp
  50 + */
  51 + private boolean tcp;
  52 +
  53 + /**
  54 + * 是否为tcp主动模式
  55 + */
  56 + private boolean tcpActive;
  57 +
  58 + /**
  59 + * 自己推流使用的端口
  60 + */
  61 + private int localPort;
  62 +
  63 + public String getIp() {
  64 + return ip;
  65 + }
  66 +
  67 + public void setIp(String ip) {
  68 + this.ip = ip;
  69 + }
  70 +
  71 + public int getPort() {
  72 + return port;
  73 + }
  74 +
  75 + public void setPort(int port) {
  76 + this.port = port;
  77 + }
  78 +
  79 + public String getSsrc() {
  80 + return ssrc;
  81 + }
  82 +
  83 + public void setSsrc(String ssrc) {
  84 + this.ssrc = ssrc;
  85 + }
  86 +
  87 + public String getPlatformId() {
  88 + return platformId;
  89 + }
  90 +
  91 + public void setPlatformId(String platformId) {
  92 + this.platformId = platformId;
  93 + }
  94 +
  95 + public String getChannelId() {
  96 + return channelId;
  97 + }
  98 +
  99 + public void setChannelId(String channelId) {
  100 + this.channelId = channelId;
  101 + }
  102 +
  103 + public int getStatus() {
  104 + return status;
  105 + }
  106 +
  107 + public void setStatus(int status) {
  108 + this.status = status;
  109 + }
  110 +
  111 + public String getApp() {
  112 + return app;
  113 + }
  114 +
  115 + public void setApp(String app) {
  116 + this.app = app;
  117 + }
  118 +
  119 + public String getStreamId() {
  120 + return streamId;
  121 + }
  122 +
  123 + public void setStreamId(String streamId) {
  124 + this.streamId = streamId;
  125 + }
  126 +
  127 + public boolean isTcp() {
  128 + return tcp;
  129 + }
  130 +
  131 + public void setTcp(boolean tcp) {
  132 + this.tcp = tcp;
  133 + }
  134 +
  135 + public int getLocalPort() {
  136 + return localPort;
  137 + }
  138 +
  139 + public void setLocalPort(int localPort) {
  140 + this.localPort = localPort;
  141 + }
  142 +
  143 + public boolean isTcpActive() {
  144 + return tcpActive;
  145 + }
  146 +
  147 + public void setTcpActive(boolean tcpActive) {
  148 + this.tcpActive = tcpActive;
  149 + }
  150 +}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -136,6 +136,7 @@ public class SIPProcessorFactory { @@ -136,6 +136,7 @@ public class SIPProcessorFactory {
136 processor.setCmderFroPlatform(cmderFroPlatform); 136 processor.setCmderFroPlatform(cmderFroPlatform);
137 processor.setPlayService(playService); 137 processor.setPlayService(playService);
138 processor.setStorager(storager); 138 processor.setStorager(storager);
  139 + processor.setRedisCatchStorage(redisCatchStorage);
139 processor.setZlmrtpServerFactory(zlmrtpServerFactory); 140 processor.setZlmrtpServerFactory(zlmrtpServerFactory);
140 return processor; 141 return processor;
141 } else if (Request.REGISTER.equals(method)) { 142 } else if (Request.REGISTER.equals(method)) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.request.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
2 2
3 -import javax.sip.Dialog;  
4 -import javax.sip.InvalidArgumentException;  
5 -import javax.sip.RequestEvent;  
6 -import javax.sip.SipException; 3 +import javax.sip.*;
7 import javax.sip.message.Request; 4 import javax.sip.message.Request;
8 5
9 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; 6 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
@@ -26,7 +23,11 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { @@ -26,7 +23,11 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
26 public void process(RequestEvent evt) { 23 public void process(RequestEvent evt) {
27 Request request = evt.getRequest(); 24 Request request = evt.getRequest();
28 Dialog dialog = evt.getDialog(); 25 Dialog dialog = evt.getDialog();
  26 + DialogState state = dialog.getState();
29 if (dialog == null) return; 27 if (dialog == null) return;
  28 + if (request.getMethod().equals(Request.INVITE) && dialog.getState()== DialogState.CONFIRMED) {
  29 + // TODO 查询并开始推流
  30 + }
30 try { 31 try {
31 Request ackRequest = null; 32 Request ackRequest = null;
32 CSeq csReq = (CSeq) request.getHeader(CSeq.NAME); 33 CSeq csReq = (CSeq) request.getHeader(CSeq.NAME);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
@@ -4,9 +4,12 @@ import javax.sdp.*; @@ -4,9 +4,12 @@ import javax.sdp.*;
4 import javax.sip.InvalidArgumentException; 4 import javax.sip.InvalidArgumentException;
5 import javax.sip.RequestEvent; 5 import javax.sip.RequestEvent;
6 import javax.sip.SipException; 6 import javax.sip.SipException;
  7 +import javax.sip.SipFactory;
  8 +import javax.sip.address.Address;
7 import javax.sip.address.SipURI; 9 import javax.sip.address.SipURI;
8 import javax.sip.header.ContentTypeHeader; 10 import javax.sip.header.ContentTypeHeader;
9 import javax.sip.header.FromHeader; 11 import javax.sip.header.FromHeader;
  12 +import javax.sip.header.HeaderFactory;
10 import javax.sip.header.SubjectHeader; 13 import javax.sip.header.SubjectHeader;
11 import javax.sip.message.Request; 14 import javax.sip.message.Request;
12 import javax.sip.message.Response; 15 import javax.sip.message.Response;
@@ -15,6 +18,7 @@ import com.alibaba.fastjson.JSONObject; @@ -15,6 +18,7 @@ import com.alibaba.fastjson.JSONObject;
15 import com.genersoft.iot.vmp.conf.MediaServerConfig; 18 import com.genersoft.iot.vmp.conf.MediaServerConfig;
16 import com.genersoft.iot.vmp.gb28181.bean.Device; 19 import com.genersoft.iot.vmp.gb28181.bean.Device;
17 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 20 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  21 +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
18 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 22 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
19 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 23 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
20 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; 24 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
@@ -100,16 +104,18 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -100,16 +104,18 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
100 platformId = uri.getUser(); 104 platformId = uri.getUser();
101 105
102 if (platformId == null || channelId == null) { 106 if (platformId == null || channelId == null) {
103 - response400Ack(evt); // 参数不全, 发400,请求错误 107 + logger.info("无法从FromHeader的Address中获取到平台id,返回404");
  108 + responseAck(evt, Response.BAD_REQUEST); // 参数不全, 发400,请求错误
104 return; 109 return;
105 } 110 }
106 // 查询平台下是否有该通道 111 // 查询平台下是否有该通道
107 DeviceChannel channel = storager.queryChannelInParentPlatform(platformId, channelId); 112 DeviceChannel channel = storager.queryChannelInParentPlatform(platformId, channelId);
108 if (channel == null) { 113 if (channel == null) {
109 - response404Ack(evt); // 通道不存在,发404,资源不存在 114 + logger.info("通道不存在,返回404");
  115 + responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在
110 return; 116 return;
111 }else { 117 }else {
112 - response100Ack(evt); // 通道存在,发100,trying 118 + responseAck(evt, Response.TRYING); // 通道存在,发100,trying
113 } 119 }
114 // 解析sdp消息, 使用jainsip 自带的sdp解析方式 120 // 解析sdp消息, 使用jainsip 自带的sdp解析方式
115 String contentString = new String(request.getRawContent()); 121 String contentString = new String(request.getRawContent());
@@ -152,107 +158,79 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -152,107 +158,79 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
152 } 158 }
153 } 159 }
154 } 160 }
155 -// Vector attributes = mediaDescription.getAttributes(false);  
156 -// for (Object attributeObj : attributes) {  
157 -// Attribute attribute = (Attribute)attributeObj;  
158 -// String name = attribute.getName();  
159 -// switch (name){  
160 -// case "recvonly":  
161 -// recvonly = true;  
162 -// break;  
163 -// case "rtpmap":  
164 -// case "connection":  
165 -// break;  
166 -// case "setup":  
167 -// mediaTransmissionTCP = true;  
168 -// if ("active".equals(attribute.getValue())) { // tcp主动模式  
169 -// tcpActive = true;  
170 -// }else if ("passive".equals(attribute.getValue())){ // tcp被动模式  
171 -// tcpActive = false;  
172 -// }  
173 -// break;  
174 -//  
175 -// }  
176 -// if ("recvonly".equals(name)) {  
177 -// recvonly = true;  
178 -// }  
179 -//  
180 -// String value = attribute.getValue();  
181 -// }  
182 break; 161 break;
183 } 162 }
184 } 163 }
185 if (port == -1) { 164 if (port == -1) {
  165 + logger.info("不支持的媒体格式,返回415");
186 // 回复不支持的格式 166 // 回复不支持的格式
187 - response415Ack(evt); // 不支持的格式,发415 167 + responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
188 return; 168 return;
189 } 169 }
190 String username = sdp.getOrigin().getUsername(); 170 String username = sdp.getOrigin().getUsername();
191 String addressStr = sdp.getOrigin().getAddress(); 171 String addressStr = sdp.getOrigin().getAddress();
192 String sessionName = sdp.getSessionName().getValue(); 172 String sessionName = sdp.getSessionName().getValue();
193 logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc); 173 logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc);
194 -//  
195 -// Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);  
196 -// if (device == null) {  
197 -// logger.warn("点播平台{}的通道{}时未找到设备信息", platformId, channel);  
198 -// response500Ack(evt);  
199 -// return;  
200 -// }  
201 -//  
202 -// // 通知下级推流,  
203 -// PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{  
204 -// // 收到推流, 回复200OK  
205 -// UUID uuid = UUID.randomUUID();  
206 -// int rtpServer = zlmrtpServerFactory.createRTPServer(uuid.toString());  
207 -// if (rtpServer == -1) {  
208 -// logger.error("为获取到可用端口");  
209 -// return;  
210 -// }else {  
211 -// zlmrtpServerFactory.closeRTPServer(uuid.toString());  
212 -// }  
213 -// // TODO 添加对tcp的支持  
214 -// MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();  
215 -// StringBuffer content = new StringBuffer(200);  
216 -// content.append("v=0\r\n");  
217 -// content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");  
218 -// content.append("s=Play\r\n");  
219 -// content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");  
220 -// content.append("t=0 0\r\n");  
221 -// content.append("m=video "+ rtpServer+" RTP/AVP 96\r\n");  
222 -// content.append("a=sendonly\r\n");  
223 -// content.append("a=rtpmap:96 PS/90000\r\n");  
224 -// content.append("y="+ ssrc + "\r\n");  
225 -// content.append("f=\r\n");  
226 -//  
227 -// try {  
228 -// responseAck(evt, content.toString());  
229 -// } catch (SipException e) {  
230 -// e.printStackTrace();  
231 -// } catch (InvalidArgumentException e) {  
232 -// e.printStackTrace();  
233 -// } catch (ParseException e) {  
234 -// e.printStackTrace();  
235 -// }  
236 -//  
237 -// // 写入redis, 超时时回复  
238 -//// redisCatchStorage.waiteAck()  
239 -// },(event -> {  
240 -// // 未知错误。直接转发设备点播的错误  
241 -// Response response = null;  
242 -// try {  
243 -// response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());  
244 -// getServerTransaction(evt).sendResponse(response);  
245 -//  
246 -// } catch (ParseException | SipException | InvalidArgumentException e) {  
247 -// e.printStackTrace();  
248 -// }  
249 -// }));  
250 -// playResult.getResult();  
251 - // 查找合适的端口推流,  
252 - // 收到ack后调用推流接口  
253 -  
254 174
  175 + Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
  176 + if (device == null) {
  177 + logger.warn("点播平台{}的通道{}时未找到设备信息", platformId, channel);
  178 + responseAck(evt, Response.SERVER_INTERNAL_ERROR);
  179 + return;
  180 + }
  181 + SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(ip, port, platformId, ssrc, channelId,
  182 + mediaTransmissionTCP);
  183 + if (tcpActive != null) {
  184 + sendRtpItem.setTcpActive(tcpActive);
  185 + }
  186 + if (sendRtpItem == null) {
  187 + logger.warn("服务器端口资源不足");
  188 + responseAck(evt, Response.BUSY_HERE);
  189 + return;
  190 + }
255 191
  192 + // 写入redis, 超时时回复
  193 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
  194 + // 通知下级推流,
  195 + PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{
  196 + // 收到推流, 回复200OK, 等待ack
  197 + sendRtpItem.setStatus(1);
  198 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
  199 + // TODO 添加对tcp的支持
  200 + MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
  201 + StringBuffer content = new StringBuffer(200);
  202 + content.append("v=0\r\n");
  203 + content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
  204 + content.append("s=Play\r\n");
  205 + content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
  206 + content.append("t=0 0\r\n");
  207 + content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
  208 + content.append("a=sendonly\r\n");
  209 + content.append("a=rtpmap:96 PS/90000\r\n");
  210 + content.append("y="+ ssrc + "\r\n");
  211 + content.append("f=\r\n");
  212 +
  213 + try {
  214 + responseAck(evt, content.toString());
  215 + } catch (SipException e) {
  216 + e.printStackTrace();
  217 + } catch (InvalidArgumentException e) {
  218 + e.printStackTrace();
  219 + } catch (ParseException e) {
  220 + e.printStackTrace();
  221 + }
  222 + },(event -> {
  223 + // 未知错误。直接转发设备点播的错误
  224 + Response response = null;
  225 + try {
  226 + response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());
  227 + getServerTransaction(evt).sendResponse(response);
  228 +
  229 + } catch (ParseException | SipException | InvalidArgumentException e) {
  230 + e.printStackTrace();
  231 + }
  232 + }));
  233 + playResult.getResult();
256 234
257 } catch (SipException | InvalidArgumentException | ParseException e) { 235 } catch (SipException | InvalidArgumentException | ParseException e) {
258 e.printStackTrace(); 236 e.printStackTrace();
@@ -263,101 +241,47 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -263,101 +241,47 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
263 } catch (SdpException e) { 241 } catch (SdpException e) {
264 e.printStackTrace(); 242 e.printStackTrace();
265 } 243 }
266 -  
267 } 244 }
268 245
269 /*** 246 /***
270 - * 回复100 trying 247 + * 回复状态码
  248 + * 100 trying
  249 + * 200 OK
  250 + * 400
  251 + * 404
271 * @param evt 252 * @param evt
272 * @throws SipException 253 * @throws SipException
273 * @throws InvalidArgumentException 254 * @throws InvalidArgumentException
274 * @throws ParseException 255 * @throws ParseException
275 */ 256 */
276 - private void response100Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { 257 + private void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException {
277 Response response = getMessageFactory().createResponse(Response.TRYING, evt.getRequest()); 258 Response response = getMessageFactory().createResponse(Response.TRYING, evt.getRequest());
278 getServerTransaction(evt).sendResponse(response); 259 getServerTransaction(evt).sendResponse(response);
279 } 260 }
280 261
281 - /***  
282 - * 回复200 OK 262 + /**
  263 + * 回复带sdp的200
283 * @param evt 264 * @param evt
  265 + * @param sdp
284 * @throws SipException 266 * @throws SipException
285 * @throws InvalidArgumentException 267 * @throws InvalidArgumentException
286 * @throws ParseException 268 * @throws ParseException
287 */ 269 */
288 private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException { 270 private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException {
289 Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); 271 Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest());
290 - ContentTypeHeader contentTypeHeader = getHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); 272 + SipFactory sipFactory = SipFactory.getInstance();
  273 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
291 response.setContent(sdp, contentTypeHeader); 274 response.setContent(sdp, contentTypeHeader);
292 - getServerTransaction(evt).sendResponse(response);  
293 - }  
294 275
295 - /***  
296 - * 回复400  
297 - * @param evt  
298 - * @throws SipException  
299 - * @throws InvalidArgumentException  
300 - * @throws ParseException  
301 - */  
302 - private void response400Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {  
303 - Response response = getMessageFactory().createResponse(Response.BAD_REQUEST, evt.getRequest());  
304 - getServerTransaction(evt).sendResponse(response);  
305 - } 276 + SipURI sipURI = (SipURI)evt.getRequest().getRequestURI();
306 277
307 - /***  
308 - * 回复404  
309 - * @param evt  
310 - * @throws SipException  
311 - * @throws InvalidArgumentException  
312 - * @throws ParseException  
313 - */  
314 - private void response404Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {  
315 - Response response = getMessageFactory().createResponse(Response.NOT_FOUND, evt.getRequest()); 278 + Address concatAddress = sipFactory.createAddressFactory().createAddress(
  279 + sipFactory.createAddressFactory().createSipURI(sipURI.getUser(), sipURI.getHost()+":"+sipURI.getPort()
  280 + ));
  281 + response.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
316 getServerTransaction(evt).sendResponse(response); 282 getServerTransaction(evt).sendResponse(response);
317 } 283 }
318 284
319 - /***  
320 - * 回复415 不支持的媒体类型  
321 - * @param evt  
322 - * @throws SipException  
323 - * @throws InvalidArgumentException  
324 - * @throws ParseException  
325 - */  
326 - private void response415Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {  
327 - Response response = getMessageFactory().createResponse(Response.UNSUPPORTED_MEDIA_TYPE, evt.getRequest());  
328 - getServerTransaction(evt).sendResponse(response);  
329 - }  
330 -  
331 - /***  
332 - * 回复488  
333 - * @param evt  
334 - * @throws SipException  
335 - * @throws InvalidArgumentException  
336 - * @throws ParseException  
337 - */  
338 - private void response488Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {  
339 - Response response = getMessageFactory().createResponse(Response.NOT_ACCEPTABLE_HERE, evt.getRequest());  
340 - getServerTransaction(evt).sendResponse(response);  
341 - }  
342 -  
343 - /***  
344 - * 回复500  
345 - * @param evt  
346 - * @throws SipException  
347 - * @throws InvalidArgumentException  
348 - * @throws ParseException  
349 - */  
350 - private void response500Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {  
351 - Response response = getMessageFactory().createResponse(Response.SERVER_INTERNAL_ERROR, evt.getRequest());  
352 - getServerTransaction(evt).sendResponse(response);  
353 - }  
354 -  
355 -  
356 -  
357 -  
358 -  
359 -  
360 -  
361 285
362 286
363 287
@@ -394,4 +318,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -394,4 +318,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
394 public void setPlayService(IPlayService playService) { 318 public void setPlayService(IPlayService playService) {
395 this.playService = playService; 319 this.playService = playService;
396 } 320 }
  321 +
  322 + public IRedisCatchStorage getRedisCatchStorage() {
  323 + return redisCatchStorage;
  324 + }
  325 +
  326 + public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
  327 + this.redisCatchStorage = redisCatchStorage;
  328 + }
397 } 329 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
1 package com.genersoft.iot.vmp.media.zlm; 1 package com.genersoft.iot.vmp.media.zlm;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
  4 +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  5 +import com.genersoft.iot.vmp.gb28181.session.SsrcUtil;
4 import org.slf4j.Logger; 6 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory; 7 import org.slf4j.LoggerFactory;
6 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Autowired;
@@ -92,4 +94,34 @@ public class ZLMRTPServerFactory { @@ -92,4 +94,34 @@ public class ZLMRTPServerFactory {
92 return currentPort++; 94 return currentPort++;
93 } 95 }
94 } 96 }
  97 +
  98 + /**
  99 + * 创建一个推流
  100 + * @param ip 推流ip
  101 + * @param port 推流端口
  102 + * @param ssrc 推流唯一标识
  103 + * @param platformId 平台id
  104 + * @param channelId 通道id
  105 + * @param tcp 是否为tcp
  106 + * @return SendRtpItem
  107 + */
  108 + public SendRtpItem createSendRtpItem(String ip, int port, String ssrc, String platformId, String channelId, boolean tcp){
  109 + String playSsrc = SsrcUtil.getPlaySsrc();
  110 + int localPort = createRTPServer(SsrcUtil.getPlaySsrc());
  111 + if (localPort != -1) {
  112 + closeRTPServer(playSsrc);
  113 + }else {
  114 + logger.error("没有可用的端口");
  115 + return null;
  116 + }
  117 + SendRtpItem sendRtpItem = new SendRtpItem();
  118 + sendRtpItem.setIp(ip);
  119 + sendRtpItem.setPort(port);
  120 + sendRtpItem.setSsrc(ssrc);
  121 + sendRtpItem.setPlatformId(platformId);
  122 + sendRtpItem.setChannelId(channelId);
  123 + sendRtpItem.setTcp(tcp);
  124 + sendRtpItem.setLocalPort(localPort);
  125 + return sendRtpItem;
  126 + }
95 } 127 }
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.MediaServerConfig; @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.MediaServerConfig;
5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
7 import com.genersoft.iot.vmp.gb28181.bean.PlatformRegister; 7 import com.genersoft.iot.vmp.gb28181.bean.PlatformRegister;
  8 +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
8 9
9 import java.util.Map; 10 import java.util.Map;
10 11
@@ -78,4 +79,6 @@ public interface IRedisCatchStorage { @@ -78,4 +79,6 @@ public interface IRedisCatchStorage {
78 String queryPlatformRegisterInfo(String callId); 79 String queryPlatformRegisterInfo(String callId);
79 80
80 void delPlatformRegisterInfo(String callId); 81 void delPlatformRegisterInfo(String callId);
  82 +
  83 + void updateSendRTPSever(SendRtpItem sendRtpItem);
81 } 84 }
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -3,10 +3,7 @@ package com.genersoft.iot.vmp.storager.impl; @@ -3,10 +3,7 @@ package com.genersoft.iot.vmp.storager.impl;
3 import com.genersoft.iot.vmp.common.StreamInfo; 3 import com.genersoft.iot.vmp.common.StreamInfo;
4 import com.genersoft.iot.vmp.common.VideoManagerConstants; 4 import com.genersoft.iot.vmp.common.VideoManagerConstants;
5 import com.genersoft.iot.vmp.conf.MediaServerConfig; 5 import com.genersoft.iot.vmp.conf.MediaServerConfig;
6 -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;  
7 -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;  
8 -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;  
9 -import com.genersoft.iot.vmp.gb28181.bean.PlatformRegister; 6 +import com.genersoft.iot.vmp.gb28181.bean.*;
10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 7 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; 8 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
12 import com.genersoft.iot.vmp.utils.redis.RedisUtil; 9 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
@@ -215,4 +212,10 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -215,4 +212,10 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
215 public void delPlatformRegisterInfo(String callId) { 212 public void delPlatformRegisterInfo(String callId) {
216 redis.del(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + callId); 213 redis.del(VideoManagerConstants.PLATFORM_REGISTER_INFO_PREFIX + callId);
217 } 214 }
  215 +
  216 + @Override
  217 + public void updateSendRTPSever(SendRtpItem sendRtpItem) {
  218 + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + sendRtpItem.getPlatformId() + "_" + sendRtpItem.getChannelId();
  219 + redis.set(key, sendRtpItem);
  220 + }
218 } 221 }