Commit 6797f77259eceea08e3767b512ecd13477141a46
1 parent
2e399faf
优化点播超时的处理,修复tcp主动点播时ssrc不一致时点播失败的问题
Showing
3 changed files
with
50 additions
and
35 deletions
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查询 | ... | ... |