Commit 6797f77259eceea08e3767b512ecd13477141a46

Authored by 648540858
1 parent 2e399faf

优化点播超时的处理,修复tcp主动点播时ssrc不一致时点播失败的问题

src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -286,39 +286,7 @@ public class PlayServiceImpl implements IPlayService {
286 286 // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
287 287 if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
288 288 if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
289   - String substring = contentString.substring(0, contentString.indexOf("y="));
290   - try {
291   - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
292   - int port = -1;
293   - Vector mediaDescriptions = sdp.getMediaDescriptions(true);
294   - for (Object description : mediaDescriptions) {
295   - MediaDescription mediaDescription = (MediaDescription) description;
296   - Media media = mediaDescription.getMedia();
297   -
298   - Vector mediaFormats = media.getMediaFormats(false);
299   - if (mediaFormats.contains("96")) {
300   - port = media.getMediaPort();
301   - break;
302   - }
303   - }
304   - logger.info("[点播-TCP主动连接对方] deviceId: {}, channelId: {}, 连接对方的地址:{}:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, sdp.getConnection().getAddress(), port, device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
305   - JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
306   - logger.info("[点播-TCP主动连接对方] 结果: {}", jsonObject);
307   - } catch (SdpException e) {
308   - logger.error("[点播-TCP主动连接对方] deviceId: {}, channelId: {}, 解析200OK的SDP信息失败", device.getDeviceId(), channelId, e);
309   - dynamicTask.stop(timeOutTaskKey);
310   - mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
311   - // 释放ssrc
312   - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
313   -
314   - streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
315   -
316   - callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
317   - InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
318   - inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
319   - InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
320   - InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
321   - }
  289 + tcpActiveHandler(device, channelId, contentString, mediaServerItem, timeOutTaskKey, ssrcInfo, callback);
322 290 }
323 291 return;
324 292 }
... ... @@ -388,6 +356,9 @@ public class PlayServiceImpl implements IPlayService {
388 356 ssrcInfo.setSsrc(ssrcInResponse);
389 357 inviteInfo.setSsrcInfo(ssrcInfo);
390 358 inviteInfo.setStream(ssrcInfo.getStream());
  359 + if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
  360 + tcpActiveHandler(device, channelId, contentString, mediaServerItem, timeOutTaskKey, ssrcInfo, callback);
  361 + }
391 362 }
392 363 }else {
393 364 logger.info("[点播消息] 收到invite 200, 下级自定义了ssrc, 但是当前模式无需修正");
... ... @@ -430,6 +401,47 @@ public class PlayServiceImpl implements IPlayService {
430 401 }
431 402 }
432 403  
  404 + private void tcpActiveHandler(Device device, String channelId, String contentString,
  405 + MediaServerItem mediaServerItem,
  406 + String timeOutTaskKey, SSRCInfo ssrcInfo, ErrorCallback<Object> callback){
  407 + if (!device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
  408 + return;
  409 + }
  410 + String substring = contentString.substring(0, contentString.indexOf("y="));
  411 + try {
  412 + SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
  413 + int port = -1;
  414 + Vector mediaDescriptions = sdp.getMediaDescriptions(true);
  415 + for (Object description : mediaDescriptions) {
  416 + MediaDescription mediaDescription = (MediaDescription) description;
  417 + Media media = mediaDescription.getMedia();
  418 +
  419 + Vector mediaFormats = media.getMediaFormats(false);
  420 + if (mediaFormats.contains("96")) {
  421 + port = media.getMediaPort();
  422 + break;
  423 + }
  424 + }
  425 + logger.info("[点播-TCP主动连接对方] deviceId: {}, channelId: {}, 连接对方的地址:{}:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, sdp.getConnection().getAddress(), port, device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
  426 + JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
  427 + logger.info("[点播-TCP主动连接对方] 结果: {}", jsonObject);
  428 + } catch (SdpException e) {
  429 + logger.error("[点播-TCP主动连接对方] deviceId: {}, channelId: {}, 解析200OK的SDP信息失败", device.getDeviceId(), channelId, e);
  430 + dynamicTask.stop(timeOutTaskKey);
  431 + mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
  432 + // 释放ssrc
  433 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
  434 +
  435 + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
  436 +
  437 + callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
  438 + InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
  439 + inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
  440 + InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
  441 + InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
  442 + }
  443 + }
  444 +
433 445 /**
434 446 * 点播成功时调用截图.
435 447 *
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
... ... @@ -67,7 +67,7 @@ public class MediaController {
67 67 && streamAuthorityInfo.getCallId().equals(callId)) {
68 68 authority = true;
69 69 }else {
70   - throw new ControllerException(ErrorCode.ERROR400);
  70 + throw new ControllerException(ErrorCode.ERROR400.getCode(), "获取播放地址鉴权失败");
71 71 }
72 72 }else {
73 73 // 是否登陆用户, 登陆用户返回完整信息
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
... ... @@ -92,6 +92,7 @@ public class PlayController {
92 92 public DeferredResult<WVPResult<StreamContent>> play(HttpServletRequest request, @PathVariable String deviceId,
93 93 @PathVariable String channelId) {
94 94  
  95 + logger.info("[开始点播] deviceId:{}, channelId:{}, ", deviceId, channelId);
95 96 // 获取可用的zlm
96 97 Device device = storager.queryVideoDevice(deviceId);
97 98 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
... ... @@ -104,13 +105,15 @@ public class PlayController {
104 105 DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
105 106  
106 107 result.onTimeout(()->{
107   - logger.info("点播接口等待超时");
  108 + logger.info("[点播等待超时] deviceId:{}, channelId:{}, ", deviceId, channelId);
108 109 // 释放rtpserver
109 110 WVPResult<StreamInfo> wvpResult = new WVPResult<>();
110 111 wvpResult.setCode(ErrorCode.ERROR100.getCode());
111 112 wvpResult.setMsg("点播超时");
112 113 requestMessage.setData(wvpResult);
113 114 resultHolder.invokeResult(requestMessage);
  115 + inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
  116 + storager.stopPlay(deviceId, channelId);
114 117 });
115 118  
116 119 // 录像查询以channelId作为deviceId查询
... ...