648540858
2022-09-08 4bda14b098bc943324c73a8365c8bcd721beaa5a
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -10,12 +10,12 @@
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
import com.genersoft.iot.vmp.gb28181.utils.HeaderUtils;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
import com.genersoft.iot.vmp.media.zlm.dto.HookType;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -33,19 +33,15 @@
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.sip.*;
import javax.sip.address.Address;
import javax.sip.address.SipURI;
import javax.sip.address.URI;
import javax.sip.header.*;
import javax.sip.message.Request;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
/**    
 * @description:设备能力接口,用于定义设备的控制、查询能力   
@@ -88,7 +84,7 @@
   private UserSetting userSetting;
   @Autowired
   private ZLMHttpHookSubscribe subscribe;
   private ZlmHttpHookSubscribe subscribe;
   @Autowired
   private SipSubscribe sipSubscribe;
@@ -251,7 +247,7 @@
         
         String tm = Long.toString(System.currentTimeMillis());
         CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
         CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
               : udpSipProvider.getNewCallId();
         Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
@@ -294,7 +290,7 @@
         
         String tm = Long.toString(System.currentTimeMillis());
         CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
         CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
               : udpSipProvider.getNewCallId();
         Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
@@ -330,7 +326,7 @@
         
         String tm = Long.toString(System.currentTimeMillis());
         CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
         CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
               : udpSipProvider.getNewCallId();
         Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null, callIdHeader);
@@ -351,16 +347,16 @@
   */
   @Override
   public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
                       ZLMHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
                       ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) {
      String stream = ssrcInfo.getStream();
      try {
         if (device == null) {
            return;
         }
         String streamMode = device.getStreamMode().toUpperCase();
//         String streamMode = device.getStreamMode().toUpperCase();
         logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
         HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtmp", mediaServerItem.getId());
         HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
         subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json)->{
            if (event != null) {
               event.response(mediaServerItemInUse, json);
@@ -376,11 +372,11 @@
         content.append("t=0 0\r\n");
         if (userSetting.isSeniorSdp()) {
            if("TCP-PASSIVE".equals(streamMode)) {
            if("TCP-PASSIVE".equalsIgnoreCase(device.getStreamMode())) {
               content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
            }else if ("TCP-ACTIVE".equals(streamMode)) {
            }else if ("TCP-ACTIVE".equalsIgnoreCase(device.getStreamMode())) {
               content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
            }else if("UDP".equals(streamMode)) {
            }else if("UDP".equalsIgnoreCase(device.getStreamMode())) {
               content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n");
            }
            content.append("a=recvonly\r\n");
@@ -392,19 +388,19 @@
            content.append("a=rtpmap:99 H265/90000\r\n");
            content.append("a=rtpmap:98 H264/90000\r\n");
            content.append("a=rtpmap:97 MPEG4/90000\r\n");
            if("TCP-PASSIVE".equals(streamMode)){ // tcp被动模式
            if("TCP-PASSIVE".equalsIgnoreCase(device.getStreamMode())){ // tcp被动模式
               content.append("a=setup:passive\r\n");
               content.append("a=connection:new\r\n");
            }else if ("TCP-ACTIVE".equals(streamMode)) { // tcp主动模式
            }else if ("TCP-ACTIVE".equalsIgnoreCase(device.getStreamMode())) { // tcp主动模式
               content.append("a=setup:active\r\n");
               content.append("a=connection:new\r\n");
            }
         }else {
            if("TCP-PASSIVE".equals(streamMode)) {
            if("TCP-PASSIVE".equalsIgnoreCase(device.getStreamMode())) {
               content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
            }else if ("TCP-ACTIVE".equals(streamMode)) {
            }else if ("TCP-ACTIVE".equalsIgnoreCase(device.getStreamMode())) {
               content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
            }else if("UDP".equals(streamMode)) {
            }else if("UDP".equalsIgnoreCase(device.getStreamMode())) {
               content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 97 98 99\r\n");
            }
            content.append("a=recvonly\r\n");
@@ -412,10 +408,10 @@
            content.append("a=rtpmap:98 H264/90000\r\n");
            content.append("a=rtpmap:97 MPEG4/90000\r\n");
            content.append("a=rtpmap:99 H265/90000\r\n");
            if ("TCP-PASSIVE".equals(streamMode)) { // tcp被动模式
            if ("TCP-PASSIVE".equalsIgnoreCase(device.getStreamMode())) { // tcp被动模式
               content.append("a=setup:passive\r\n");
               content.append("a=connection:new\r\n");
            } else if ("TCP-ACTIVE".equals(streamMode)) { // tcp主动模式
            } else if ("TCP-ACTIVE".equalsIgnoreCase(device.getStreamMode())) { // tcp主动模式
               content.append("a=setup:active\r\n");
               content.append("a=connection:new\r\n");
            }
@@ -427,7 +423,7 @@
         String tm = Long.toString(System.currentTimeMillis());
         CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
         CallIdHeader callIdHeader = device.getTransport().equalsIgnoreCase("TCP") ? tcpSipProvider.getNewCallId()
               : udpSipProvider.getNewCallId();
         Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader);
@@ -460,7 +456,7 @@
   @Override
   public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
                          String startTime, String endTime, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent,
                          SipSubscribe.Event errorEvent) {
                          SipSubscribe.Event okEvent,SipSubscribe.Event errorEvent) {
      try {
         logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
@@ -474,14 +470,14 @@
           content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" "
               +DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n");
         String streamMode = device.getStreamMode().toUpperCase();
         String streamMode = device.getStreamMode();
         if (userSetting.isSeniorSdp()) {
            if("TCP-PASSIVE".equals(streamMode)) {
            if("TCP-PASSIVE".equalsIgnoreCase(streamMode)) {
               content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
            }else if ("TCP-ACTIVE".equals(streamMode)) {
            }else if ("TCP-ACTIVE".equalsIgnoreCase(streamMode)) {
               content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
            }else if("UDP".equals(streamMode)) {
            }else if("UDP".equalsIgnoreCase(streamMode)) {
               content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n");
            }
            content.append("a=recvonly\r\n");
@@ -493,19 +489,19 @@
            content.append("a=rtpmap:99 H265/90000\r\n");
            content.append("a=rtpmap:98 H264/90000\r\n");
            content.append("a=rtpmap:97 MPEG4/90000\r\n");
            if("TCP-PASSIVE".equals(streamMode)){ // tcp被动模式
            if("TCP-PASSIVE".equalsIgnoreCase(streamMode)){ // tcp被动模式
               content.append("a=setup:passive\r\n");
               content.append("a=connection:new\r\n");
            }else if ("TCP-ACTIVE".equals(streamMode)) { // tcp主动模式
            }else if ("TCP-ACTIVE".equalsIgnoreCase(streamMode)) { // tcp主动模式
               content.append("a=setup:active\r\n");
               content.append("a=connection:new\r\n");
            }
         }else {
            if("TCP-PASSIVE".equals(streamMode)) {
            if("TCP-PASSIVE".equalsIgnoreCase(streamMode)) {
               content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
            }else if ("TCP-ACTIVE".equals(streamMode)) {
            }else if ("TCP-ACTIVE".equalsIgnoreCase(streamMode)) {
               content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 97 98 99\r\n");
            }else if("UDP".equals(streamMode)) {
            }else if("UDP".equalsIgnoreCase(streamMode)) {
               content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 97 98 99\r\n");
            }
            content.append("a=recvonly\r\n");
@@ -513,10 +509,10 @@
            content.append("a=rtpmap:97 MPEG4/90000\r\n");
            content.append("a=rtpmap:98 H264/90000\r\n");
            content.append("a=rtpmap:99 H265/90000\r\n");
            if("TCP-PASSIVE".equals(streamMode)){ // tcp被动模式
            if("TCP-PASSIVE".equalsIgnoreCase(streamMode)){ // tcp被动模式
               content.append("a=setup:passive\r\n");
               content.append("a=connection:new\r\n");
            }else if ("TCP-ACTIVE".equals(streamMode)) { // tcp主动模式
            }else if ("TCP-ACTIVE".equalsIgnoreCase(streamMode)) { // tcp主动模式
               content.append("a=setup:active\r\n");
               content.append("a=connection:new\r\n");
            }
@@ -528,7 +524,7 @@
         CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
               : udpSipProvider.getNewCallId();
         HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtmp", mediaServerItem.getId());
         HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
         // 添加订阅
         subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json)->{
                  if (hookEvent != null) {
@@ -539,10 +535,11 @@
               });
           Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
           transmitRequest(device, request, errorEvent, okEvent -> {
            ResponseEvent responseEvent = (ResponseEvent) okEvent.event;
           transmitRequest(device, request, errorEvent, event -> {
            ResponseEvent responseEvent = (ResponseEvent) event.event;
              streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction(), VideoStreamSessionManager.SessionType.playback);
            streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), okEvent.dialog);
            streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), event.dialog);
            okEvent.response(event);
         });
         if (inviteStreamCallback != null) {
            inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));
@@ -640,7 +637,7 @@
                  hookEvent.call(new InviteStreamInfo(mediaServerItem, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));
                  subscribe.removeSubscribe(hookSubscribe);
                  hookSubscribe.getContent().put("regist", false);
                  hookSubscribe.getContent().put("schema", "rtmp");
                  hookSubscribe.getContent().put("schema", "rtsp");
                  // 添加流注销的订阅,注销了后向设备发送bye
                  subscribe.addSubscribe(hookSubscribe,
                        (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd)->{
@@ -740,15 +737,7 @@
         // 增加Contact header
         Address concatAddress = sipFactory.createAddressFactory().createAddress(sipFactory.createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getIp()+":"+sipConfig.getPort()));
         byeRequest.addHeader(sipFactory.createHeaderFactory().createContactHeader(concatAddress));
         List<String> agentParam = new ArrayList<>();
         agentParam.add("wvp-pro");
         // TODO 添加版本信息以及日期
         UserAgentHeader userAgentHeader = null;
         try {
            userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
         } catch (ParseException e) {
            throw new RuntimeException(e);
         }
         UserAgentHeader userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory);
         byeRequest.addHeader(userAgentHeader);
         ClientTransaction clientTransaction = null;
         if("TCP".equals(protocol)) {
@@ -1677,14 +1666,11 @@
         clientTransaction = udpSipProvider.getNewClientTransaction(request);
      }
      if (request.getHeader(UserAgentHeader.NAME) == null) {
         List<String> agentParam = new ArrayList<>();
         agentParam.add("wvp-pro");
         // TODO 添加版本信息以及日期
         UserAgentHeader userAgentHeader = null;
         try {
            userAgentHeader = sipFactory.createHeaderFactory().createUserAgentHeader(agentParam);
            userAgentHeader = HeaderUtils.createUserAgentHeader(sipFactory);
         } catch (ParseException e) {
            throw new RuntimeException(e);
            logger.error("添加UserAgentHeader失败", e);
         }
         request.addHeader(userAgentHeader);
      }
@@ -1913,7 +1899,7 @@
   private void sendNotify(Device device, String catalogXmlContent,
                     SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent,  SipSubscribe.Event okEvent )
         throws NoSuchFieldException, IllegalAccessException, SipException, ParseException {
         throws SipException, ParseException {
      MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
      String characterSet = device.getCharset();
      // 设置编码, 防止中文乱码