|  | @@ -1,29 +1,42 @@
 | 
	
		
			
				|  |  |  package com.genersoft.iot.vmp.service.impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import com.genersoft.iot.vmp.common.InviteInfo;
 | 
	
		
			
				|  |  | +import com.genersoft.iot.vmp.common.InviteSessionType;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.common.StreamInfo;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.conf.DynamicTask;
 | 
	
		
			
				|  |  | +import com.genersoft.iot.vmp.conf.UserSetting;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.gb28181.bean.Device;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
 | 
	
		
			
				|  |  | +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
 | 
	
		
			
				|  |  | +import com.genersoft.iot.vmp.media.event.hook.Hook;
 | 
	
		
			
				|  |  | +import com.genersoft.iot.vmp.media.event.hook.HookType;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
 | 
	
		
			
				|  |  | +import com.genersoft.iot.vmp.media.service.IMediaNodeServerService;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.media.service.IMediaServerService;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.service.IReceiveRtpServerService;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.service.bean.ErrorCallback;
 | 
	
		
			
				|  |  | +import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.service.bean.RTPServerParam;
 | 
	
		
			
				|  |  |  import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 | 
	
		
			
				|  |  | +import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  |  import org.springframework.context.event.EventListener;
 | 
	
		
			
				|  |  |  import org.springframework.scheduling.annotation.Async;
 | 
	
		
			
				|  |  | +import org.springframework.security.core.parameters.P;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  | +import org.springframework.util.Assert;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.sip.InvalidArgumentException;
 | 
	
		
			
				|  |  |  import javax.sip.SipException;
 | 
	
		
			
				|  |  |  import java.text.ParseException;
 | 
	
		
			
				|  |  |  import java.util.List;
 | 
	
		
			
				|  |  | +import java.util.UUID;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +@Slf4j
 | 
	
		
			
				|  |  |  @Service
 | 
	
		
			
				|  |  |  public class RtpServerServiceImpl implements IReceiveRtpServerService {
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -33,6 +46,12 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private DynamicTask dynamicTask;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private SSRCFactory ssrcFactory;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private UserSetting userSetting;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 流到来的处理
 | 
	
		
			
				|  |  |       */
 | 
	
	
		
			
				|  | @@ -53,9 +72,65 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public SSRCInfo openRTPServer(RTPServerParam rtpServerParam, ErrorCallback<StreamInfo> callback) {
 | 
	
		
			
				|  |  | -        // 开启流到来的监听
 | 
	
		
			
				|  |  | +        if (callback == null) {
 | 
	
		
			
				|  |  | +            log.warn("[开启RTP收流] 失败,回调为NULL");
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (rtpServerParam.getMediaServerItem() == null) {
 | 
	
		
			
				|  |  | +            log.warn("[开启RTP收流] 失败,媒体节点为NULL");
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 获取mediaServer可用的ssrc
 | 
	
		
			
				|  |  | +        final String ssrc;
 | 
	
		
			
				|  |  | +        if (rtpServerParam.getPresetSsrc() != null) {
 | 
	
		
			
				|  |  | +            ssrc = rtpServerParam.getPresetSsrc();
 | 
	
		
			
				|  |  | +        }else {
 | 
	
		
			
				|  |  | +            if (rtpServerParam.isPlayback()) {
 | 
	
		
			
				|  |  | +                ssrc = ssrcFactory.getPlayBackSsrc(rtpServerParam.getMediaServerItem().getId());
 | 
	
		
			
				|  |  | +            }else {
 | 
	
		
			
				|  |  | +                ssrc = ssrcFactory.getPlaySsrc(rtpServerParam.getMediaServerItem().getId());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        final String streamId;
 | 
	
		
			
				|  |  | +        if (rtpServerParam.getStreamId() == null) {
 | 
	
		
			
				|  |  | +            streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase();
 | 
	
		
			
				|  |  | +        }else {
 | 
	
		
			
				|  |  | +            streamId = rtpServerParam.getStreamId();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (rtpServerParam.isSsrcCheck() && rtpServerParam.getTcpMode() > 0) {
 | 
	
		
			
				|  |  | +            // 目前zlm不支持 tcp模式更新ssrc,暂时关闭ssrc校验
 | 
	
		
			
				|  |  | +            log.warn("[openRTPServer] 平台对接时下级可能自定义ssrc,但是tcp模式zlm收流目前无法更新ssrc,可能收流超时,此时请使用udp收流或者关闭ssrc校验");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        int rtpServerPort;
 | 
	
		
			
				|  |  | +        if (rtpServerParam.getMediaServerItem().isRtpEnable()) {
 | 
	
		
			
				|  |  | +            rtpServerPort = mediaServerService.createRTPServer(rtpServerParam.getMediaServerItem(), streamId,
 | 
	
		
			
				|  |  | +                    rtpServerParam.isSsrcCheck() ? Long.parseLong(ssrc) : 0, rtpServerParam.getPort(), rtpServerParam.isOnlyAuto(),
 | 
	
		
			
				|  |  | +                    rtpServerParam.isDisableAudio(), rtpServerParam.isReUsePort(), rtpServerParam.getTcpMode());
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            rtpServerPort = rtpServerParam.getMediaServerItem().getRtpProxyPort();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (rtpServerPort == 0) {
 | 
	
		
			
				|  |  | +            callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null);
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        SSRCInfo ssrcInfo = new SSRCInfo(rtpServerPort, ssrc, streamId);
 | 
	
		
			
				|  |  |          // 设置流超时的定时任务
 | 
	
		
			
				|  |  | -        // 调用节点,开启端口监听
 | 
	
		
			
				|  |  | +        String timeOutTaskKey = UUID.randomUUID().toString();
 | 
	
		
			
				|  |  | +        dynamicTask.startDelay(timeOutTaskKey, () -> {
 | 
	
		
			
				|  |  | +            // 收流超时
 | 
	
		
			
				|  |  | +            // 释放ssrc
 | 
	
		
			
				|  |  | +            if (rtpServerParam.getPresetSsrc() == null) {
 | 
	
		
			
				|  |  | +                ssrcFactory.releaseSsrc(rtpServerParam.getMediaServerItem().getId(), ssrc);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            // 关闭收流端口
 | 
	
		
			
				|  |  | +            mediaServerService.closeRTPServer(rtpServerParam.getMediaServerItem(), streamId);
 | 
	
		
			
				|  |  | +        }, userSetting.getPlayTimeout());
 | 
	
		
			
				|  |  | +        // 开启流到来的监听
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 |