648540858
2022-03-17 59ef6e67d3a1357c19039527dac47747e2ac20fe
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -6,6 +6,8 @@
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetup;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback;
import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo;
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
@@ -445,26 +447,12 @@
    * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
    */ 
   @Override
   public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event
         , SipSubscribe.Event errorEvent) {
   public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
                          String startTime, String endTime, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent,
                          SipSubscribe.Event errorEvent) {
      try {
         logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
         // 添加订阅
         JSONObject subscribeKey = new JSONObject();
         subscribeKey.put("app", "rtp");
         subscribeKey.put("stream", ssrcInfo.getStream());
         subscribeKey.put("regist", true);
         subscribeKey.put("schema", "rtmp");
         subscribeKey.put("mediaServerId", mediaServerItem.getId());
         logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
         subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
               (MediaServerItem mediaServerItemInUse, JSONObject json)->{
            if (event != null) {
               event.response(mediaServerItemInUse, json);
            }
         });
         StringBuffer content = new StringBuffer(200);
           content.append("v=0\r\n");
@@ -530,6 +518,21 @@
         CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
               : udpSipProvider.getNewCallId();
         // 添加订阅
         JSONObject subscribeKey = new JSONObject();
         subscribeKey.put("app", "rtp");
         subscribeKey.put("stream", ssrcInfo.getStream());
         subscribeKey.put("regist", true);
         subscribeKey.put("schema", "rtmp");
         subscribeKey.put("mediaServerId", mediaServerItem.getId());
         logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey);
         subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
               (MediaServerItem mediaServerItemInUse, JSONObject json)->{
                  if (hookEvent != null) {
                     InviteStreamInfo inviteStreamInfo = new InviteStreamInfo(mediaServerItemInUse, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream());
                     hookEvent.call(inviteStreamInfo);
                  }
               });
           Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
           transmitRequest(device, request, errorEvent, okEvent -> {
@@ -537,6 +540,9 @@
              streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction());
            streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), okEvent.dialog);
         });
         if (inviteStreamCallback != null) {
            inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));
         }
      } catch ( SipException | ParseException | InvalidArgumentException e) {
         e.printStackTrace();
      }
@@ -552,23 +558,10 @@
    * @param downloadSpeed 下载倍速参数
    */ 
   @Override
   public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event
   public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, InviteStreamCallback event
         , SipSubscribe.Event errorEvent) {
      try {
         logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
         // 添加订阅
         JSONObject subscribeKey = new JSONObject();
         subscribeKey.put("app", "rtp");
         subscribeKey.put("stream", ssrcInfo.getStream());
         subscribeKey.put("regist", true);
         subscribeKey.put("mediaServerId", mediaServerItem.getId());
         logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
         subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
               (MediaServerItem mediaServerItemInUse, JSONObject json)->{
            event.response(mediaServerItemInUse, json);
            subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
         });
         StringBuffer content = new StringBuffer(200);
           content.append("v=0\r\n");
@@ -637,6 +630,19 @@
         CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
               : udpSipProvider.getNewCallId();
         // 添加订阅
         JSONObject subscribeKey = new JSONObject();
         subscribeKey.put("app", "rtp");
         subscribeKey.put("stream", ssrcInfo.getStream());
         subscribeKey.put("regist", true);
         subscribeKey.put("mediaServerId", mediaServerItem.getId());
         logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
         subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
               (MediaServerItem mediaServerItemInUse, JSONObject json)->{
                  event.call(new InviteStreamInfo(mediaServerItem, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));
                  subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
               });
           Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
           ClientTransaction transaction = transmitRequest(device, request, errorEvent);
@@ -652,18 +658,19 @@
    * 视频流停止, 不使用回调
    */
   @Override
   public void streamByeCmd(String deviceId, String channelId, String stream) {
      streamByeCmd(deviceId, channelId, stream, null);
   public void streamByeCmd(String deviceId, String channelId, String stream, String callId) {
      streamByeCmd(deviceId, channelId, stream, callId, null);
   }
   /**
    * 视频流停止
    */
   @Override
   public void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent) {
   public void streamByeCmd(String deviceId, String channelId, String stream, String callId, SipSubscribe.Event okEvent) {
      try {
         SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, null, stream);
         ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream);
         if (transaction == null) {
            logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId);
            SipSubscribe.EventResult<Object> eventResult = new SipSubscribe.EventResult<>();
@@ -672,7 +679,20 @@
            }
            return;
         }
         SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, stream);
         SIPDialog dialog;
         if (callId != null) {
            dialog = streamSession.getDialogByCallId(deviceId, channelId, callId);
         }else {
            if (stream == null) return;
            dialog = streamSession.getDialogByStream(deviceId, channelId, stream);
         }
         if (ssrcTransaction != null) {
            MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
            mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransaction.getSsrc());
            mediaServerService.closeRTPServer(deviceId, channelId, ssrcTransaction.getStream());
            streamSession.remove(deviceId, channelId, ssrcTransaction.getStream());
         }
         if (dialog == null) {
            logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId);
            return;
