|
|
@@ -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());
|
|
|
+ // 开启流到来的监听
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
}
|
|
|
|