Browse Source

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

648540858 2 years ago
parent
commit
6797f77259

+ 45 - 33
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java

@@ -286,39 +286,7 @@ public class PlayServiceImpl implements IPlayService {
                     // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
                     if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
                         if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
-                            String substring = contentString.substring(0, contentString.indexOf("y="));
-                            try {
-                                SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
-                                int port = -1;
-                                Vector mediaDescriptions = sdp.getMediaDescriptions(true);
-                                for (Object description : mediaDescriptions) {
-                                    MediaDescription mediaDescription = (MediaDescription) description;
-                                    Media media = mediaDescription.getMedia();
-
-                                    Vector mediaFormats = media.getMediaFormats(false);
-                                    if (mediaFormats.contains("96")) {
-                                        port = media.getMediaPort();
-                                        break;
-                                    }
-                                }
-                                logger.info("[点播-TCP主动连接对方] deviceId: {}, channelId: {}, 连接对方的地址:{}:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, sdp.getConnection().getAddress(), port, device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
-                                JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
-                                logger.info("[点播-TCP主动连接对方] 结果: {}", jsonObject);
-                            } catch (SdpException e) {
-                                logger.error("[点播-TCP主动连接对方] deviceId: {}, channelId: {}, 解析200OK的SDP信息失败", device.getDeviceId(), channelId, e);
-                                dynamicTask.stop(timeOutTaskKey);
-                                mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
-                                // 释放ssrc
-                                mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
-
-                                streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
-
-                                callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
-                                        InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
-                                inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
-                                        InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
-                                        InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
-                            }
+                            tcpActiveHandler(device, channelId, contentString, mediaServerItem, timeOutTaskKey, ssrcInfo, callback);
                         }
                         return;
                     }
@@ -388,6 +356,9 @@ public class PlayServiceImpl implements IPlayService {
                             ssrcInfo.setSsrc(ssrcInResponse);
                             inviteInfo.setSsrcInfo(ssrcInfo);
                             inviteInfo.setStream(ssrcInfo.getStream());
+                            if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
+                                tcpActiveHandler(device, channelId, contentString, mediaServerItem, timeOutTaskKey, ssrcInfo, callback);
+                            }
                         }
                     }else {
                         logger.info("[点播消息] 收到invite 200, 下级自定义了ssrc, 但是当前模式无需修正");
@@ -430,6 +401,47 @@ public class PlayServiceImpl implements IPlayService {
         }
     }
 
+    private void tcpActiveHandler(Device device, String channelId, String contentString,
+                                  MediaServerItem mediaServerItem,
+                                  String timeOutTaskKey, SSRCInfo ssrcInfo, ErrorCallback<Object> callback){
+        if (!device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
+            return;
+        }
+        String substring = contentString.substring(0, contentString.indexOf("y="));
+        try {
+            SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
+            int port = -1;
+            Vector mediaDescriptions = sdp.getMediaDescriptions(true);
+            for (Object description : mediaDescriptions) {
+                MediaDescription mediaDescription = (MediaDescription) description;
+                Media media = mediaDescription.getMedia();
+
+                Vector mediaFormats = media.getMediaFormats(false);
+                if (mediaFormats.contains("96")) {
+                    port = media.getMediaPort();
+                    break;
+                }
+            }
+            logger.info("[点播-TCP主动连接对方] deviceId: {}, channelId: {}, 连接对方的地址:{}:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, sdp.getConnection().getAddress(), port, device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
+            JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
+            logger.info("[点播-TCP主动连接对方] 结果: {}", jsonObject);
+        } catch (SdpException e) {
+            logger.error("[点播-TCP主动连接对方] deviceId: {}, channelId: {}, 解析200OK的SDP信息失败", device.getDeviceId(), channelId, e);
+            dynamicTask.stop(timeOutTaskKey);
+            mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
+            // 释放ssrc
+            mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
+
+            streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+
+            callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
+                    InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
+            inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
+                    InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
+                    InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
+        }
+    }
+
     /**
      * 点播成功时调用截图.
      *

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java

@@ -67,7 +67,7 @@ public class MediaController {
                     && streamAuthorityInfo.getCallId().equals(callId)) {
                 authority = true;
             }else {
-                throw new ControllerException(ErrorCode.ERROR400);
+                throw new ControllerException(ErrorCode.ERROR400.getCode(), "获取播放地址鉴权失败");
             }
         }else {
             // 是否登陆用户, 登陆用户返回完整信息

+ 4 - 1
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java

@@ -92,6 +92,7 @@ public class PlayController {
 	public DeferredResult<WVPResult<StreamContent>> play(HttpServletRequest request, @PathVariable String deviceId,
 														 @PathVariable String channelId) {
 
+		logger.info("[开始点播] deviceId:{}, channelId:{}, ", deviceId, channelId);
 		// 获取可用的zlm
 		Device device = storager.queryVideoDevice(deviceId);
 		MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
@@ -104,13 +105,15 @@ public class PlayController {
 		DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
 
 		result.onTimeout(()->{
-			logger.info("点播接口等待超时");
+			logger.info("[点播等待超时] deviceId:{}, channelId:{}, ", deviceId, channelId);
 			// 释放rtpserver
 			WVPResult<StreamInfo> wvpResult = new WVPResult<>();
 			wvpResult.setCode(ErrorCode.ERROR100.getCode());
 			wvpResult.setMsg("点播超时");
 			requestMessage.setData(wvpResult);
 			resultHolder.invokeResult(requestMessage);
+			inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
+			storager.stopPlay(deviceId, channelId);
 		});
 
 		// 录像查询以channelId作为deviceId查询