From ab3d0da1150c3d2303f2cdb1b64f01e120055068 Mon Sep 17 00:00:00 2001 From: lin <648540858@qq.com> Date: Mon, 13 Apr 2026 23:05:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0MediaStreamUtil=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E5=BA=94=E7=94=A8=E5=B8=B8=E9=87=8F=EF=BC=8C=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E4=BD=BF=E7=94=A8RTP=5FAPP=E6=9B=BF=E4=BB=A3GB28181?= =?UTF-8?q?=EF=BC=8C=E8=B0=83=E6=95=B4=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E5=8D=95=E7=AB=AF=E5=8F=A3=E6=94=B6?= =?UTF-8?q?=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/common/enums/MediaStreamUtil.java | 55 +++++++++++++++++-- .../iot/vmp/gb28181/bean/SendRtpInfo.java | 2 +- .../service/impl/InviteStreamServiceImpl.java | 2 +- .../gb28181/service/impl/PlayServiceImpl.java | 48 ++++++++-------- .../transmit/cmd/impl/SIPCommander.java | 6 +- .../cmd/MediaStatusNotifyMessageHandler.java | 2 +- .../jt1078/service/Ijt1078PlayService.java | 2 - .../service/impl/jt1078PlayServiceImpl.java | 50 ++++++++--------- .../vmp/media/abl/ABLHttpHookListener.java | 4 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 4 +- .../vmp/service/impl/MediaServiceImpl.java | 23 +++----- .../service/impl/RtpServerServiceImpl.java | 6 +- .../iot/vmp/vmanager/ps/PsController.java | 4 +- .../iot/vmp/vmanager/rtp/RtpController.java | 6 +- .../vmp/web/gb28181/ApiStreamController.java | 2 +- 15 files changed, 124 insertions(+), 92 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/common/enums/MediaStreamUtil.java b/src/main/java/com/genersoft/iot/vmp/common/enums/MediaStreamUtil.java index da52fd74b..1ae95860d 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/enums/MediaStreamUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/common/enums/MediaStreamUtil.java @@ -1,17 +1,62 @@ package com.genersoft.iot.vmp.common.enums; public class MediaStreamUtil { - public final static String RTPServerApp = "rtp"; - public final static String GB28181 = "rtp"; + public final static String RTP_APP = "rtp"; + public final static String RTP_STREAM_REST_PREFIX = "s"; + public final static String GB28181_TALK = "talk"; public final static String GB28181_BROADCAST = "broadcast"; - public final static String JT1078 = "1078"; + + public final static String JT_TALK = "jt_talk"; + public final static String JT1078_STREAM_PREFIX = RTP_STREAM_REST_PREFIX + "_jt"; + public final static String JT1078_STREAM_PLAY_PREFIX = RTP_STREAM_REST_PREFIX + "_jt_play"; + public final static String JT1078_STREAM_PLAYBACK_PREFIX = RTP_STREAM_REST_PREFIX + "_jt_playback"; public static boolean isKeywords(String app) { - return GB28181.equals(app) || GB28181_TALK.equals(app) || GB28181_BROADCAST.equals(app) || JT1078.equals(app); + return RTP_APP.equals(app) || GB28181_TALK.equals(app) || GB28181_BROADCAST.equals(app); } public static boolean isGB28181(String app, String streamId) { - return GB28181.equals(app) || GB28181_TALK.equals(app) || GB28181_BROADCAST.equals(app); + return RTP_APP.equals(app) || !streamId.startsWith(RTP_STREAM_REST_PREFIX); + } + + public static boolean isTalk(String app, String streamId) { + return GB28181_TALK.equals(app); + } + + public static boolean isBroadcast(String app, String streamId) { + return GB28181_BROADCAST.equals(app); + } + + public static boolean isJT1078(String app, String streamId) { + return RTP_APP.equals(app) || streamId.startsWith(JT1078_STREAM_PREFIX); + } + + public static String getJTPlayStreamId(String phoneNumber, int channelId) { + return String.format("%s_%s_%s", JT1078_STREAM_PLAY_PREFIX, phoneNumber, channelId); + } + + public static boolean isJT1078Play(String app, String stream) { + return RTP_APP.equals(app) || stream.startsWith(JT1078_STREAM_PLAY_PREFIX); + } + + public static boolean isJT1078Playback(String app, String stream) { + return RTP_APP.equals(app) || stream.startsWith(JT1078_STREAM_PLAYBACK_PREFIX); + } + + public static boolean isJT1078Talk(String app, String stream) { + return JT_TALK.equals(app); + } + + public static String getJTPlaybackStreamId(String phoneNumber, Integer channelId, String startTime, String endTime) { + return String.format("%s_%s_%s_%s_%s", JT1078_STREAM_PLAYBACK_PREFIX, phoneNumber, channelId, startTime, endTime); + } + + public static String getJTTalkStreamId(String phoneNumber, Integer channelId) { + return String.format("%s_%s_%s", JT_TALK, phoneNumber, channelId); + } + + public static String getJTTalkReceiveStreamId(String phoneNumber, Integer channelId) { + return getJTTalkStreamId(phoneNumber, channelId) + "_receive"; } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpInfo.java index 2ac7b97c9..f01299564 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpInfo.java @@ -205,7 +205,7 @@ public class SendRtpInfo { sendRtpItem.setChannelId(channelId); sendRtpItem.setTcp(isTcp); sendRtpItem.setRtcp(rtcp); - sendRtpItem.setApp(MediaStreamUtil.GB28181); + sendRtpItem.setApp(MediaStreamUtil.RTP_APP); sendRtpItem.setLocalPort(localPort); sendRtpItem.setServerId(serverId); sendRtpItem.setMediaServerId(mediaServer.getId()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/InviteStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/InviteStreamServiceImpl.java index 479ff8697..dbac486b5 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/InviteStreamServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/InviteStreamServiceImpl.java @@ -50,7 +50,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @Async @EventListener public void onApplicationEvent(MediaDepartureEvent event) { - if ("rtsp".equals(event.getSchema()) && MediaStreamUtil.GB28181.equals(event.getApp())) { + if ("rtsp".equals(event.getSchema()) && MediaStreamUtil.isGB28181(event.getApp(), event.getStream())) { InviteInfo inviteInfo = getInviteInfoByStream(null, event.getStream()); if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) { removeInviteInfo(inviteInfo); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java index 787eec9fa..ba108044b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java @@ -228,7 +228,7 @@ public class PlayServiceImpl implements IPlayService { } } } - }else if (MediaStreamUtil.GB28181.equals(event.getApp())) { + }else if (MediaStreamUtil.isGB28181(event.getApp(), event.getStream())) { // 释放ssrc InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, event.getStream()); if (inviteInfo != null && inviteInfo.getStatus() == InviteSessionStatus.ok @@ -246,7 +246,7 @@ public class PlayServiceImpl implements IPlayService { @Async @EventListener public void onApplicationEvent(MediaNotFoundEvent event) { - if (!MediaStreamUtil.GB28181.equals(event.getApp())) { + if (!MediaStreamUtil.isGB28181(event.getApp(), event.getStream())) { return; } String[] s = event.getStream().split("_"); @@ -354,7 +354,7 @@ public class PlayServiceImpl implements IPlayService { return inviteInfoInCatch.getSsrcInfo(); } MediaServer mediaInfo = streamInfo.getMediaServer(); - Boolean ready = mediaServerService.isStreamReady(mediaInfo, MediaStreamUtil.GB28181, streamId); + Boolean ready = mediaServerService.isStreamReady(mediaInfo, MediaStreamUtil.RTP_APP, streamId); if (ready != null && ready) { if(callback != null) { callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo); @@ -410,14 +410,14 @@ public class PlayServiceImpl implements IPlayService { } inviteStreamService.call(InviteSessionType.PLAY, channel.getId(), null, code, msg, null); inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getId()); - SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaStreamUtil.GB28181, streamId); + SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaStreamUtil.RTP_APP, streamId); if (ssrcTransaction != null) { try { - cmder.streamByeCmd(device, channel.getDeviceId(), MediaStreamUtil.GB28181, streamId, null, null); + cmder.streamByeCmd(device, channel.getDeviceId(), MediaStreamUtil.RTP_APP, streamId, null, null); } catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) { log.error("[点播超时], 发送BYE失败 {}", e.getMessage()); } finally { - sessionManager.removeByStream(MediaStreamUtil.GB28181, streamId); + sessionManager.removeByStream(MediaStreamUtil.RTP_APP, streamId); } } } @@ -680,7 +680,7 @@ public class PlayServiceImpl implements IPlayService { String fileName = deviceId + "_" + channelId + ".jpg"; // 请求截图 log.info("[请求截图]: " + fileName); - mediaServerService.getSnap(mediaServerItemInuse, MediaStreamUtil.GB28181, stream, 15, 1, path, fileName); + mediaServerService.getSnap(mediaServerItemInuse, MediaStreamUtil.RTP_APP, stream, 15, 1, path, fileName); } public StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, MediaInfo mediaInfo, Device device, DeviceChannel channel) { @@ -791,14 +791,14 @@ public class PlayServiceImpl implements IPlayService { } inviteStreamService.call(InviteSessionType.PLAYBACK, channel.getId(), null, code, msg, null); inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAYBACK, channel.getId()); - SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaStreamUtil.GB28181, stream); + SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaStreamUtil.RTP_APP, stream); if (ssrcTransaction != null) { try { - cmder.streamByeCmd(device, channel.getDeviceId(), MediaStreamUtil.GB28181, stream, null, null); + cmder.streamByeCmd(device, channel.getDeviceId(), MediaStreamUtil.RTP_APP, stream, null, null); } catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) { log.error("[录像回放] 发送BYE失败 {}", e.getMessage()); } finally { - sessionManager.removeByStream(MediaStreamUtil.GB28181, stream); + sessionManager.removeByStream(MediaStreamUtil.RTP_APP, stream); } } } @@ -939,19 +939,19 @@ public class PlayServiceImpl implements IPlayService { if (ssrcInResponse != null) { // 单端口 // 重新订阅流上线 - SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaStreamUtil.GB28181, inviteInfo.getStream()); + SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaStreamUtil.RTP_APP, inviteInfo.getStream()); if (ssrcTransaction == null) { return; } releaseAllocatedSsrc(mediaServerItem, ssrcInfo); - sessionManager.removeByStream(MediaStreamUtil.GB28181, inviteInfo.getStream()); + sessionManager.removeByStream(MediaStreamUtil.RTP_APP, inviteInfo.getStream()); inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse); ssrcTransaction.setDeviceId(device.getDeviceId()); ssrcTransaction.setChannelId(ssrcTransaction.getChannelId()); ssrcTransaction.setCallId(ssrcTransaction.getCallId()); ssrcTransaction.setSsrc(ssrcInResponse); ssrcTransaction.setAllocatedSsrc(null); - ssrcTransaction.setApp(MediaStreamUtil.GB28181); + ssrcTransaction.setApp(MediaStreamUtil.RTP_APP); ssrcTransaction.setStream(inviteInfo.getStream()); ssrcTransaction.setMediaServerId(mediaServerItem.getId()); ssrcTransaction.setSipTransactionInfo(new SipTransactionInfo((SIPResponse) responseEvent.getResponse())); @@ -1096,7 +1096,7 @@ public class PlayServiceImpl implements IPlayService { inviteStreamService.updateInviteInfo(inviteInfoForNew, 60*15L); } }; - Hook hook = Hook.getInstance(HookType.on_record_mp4, MediaStreamUtil.GB28181, ssrcInfo.getStream(), mediaServer.getId()); + Hook hook = Hook.getInstance(HookType.on_record_mp4, MediaStreamUtil.RTP_APP, ssrcInfo.getStream(), mediaServer.getId()); // 设置过期时间,下载失败时自动处理订阅数据 hook.setExpireTime(System.currentTimeMillis() + 24 * 60 * 60 * 1000); subscribe.addSubscribe(hook, hookEventForRecord); @@ -1116,7 +1116,7 @@ public class PlayServiceImpl implements IPlayService { InviteInfo inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, channel.getId(), stream); if (inviteInfo == null) { - String app = MediaStreamUtil.GB28181; + String app = MediaStreamUtil.RTP_APP; StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); if (streamAuthorityInfo != null) { List allList = cloudRecordService.getAllList(null, app, stream, null, null, null, streamAuthorityInfo.getCallId(), null); @@ -1158,7 +1158,7 @@ public class PlayServiceImpl implements IPlayService { log.warn("[获取下载进度] 查询录像信息时发现节点不存在"); return null; } - String app = MediaStreamUtil.GB28181; + String app = MediaStreamUtil.RTP_APP; Long duration = mediaServerService.updateDownloadProcess(mediaServerItem, app, stream); if (duration == null || duration == 0) { inviteInfo.getStreamInfo().setProgress(0); @@ -1201,7 +1201,7 @@ public class PlayServiceImpl implements IPlayService { public StreamInfo onPublishHandler(MediaServer mediaServerItem, MediaInfo mediaInfo, Device device, DeviceChannel channel) { - StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, MediaStreamUtil.GB28181, mediaInfo.getStream(), mediaInfo, null); + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, MediaStreamUtil.RTP_APP, mediaInfo.getStream(), mediaInfo, null); streamInfo.setDeviceId(device.getDeviceId()); streamInfo.setChannelId(channel.getId()); return streamInfo; @@ -1647,7 +1647,7 @@ public class PlayServiceImpl implements IPlayService { String path = "snap"; // 请求截图 log.info("[请求截图]: " + fileName); - mediaServerService.getSnap(mediaServer, MediaStreamUtil.GB28181, inviteInfo.getStreamInfo().getStream(), 15, 1, path, fileName); + mediaServerService.getSnap(mediaServer, MediaStreamUtil.RTP_APP, inviteInfo.getStreamInfo().getStream(), 15, 1, path, fileName); File snapFile = new File(path + File.separator + fileName); if (snapFile.exists()) { errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), snapFile.getAbsoluteFile()); @@ -1697,7 +1697,7 @@ public class PlayServiceImpl implements IPlayService { String path = "snap"; // 请求截图 log.info("[请求截图]: 返回byte数组" ); - byte[] snapByteArray = mediaServerService.getSnap(mediaServer, MediaStreamUtil.GB28181, inviteInfo.getStreamInfo().getStream(), 15, 1, path, null); + byte[] snapByteArray = mediaServerService.getSnap(mediaServer, MediaStreamUtil.RTP_APP, inviteInfo.getStreamInfo().getStream(), 15, 1, path, null); if (snapByteArray != null) { errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), snapByteArray); }else { @@ -1711,7 +1711,7 @@ public class PlayServiceImpl implements IPlayService { if (code == InviteErrorCode.SUCCESS.getCode()) { InviteInfo inviteInfoForPlay = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getGbId()); if (inviteInfoForPlay != null && inviteInfoForPlay.getStreamInfo() != null) { - byte[] snapByteArray = mediaServerService.getSnap(data.getMediaServer(), MediaStreamUtil.GB28181, data.getStream(), 15, 1, null, null); + byte[] snapByteArray = mediaServerService.getSnap(data.getMediaServer(), MediaStreamUtil.RTP_APP, data.getStream(), 15, 1, null, null); errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), snapByteArray); }else { errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null); @@ -1740,7 +1740,7 @@ public class PlayServiceImpl implements IPlayService { if (InviteSessionStatus.ok == inviteInfo.getStatus()) { try { log.info("[停止点播/回放/下载] {}/{}", device.getDeviceId(), channel.getDeviceId()); - cmder.streamByeCmd(device, channel.getDeviceId(), MediaStreamUtil.GB28181, inviteInfo.getStream(), null, null); + cmder.streamByeCmd(device, channel.getDeviceId(), MediaStreamUtil.RTP_APP, inviteInfo.getStream(), null, null); } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) { log.error("[命令发送失败] 停止点播/回放/下载, 发送BYE: {}", e.getMessage()); throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); @@ -1751,7 +1751,7 @@ public class PlayServiceImpl implements IPlayService { deviceChannelService.stopPlay(channel.getId()); } if (inviteInfo.getStreamInfo() != null) { - receiveRtpServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), MediaStreamUtil.GB28181, stream); + receiveRtpServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), MediaStreamUtil.RTP_APP, stream); } } } @@ -1773,7 +1773,7 @@ public class PlayServiceImpl implements IPlayService { if (InviteSessionStatus.ok == inviteInfo.getStatus()) { try { log.info("[停止点播/回放/下载] {}/{}", device.getDeviceId(), channel.getDeviceId()); - cmder.streamByeCmd(device, channel.getDeviceId(), MediaStreamUtil.GB28181, inviteInfo.getStream(), null, null); + cmder.streamByeCmd(device, channel.getDeviceId(), MediaStreamUtil.RTP_APP, inviteInfo.getStream(), null, null); } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) { log.warn("[命令发送失败] 停止点播/回放/下载, 发送BYE: {}", e.getMessage()); } @@ -1783,7 +1783,7 @@ public class PlayServiceImpl implements IPlayService { deviceChannelService.stopPlay(channel.getId()); } if (inviteInfo.getStreamInfo() != null) { - receiveRtpServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), MediaStreamUtil.GB28181, inviteInfo.getStream()); + receiveRtpServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), MediaStreamUtil.RTP_APP, inviteInfo.getStream()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index f1d9163c8..6a2c915eb 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -509,7 +509,7 @@ public class SIPCommander implements ISIPCommander { } log.info("[语音喊话] {} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getIp(), sendRtpItem.getPort()); - Hook hook = Hook.getInstance(HookType.on_media_arrival, MediaStreamUtil.GB28181, stream, mediaServerItem.getId()); + Hook hook = Hook.getInstance(HookType.on_media_arrival, MediaStreamUtil.RTP_APP, stream, mediaServerItem.getId()); subscribe.addSubscribe(hook, (hookData) -> { if (event != null) { event.response(hookData); @@ -519,7 +519,7 @@ public class SIPCommander implements ISIPCommander { CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); callIdHeader.setCallId(callId); - Hook publishHook = Hook.getInstance(HookType.on_publish, MediaStreamUtil.GB28181, stream, mediaServerItem.getId()); + Hook publishHook = Hook.getInstance(HookType.on_publish, MediaStreamUtil.RTP_APP, stream, mediaServerItem.getId()); subscribe.addSubscribe(publishHook, (hookData) -> { if (eventForPush != null) { eventForPush.response(hookData); @@ -1396,7 +1396,7 @@ public class SIPCommander implements ISIPCommander { @Override public void playbackControlCmd(Device device, DeviceChannel channel, String stream, String content, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException { - SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaStreamUtil.GB28181, stream); + SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaStreamUtil.RTP_APP, stream); if (ssrcTransaction == null) { log.info("[回放控制]未找到视频流信息,设备:{}, 流ID: {}", device.getDeviceId(), stream); return; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java index d1b8638a4..83f329412 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java @@ -99,7 +99,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i playService.stop(inviteInfo); } // 去除监听流注销自动停止下载的监听 - Hook hook = Hook.getInstance(HookType.on_media_arrival, MediaStreamUtil.GB28181, ssrcTransaction.getStream(), ssrcTransaction.getMediaServerId()); + Hook hook = Hook.getInstance(HookType.on_media_arrival, MediaStreamUtil.RTP_APP, ssrcTransaction.getStream(), ssrcTransaction.getMediaServerId()); subscribe.removeSubscribe(hook); if (ssrcTransaction.getPlatformId() != null) { // 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题,需要将点播CallId进行上下级绑定 diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/service/Ijt1078PlayService.java b/src/main/java/com/genersoft/iot/vmp/jt1078/service/Ijt1078PlayService.java index c0f8fd340..9c4453b90 100644 --- a/src/main/java/com/genersoft/iot/vmp/jt1078/service/Ijt1078PlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/service/Ijt1078PlayService.java @@ -12,8 +12,6 @@ import java.util.List; public interface Ijt1078PlayService { - JTMediaStreamType checkStreamFromJt(String stream); - void play(String phoneNumber, Integer channelId, int type, CommonCallback> callback); void playback(String phoneNumber, Integer channelId, String startTime, String endTime, Integer type, diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/service/impl/jt1078PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/jt1078/service/impl/jt1078PlayServiceImpl.java index a8b9d350c..2cae36a1c 100644 --- a/src/main/java/com/genersoft/iot/vmp/jt1078/service/impl/jt1078PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/service/impl/jt1078PlayServiceImpl.java @@ -53,8 +53,6 @@ import java.util.concurrent.ConcurrentHashMap; @Slf4j public class jt1078PlayServiceImpl implements Ijt1078PlayService { - public static final String talkApp = "jt_talk"; - @Autowired private ISendRtpServerService sendRtpServerService; @@ -88,7 +86,7 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { @Async @EventListener public void onApplicationEvent(MediaArrivalEvent event) { - if (event.getApp().equals(talkApp) && event.getStream().endsWith("_talk")) { + if (MediaStreamUtil.JT_TALK.equals(event.getApp()) && event.getStream().endsWith("_talk")) { // 收到对JT讲的流 if (event.getStream().indexOf("_") <= 0) { log.info("[JT-对讲流到来] 流格式有误,stream应该为jt_[phoneNumber]_[channelId]_talk"); @@ -129,7 +127,7 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { if (!userSetting.getAutoApplyPlay()) { return; } - JTMediaStreamType jtMediaStreamType = checkStreamFromJt(event.getStream()); + JTMediaStreamType jtMediaStreamType = checkStreamFromJt(event.getApp(), event.getStream()); if (jtMediaStreamType == null){ return; } @@ -163,17 +161,15 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { /** * 校验流是否是属于部标的 */ - @Override - public JTMediaStreamType checkStreamFromJt(String stream) { - if (!stream.startsWith("jt_")) { + private JTMediaStreamType checkStreamFromJt(String app, String stream) { + if (!MediaStreamUtil.isJT1078(app, stream)) { return null; } - String[] streamParamArray = stream.split("_"); - if (streamParamArray.length == 3) { + if (MediaStreamUtil.isJT1078Play(app, stream)) { return JTMediaStreamType.PLAY; - }else if (streamParamArray.length == 5) { + }else if (MediaStreamUtil.isJT1078Playback(app, stream)) { return JTMediaStreamType.PLAYBACK; - }else if (streamParamArray.length == 4) { + }else if (MediaStreamUtil.isJT1078Talk(app, stream)) { return JTMediaStreamType.TALK; }else { return null; @@ -199,7 +195,7 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { private void play(JTDevice device, JTChannel channel, int type, CommonCallback> callback) { String phoneNumber = device.getPhoneNumber(); int channelId = channel.getChannelId(); - String stream = phoneNumber + "_" + channelId; + String stream = MediaStreamUtil.getJTPlayStreamId(phoneNumber, channelId); // 检查流是否已经存在,存在则返回 String playKey = VideoManagerConstants.INVITE_INFO_1078_PLAY + phoneNumber + ":" + channelId; List>> errorCallbacks = inviteErrorCallbackMap.computeIfAbsent(playKey, k -> new ArrayList<>()); @@ -209,7 +205,7 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { MediaServer mediaServer = streamInfo.getMediaServer(); if (mediaServer != null) { // 查询流是否存在,不存在则删除缓存数据 - MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServer, MediaStreamUtil.JT1078, streamInfo.getStream()); + MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServer, MediaStreamUtil.RTP_APP, streamInfo.getStream()); if (mediaInfo != null) { log.info("[JT-点播] 点播已经存在,直接返回, phoneNumber: {}, channelId: {}", phoneNumber, channelId); for (CommonCallback> errorCallback : errorCallbacks) { @@ -237,7 +233,7 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { // 开启收流端口 RTPServerParam rtpServerParam = new RTPServerParam(); rtpServerParam.setMediaServer(mediaServer); - rtpServerParam.setApp(MediaStreamUtil.JT1078); + rtpServerParam.setApp(MediaStreamUtil.RTP_APP); rtpServerParam.setStreamId(stream); rtpServerParam.setPort(0); rtpServerParam.setTcpMode(1); // 1 表示tcp被动 @@ -263,8 +259,8 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { String path = "snap"; String fileName = phoneNumber + "_" + channelId + ".jpg"; // 请求截图 - log.info("[请求截图]: " + fileName); - mediaServerService.getSnap(mediaServer, MediaStreamUtil.JT1078, stream, 15, 1, path, fileName); + log.info("[请求截图]: {}", fileName); + mediaServerService.getSnap(mediaServer, MediaStreamUtil.RTP_APP, stream, 15, 1, path, fileName); }else { if (callback != null) { callback.run(WVPResult.fail(code, msg)); @@ -294,7 +290,7 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { } public StreamInfo onPublishHandler(MediaServer mediaServerItem, HookData hookData, String phoneNumber, Integer channelId) { - StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, MediaStreamUtil.JT1078, hookData.getStream(), hookData.getMediaInfo(), null); + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, MediaStreamUtil.RTP_APP, hookData.getStream(), hookData.getMediaInfo(), null); streamInfo.setDeviceId(phoneNumber); streamInfo.setChannelId(channelId); return streamInfo; @@ -437,8 +433,8 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { redisTemplate.delete(playbackKey); } - String app = MediaStreamUtil.JT1078; - String stream = String.format("%s_%s_%s_%s", phoneNumber, channelId, + String app = MediaStreamUtil.RTP_APP; + String stream = MediaStreamUtil.getJTPlaybackStreamId(phoneNumber, channelId, DateUtil.yyyy_MM_dd_HH_mm_ssToUrl(startTime), DateUtil.yyyy_MM_dd_HH_mm_ssToUrl(endTime)); MediaServer mediaServer; if (org.springframework.util.ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) { @@ -456,7 +452,7 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { // 开启收流端口 RTPServerParam rtpServerParam = new RTPServerParam(); rtpServerParam.setMediaServer(mediaServer); - rtpServerParam.setApp(MediaStreamUtil.JT1078); + rtpServerParam.setApp(MediaStreamUtil.RTP_APP); rtpServerParam.setStreamId(stream); rtpServerParam.setPort(0); rtpServerParam.setTcpMode(1); // 1 表示tcp被动 @@ -594,7 +590,7 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { JTDevice device = jt1078Service.getDevice(phoneNumber); Assert.notNull(device, "部标设备不存在"); - String stream = "jt_" + phoneNumber + "_" + channelId + "_talk"; + String stream = MediaStreamUtil.getJTTalkStreamId(phoneNumber, channelId); MediaServer mediaServer; if (org.springframework.util.ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) { @@ -604,9 +600,9 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { } // 检查待发送的流是否存在, - MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServer, talkApp, stream); + MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServer, MediaStreamUtil.JT_TALK, stream); Assert.isNull(mediaInfo, "对讲已经存在"); - return mediaServerService.getStreamInfoByAppAndStream(mediaServer, talkApp, stream, null, null, null, false); + return mediaServerService.getStreamInfoByAppAndStream(mediaServer, MediaStreamUtil.JT_TALK, stream, null, null, null, false); } private void sendTalk(JTDevice device, Integer channelId, MediaServer mediaServer, String app, String stream) { @@ -617,17 +613,17 @@ public class jt1078PlayServiceImpl implements Ijt1078PlayService { } String phoneNumber = device.getPhoneNumber(); - + String receiveStream = MediaStreamUtil.getJTTalkReceiveStreamId(phoneNumber, channelId); // 开启收流端口, zlm发送1078的rtp流需要将ssrc字段设置为 imei_channel格式 String ssrc = device.getPhoneNumber() + "_" + channelId; - SendRtpInfo sendRtpInfo = sendRtpServerService.createSendRtpInfo(mediaServer, null, null, ssrc, phoneNumber, talkApp, stream, channelId, true, false); + SendRtpInfo sendRtpInfo = sendRtpServerService.createSendRtpInfo(mediaServer, null, null, ssrc, phoneNumber, MediaStreamUtil.JT_TALK, stream, channelId, true, false); sendRtpInfo.setTcpActive(true); sendRtpInfo.setUsePs(false); sendRtpInfo.setOnlyAudio(true); - sendRtpInfo.setReceiveStream(stream + "_talk"); + sendRtpInfo.setReceiveStream(receiveStream); // 设置hook监听 - Hook hook = Hook.getInstance(HookType.on_media_arrival, MediaStreamUtil.JT1078, sendRtpInfo.getReceiveStream(), mediaServer.getId()); + Hook hook = Hook.getInstance(HookType.on_media_arrival, MediaStreamUtil.RTP_APP, sendRtpInfo.getReceiveStream(), mediaServer.getId()); subscribe.addSubscribe(hook, (hookData) -> { log.info("[JT-对讲] 对讲连接建立, phoneNumber: {}, channelId: {}", phoneNumber, channelId); subscribe.removeSubscribe(hook); diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java index 2410f02fa..f888d0b55 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java @@ -189,14 +189,14 @@ public class ABLHttpHookListener { logger.info("[ABL HOOK] 码流不到达通知:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); try { - if (MediaStreamUtil.GB28181.equals(param.getApp())) { + if (MediaStreamUtil.RTP_APP.equals(param.getApp())) { return HookResult.SUCCESS(); } MediaRtpServerTimeoutEvent event = new MediaRtpServerTimeoutEvent(this); MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); if (mediaServerItem != null) { event.setMediaServer(mediaServerItem); - event.setApp(MediaStreamUtil.GB28181); + event.setApp(MediaStreamUtil.RTP_APP); applicationEventPublisher.publishEvent(event); } }catch (Exception e) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index ffaea66bb..6709d4158 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -263,7 +263,7 @@ public class ZLMHttpHookListener { log.info("[ZLM HOOK] rtp发送关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); // 查找对应的上级推流,发送停止 - if (!MediaStreamUtil.GB28181.equals(param.getApp())) { + if (!MediaStreamUtil.RTP_APP.equals(param.getApp())) { return HookResult.SUCCESS(); } try { @@ -294,7 +294,7 @@ public class ZLMHttpHookListener { MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); if (mediaServerItem != null) { event.setMediaServer(mediaServerItem); - event.setApp(MediaStreamUtil.GB28181); + event.setApp(MediaStreamUtil.RTP_APP); applicationEventPublisher.publishEvent(event); } }catch (Exception e) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 769c7faad..b8e380bc0 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -83,7 +83,7 @@ public class MediaServiceImpl implements IMediaService { if (app == null || stream == null) { return false; } - if (MediaStreamUtil.GB28181.equals(app)) { + if (MediaStreamUtil.RTP_APP.equals(app)) { return true; } StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); @@ -96,14 +96,8 @@ public class MediaServiceImpl implements IMediaService { @Override public ResultForOnPublish authenticatePublish(MediaServer mediaServer, String app, String stream, String params) { // 推流鉴权的处理 - if (!MediaStreamUtil.GB28181.equals(app) && !MediaStreamUtil.JT1078.equals(app) ) { - if (MediaStreamUtil.GB28181_TALK.equals(app) && stream.endsWith("_talk")) { - ResultForOnPublish result = new ResultForOnPublish(); - result.setEnable_mp4(false); - result.setEnable_audio(true); - return result; - } - if ("jt_talk".equals(app) && stream.endsWith("_talk")) { + if (!MediaStreamUtil.RTP_APP.equals(app)) { + if (MediaStreamUtil.GB28181_TALK.equals(app) || MediaStreamUtil.JT_TALK.equals(app)) { ResultForOnPublish result = new ResultForOnPublish(); result.setEnable_mp4(false); result.setEnable_audio(true); @@ -156,9 +150,8 @@ public class MediaServiceImpl implements IMediaService { ResultForOnPublish result = new ResultForOnPublish(); result.setEnable_audio(true); - // 国标流 - if (MediaStreamUtil.GB28181.equals(app)) { - + // RTP SERVER 收流 + if (MediaStreamUtil.isGB28181(app, stream)) { InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, stream); if (inviteInfo != null) { @@ -224,7 +217,7 @@ public class MediaServiceImpl implements IMediaService { }else { result.setEnable_mp4(userSetting.getRecordPushLive()); } - if (app.equalsIgnoreCase(MediaStreamUtil.GB28181)) { + if (app.equalsIgnoreCase(MediaStreamUtil.RTP_APP)) { String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_" + stream; OtherRtpSendInfo otherRtpSendInfo = (OtherRtpSendInfo) redisTemplate.opsForValue().get(receiveKey); @@ -244,7 +237,7 @@ public class MediaServiceImpl implements IMediaService { return false; } // 国标类型的流 - if (MediaStreamUtil.GB28181.equals(app)) { + if (MediaStreamUtil.RTP_APP.equals(app)) { result = userSetting.getStreamOnDemand(); // 国标流, 点播/录像回放/录像下载 InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, stream); @@ -261,7 +254,7 @@ public class MediaServiceImpl implements IMediaService { } return result; } - }else if (MediaStreamUtil.JT1078.equals(app)) { + }else if (MediaStreamUtil.RTP_APP.equals(app)) { // 判断是否是1078播放类型 JTMediaStreamType jtMediaStreamType = ijt1078Service.checkStreamFromJt(stream); if (jtMediaStreamType != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RtpServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RtpServerServiceImpl.java index b9b34722d..8ee28c0ce 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/RtpServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/RtpServerServiceImpl.java @@ -101,11 +101,11 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService { log.warn("[openRTPServer] 平台对接时下级可能自定义ssrc,但是tcp模式zlm收流目前无法更新ssrc,可能收流超时,此时请使用udp收流或者关闭ssrc校验"); } - SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.GB28181, streamId); + SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamId); if (presetSSRC == null) { ssrcInfo.setAllocatedSsrc(ssrc); } - RTPServerParam rtpServerParam = new RTPServerParam(mediaServer, MediaStreamUtil.GB28181, streamId, ssrcCheck ? Long.parseLong(ssrc): 0L, null, onlyAuto, disableAuto, false, tcpMode); + RTPServerParam rtpServerParam = new RTPServerParam(mediaServer, MediaStreamUtil.RTP_APP, streamId, ssrcCheck ? Long.parseLong(ssrc): 0L, null, onlyAuto, disableAuto, false, tcpMode); int rtpServerPort = openRTPServer(rtpServerParam, ((code, msg, data) -> { if (code == InviteErrorCode.SUCCESS.getCode()) { OpenRTPServerResult openRTPServerResult = new OpenRTPServerResult(); @@ -124,7 +124,7 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService { } })); ssrcInfo.setPort(rtpServerPort); - return new SSRCInfo(rtpServerPort, ssrc, MediaStreamUtil.GB28181, streamId); + return new SSRCInfo(rtpServerPort, ssrc, MediaStreamUtil.RTP_APP, streamId); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index bd549d444..c90010aea 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -101,7 +101,7 @@ public class PsController { RTPServerParam rtpServerParam = new RTPServerParam(); rtpServerParam.setMediaServer(mediaServer); - rtpServerParam.setApp(MediaStreamUtil.GB28181); + rtpServerParam.setApp(MediaStreamUtil.RTP_APP); rtpServerParam.setStreamId(stream); rtpServerParam.setSsrc(ssrcInt); rtpServerParam.setTcpMode(tcpMode); @@ -162,7 +162,7 @@ public class PsController { public void closeRtpServer(String stream) { log.info("[第三方PS服务对接->关闭收流] stream->{}", stream); MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); - receiveRtpServerService.closeRTPServer(mediaServerItem, MediaStreamUtil.GB28181, stream); + receiveRtpServerService.closeRTPServer(mediaServerItem, MediaStreamUtil.RTP_APP, stream); String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_PS_INFO + userSetting.getServerId() + "_*_" + stream; List scan = RedisUtil.scan(redisTemplate, receiveKey); if (!scan.isEmpty()) { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index c768b4916..e20c6039b 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -101,7 +101,7 @@ public class RtpController { RTPServerParam rtpServerParam = new RTPServerParam(); rtpServerParam.setMediaServer(mediaServer); - rtpServerParam.setApp(MediaStreamUtil.GB28181); + rtpServerParam.setApp(MediaStreamUtil.RTP_APP); rtpServerParam.setStreamId(stream); rtpServerParam.setSsrc(ssrcInt); rtpServerParam.setTcpMode(tcpMode); @@ -173,8 +173,8 @@ public class RtpController { public void closeRtpServer(String stream) { log.info("[第三方服务对接->关闭收流] stream->{}", stream); MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); - receiveRtpServerService.closeRTPServer(mediaServerItem, MediaStreamUtil.GB28181, stream); - receiveRtpServerService.closeRTPServer(mediaServerItem, MediaStreamUtil.GB28181, stream+ "_a"); + receiveRtpServerService.closeRTPServer(mediaServerItem, MediaStreamUtil.RTP_APP, stream); + receiveRtpServerService.closeRTPServer(mediaServerItem, MediaStreamUtil.RTP_APP, stream+ "_a"); String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_*_" + stream; List scan = RedisUtil.scan(redisTemplate, receiveKey); if (scan.size() > 0) { diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java index 7b8cca1be..2380c6c0f 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java @@ -247,7 +247,7 @@ public class ApiStreamController { } try { - cmder.streamByeCmd(device, code, MediaStreamUtil.GB28181, inviteInfo.getStream(), null, null); + cmder.streamByeCmd(device, code, MediaStreamUtil.RTP_APP, inviteInfo.getStream(), null, null); } catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) { JSONObject result = new JSONObject(); result.put("error","发送BYE失败:" + e.getMessage());