@@ -716,12 +736,6 @@
         dialog.sendRequest(clientTransaction);
         if (ssrcTransaction != null) {
            MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
            mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransaction.getSsrc());
            mediaServerService.closeRTPServer(deviceId, channelId, ssrcTransaction.getStream());
            streamSession.remove(deviceId, channelId, ssrcTransaction.getStream());
         }
      } catch (SipException | ParseException e) {
         e.printStackTrace();
      }
@@ -1106,8 +1120,9 @@
   @Override
   public boolean deviceStatusQuery(Device device, SipSubscribe.Event errorEvent) {
      try {
         String charset = device.getCharset();
         StringBuffer catalogXml = new StringBuffer(200);
         catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
         catalogXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
         catalogXml.append("<Query>\r\n");
         catalogXml.append("<CmdType>DeviceStatus</CmdType>\r\n");
         catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
@@ -1139,7 +1154,8 @@
   public boolean deviceInfoQuery(Device device) {
      try {
         StringBuffer catalogXml = new StringBuffer(200);
         catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
         String charset = device.getCharset();
         catalogXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
         catalogXml.append("<Query>\r\n");
         catalogXml.append("<CmdType>DeviceInfo</CmdType>\r\n");
         catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
@@ -1171,7 +1187,8 @@
   public boolean catalogQuery(Device device, SipSubscribe.Event errorEvent) {
      try {
         StringBuffer catalogXml = new StringBuffer(200);
         catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
         String charset = device.getCharset();
         catalogXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
         catalogXml.append("<Query>\r\n");
         catalogXml.append("<CmdType>Catalog</CmdType>\r\n");
         catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
@@ -1210,7 +1227,8 @@
      }
      try {
         StringBuffer recordInfoXml = new StringBuffer(200);
         recordInfoXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
         String charset = device.getCharset();
         recordInfoXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
         recordInfoXml.append("<Query>\r\n");
         recordInfoXml.append("<CmdType>RecordInfo</CmdType>\r\n");
         recordInfoXml.append("<SN>" + sn + "</SN>\r\n");
@@ -1382,7 +1400,8 @@
   public boolean mobilePostitionQuery(Device device, SipSubscribe.Event errorEvent) {
      try {
         StringBuffer mobilePostitionXml = new StringBuffer(200);
         mobilePostitionXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
         String charset = device.getCharset();
         mobilePostitionXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
         mobilePostitionXml.append("<Query>\r\n");
         mobilePostitionXml.append("<CmdType>MobilePosition</CmdType>\r\n");
         mobilePostitionXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
@@ -1417,7 +1436,8 @@
   public boolean mobilePositionSubscribe(Device device, int expires, int interval) {
      try {
         StringBuffer subscribePostitionXml = new StringBuffer(200);
         subscribePostitionXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
         String charset = device.getCharset();
         subscribePostitionXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
         subscribePostitionXml.append("<Query>\r\n");
         subscribePostitionXml.append("<CmdType>MobilePosition</CmdType>\r\n");
         subscribePostitionXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
@@ -1459,7 +1479,8 @@
   public boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime) {
      try {
         StringBuffer cmdXml = new StringBuffer(200);
         cmdXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
         String charset = device.getCharset();
         cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
         cmdXml.append("<Query>\r\n");
         cmdXml.append("<CmdType>Alarm</CmdType>\r\n");
         cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
@@ -1504,7 +1525,8 @@
   public boolean catalogSubscribe(Device device, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
      try {
         StringBuffer cmdXml = new StringBuffer(200);
         cmdXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
         String charset = device.getCharset();
         cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
         cmdXml.append("<Query>\r\n");
         cmdXml.append("<CmdType>Catalog</CmdType>\r\n");
         cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
@@ -1606,7 +1628,7 @@
         content.append("PAUSE RTSP/1.0\r\n");
         content.append("CSeq: " + cseq + "\r\n");
         content.append("PauseTime: now\r\n");
         Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString(), cseq);
         Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString());
         if (request == null) {
            return;
         }
@@ -1637,7 +1659,7 @@
         content.append("PLAY RTSP/1.0\r\n");
         content.append("CSeq: " + cseq + "\r\n");
         content.append("Range: npt=now-\r\n");
         Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString(), cseq);
         Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString());
         if (request == null) return;
         logger.info(request.toString());
         ClientTransaction clientTransaction = null;
@@ -1666,7 +1688,7 @@
         content.append("CSeq: " + cseq + "\r\n");
         content.append("Range: npt=" + Math.abs(seekTime) + "-\r\n");
         Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString(), cseq);
         Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString());
         if (request == null) return;
         logger.info(request.toString());
         ClientTransaction clientTransaction = null;
@@ -1694,7 +1716,7 @@
         content.append("PLAY RTSP/1.0\r\n");
         content.append("CSeq: " + cseq + "\r\n");
         content.append("Scale: " + String.format("%.1f",speed) + "\r\n");
         Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString(), cseq);
         Request request = headerProvider.createInfoRequest(device, streamInfo, content.toString());
         if (request == null) return;
         logger.info(request.toString());
         ClientTransaction clientTransaction = null;