648540858 1 år sedan
förälder
incheckning
cc302be2f2
19 ändrade filer med 139 tillägg och 111 borttagningar
  1. 10 9
      src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
  2. 5 7
      src/main/java/com/genersoft/iot/vmp/gb28181/controller/PlayController.java
  3. 4 2
      src/main/java/com/genersoft/iot/vmp/gb28181/controller/PlaybackController.java
  4. 3 0
      src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java
  5. 1 0
      src/main/java/com/genersoft/iot/vmp/gb28181/service/IDeviceService.java
  6. 4 4
      src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlayService.java
  7. 6 1
      src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java
  8. 15 15
      src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlatformServiceImpl.java
  9. 6 4
      src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java
  10. 5 5
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
  11. 0 8
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
  12. 10 10
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
  13. 0 11
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
  14. 17 10
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
  15. 15 7
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
  16. 9 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java
  17. 11 6
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
  18. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
  19. 17 9
      src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java

+ 10 - 9
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java

@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo;
 import com.genersoft.iot.vmp.media.bean.MediaServer;
 import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
 import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
 
 import java.io.Serializable;
 import java.util.Objects;
@@ -17,9 +18,9 @@ public class StreamInfo implements Serializable, Cloneable{
     @Schema(description = "流ID")
     private String stream;
     @Schema(description = "设备编号")
-    private String deviceID;
-    @Schema(description = "通道编号")
-    private String channelId;
+    private String deviceId;
+    @Schema(description = "通道ID")
+    private Integer channelId;
 
     @Schema(description = "IP")
     private String ip;
@@ -357,19 +358,19 @@ public class StreamInfo implements Serializable, Cloneable{
         this.app = app;
     }
 
-    public String getDeviceID() {
-        return deviceID;
+    public String getDeviceId() {
+        return deviceId;
     }
 
-    public void setDeviceID(String deviceID) {
-        this.deviceID = deviceID;
+    public void setDeviceId(String deviceId) {
+        this.deviceId = deviceId;
     }
 
-    public String getChannelId() {
+    public Integer getChannelId() {
         return channelId;
     }
 
-    public void setChannelId(String channelId) {
+    public void setChannelId(Integer channelId) {
         this.channelId = channelId;
     }
 

+ 5 - 7
src/main/java/com/genersoft/iot/vmp/gb28181/controller/PlayController.java

@@ -228,13 +228,11 @@ public class PlayController {
 		if (log.isDebugEnabled()) {
 			log.debug("停止语音广播API调用");
 		}
-//		try {
-//			playService.stopAudioBroadcast(deviceId, channelId);
-//		} catch (InvalidArgumentException | ParseException  | SipException e) {
-//			logger.error("[命令发送失败] 停止语音: {}", e.getMessage());
-//			throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " +  e.getMessage());
-//		}
-		playService.stopAudioBroadcast(deviceId, channelId);
+		Device device = deviceService.getDeviceByDeviceId(deviceId);
+		Assert.notNull(device, "设备不存在");
+		DeviceChannel channel = deviceChannelService.getOne(deviceId, channelId);
+		Assert.notNull(channel, "通道不存在");
+		playService.stopAudioBroadcast(device, channel);
 	}
 
 	@Operation(summary = "获取所有的ssrc", security = @SecurityRequirement(name = JwtUtils.HEADER))

+ 4 - 2
src/main/java/com/genersoft/iot/vmp/gb28181/controller/PlaybackController.java

@@ -211,8 +211,9 @@ public class PlaybackController {
 			throw new ControllerException(ErrorCode.ERROR400.getCode(), "streamId不存在");
 		}
 		Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
+		DeviceChannel channel = channelService.getOneById(inviteInfo.getChannelId());
 		try {
-			cmder.playSeekCmd(device, inviteInfo.getStreamInfo(), seekTime);
+			cmder.playSeekCmd(device, channel, inviteInfo.getStreamInfo(), seekTime);
 		} catch (InvalidArgumentException | ParseException | SipException e) {
 			throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
 		}
@@ -235,8 +236,9 @@ public class PlaybackController {
 			throw new ControllerException(ErrorCode.ERROR100.getCode(), "不支持的speed(0.25 0.5 1、2、4)");
 		}
 		Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
+		DeviceChannel channel = channelService.getOneById(inviteInfo.getChannelId());
 		try {
-			cmder.playSpeedCmd(device, inviteInfo.getStreamInfo(), speed);
+			cmder.playSpeedCmd(device, channel, inviteInfo.getStreamInfo(), speed);
 		} catch (InvalidArgumentException | ParseException | SipException e) {
 			throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
 		}

+ 3 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java

@@ -350,4 +350,7 @@ public interface DeviceMapper {
 
     @Select("select * from wvp_device where id = #{id}")
     Device query(@Param("id") Integer id);
+
+    @Select("select wd.* from wvp_device wd left join wvp_device_channel wdc on wd.id = wdc.device_db_id  where wdc.id = #{channelId}")
+    Device queryByChannelId(@Param("channelId") Integer channelId);
 }

+ 1 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/service/IDeviceService.java

@@ -167,4 +167,5 @@ public interface IDeviceService {
 
     Device getDevice(Integer gbDeviceDbId);
 
+    Device getDeviceByChannelId(Integer channelId);
 }

+ 4 - 4
src/main/java/com/genersoft/iot/vmp/gb28181/service/IPlayService.java

@@ -35,17 +35,17 @@ public interface IPlayService {
     void download(Device device, DeviceChannel channel, String startTime, String endTime, int downloadSpeed, ErrorCallback<StreamInfo> callback);
     void download(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, String startTime, String endTime, int downloadSpeed, ErrorCallback<StreamInfo> callback);
 
-    StreamInfo getDownLoadInfo(Device deviceId, DeviceChannel channelId, String stream);
+    StreamInfo getDownLoadInfo(Device device, DeviceChannel channel, String stream);
 
     void zlmServerOnline(String mediaServerId);
 
     AudioBroadcastResult audioBroadcast(Device device, String channelId, Boolean broadcastMode);
 
-    boolean audioBroadcastCmd(Device device, DeviceChannel channelId, MediaServer mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException;
+    boolean audioBroadcastCmd(Device device, DeviceChannel channel, MediaServer mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException;
 
-    boolean audioBroadcastInUse(Device device, DeviceChannel channelId);
+    boolean audioBroadcastInUse(Device device, DeviceChannel channel);
 
-    void stopAudioBroadcast(Device deviceId, DeviceChannel channelId);
+    void stopAudioBroadcast(Device device, DeviceChannel channel);
 
     void pauseRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException;
 

+ 6 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java

@@ -246,7 +246,7 @@ public class DeviceServiceImpl implements IDeviceService {
                     mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), null);
                 }
 
-                audioBroadcastManager.del(deviceId, audioBroadcastCatch.getChannelId());
+                audioBroadcastManager.del(audioBroadcastCatch.getChannelId());
             }
         }
     }
@@ -573,4 +573,9 @@ public class DeviceServiceImpl implements IDeviceService {
     public Device getDevice(Integer id) {
         return deviceMapper.query(id);
     }
+
+    @Override
+    public Device getDeviceByChannelId(Integer channelId) {
+        return deviceMapper.queryByChannelId(channelId);
+    }
 }

+ 15 - 15
src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlatformServiceImpl.java

@@ -492,7 +492,7 @@ public class PlatformServiceImpl implements IPlatformService {
             log.info("[国标级联] 语音喊话未找到可用的zlm. platform: {}", platform.getServerGBId());
             return;
         }
-        InviteInfo inviteInfoForOld = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, platform.getServerGBId(), channel.getGbDeviceId());
+        InviteInfo inviteInfoForOld = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getGbId());
 
         if (inviteInfoForOld != null && inviteInfoForOld.getStreamInfo() != null) {
             // 如果zlm不存在这个流,则删除数据即可
@@ -549,7 +549,7 @@ public class PlatformServiceImpl implements IPlatformService {
         String timeOutTaskKey = UUID.randomUUID().toString();
         dynamicTask.startDelay(timeOutTaskKey, () -> {
             // 执行超时任务时查询是否已经成功,成功了则不执行超时任务,防止超时任务取消失败的情况
-            InviteInfo inviteInfoForBroadcast = inviteStreamService.getInviteInfo(InviteSessionType.BROADCAST, platform.getServerGBId(), channel.getGbDeviceId(), null);
+            InviteInfo inviteInfoForBroadcast = inviteStreamService.getInviteInfo(InviteSessionType.BROADCAST, channel.getGbId(), null);
             if (inviteInfoForBroadcast == null) {
                 log.info("[国标级联] 发起语音喊话 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", platform.getServerGBId(), channel.getGbDeviceId(), ssrcInfo.getPort(), ssrcInfo.getSsrc());
                 // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
@@ -570,7 +570,7 @@ public class PlatformServiceImpl implements IPlatformService {
             log.info("[国标级联] 发起语音喊话 收到上级推流 deviceId: {}, channelId: {}", platform.getServerGBId(), channel.getGbDeviceId());
             dynamicTask.stop(timeOutTaskKey);
             // hook响应
-            onPublishHandlerForBroadcast(hookData.getMediaServer(), hookData.getMediaInfo(), platform.getServerGBId(), channel.getGbDeviceId());
+            onPublishHandlerForBroadcast(hookData.getMediaServer(), hookData.getMediaInfo(), platform, channel);
             // 收到流
             if (hookEvent != null) {
                 hookEvent.response(hookData);
@@ -626,11 +626,11 @@ public class PlatformServiceImpl implements IPlatformService {
         });
     }
 
-    public void onPublishHandlerForBroadcast(MediaServer mediaServerItem, MediaInfo mediaInfo, String platFormServerId, String channelId) {
+    public void onPublishHandlerForBroadcast(MediaServer mediaServerItem, MediaInfo mediaInfo, Platform platform, CommonGBChannel channel) {
         StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, mediaInfo.getApp(), mediaInfo.getStream(), mediaInfo, null);
-        streamInfo.setChannelId(channelId);
+        streamInfo.setChannelId(channel.getGbId());
 
-        InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, platFormServerId, channelId);
+        InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getGbId());
         if (inviteInfo != null) {
             inviteInfo.setStatus(InviteSessionStatus.ok);
             inviteInfo.setStreamInfo(streamInfo);
@@ -654,7 +654,7 @@ public class PlatformServiceImpl implements IPlatformService {
             if (mediaServerItem.isRtpEnable()) {
                 // 多端口
                 if (tcpMode == 2) {
-                    tcpActiveHandler(platform, channel.getGbDeviceId(), contentString, mediaServerItem, tcpMode, ssrcCheck,
+                    tcpActiveHandler(platform, channel, contentString, mediaServerItem, tcpMode, ssrcCheck,
                             timeOutTaskKey, ssrcInfo, callback);
                 }
             }else {
@@ -678,7 +678,7 @@ public class PlatformServiceImpl implements IPlatformService {
                     if (!result) {
                         try {
                             log.warn("[Invite 200OK] 更新ssrc失败,停止喊话 {}/{}", platform.getServerGBId(), channel.getGbDeviceId());
-                            commanderForPlatform.streamByeCmd(platform, channel.getGbDeviceId(), ssrcInfo.getStream(), null, null);
+                            commanderForPlatform.streamByeCmd(platform, channel, ssrcInfo.getStream(), null, null);
                         } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
                             log.error("[命令发送失败] 停止播放, 发送BYE: {}", e.getMessage());
                         }
@@ -691,7 +691,7 @@ public class PlatformServiceImpl implements IPlatformService {
 
                         callback.run(InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
                                 "下级自定义了ssrc,重新设置收流信息失败", null);
-                        inviteStreamService.call(inviteSessionType, platform.getServerGBId(), channel.getGbDeviceId(), null,
+                        inviteStreamService.call(inviteSessionType, channel.getGbId(), null,
                                 InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
                                 "下级自定义了ssrc,重新设置收流信息失败", null);
 
@@ -701,7 +701,7 @@ public class PlatformServiceImpl implements IPlatformService {
                         inviteInfo.setStream(ssrcInfo.getStream());
                         if (tcpMode == 2) {
                             if (mediaServerItem.isRtpEnable()) {
-                                tcpActiveHandler(platform, channel.getGbDeviceId(), contentString, mediaServerItem, tcpMode, ssrcCheck,
+                                tcpActiveHandler(platform, channel, contentString, mediaServerItem, tcpMode, ssrcCheck,
                                         timeOutTaskKey, ssrcInfo, callback);
                             }else {
                                 log.warn("[Invite 200OK] 单端口收流模式不支持tcp主动模式收流");
@@ -715,7 +715,7 @@ public class PlatformServiceImpl implements IPlatformService {
                     inviteInfo.setStream(ssrcInfo.getStream());
                     if (tcpMode == 2) {
                         if (mediaServerItem.isRtpEnable()) {
-                            tcpActiveHandler(platform, channel.getGbDeviceId(), contentString, mediaServerItem, tcpMode, ssrcCheck,
+                            tcpActiveHandler(platform, channel, contentString, mediaServerItem, tcpMode, ssrcCheck,
                                     timeOutTaskKey, ssrcInfo, callback);
                         }else {
                             log.warn("[Invite 200OK] 单端口收流模式不支持tcp主动模式收流");
@@ -746,7 +746,7 @@ public class PlatformServiceImpl implements IPlatformService {
     }
 
 
-    private void tcpActiveHandler(Platform platform, String channelId, String contentString,
+    private void tcpActiveHandler(Platform platform, CommonGBChannel channel, String contentString,
                                   MediaServer mediaServerItem, int tcpMode, boolean ssrcCheck,
                                   String timeOutTaskKey, SSRCInfo ssrcInfo, ErrorCallback<Object> callback){
         if (tcpMode != 2) {
@@ -774,11 +774,11 @@ public class PlatformServiceImpl implements IPlatformService {
                 }
             }
             log.info("[TCP主动连接对方] serverGbId: {}, channelId: {}, 连接对方的地址:{}:{}, SSRC: {}, SSRC校验:{}",
-                    platform.getServerGBId(), channelId, sdp.getConnection().getAddress(), port, ssrcInfo.getSsrc(), ssrcCheck);
+                    platform.getServerGBId(), channel.getGbDeviceId(), sdp.getConnection().getAddress(), port, ssrcInfo.getSsrc(), ssrcCheck);
             Boolean result = mediaServerService.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
             log.info("[TCP主动连接对方] 结果: {}", result);
         } catch (SdpException e) {
-            log.error("[TCP主动连接对方] serverGbId: {}, channelId: {}, 解析200OK的SDP信息失败", platform.getServerGBId(), channelId, e);
+            log.error("[TCP主动连接对方] serverGbId: {}, channelId: {}, 解析200OK的SDP信息失败", platform.getServerGBId(), channel.getGbDeviceId(), e);
             dynamicTask.stop(timeOutTaskKey);
             mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
             // 释放ssrc
@@ -788,7 +788,7 @@ public class PlatformServiceImpl implements IPlatformService {
 
             callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
                     InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
-            inviteStreamService.call(InviteSessionType.PLAY, platform.getServerGBId(), channelId, null,
+            inviteStreamService.call(InviteSessionType.PLAY, channel.getGbId(), null,
                     InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
                     InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
         }

+ 6 - 4
src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java

@@ -1129,8 +1129,8 @@ public class PlayServiceImpl implements IPlayService {
 
     public StreamInfo onPublishHandler(MediaServer mediaServerItem, MediaInfo mediaInfo, Device device, DeviceChannel channel) {
         StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", mediaInfo.getStream(), mediaInfo, null);
-        streamInfo.setDeviceID(device.getDeviceId());
-        streamInfo.setChannelId(channel.getDeviceId());
+        streamInfo.setDeviceId(device.getDeviceId());
+        streamInfo.setChannelId(channel.getId());
         return streamInfo;
     }
 
@@ -1380,7 +1380,8 @@ public class PlayServiceImpl implements IPlayService {
             throw new ServiceException("暂停RTP接收失败");
         }
         Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
-        cmder.playPauseCmd(device, inviteInfo.getStreamInfo());
+        DeviceChannel channel = deviceChannelService.getOneById(inviteInfo.getChannelId());
+        cmder.playPauseCmd(device, channel, inviteInfo.getStreamInfo());
     }
 
     @Override
@@ -1408,7 +1409,8 @@ public class PlayServiceImpl implements IPlayService {
             throw new ServiceException("继续RTP接收失败");
         }
         Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
-        cmder.playResumeCmd(device, inviteInfo.getStreamInfo());
+        DeviceChannel channel = deviceChannelService.getOneById(inviteInfo.getChannelId());
+        cmder.playResumeCmd(device, channel, inviteInfo.getStreamInfo());
     }
 
     @Override

+ 5 - 5
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java

@@ -141,22 +141,22 @@ public interface ISIPCommander {
 	/**
 	 * 回放暂停
 	 */
-	void playPauseCmd(Device device, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException;
+	void playPauseCmd(Device device, DeviceChannel channel, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException;
 
 	/**
 	 * 回放恢复
 	 */
-	void playResumeCmd(Device device, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException;
+	void playResumeCmd(Device device, DeviceChannel channel, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException;
 
 	/**
 	 * 回放拖动播放
 	 */
-	void playSeekCmd(Device device, StreamInfo streamInfo, long seekTime) throws InvalidArgumentException, ParseException, SipException;
+	void playSeekCmd(Device device, DeviceChannel channel, StreamInfo streamInfo, long seekTime) throws InvalidArgumentException, ParseException, SipException;
 
 	/**
 	 * 回放倍速播放
 	 */
-	void playSpeedCmd(Device device, StreamInfo streamInfo, Double speed) throws InvalidArgumentException, ParseException, SipException;
+	void playSpeedCmd(Device device, DeviceChannel channel, StreamInfo streamInfo, Double speed) throws InvalidArgumentException, ParseException, SipException;
 	
 	/**
 	 * 回放控制
@@ -164,7 +164,7 @@ public interface ISIPCommander {
 	 * @param streamInfo
 	 * @param content
 	 */
-	void playbackControlCmd(Device device, StreamInfo streamInfo, String content,SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException;
+	void playbackControlCmd(Device device, DeviceChannel channel, StreamInfo streamInfo, String content,SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException;
 
 
     void streamByeCmdForDeviceInvite(Device device, String channelId, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException;

+ 0 - 8
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java

@@ -142,14 +142,6 @@ public interface ISIPCommanderForPlatform {
      */
     void sendMediaStatusNotify(Platform platform, SendRtpInfo sendRtpItem) throws SipException, InvalidArgumentException, ParseException;
 
-    /**
-     * 向发起点播的上级回复bye
-     *
-     * @param platform 平台信息
-     * @param callId   callId
-     */
-    void streamByeCmd(Platform platform, String callId) throws SipException, InvalidArgumentException, ParseException;
-
     void streamByeCmd(Platform platform, SendRtpInfo sendRtpItem, CommonGBChannel channel) throws SipException, InvalidArgumentException, ParseException;
 
     void streamByeCmd(Platform platform, CommonGBChannel channel, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException;

+ 10 - 10
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java

@@ -1349,13 +1349,13 @@ public class SIPCommander implements ISIPCommander {
      * 回放暂停
      */
     @Override
-    public void playPauseCmd(Device device, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException {
+    public void playPauseCmd(Device device, DeviceChannel channel, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException {
         StringBuffer content = new StringBuffer(200);
         content.append("PAUSE RTSP/1.0\r\n");
         content.append("CSeq: " + getInfoCseq() + "\r\n");
         content.append("PauseTime: now\r\n");
 
-        playbackControlCmd(device, streamInfo, content.toString(), null, null);
+        playbackControlCmd(device, channel, streamInfo, content.toString(), null, null);
     }
 
 
@@ -1363,39 +1363,39 @@ public class SIPCommander implements ISIPCommander {
      * 回放恢复
      */
     @Override
-    public void playResumeCmd(Device device, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException {
+    public void playResumeCmd(Device device, DeviceChannel channel, StreamInfo streamInfo) throws InvalidArgumentException, ParseException, SipException {
         StringBuffer content = new StringBuffer(200);
         content.append("PLAY RTSP/1.0\r\n");
         content.append("CSeq: " + getInfoCseq() + "\r\n");
         content.append("Range: npt=now-\r\n");
 
-        playbackControlCmd(device, streamInfo, content.toString(), null, null);
+        playbackControlCmd(device, channel, streamInfo, content.toString(), null, null);
     }
 
     /**
      * 回放拖动播放
      */
     @Override
-    public void playSeekCmd(Device device, StreamInfo streamInfo, long seekTime) throws InvalidArgumentException, ParseException, SipException {
+    public void playSeekCmd(Device device, DeviceChannel channel, StreamInfo streamInfo, long seekTime) throws InvalidArgumentException, ParseException, SipException {
         StringBuffer content = new StringBuffer(200);
         content.append("PLAY RTSP/1.0\r\n");
         content.append("CSeq: " + getInfoCseq() + "\r\n");
         content.append("Range: npt=" + Math.abs(seekTime) + "-\r\n");
 
-        playbackControlCmd(device, streamInfo, content.toString(), null, null);
+        playbackControlCmd(device, channel, streamInfo, content.toString(), null, null);
     }
 
     /**
      * 回放倍速播放
      */
     @Override
-    public void playSpeedCmd(Device device, StreamInfo streamInfo, Double speed) throws InvalidArgumentException, ParseException, SipException {
+    public void playSpeedCmd(Device device, DeviceChannel channel, StreamInfo streamInfo, Double speed) throws InvalidArgumentException, ParseException, SipException {
         StringBuffer content = new StringBuffer(200);
         content.append("PLAY RTSP/1.0\r\n");
         content.append("CSeq: " + getInfoCseq() + "\r\n");
         content.append("Scale: " + String.format("%.6f", speed) + "\r\n");
 
-        playbackControlCmd(device, streamInfo, content.toString(), null, null);
+        playbackControlCmd(device, channel, streamInfo, content.toString(), null, null);
     }
 
     private int getInfoCseq() {
@@ -1403,7 +1403,7 @@ public class SIPCommander implements ISIPCommander {
     }
 
     @Override
-    public void playbackControlCmd(Device device, StreamInfo streamInfo, String content, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException {
+    public void playbackControlCmd(Device device, DeviceChannel channel, StreamInfo streamInfo, String content, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException {
 
         SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(streamInfo.getStream());
         if (ssrcTransaction == null) {
@@ -1411,7 +1411,7 @@ public class SIPCommander implements ISIPCommander {
             return;
         }
 
-        SIPRequest request = headerProvider.createInfoRequest(device, streamInfo.getChannelId(), content.toString(), ssrcTransaction.getSipTransactionInfo());
+        SIPRequest request = headerProvider.createInfoRequest(device, channel.getDeviceId(), content, ssrcTransaction.getSipTransactionInfo());
         if (request == null) {
             log.info("[回放控制]构建Request信息失败,设备:{}, 流ID: {}", device.getDeviceId(), streamInfo.getStream());
             return;

+ 0 - 11
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java

@@ -620,17 +620,6 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
 
     }
 
-    @Override
-    public void streamByeCmd(Platform platform, String callId) throws SipException, InvalidArgumentException, ParseException {
-        if (platform == null) {
-            return;
-        }
-        SendRtpInfo sendRtpItem = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), null, null, callId);
-        if (sendRtpItem != null) {
-            streamByeCmd(platform, sendRtpItem, );
-        }
-    }
-
     @Override
     public synchronized void streamByeCmd(Platform platform, SendRtpInfo sendRtpItem, CommonGBChannel channel) throws SipException, InvalidArgumentException, ParseException {
         if (sendRtpItem == null ) {

+ 17 - 10
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java

@@ -152,7 +152,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
 			}
 			MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
 			if (mediaServer != null) {
-				AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.getByDeviceId(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
+				AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getChannelId());
 				if (audioBroadcastCatch != null && audioBroadcastCatch.getSipTransactionInfo().getCallId().equals(callIdHeader.getCallId())) {
 					// 来自上级平台的停止对讲
 					log.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
@@ -167,10 +167,16 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
 						Device device = deviceService.getDeviceByDeviceId(sendRtpItem.getDeviceId());
 						if (device == null) {
 							log.info("[收到bye] {} 通知设备停止推流时未找到设备信息", streamId);
+							return;
+						}
+						DeviceChannel deviceChannel = deviceChannelService.getOneById(sendRtpItem.getChannelId());
+						if (deviceChannel == null) {
+							log.info("[收到bye] {} 通知设备停止推流时未找到通道信息", streamId);
+							return;
 						}
 						try {
 							log.info("[停止点播] {}/{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
-							cmder.streamByeCmd(device, sendRtpItem.getChannelId(), streamId, null);
+							cmder.streamByeCmd(device, deviceChannel.getDeviceId(), streamId, null);
 						} catch (InvalidArgumentException | ParseException | SipException |
 								 SsrcTransactionNotFoundException e) {
 							log.error("[收到bye] {} 无其它观看者,通知设备停止推流, 发送BYE失败 {}",streamId, e.getMessage());
@@ -190,7 +196,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
 		if (platform != null ) {
 			if (ssrcTransaction.getType().equals(InviteSessionType.BROADCAST)) {
 				log.info("[收到bye] 上级停止语音对讲,来自:{}, 通道已停止推流: {}", ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId());
-				CommonGBChannel channel = channelService.queryOneWithPlatform(platform.getId(), ssrcTransaction.getChannelId());
+				CommonGBChannel channel = channelService.getOne(ssrcTransaction.getChannelId());
 				if (channel == null) {
 					log.info("[收到bye] 未找到通道,设备:{}, 通道:{}", ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId());
 					return;
@@ -198,8 +204,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
 				String mediaServerId = ssrcTransaction.getMediaServerId();
 				platformService.stopBroadcast(platform, channel, ssrcTransaction.getStream(), false,
 						mediaServerService.getOne(mediaServerId));
-
-				playService.stopAudioBroadcast(ssrcTransaction.getDeviceId(), channel.getGbDeviceId());
+				Device device = deviceService.getDeviceByDeviceId(ssrcTransaction.getDeviceId());
+				DeviceChannel deviceChannel = deviceChannelService.getOneById(ssrcTransaction.getChannelId());
+				playService.stopAudioBroadcast(device, deviceChannel);
 			}
 
 		}else {
@@ -208,7 +215,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
 				log.info("[收到bye] 未找到设备:{} ", ssrcTransaction.getDeviceId());
 				return;
 			}
-			DeviceChannel channel = deviceChannelService.getOne(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId());
+			DeviceChannel channel = deviceChannelService.getOneById(ssrcTransaction.getChannelId());
 			if (channel == null) {
 				log.info("[收到bye] 未找到通道,设备:{}, 通道:{}", ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId());
 				return;
@@ -229,15 +236,15 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
 				case BROADCAST:
 				case TALK:
 					// 查找来源的对讲设备,发送停止
-					Device sourceDevice = storager.queryVideoDeviceByPlatformIdAndChannelId(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId());
-					AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.getByDeviceId(ssrcTransaction.getDeviceId(), channel.getDeviceId());
+					Device sourceDevice = deviceService.getDeviceByChannelId(ssrcTransaction.getChannelId());
+					AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(channel.getId());
 					if (sourceDevice != null) {
-						playService.stopAudioBroadcast(sourceDevice.getDeviceId(), channel.getDeviceId());
+						playService.stopAudioBroadcast(sourceDevice, channel);
 					}
 					if (audioBroadcastCatch != null) {
 						// 来自上级平台的停止对讲
 						log.info("[停止对讲] 来自上级,平台:{}, 通道:{}", ssrcTransaction.getDeviceId(), channel.getDeviceId());
-						audioBroadcastManager.del(ssrcTransaction.getDeviceId(), channel.getDeviceId());
+						audioBroadcastManager.del(channel.getId());
 					}
 					break;
 			}

+ 15 - 7
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java

@@ -730,7 +730,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
 
     private void sendBye(Platform platform, String callId) {
         try {
-            cmderFroPlatform.streamByeCmd(platform, callId);
+            SendRtpInfo sendRtpItem = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), null, null, callId);
+            if (sendRtpItem == null) {
+                return;
+            }
+            CommonGBChannel channel = channelService.getOne(sendRtpItem.getChannelId());
+            if (channel == null) {
+                return;
+            }
+            cmderFroPlatform.streamByeCmd(platform, sendRtpItem, channel);
         } catch (SipException | InvalidArgumentException | ParseException e) {
             log.error("[命令发送失败] 上级Invite 发送BYE: {}", e.getMessage());
         }
@@ -798,7 +806,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
                 responseAck(request, Response.TRYING);
             } catch (SipException | InvalidArgumentException | ParseException e) {
                 log.error("[命令发送失败] invite BAD_REQUEST: {}", e.getMessage());
-                playService.stopAudioBroadcast(device.getDeviceId(), deviceChannel.getDeviceId());
+                playService.stopAudioBroadcast(device, deviceChannel);
                 return;
             }
             String contentString = new String(request.getRawContent());
@@ -843,7 +851,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
                         responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
                     } catch (SipException | InvalidArgumentException | ParseException e) {
                         log.error("[命令发送失败] invite 不支持的媒体格式: {}", e.getMessage());
-                        playService.stopAudioBroadcast(device.getDeviceId(), deviceChannel.getDeviceId());
+                        playService.stopAudioBroadcast(device, deviceChannel);
                         return;
                     }
                     return;
@@ -859,7 +867,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
                         responseAck(request, Response.BUSY_HERE);
                     } catch (SipException | InvalidArgumentException | ParseException e) {
                         log.error("[命令发送失败] invite 未找到可用的zlm: {}", e.getMessage());
-                        playService.stopAudioBroadcast(device.getDeviceId(), deviceChannel.getDeviceId());
+                        playService.stopAudioBroadcast(device, deviceChannel);
                     }
                     return;
                 }
@@ -877,7 +885,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
                         responseAck(request, Response.BUSY_HERE);
                     } catch (SipException | InvalidArgumentException | ParseException e) {
                         log.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage());
-                        playService.stopAudioBroadcast(device.getDeviceId(), deviceChannel.getDeviceId());
+                        playService.stopAudioBroadcast(device, deviceChannel);
                         return;
                     }
                     return;
@@ -912,11 +920,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
                         log.error("[命令发送失败] 语音通话 回复410失败, {}", e.getMessage());
                         return;
                     }
-                    playService.stopAudioBroadcast(device.getDeviceId(), deviceChannel.getDeviceId());
+                    playService.stopAudioBroadcast(device, deviceChannel);
                 }
             } catch (SdpException e) {
                 log.error("[SDP解析异常]", e);
-                playService.stopAudioBroadcast(device.getDeviceId(), deviceChannel.getDeviceId());
+                playService.stopAudioBroadcast(device, deviceChannel);
             }
         } else {
             log.warn("来自无效设备/平台的请求");

+ 9 - 2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java

@@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.common.InviteInfo;
 import com.genersoft.iot.vmp.common.InviteSessionType;
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
 import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
 import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
 import com.genersoft.iot.vmp.gb28181.service.IPlatformService;
@@ -54,6 +55,9 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
     @Autowired
     private IDeviceService deviceService;
 
+    @Autowired
+    private IDeviceChannelService deviceChannelService;
+
     @Autowired
     private SIPCommander cmder;
 
@@ -112,9 +116,10 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
                         return;
                     }
                     Device device1 = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
-                    if (inviteInfo.getStreamInfo() != null) {
+                    DeviceChannel deviceChannel = deviceChannelService.getOneById(inviteInfo.getChannelId());
+                    if (device1 != null && deviceChannel != null && inviteInfo.getStreamInfo() != null) {
                         // 不解析协议, 直接转发给对应的设备
-                        cmder.playbackControlCmd(device1,inviteInfo.getStreamInfo(),new String(evt.getRequest().getRawContent()),eventResult -> {
+                        cmder.playbackControlCmd(device1, deviceChannel, inviteInfo.getStreamInfo(),new String(evt.getRequest().getRawContent()), eventResult -> {
                             // 失败的回复
                             try {
                                 responseAck(request, eventResult.statusCode, eventResult.msg);
@@ -129,6 +134,8 @@ public class InfoRequestProcessor extends SIPRequestProcessorParent implements I
                                 log.error("[命令发送失败] 国标级联 录像控制: {}", e.getMessage());
                             }
                         });
+                    }else {
+                        responseAck(request, Response.NOT_FOUND, "not found");
                     }
 
                 }

+ 11 - 6
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java

@@ -3,10 +3,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify
 import com.genersoft.iot.vmp.common.InviteInfo;
 import com.genersoft.iot.vmp.common.InviteSessionType;
 import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.bean.Platform;
-import com.genersoft.iot.vmp.gb28181.bean.SendRtpInfo;
-import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
+import com.genersoft.iot.vmp.gb28181.bean.*;
+import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
 import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
 import com.genersoft.iot.vmp.gb28181.service.IPlatformService;
 import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
@@ -68,6 +66,9 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
     @Autowired
     private SipInviteSessionManager sessionManager;
 
+    @Autowired
+    private IDeviceChannelService deviceChannelService;
+
     @Override
     public void afterPropertiesSet() throws Exception {
         notifyMessageHandler.addHandler(cmdType, this);
@@ -95,9 +96,13 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
                     inviteInfo.getStreamInfo().setProgress(1);
                     inviteStreamService.updateInviteInfo(inviteInfo);
                 }
-
+                DeviceChannel deviceChannel = deviceChannelService.getOneById(ssrcTransaction.getChannelId());
+                if (deviceChannel == null) {
+                    log.warn("[级联消息发送]:未找到国标设备通道: {}", ssrcTransaction.getChannelId());
+                    return;
+                }
                 try {
-                    cmder.streamByeCmd(device, ssrcTransaction.getChannelId(), null, callIdHeader.getCallId());
+                    cmder.streamByeCmd(device, deviceChannel.getDeviceId(), null, callIdHeader.getCallId());
                 } catch (InvalidArgumentException | ParseException  | SipException | SsrcTransactionNotFoundException e) {
                     log.error("[录像流]推送完毕,收到关流通知, 发送BYE失败 {}", e.getMessage());
                 }

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java

@@ -84,7 +84,7 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
                 audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.WaiteInvite);
                 audioBroadcastManager.update(audioBroadcastCatch);
             }else {
-                playService.stopAudioBroadcast(device.getDeviceId(), channelId);
+                playService.stopAudioBroadcast(device, channel);
             }
         } catch (ParseException | SipException | InvalidArgumentException e) {
             log.error("[命令发送失败] 国标级联 语音喊话: {}", e.getMessage());

+ 17 - 9
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java

@@ -7,10 +7,7 @@ import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
 import com.genersoft.iot.vmp.gb28181.bean.*;
-import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
-import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
-import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
-import com.genersoft.iot.vmp.gb28181.service.IPlatformService;
+import com.genersoft.iot.vmp.gb28181.service.*;
 import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
@@ -69,6 +66,9 @@ public class MediaServiceImpl implements IMediaService {
     @Autowired
     private IPlatformService platformService;
 
+    @Autowired
+    private IGbChannelService channelService;
+
     @Autowired
     private IDeviceService deviceService;
 
@@ -229,21 +229,29 @@ public class MediaServiceImpl implements IMediaService {
                 if (inviteInfo.getType() == InviteSessionType.DOWNLOAD) {
                     return false;
                 }
+                DeviceChannel deviceChannel = deviceChannelService.getOneById(inviteInfo.getChannelId());
+                if (deviceChannel == null) {
+                    return false;
+                }
                 // 收到无人观看说明流也没有在往上级推送
-                if (redisCatchStorage.isChannelSendingRTP(inviteInfo.getChannelId())) {
-                    List<SendRtpInfo> sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId(inviteInfo.getChannelId());
+                if (redisCatchStorage.isChannelSendingRTP(deviceChannel.getDeviceId())) {
+                    List<SendRtpInfo> sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId(deviceChannel.getDeviceId());
                     if (!sendRtpItems.isEmpty()) {
                         for (SendRtpInfo sendRtpItem : sendRtpItems) {
                             Platform parentPlatform = platformService.queryPlatformByServerGBId(sendRtpItem.getPlatformId());
+                            CommonGBChannel channel = channelService.getOne(sendRtpItem.getChannelId());
+                            if (channel == null) {
+                                continue;
+                            }
                             try {
-                                commanderForPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
+                                commanderForPlatform.streamByeCmd(parentPlatform, sendRtpItem, channel);
                             } catch (SipException | InvalidArgumentException | ParseException e) {
                                 log.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
                             }
-                            redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
+                            redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), channel.getGbDeviceId(),
                                     sendRtpItem.getCallId(), sendRtpItem.getStream());
                             if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) {
-                                redisCatchStorage.sendPlatformStopPlayMsg(sendRtpItem,parentPlatform);
+                                redisCatchStorage.sendPlatformStopPlayMsg(sendRtpItem, parentPlatform, channel);
                             }
                         }
                     }