From 1768565ce045d4beddccc82d10b533ea3022cf8d Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 18 Mar 2024 23:42:18 +0800 Subject: [PATCH 01/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=9C=8D=E5=8A=A1=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/conf/CloudRecordTimer.java | 5 +- .../iot/vmp/conf/ProxyServletConfig.java | 2 +- .../genersoft/iot/vmp/conf/WVPTimerTask.java | 4 - .../iot/vmp/gb28181/event/EventPublisher.java | 10 +- .../iot/vmp/gb28181/task/SipRunner.java | 2 +- .../transmit/cmd/impl/SIPCommander.java | 3 +- .../cmd/impl/SIPCommanderFroPlatform.java | 2 +- .../request/impl/AckRequestProcessor.java | 2 +- .../request/impl/ByeRequestProcessor.java | 1 + .../request/impl/InviteRequestProcessor.java | 1 + .../cmd/BroadcastNotifyMessageHandler.java | 3 +- .../vmp/media/IMediaNodeServerService.java | 20 ++ .../IMediaServerService.java | 2 +- .../media/abl/ABLMediaNodeServerService.java | 8 + .../impl/MediaServerServiceImpl.java | 145 ++++---- .../vmp/media/zlm/ZLMHttpHookListener.java | 1 + .../vmp/media/zlm/ZLMMediaListManager.java | 2 +- .../media/zlm/ZLMMediaNodeServerService.java | 9 + .../iot/vmp/media/zlm/ZLMRunner.java | 3 +- .../vmp/media/zlm/dto/MediaServerItem.java | 10 + ...act.java => MediaServerEventAbstract.java} | 5 +- .../zlm/event/MediaServerOfflineEvent.java | 11 + .../zlm/event/MediaServerOnlineEvent.java | 11 + ...va => MediaServerStatusEventListener.java} | 10 +- .../vmp/media/zlm/event/ZLMOfflineEvent.java | 11 - .../vmp/media/zlm/event/ZLMOnlineEvent.java | 11 - .../service/impl/CloudRecordServiceImpl.java | 2 +- .../vmp/service/impl/DeviceServiceImpl.java | 2 +- .../vmp/service/impl/MediaServiceImpl.java | 8 +- .../vmp/service/impl/PlatformServiceImpl.java | 10 +- .../iot/vmp/service/impl/PlayServiceImpl.java | 1 + .../service/impl/StreamProxyServiceImpl.java | 4 +- .../service/impl/StreamPushServiceImpl.java | 2 +- .../redisMsg/RedisGbPlayMsgListener.java | 2 +- .../RedisPushStreamCloseResponseListener.java | 2 +- .../RedisPushStreamStatusListMsgListener.java | 2 +- .../cloudRecord/CloudRecordController.java | 7 +- .../vmanager/gb28181/play/PlayController.java | 2 +- .../iot/vmp/vmanager/ps/PsController.java | 2 +- .../iot/vmp/vmanager/rtp/RtpController.java | 2 +- .../vmp/vmanager/server/ServerController.java | 1 + .../streamProxy/StreamProxyController.java | 2 +- .../streamPush/StreamPushController.java | 2 +- 数据库/abl/初始化-mysql-2.7.0.sql | 325 ++++++++++++++++++ .../abl/初始化-postgresql-kingbase-2.7.0.sql | 325 ++++++++++++++++++ 数据库/abl/更新-mysql-2.7.0.sql | 2 + 数据库/abl/更新-postgresql-kingbase-2.7.0.sql | 2 + 47 files changed, 844 insertions(+), 157 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java rename src/main/java/com/genersoft/iot/vmp/{service => media}/IMediaServerService.java (98%) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java rename src/main/java/com/genersoft/iot/vmp/{service => media}/impl/MediaServerServiceImpl.java (83%) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java rename src/main/java/com/genersoft/iot/vmp/media/zlm/event/{ZLMEventAbstract.java => MediaServerEventAbstract.java} (71%) create mode 100755 src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOfflineEvent.java create mode 100755 src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOnlineEvent.java rename src/main/java/com/genersoft/iot/vmp/media/zlm/event/{ZLMStatusEventListener.java => MediaServerStatusEventListener.java} (83%) delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOfflineEvent.java delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOnlineEvent.java create mode 100644 数据库/abl/初始化-mysql-2.7.0.sql create mode 100644 数据库/abl/初始化-postgresql-kingbase-2.7.0.sql create mode 100644 数据库/abl/更新-mysql-2.7.0.sql create mode 100644 数据库/abl/更新-postgresql-kingbase-2.7.0.sql diff --git a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java index f98977fa4..92e7f51f1 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java @@ -2,13 +2,11 @@ package com.genersoft.iot.vmp.conf; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper; -import com.genersoft.iot.vmp.vmanager.cloudRecord.CloudRecordController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -16,7 +14,6 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.File; -import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java index a7416a8e7..dbab513d1 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.conf; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/WVPTimerTask.java b/src/main/java/com/genersoft/iot/vmp/conf/WVPTimerTask.java index 77d83ee22..c58625501 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/WVPTimerTask.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/WVPTimerTask.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.conf; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -14,9 +13,6 @@ public class WVPTimerTask { @Autowired private IRedisCatchStorage redisCatchStorage; - @Autowired - private IMediaServerService mediaServerService; - @Value("${server.port}") private int serverPort; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java index d56e744da..c363583a0 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java @@ -4,8 +4,8 @@ import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent; import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; -import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent; -import com.genersoft.iot.vmp.media.zlm.event.ZLMOnlineEvent; +import com.genersoft.iot.vmp.media.zlm.event.MediaServerOfflineEvent; +import com.genersoft.iot.vmp.media.zlm.event.MediaServerOnlineEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; @@ -40,13 +40,13 @@ public class EventPublisher { } public void zlmOfflineEventPublish(String mediaServerId){ - ZLMOfflineEvent outEvent = new ZLMOfflineEvent(this); + MediaServerOfflineEvent outEvent = new MediaServerOfflineEvent(this); outEvent.setMediaServerId(mediaServerId); applicationEventPublisher.publishEvent(outEvent); } - public void zlmOnlineEventPublish(String mediaServerId) { - ZLMOnlineEvent outEvent = new ZLMOnlineEvent(this); + public void mediaServerOnlineEventPublish(String mediaServerId) { + MediaServerOnlineEvent outEvent = new MediaServerOnlineEvent(this); outEvent.setMediaServerId(mediaServerId); applicationEventPublisher.publishEvent(outEvent); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java index 5ca95a0d8..010f1140c 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.service.impl.PlatformServiceImpl; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 723c715fa..91595f8dc 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -25,7 +25,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamPush; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.message.SIPRequest; @@ -44,7 +44,6 @@ import javax.sip.SipFactory; import javax.sip.header.CallIdHeader; import javax.sip.message.Request; import java.text.ParseException; -import java.util.ArrayList; import java.util.List; /** diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index abd32fbaa..7c9036b05 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index 70048209f..37ae5b670 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg; import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java index f66e3c380..36f9d6bdf 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java @@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.*; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 3205498f3..f75cc4d7f 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java index a05847aae..e7191bf47 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; @@ -12,7 +11,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java new file mode 100644 index 000000000..c72c7e232 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java @@ -0,0 +1,20 @@ +package com.genersoft.iot.vmp.media; + +import com.genersoft.iot.vmp.common.CommonCallback; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; + +public interface IMediaNodeServerService { + int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); + + void closeRtpServer(MediaServerItem mediaServerItem, String streamId); + + void closeRtpServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback); + + void closeStreams(MediaServerItem mediaServerItem, String rtp, String streamId); + + Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc); + + boolean checkNodeId(MediaServerItem mediaServerItem); + + void online(MediaServerItem mediaServerItem); +} diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/IMediaServerService.java similarity index 98% rename from src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java rename to src/main/java/com/genersoft/iot/vmp/media/IMediaServerService.java index 2e6151d67..49203d2c2 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/IMediaServerService.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.service; +package com.genersoft.iot.vmp.media; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java new file mode 100644 index 000000000..6e86153d9 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -0,0 +1,8 @@ +package com.genersoft.iot.vmp.media.abl; + +import com.genersoft.iot.vmp.media.IMediaNodeServerService; +import org.springframework.stereotype.Service; + +@Service("abl") +public class ABLMediaNodeServerService implements IMediaNodeServerService { +} diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java similarity index 83% rename from src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java rename to src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java index 190d665b6..4e8ed274d 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.service.impl; +package com.genersoft.iot.vmp.media.impl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; @@ -12,11 +12,12 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; +import com.genersoft.iot.vmp.media.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.*; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -25,30 +26,23 @@ import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.JsonUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import com.genersoft.iot.vmp.vmanager.bean.RecordFile; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; -import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import java.io.File; import java.time.LocalDateTime; import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; /** * 媒体服务器节点管理 @@ -82,9 +76,6 @@ public class MediaServerServiceImpl implements IMediaServerService { @Autowired private AssistRESTfulUtils assistRESTfulUtils; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Autowired private MediaServerMapper mediaServerMapper; @@ -113,20 +104,16 @@ public class MediaServerServiceImpl implements IMediaServerService { @Autowired private RedisTemplate redisTemplate; - @Qualifier("taskExecutor") @Autowired - private ThreadPoolTaskExecutor taskExecutor; - - - + private Map nodeServerServiceMap; /** * 初始化 */ @Override - public void updateVmServer(List mediaServerItemList) { - logger.info("[zlm] 缓存初始化 "); + public void updateVmServer(List mediaServerItemList) { + logger.info("[媒体服务节点] 缓存初始化 "); for (MediaServerItem mediaServerItem : mediaServerItemList) { if (ObjectUtils.isEmpty(mediaServerItem.getId())) { continue; @@ -173,7 +160,12 @@ public class MediaServerServiceImpl implements IMediaServerService { } int rtpServerPort; if (mediaServerItem.isRtpEnable()) { - rtpServerPort = zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrcCheck ? Long.parseLong(ssrc) : 0, port, onlyAuto, reUsePort, tcpMode); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[openRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return null; + } + rtpServerPort = mediaNodeServerService.createRTPServer(mediaServerItem, streamId, ssrcCheck ? Long.parseLong(ssrc) : 0, port, onlyAuto, reUsePort, tcpMode); } else { rtpServerPort = mediaServerItem.getRtpProxyPort(); } @@ -191,7 +183,12 @@ public class MediaServerServiceImpl implements IMediaServerService { if (mediaServerItem == null) { return; } - zlmServerFactory.closeRtpServer(mediaServerItem, streamId); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return; + } + mediaNodeServerService.closeRtpServer(mediaServerItem, streamId); } @Override @@ -200,21 +197,42 @@ public class MediaServerServiceImpl implements IMediaServerService { callback.run(false); return; } - zlmServerFactory.closeRtpServer(mediaServerItem, streamId, callback); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return; + } + mediaNodeServerService.closeRtpServer(mediaServerItem, streamId, callback); } @Override public void closeRTPServer(String mediaServerId, String streamId) { MediaServerItem mediaServerItem = this.getOne(mediaServerId); - if (mediaServerItem != null && mediaServerItem.isRtpEnable()) { + if (mediaServerItem == null) { + return; + } + if (mediaServerItem.isRtpEnable()) { closeRTPServer(mediaServerItem, streamId); } - zlmresTfulUtils.closeStreams(mediaServerItem, "rtp", streamId); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return; + } + mediaNodeServerService.closeStreams(mediaServerItem, "rtp", streamId); } @Override public Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) { - return zlmServerFactory.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); + if (mediaServerItem == null) { + return false; + } + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[updateRtpServerSSRC] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return false; + } + return mediaNodeServerService.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); } @Override @@ -227,12 +245,11 @@ public class MediaServerServiceImpl implements IMediaServerService { } /** - * zlm 重启后重置他的推流信息, TODO 给正在使用的设备发送停止命令 + * 媒体服务节点 重启后重置他的推流信息, TODO 给正在使用的设备发送停止命令 */ @Override public void clearRTPServer(MediaServerItem mediaServerItem) { ssrcFactory.reset(mediaServerItem.getId()); - } @@ -301,7 +318,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } /** - * 获取单个zlm服务器 + * 获取单个媒体服务节点服务器 * @param mediaServerId 服务id * @return MediaServerItem */ @@ -331,24 +348,20 @@ public class MediaServerServiceImpl implements IMediaServerService { mediaServerItem.setCreateTime(DateUtil.getNow()); mediaServerItem.setUpdateTime(DateUtil.getNow()); mediaServerItem.setHookAliveInterval(30f); - JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); - if (responseJSON != null) { - JSONArray data = responseJSON.getJSONArray("data"); - if (data != null && data.size() > 0) { - ZLMServerConfig zlmServerConfig= JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); - if (mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()) != null) { - throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败,媒体服务ID [ " + zlmServerConfig.getGeneralMediaServerId() + " ] 已存在,请修改媒体服务器配置"); - } - mediaServerItem.setId(zlmServerConfig.getGeneralMediaServerId()); - zlmServerConfig.setIp(mediaServerItem.getIp()); - mediaServerMapper.add(mediaServerItem); - zlmServerOnline(zlmServerConfig); - }else { - throw new ControllerException(ErrorCode.ERROR100.getCode(),"连接失败"); - } - + if (mediaServerItem.getType() == null) { + logger.info("[添加媒体节点] 失败, mediaServerItem的类型:为空"); + return; + } + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[添加媒体节点] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return; + } + if (mediaNodeServerService.checkNodeId(mediaServerItem)) { + mediaServerMapper.add(mediaServerItem); + mediaNodeServerService.online(mediaServerItem); }else { - throw new ControllerException(ErrorCode.ERROR100.getCode(),"连接失败"); + throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败,媒体服务ID [ " + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); } } @@ -364,7 +377,7 @@ public class MediaServerServiceImpl implements IMediaServerService { TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition); int delResult = mediaServerMapper.delDefault(); if (delResult == 0) { - logger.error("移除数据库默认zlm节点失败"); + logger.error("移除数据库默认媒体服务节点节点失败"); //事务回滚 dataSourceTransactionManager.rollback(transactionStatus); return 0; @@ -378,19 +391,19 @@ public class MediaServerServiceImpl implements IMediaServerService { } /** - * 处理zlm上线 - * @param zlmServerConfig zlm上线携带的参数 + * 处理媒体服务节点上线 + * @param zlmServerConfig 媒体服务节点上线携带的参数 */ @Override public void zlmServerOnline(ZLMServerConfig zlmServerConfig) { MediaServerItem serverItem = mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()); if (serverItem == null) { - logger.warn("[未注册的zlm] 拒接接入:{}来自{}:{}", zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(),zlmServerConfig.getHttpPort() ); - logger.warn("请检查ZLM的配置是否与WVP的一致"); + logger.warn("[未注册的媒体服务节点] 拒接接入:{}来自{}:{}", zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(),zlmServerConfig.getHttpPort() ); + logger.warn("请检查媒体服务节点的ID配置是否与WVP的一致"); return; }else { - logger.info("[ZLM] 正在连接 : {} -> {}:{}", + logger.info("[媒体服务节点] 正在连接 : {} -> {}:{}", zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); } serverItem.setHookAliveInterval(zlmServerConfig.getHookAliveInterval()); @@ -418,7 +431,7 @@ public class MediaServerServiceImpl implements IMediaServerService { serverItem.setStatus(true); if (ObjectUtils.isEmpty(serverItem.getId())) { - logger.warn("[未注册的zlm] serverItem缺少ID, 无法接入:{}:{}", zlmServerConfig.getIp(),zlmServerConfig.getHttpPort() ); + logger.warn("[未注册的媒体服务节点] serverItem缺少ID, 无法接入:{}:{}", zlmServerConfig.getIp(),zlmServerConfig.getHttpPort() ); return; } mediaServerMapper.update(serverItem); @@ -436,9 +449,9 @@ public class MediaServerServiceImpl implements IMediaServerService { final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId(); dynamicTask.stop(zlmKeepaliveKey); dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (serverItem.getHookAliveInterval().intValue() + 5) * 1000); - publisher.zlmOnlineEventPublish(serverItem.getId()); + publisher.mediaServerOnlineEventPublish(serverItem.getId()); - logger.info("[ZLM] 连接成功 {} - {}:{} ", + logger.info("[媒体服务节点] 连接成功 {} - {}:{} ", zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); } @@ -452,12 +465,12 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public void run() { - logger.info("[zlm心跳到期]:" + serverItem.getId()); + logger.info("[媒体服务节点心跳到期]:" + serverItem.getId()); // 发起http请求验证zlm是否确实无法连接,如果确实无法连接则发送离线事件,否则不作处理 JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(serverItem); if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) { - logger.info("[zlm心跳到期]:{}验证后zlm仍在线,恢复心跳信息,请检查zlm是否可以正常向wvp发送心跳", serverItem.getId()); - // 添加zlm信息 + logger.info("[媒体服务节点心跳到期]:{}验证后媒体服务节点仍在线,恢复心跳信息,请检查媒体服务节点是否可以正常向wvp发送心跳", serverItem.getId()); + // 添加媒体服务节点信息 updateMediaServerKeepalive(serverItem.getId(), null); }else { publisher.zlmOfflineEventPublish(serverItem.getId()); @@ -556,13 +569,13 @@ public class MediaServerServiceImpl implements IMediaServerService { } /** - * 对zlm服务器进行基础配置 + * 对媒体服务节点服务器进行基础配置 * @param mediaServerItem 服务ID - * @param restart 是否重启zlm + * @param restart 是否重启媒体服务节点 */ @Override public void setZLMConfig(MediaServerItem mediaServerItem, boolean restart) { - logger.info("[ZLM] 正在设置 :{} -> {}:{}", + logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); String protocol = sslEnabled ? "https" : "http"; String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); @@ -612,17 +625,17 @@ public class MediaServerServiceImpl implements IMediaServerService { if (responseJSON != null && responseJSON.getInteger("code") == 0) { if (restart) { - logger.info("[ZLM] 设置成功,开始重启以保证配置生效 {} -> {}:{}", + logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); zlmresTfulUtils.restartServer(mediaServerItem); }else { - logger.info("[ZLM] 设置成功 {} -> {}:{}", + logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); } }else { - logger.info("[ZLM] 设置zlm失败 {} -> {}:{}", + logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); } @@ -701,11 +714,11 @@ public class MediaServerServiceImpl implements IMediaServerService { // 缓存不存在,从数据库查询,如果数据库不存在则是错误的 mediaServerItem = getOneFromDatabase(mediaServerId); if (mediaServerItem == null) { - logger.warn("[更新ZLM 保活信息] 流媒体{}尚未加入使用,请检查节点中是否含有此流媒体 ", mediaServerId); + logger.warn("[更新媒体服务节点 保活信息] 流媒体{}尚未加入使用,请检查节点中是否含有此流媒体 ", mediaServerId); return; } - // zlm连接重试 - logger.warn("[更新ZLM 保活信息]尝试链接zml id {}", mediaServerId); + // 媒体服务节点连接重试 + logger.warn("[更新媒体服务节点 保活信息]尝试链接zml id {}", mediaServerId); ssrcFactory.initMediaServerSSRC(mediaServerItem.getId(), null); String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(); redisTemplate.opsForValue().set(key, mediaServerItem); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 72df8a053..1ac61bd1f 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index cbc5fde6e..686649cab 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java new file mode 100644 index 000000000..4b9013cfb --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -0,0 +1,9 @@ +package com.genersoft.iot.vmp.media.zlm; + +import com.genersoft.iot.vmp.media.IMediaNodeServerService; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +@Service("zlm") +public class ZLMMediaNodeServerService implements IMediaNodeServerService { +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java index 4a781f312..1d8c81be8 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java @@ -9,8 +9,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForServerStarted; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java index cebfec3b0..d00cfbe4a 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java @@ -85,6 +85,8 @@ public class MediaServerItem{ @Schema(description = "录像存储路径") private String recordPath; + @Schema(description = "类型: zlm/abl") + private String type; public MediaServerItem() { } @@ -318,4 +320,12 @@ public class MediaServerItem{ public void setRecordPath(String recordPath) { this.recordPath = recordPath; } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMEventAbstract.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerEventAbstract.java similarity index 71% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMEventAbstract.java rename to src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerEventAbstract.java index 8ffbddea0..66108fc90 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMEventAbstract.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerEventAbstract.java @@ -1,9 +1,8 @@ package com.genersoft.iot.vmp.media.zlm.event; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; import org.springframework.context.ApplicationEvent; -public abstract class ZLMEventAbstract extends ApplicationEvent { +public abstract class MediaServerEventAbstract extends ApplicationEvent { private static final long serialVersionUID = 1L; @@ -11,7 +10,7 @@ public abstract class ZLMEventAbstract extends ApplicationEvent { private String mediaServerId; - public ZLMEventAbstract(Object source) { + public MediaServerEventAbstract(Object source) { super(source); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOfflineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOfflineEvent.java new file mode 100755 index 000000000..de0ed3344 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOfflineEvent.java @@ -0,0 +1,11 @@ +package com.genersoft.iot.vmp.media.zlm.event; + +/** + * zlm离线事件类 + */ +public class MediaServerOfflineEvent extends MediaServerEventAbstract { + + public MediaServerOfflineEvent(Object source) { + super(source); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOnlineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOnlineEvent.java new file mode 100755 index 000000000..d3a746a5f --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOnlineEvent.java @@ -0,0 +1,11 @@ +package com.genersoft.iot.vmp.media.zlm.event; + +/** + * zlm在线事件 + */ +public class MediaServerOnlineEvent extends MediaServerEventAbstract { + + public MediaServerOnlineEvent(Object source) { + super(source); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java similarity index 83% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java rename to src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java index bad8e5605..c9a09d7bf 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMStatusEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.event; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IStreamPushService; @@ -20,9 +20,9 @@ import org.springframework.stereotype.Component; * @date: 2020年5月6日 下午1:51:23 */ @Component -public class ZLMStatusEventListener { +public class MediaServerStatusEventListener { - private final static Logger logger = LoggerFactory.getLogger(ZLMStatusEventListener.class); + private final static Logger logger = LoggerFactory.getLogger(MediaServerStatusEventListener.class); @Autowired private IStreamPushService streamPushService; @@ -38,7 +38,7 @@ public class ZLMStatusEventListener { @Async("taskExecutor") @EventListener - public void onApplicationEvent(ZLMOnlineEvent event) { + public void onApplicationEvent(MediaServerOnlineEvent event) { logger.info("[ZLM] 上线 ID:" + event.getMediaServerId()); streamPushService.zlmServerOnline(event.getMediaServerId()); streamProxyService.zlmServerOnline(event.getMediaServerId()); @@ -47,7 +47,7 @@ public class ZLMStatusEventListener { @Async("taskExecutor") @EventListener - public void onApplicationEvent(ZLMOfflineEvent event) { + public void onApplicationEvent(MediaServerOfflineEvent event) { logger.info("[ZLM] 离线,ID:" + event.getMediaServerId()); // 处理ZLM离线 diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOfflineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOfflineEvent.java deleted file mode 100755 index 8207bdd3b..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOfflineEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm.event; - -/** - * zlm离线事件类 - */ -public class ZLMOfflineEvent extends ZLMEventAbstract { - - public ZLMOfflineEvent(Object source) { - super(source); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOnlineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOnlineEvent.java deleted file mode 100755 index 612ff9d09..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/ZLMOnlineEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm.event; - -/** - * zlm在线事件 - */ -public class ZLMOnlineEvent extends ZLMEventAbstract { - - public ZLMOnlineEvent(Object source) { - super(source); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java index a23252f64..e18db682b 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.service.ICloudRecordService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index 1dc7db448..9a1a5b395 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 784f43f3d..cca27e8f6 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.service.impl; -import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; @@ -8,7 +7,7 @@ import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; @@ -22,13 +21,9 @@ public class MediaServiceImpl implements IMediaService { @Autowired private IRedisCatchStorage redisCatchStorage; - @Autowired - private IVideoManagerStorage storager; - @Autowired private IMediaServerService mediaServerService; - @Autowired private MediaConfig mediaConfig; @@ -36,7 +31,6 @@ public class MediaServiceImpl implements IMediaService { private ZLMRESTfulUtils zlmresTfulUtils; - @Override public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String callId) { return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null, callId, true); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 06c621e58..3bd01538b 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -15,14 +15,12 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.*; @@ -31,7 +29,6 @@ import com.genersoft.iot.vmp.storager.dao.*; import com.genersoft.iot.vmp.utils.DateUtil; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; -import gov.nist.javax.sip.message.SIPRequest; import gov.nist.javax.sip.message.SIPResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,17 +38,12 @@ import org.springframework.stereotype.Service; import javax.sdp.*; import javax.sip.InvalidArgumentException; import javax.sip.ResponseEvent; -import javax.sip.PeerUnavailableException; import javax.sip.SipException; import java.text.ParseException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; import java.util.*; /** diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index c8d203f49..0bde0cfbc 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -18,6 +18,7 @@ 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.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 59c5acef2..120222461 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -8,7 +8,6 @@ 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.ControllerException; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; @@ -19,13 +18,12 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; -import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper; import com.genersoft.iot.vmp.utils.DateUtil; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index e2d7e68c8..51bd3ded7 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index eb261e345..eedc2be4c 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 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.MediaServerItem; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.utils.redis.RedisUtil; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java index 1d7c2fd50..f47bd1f74 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java index 65239c8f0..13edaee92 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java @@ -5,7 +5,7 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.utils.DateUtil; import org.slf4j.Logger; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java index b3d199088..b4552b7d9 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -1,15 +1,11 @@ package com.genersoft.iot.vmp.vmanager.cloudRecord; import com.alibaba.fastjson2.JSONArray; -import com.genersoft.iot.vmp.conf.DynamicTask; -import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; -import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.ICloudRecordService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; @@ -22,7 +18,6 @@ import org.apache.commons.lang3.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index ca8cbcf8d..04245b169 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index dbbc7b0bc..5b1589e42 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index 5bd4b9dca..208c58c19 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index d1c72fc0a..7a417c833 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.VersionInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index 956500048..bcc205c86 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java index 8202bf5aa..d10a2845b 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.media.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler; diff --git a/数据库/abl/初始化-mysql-2.7.0.sql b/数据库/abl/初始化-mysql-2.7.0.sql new file mode 100644 index 000000000..7fece768a --- /dev/null +++ b/数据库/abl/初始化-mysql-2.7.0.sql @@ -0,0 +1,325 @@ +/*建表*/ +create table wvp_device ( + id serial primary key , + device_id character varying(50) not null , + name character varying(255), + manufacturer character varying(255), + model character varying(255), + firmware character varying(255), + transport character varying(50), + stream_mode character varying(50), + on_line bool default false, + register_time character varying(50), + keepalive_time character varying(50), + ip character varying(50), + create_time character varying(50), + update_time character varying(50), + port integer, + expires integer, + subscribe_cycle_for_catalog integer DEFAULT 0, + subscribe_cycle_for_mobile_position integer DEFAULT 0, + mobile_position_submission_interval integer DEFAULT 5, + subscribe_cycle_for_alarm integer DEFAULT 0, + host_address character varying(50), + charset character varying(50), + ssrc_check bool default false, + geo_coord_sys character varying(50), + media_server_id character varying(50), + custom_name character varying(255), + sdp_ip character varying(50), + local_ip character varying(50), + password character varying(255), + as_message_channel bool default false, + keepalive_interval_time integer, + switch_primary_sub_stream bool default false, + broadcast_push_after_ack bool default false, + constraint uk_device_device unique (device_id) +); + +create table wvp_device_alarm ( + id serial primary key , + device_id character varying(50) not null, + channel_id character varying(50) not null, + alarm_priority character varying(50), + alarm_method character varying(50), + alarm_time character varying(50), + alarm_description character varying(255), + longitude double precision, + latitude double precision, + alarm_type character varying(50), + create_time character varying(50) not null +); + +create table wvp_device_channel ( + id serial primary key , + channel_id character varying(50) not null, + name character varying(255), + custom_name character varying(255), + manufacture character varying(50), + model character varying(50), + owner character varying(50), + civil_code character varying(50), + block character varying(50), + address character varying(50), + parent_id character varying(50), + safety_way integer, + register_way integer, + cert_num character varying(50), + certifiable integer, + err_code integer, + end_time character varying(50), + secrecy character varying(50), + ip_address character varying(50), + port integer, + password character varying(255), + ptz_type integer, + custom_ptz_type integer, + status bool default false, + longitude double precision, + custom_longitude double precision, + latitude double precision, + custom_latitude double precision, + stream_id character varying(255), + device_id character varying(50) not null, + parental character varying(50), + has_audio bool default false, + create_time character varying(50) not null, + update_time character varying(50) not null, + sub_count integer, + longitude_gcj02 double precision, + latitude_gcj02 double precision, + longitude_wgs84 double precision, + latitude_wgs84 double precision, + business_group_id character varying(50), + gps_time character varying(50), + stream_identification character varying(50), + constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) +); + +create table wvp_device_mobile_position ( + id serial primary key, + device_id character varying(50) not null, + channel_id character varying(50) not null, + device_name character varying(255), + time character varying(50), + longitude double precision, + latitude double precision, + altitude double precision, + speed double precision, + direction double precision, + report_source character varying(50), + longitude_gcj02 double precision, + latitude_gcj02 double precision, + longitude_wgs84 double precision, + latitude_wgs84 double precision, + create_time character varying(50) +); + +create table wvp_gb_stream ( + gb_stream_id serial primary key, + app character varying(255) not null, + stream character varying(255) not null, + gb_id character varying(50) not null, + name character varying(255), + longitude double precision, + latitude double precision, + stream_type character varying(50), + media_server_id character varying(50), + create_time character varying(50), + constraint uk_gb_stream_unique_gb_id unique (gb_id), + constraint uk_gb_stream_unique_app_stream unique (app, stream) +); + +create table wvp_log ( + id serial primary key , + name character varying(50), + type character varying(50), + uri character varying(200), + address character varying(50), + result character varying(50), + timing bigint, + username character varying(50), + create_time character varying(50) +); + +create table wvp_media_server ( + id character varying(255) primary key , + ip character varying(50), + hook_ip character varying(50), + sdp_ip character varying(50), + stream_ip character varying(50), + http_port integer, + http_ssl_port integer, + rtmp_port integer, + rtmp_ssl_port integer, + rtp_proxy_port integer, + rtsp_port integer, + rtsp_ssl_port integer, + auto_config bool default false, + secret character varying(50), + type character varying(50) default 'zlm', + rtp_enable bool default false, + rtp_port_range character varying(50), + send_rtp_port_range character varying(50), + record_assist_port integer, + default_server bool default false, + create_time character varying(50), + update_time character varying(50), + hook_alive_interval integer, + record_path character varying(255), + record_day integer default 7, + constraint uk_media_server_unique_ip_http_port unique (ip, http_port) +); + +create table wvp_platform ( + id serial primary key , + enable bool default false, + name character varying(255), + server_gb_id character varying(50), + server_gb_domain character varying(50), + server_ip character varying(50), + server_port integer, + device_gb_id character varying(50), + device_ip character varying(50), + device_port character varying(50), + username character varying(255), + password character varying(50), + expires character varying(50), + keep_timeout character varying(50), + transport character varying(50), + character_set character varying(50), + catalog_id character varying(50), + ptz bool default false, + rtcp bool default false, + status bool default false, + start_offline_push bool default false, + administrative_division character varying(50), + catalog_group integer, + create_time character varying(50), + update_time character varying(50), + as_message_channel bool default false, + auto_push_channel bool default false, + constraint uk_platform_unique_server_gb_id unique (server_gb_id) +); + +create table wvp_platform_catalog ( + id character varying(50), + platform_id character varying(50), + name character varying(255), + parent_id character varying(50), + civil_code character varying(50), + business_group_id character varying(50), + constraint uk_platform_catalog_id_platform_id unique (id, platform_id) +); + +create table wvp_platform_gb_channel ( + id serial primary key , + platform_id character varying(50), + catalog_id character varying(50), + device_channel_id integer, + constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id) +); + +create table wvp_platform_gb_stream ( + id serial primary key, + platform_id character varying(50), + catalog_id character varying(50), + gb_stream_id integer, + constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id) +); + +create table wvp_stream_proxy ( + id serial primary key, + type character varying(50), + app character varying(255), + stream character varying(255), + url character varying(255), + src_url character varying(255), + dst_url character varying(255), + timeout_ms integer, + ffmpeg_cmd_key character varying(255), + rtp_type character varying(50), + media_server_id character varying(50), + enable_audio bool default false, + enable_mp4 bool default false, + enable bool default false, + status boolean, + enable_remove_none_reader bool default false, + create_time character varying(50), + name character varying(255), + update_time character varying(50), + stream_key character varying(255), + enable_disable_none_reader bool default false, + constraint uk_stream_proxy_app_stream unique (app, stream) +); + +create table wvp_stream_push ( + id serial primary key, + app character varying(255), + stream character varying(255), + total_reader_count character varying(50), + origin_type integer, + origin_type_str character varying(50), + create_time character varying(50), + alive_second integer, + media_server_id character varying(50), + server_id character varying(50), + push_time character varying(50), + status bool default false, + update_time character varying(50), + push_ing bool default false, + self bool default false, + constraint uk_stream_push_app_stream unique (app, stream) +); +create table wvp_cloud_record ( + id serial primary key, + app character varying(255), + stream character varying(255), + call_id character varying(255), + start_time bigint, + end_time bigint, + media_server_id character varying(50), + file_name character varying(255), + folder character varying(255), + file_path character varying(255), + collect bool default false, + file_size bigint, + time_len bigint, + constraint uk_stream_push_app_stream_path unique (app, stream, file_path) +); + +create table wvp_user ( + id serial primary key, + username character varying(255), + password character varying(255), + role_id integer, + create_time character varying(50), + update_time character varying(50), + push_key character varying(50), + constraint uk_user_username unique (username) +); + +create table wvp_user_role ( + id serial primary key, + name character varying(50), + authority character varying(50), + create_time character varying(50), + update_time character varying(50) +); +create table wvp_resources_tree ( + id serial primary key , + is_catalog bool default true, + device_channel_id integer , + gb_stream_id integer, + name character varying(255), + parentId integer, + path character varying(255) +); + + +/*初始数据*/ +INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); +INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); + + + diff --git a/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql b/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql new file mode 100644 index 000000000..656f7a006 --- /dev/null +++ b/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql @@ -0,0 +1,325 @@ +/*建表*/ +create table wvp_device ( + id serial primary key , + device_id character varying(50) not null , + name character varying(255), + manufacturer character varying(255), + model character varying(255), + firmware character varying(255), + transport character varying(50), + stream_mode character varying(50), + on_line bool default false, + register_time character varying(50), + keepalive_time character varying(50), + ip character varying(50), + create_time character varying(50), + update_time character varying(50), + port integer, + expires integer, + subscribe_cycle_for_catalog integer DEFAULT 0, + subscribe_cycle_for_mobile_position integer DEFAULT 0, + mobile_position_submission_interval integer DEFAULT 5, + subscribe_cycle_for_alarm integer DEFAULT 0, + host_address character varying(50), + charset character varying(50), + ssrc_check bool default false, + geo_coord_sys character varying(50), + media_server_id character varying(50), + custom_name character varying(255), + sdp_ip character varying(50), + local_ip character varying(50), + password character varying(255), + as_message_channel bool default false, + keepalive_interval_time integer, + switch_primary_sub_stream bool default false, + broadcast_push_after_ack bool default false, + constraint uk_device_device unique (device_id) +); + +create table wvp_device_alarm ( + id serial primary key , + device_id character varying(50) not null, + channel_id character varying(50) not null, + alarm_priority character varying(50), + alarm_method character varying(50), + alarm_time character varying(50), + alarm_description character varying(255), + longitude double precision, + latitude double precision, + alarm_type character varying(50), + create_time character varying(50) not null +); + +create table wvp_device_channel ( + id serial primary key , + channel_id character varying(50) not null, + name character varying(255), + custom_name character varying(255), + manufacture character varying(50), + model character varying(50), + owner character varying(50), + civil_code character varying(50), + block character varying(50), + address character varying(50), + parent_id character varying(50), + safety_way integer, + register_way integer, + cert_num character varying(50), + certifiable integer, + err_code integer, + end_time character varying(50), + secrecy character varying(50), + ip_address character varying(50), + port integer, + password character varying(255), + ptz_type integer, + custom_ptz_type integer, + status bool default false, + longitude double precision, + custom_longitude double precision, + latitude double precision, + custom_latitude double precision, + stream_id character varying(255), + device_id character varying(50) not null, + parental character varying(50), + has_audio bool default false, + create_time character varying(50) not null, + update_time character varying(50) not null, + sub_count integer, + longitude_gcj02 double precision, + latitude_gcj02 double precision, + longitude_wgs84 double precision, + latitude_wgs84 double precision, + business_group_id character varying(50), + gps_time character varying(50), + stream_identification character varying(50), + constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) +); + +create table wvp_device_mobile_position ( + id serial primary key, + device_id character varying(50) not null, + channel_id character varying(50) not null, + device_name character varying(255), + time character varying(50), + longitude double precision, + latitude double precision, + altitude double precision, + speed double precision, + direction double precision, + report_source character varying(50), + longitude_gcj02 double precision, + latitude_gcj02 double precision, + longitude_wgs84 double precision, + latitude_wgs84 double precision, + create_time character varying(50) +); + +create table wvp_gb_stream ( + gb_stream_id serial primary key, + app character varying(255) not null, + stream character varying(255) not null, + gb_id character varying(50) not null, + name character varying(255), + longitude double precision, + latitude double precision, + stream_type character varying(50), + media_server_id character varying(50), + create_time character varying(50), + constraint uk_gb_stream_unique_gb_id unique (gb_id), + constraint uk_gb_stream_unique_app_stream unique (app, stream) +); + +create table wvp_log ( + id serial primary key , + name character varying(50), + type character varying(50), + uri character varying(200), + address character varying(50), + result character varying(50), + timing bigint, + username character varying(50), + create_time character varying(50) +); + +create table wvp_media_server ( + id character varying(255) primary key , + ip character varying(50), + hook_ip character varying(50), + sdp_ip character varying(50), + stream_ip character varying(50), + http_port integer, + http_ssl_port integer, + rtmp_port integer, + rtmp_ssl_port integer, + rtp_proxy_port integer, + rtsp_port integer, + rtsp_ssl_port integer, + auto_config bool default false, + secret character varying(50), + type character varying(50) default 'zlm', + rtp_enable bool default false, + rtp_port_range character varying(50), + send_rtp_port_range character varying(50), + record_assist_port integer, + default_server bool default false, + create_time character varying(50), + update_time character varying(50), + hook_alive_interval integer, + record_path character varying(255), + record_day integer default 7, + constraint uk_media_server_unique_ip_http_port unique (ip, http_port) +); + +create table wvp_platform ( + id serial primary key , + enable bool default false, + name character varying(255), + server_gb_id character varying(50), + server_gb_domain character varying(50), + server_ip character varying(50), + server_port integer, + device_gb_id character varying(50), + device_ip character varying(50), + device_port character varying(50), + username character varying(255), + password character varying(50), + expires character varying(50), + keep_timeout character varying(50), + transport character varying(50), + character_set character varying(50), + catalog_id character varying(50), + ptz bool default false, + rtcp bool default false, + status bool default false, + start_offline_push bool default false, + administrative_division character varying(50), + catalog_group integer, + create_time character varying(50), + update_time character varying(50), + as_message_channel bool default false, + auto_push_channel bool default false, + constraint uk_platform_unique_server_gb_id unique (server_gb_id) +); + +create table wvp_platform_catalog ( + id character varying(50), + platform_id character varying(50), + name character varying(255), + parent_id character varying(50), + civil_code character varying(50), + business_group_id character varying(50), + constraint uk_platform_catalog_id_platform_id unique (id, platform_id) +); + +create table wvp_platform_gb_channel ( + id serial primary key , + platform_id character varying(50), + catalog_id character varying(50), + device_channel_id integer, + constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id) +); + +create table wvp_platform_gb_stream ( + id serial primary key, + platform_id character varying(50), + catalog_id character varying(50), + gb_stream_id integer, + constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id) +); + +create table wvp_stream_proxy ( + id serial primary key, + type character varying(50), + app character varying(255), + stream character varying(255), + url character varying(255), + src_url character varying(255), + dst_url character varying(255), + timeout_ms integer, + ffmpeg_cmd_key character varying(255), + rtp_type character varying(50), + media_server_id character varying(50), + enable_audio bool default false, + enable_mp4 bool default false, + enable bool default false, + status boolean, + enable_remove_none_reader bool default false, + create_time character varying(50), + name character varying(255), + update_time character varying(50), + stream_key character varying(255), + enable_disable_none_reader bool default false, + constraint uk_stream_proxy_app_stream unique (app, stream) +); + +create table wvp_stream_push ( + id serial primary key, + app character varying(255), + stream character varying(255), + total_reader_count character varying(50), + origin_type integer, + origin_type_str character varying(50), + create_time character varying(50), + alive_second integer, + media_server_id character varying(50), + server_id character varying(50), + push_time character varying(50), + status bool default false, + update_time character varying(50), + push_ing bool default false, + self bool default false, + constraint uk_stream_push_app_stream unique (app, stream) +); +create table wvp_cloud_record ( + id serial primary key, + app character varying(255), + stream character varying(255), + call_id character varying(255), + start_time int8, + end_time int8, + media_server_id character varying(50), + file_name character varying(255), + folder character varying(255), + file_path character varying(255), + collect bool default false, + file_size int8, + time_len int8, + constraint uk_stream_push_app_stream_path unique (app, stream, file_path) +); + +create table wvp_user ( + id serial primary key, + username character varying(255), + password character varying(255), + role_id integer, + create_time character varying(50), + update_time character varying(50), + push_key character varying(50), + constraint uk_user_username unique (username) +); + +create table wvp_user_role ( + id serial primary key, + name character varying(50), + authority character varying(50), + create_time character varying(50), + update_time character varying(50) +); +create table wvp_resources_tree ( + id serial primary key , + is_catalog bool default true, + device_channel_id integer , + gb_stream_id integer, + name character varying(255), + parentId integer, + path character varying(255) +); + + +/*初始数据*/ +INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); +INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); + + + diff --git a/数据库/abl/更新-mysql-2.7.0.sql b/数据库/abl/更新-mysql-2.7.0.sql new file mode 100644 index 000000000..2b38f06dd --- /dev/null +++ b/数据库/abl/更新-mysql-2.7.0.sql @@ -0,0 +1,2 @@ +alter table wvp_media_server + add type character varying(50) default 'zlm',; diff --git a/数据库/abl/更新-postgresql-kingbase-2.7.0.sql b/数据库/abl/更新-postgresql-kingbase-2.7.0.sql new file mode 100644 index 000000000..45f695938 --- /dev/null +++ b/数据库/abl/更新-postgresql-kingbase-2.7.0.sql @@ -0,0 +1,2 @@ +alter table wvp_media_server + add type character varying(50) default 'zlm',; \ No newline at end of file From 620a4803da1fa01ef02e17f4a9d5a997a7aa4830 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 18 Mar 2024 23:56:27 +0800 Subject: [PATCH 02/58] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=90=8E=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/IMediaNodeServerService.java | 4 +- .../media/abl/ABLMediaNodeServerService.java | 37 +++++++++++ .../media/impl/MediaServerServiceImpl.java | 3 + .../media/zlm/ZLMMediaNodeServerService.java | 62 +++++++++++++++++++ 4 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java index c72c7e232..992379d66 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java @@ -10,9 +10,9 @@ public interface IMediaNodeServerService { void closeRtpServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback); - void closeStreams(MediaServerItem mediaServerItem, String rtp, String streamId); + void closeStreams(MediaServerItem mediaServerItem, String app, String stream); - Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc); + Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String stream, String ssrc); boolean checkNodeId(MediaServerItem mediaServerItem); diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index 6e86153d9..0c65b2fcf 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -1,8 +1,45 @@ package com.genersoft.iot.vmp.media.abl; +import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.media.IMediaNodeServerService; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.springframework.stereotype.Service; @Service("abl") public class ABLMediaNodeServerService implements IMediaNodeServerService { + + @Override + public int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { + return 0; + } + + @Override + public void closeRtpServer(MediaServerItem mediaServerItem, String streamId) { + + } + + @Override + public void closeRtpServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback) { + + } + + @Override + public void closeStreams(MediaServerItem mediaServerItem, String rtp, String streamId) { + + } + + @Override + public Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) { + return null; + } + + @Override + public boolean checkNodeId(MediaServerItem mediaServerItem) { + return false; + } + + @Override + public void online(MediaServerItem mediaServerItem) { + + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java index 4e8ed274d..4a03f1ea2 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java @@ -352,6 +352,9 @@ public class MediaServerServiceImpl implements IMediaServerService { logger.info("[添加媒体节点] 失败, mediaServerItem的类型:为空"); return; } + if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败,媒体服务ID [ " + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); + } IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); if (mediaNodeServerService == null) { logger.info("[添加媒体节点] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 4b9013cfb..7694967b0 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -1,9 +1,71 @@ package com.genersoft.iot.vmp.media.zlm; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.media.IMediaNodeServerService; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @Service("zlm") public class ZLMMediaNodeServerService implements IMediaNodeServerService { + + @Autowired + private ZLMRESTfulUtils zlmresTfulUtils; + + @Autowired + private ZLMServerFactory zlmServerFactory; + + @Override + public int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { + return zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode);; + } + + @Override + public void closeRtpServer(MediaServerItem mediaServerItem, String streamId) { + zlmresTfulUtils.closeStreams(mediaServerItem, "rtp", streamId); + } + + @Override + public void closeRtpServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback) { + zlmServerFactory.closeRtpServer(mediaServerItem, streamId, callback); + } + + @Override + public void closeStreams(MediaServerItem mediaServerItem, String app, String stream) { + zlmresTfulUtils.closeStreams(mediaServerItem, app, stream); + } + + @Override + public Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) { + return zlmServerFactory.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); + } + + @Override + public boolean checkNodeId(MediaServerItem mediaServerItem) { + if (mediaServerItem == null) { + return false; + } + JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); + if (responseJSON != null) { + JSONArray data = responseJSON.getJSONArray("data"); + if (data != null && !data.isEmpty()) { + ZLMServerConfig zlmServerConfig= JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); + return zlmServerConfig.getGeneralMediaServerId().equals(mediaServerItem.getId()); + }else { + return false; + } + + }else { + return false; + } + } + + @Override + public void online(MediaServerItem mediaServerItem) { + + } } From 1e0b73b9392592aa36e66cf63c359ab6331f8448 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 19 Mar 2024 17:52:11 +0800 Subject: [PATCH 03/58] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/conf/CloudRecordTimer.java | 2 +- .../iot/vmp/conf/ProxyServletConfig.java | 2 +- .../iot/vmp/gb28181/task/SipRunner.java | 2 +- .../transmit/cmd/impl/SIPCommander.java | 2 +- .../cmd/impl/SIPCommanderFroPlatform.java | 2 +- .../request/impl/AckRequestProcessor.java | 2 +- .../request/impl/ByeRequestProcessor.java | 2 +- .../request/impl/InviteRequestProcessor.java | 2 +- .../cmd/BroadcastNotifyMessageHandler.java | 2 +- .../ZLMRunner.java => MediaServerConfig.java} | 26 +++++++++++++------ .../media/abl/ABLMediaNodeServerService.java | 2 +- .../IMediaNodeServerService.java | 2 +- .../{ => service}/IMediaServerService.java | 3 +-- .../impl/MediaServerServiceImpl.java | 6 ++--- .../vmp/media/zlm/ZLMHttpHookListener.java | 2 +- .../vmp/media/zlm/ZLMMediaListManager.java | 2 +- .../media/zlm/ZLMMediaNodeServerService.java | 3 +-- .../event/MediaServerStatusEventListener.java | 2 +- .../service/impl/CloudRecordServiceImpl.java | 2 +- .../vmp/service/impl/DeviceServiceImpl.java | 2 +- .../vmp/service/impl/MediaServiceImpl.java | 3 +-- .../vmp/service/impl/PlatformServiceImpl.java | 2 +- .../iot/vmp/service/impl/PlayServiceImpl.java | 2 +- .../service/impl/StreamProxyServiceImpl.java | 2 +- .../service/impl/StreamPushServiceImpl.java | 2 +- .../redisMsg/RedisGbPlayMsgListener.java | 2 +- .../RedisPushStreamCloseResponseListener.java | 2 +- .../RedisPushStreamStatusListMsgListener.java | 2 +- .../cloudRecord/CloudRecordController.java | 2 +- .../vmanager/gb28181/play/PlayController.java | 2 +- .../iot/vmp/vmanager/ps/PsController.java | 2 +- .../iot/vmp/vmanager/rtp/RtpController.java | 2 +- .../vmp/vmanager/server/ServerController.java | 2 +- .../streamProxy/StreamProxyController.java | 2 +- .../streamPush/StreamPushController.java | 2 +- 35 files changed, 54 insertions(+), 47 deletions(-) rename src/main/java/com/genersoft/iot/vmp/media/{zlm/ZLMRunner.java => MediaServerConfig.java} (91%) rename src/main/java/com/genersoft/iot/vmp/media/{ => service}/IMediaNodeServerService.java (94%) rename src/main/java/com/genersoft/iot/vmp/media/{ => service}/IMediaServerService.java (96%) rename src/main/java/com/genersoft/iot/vmp/media/{ => service}/impl/MediaServerServiceImpl.java (99%) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java index 92e7f51f1..e5ab4cf29 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java @@ -4,7 +4,7 @@ package com.genersoft.iot.vmp.conf; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper; import org.slf4j.Logger; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java index dbab513d1..560cae21f 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.conf; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java index 010f1140c..852db420c 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.service.impl.PlatformServiceImpl; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 91595f8dc..cb156a8c8 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -25,7 +25,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamPush; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.message.SIPRequest; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 7c9036b05..f2869855f 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index 37ae5b670..e6d8fc127 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg; import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java index 36f9d6bdf..dda53d0b4 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.*; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index f75cc4d7f..4157fc83f 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -18,7 +18,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java index e7191bf47..fe19ec622 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java similarity index 91% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java rename to src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java index 1d8c81be8..e578f03a0 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm; +package com.genersoft.iot.vmp.media; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; @@ -6,10 +6,13 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; +import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; +import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForServerStarted; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -26,14 +29,14 @@ import java.util.concurrent.ConcurrentHashMap; @Component @Order(value=12) -public class ZLMRunner implements CommandLineRunner { +public class MediaServerConfig implements CommandLineRunner { - private final static Logger logger = LoggerFactory.getLogger(ZLMRunner.class); + private final static Logger logger = LoggerFactory.getLogger(MediaServerConfig.class); private Map startGetMedia; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; +// @Autowired +// private ZLMRESTfulUtils zlmresTfulUtils; @Autowired private ZlmHttpHookSubscribe hookSubscribe; @@ -57,20 +60,27 @@ public class ZLMRunner implements CommandLineRunner { MediaServerItem defaultMediaServer = mediaServerService.getDefaultMediaServer(); if (defaultMediaServer == null) { mediaServerService.addToDatabase(mediaConfig.getMediaSerItem()); + // 发送媒体节点增加事件 }else { MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem(); mediaServerService.updateToDatabase(mediaSerItem); + // 发送媒体节点更新事件 + } mediaServerService.syncCatchFromDatabase(); + + + + HookSubscribeForServerStarted hookSubscribeForServerStarted = HookSubscribeFactory.on_server_started(); - // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 + // 订阅 媒体节点启动事件, 新的媒体节点也会从这里进入系统 hookSubscribe.addSubscribe(hookSubscribeForServerStarted, (mediaServerItem, hookParam)->{ ZLMServerConfig zlmServerConfig = (ZLMServerConfig)hookParam; if (zlmServerConfig !=null ) { if (startGetMedia != null) { startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId()); - if (startGetMedia.size() == 0) { + if (startGetMedia.isEmpty()) { hookSubscribe.removeSubscribe(HookSubscribeFactory.on_server_started()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index 0c65b2fcf..cbce1d6bb 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.media.abl; import com.genersoft.iot.vmp.common.CommonCallback; -import com.genersoft.iot.vmp.media.IMediaNodeServerService; +import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java similarity index 94% rename from src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java rename to src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 992379d66..cc8b66b8c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media; +package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; diff --git a/src/main/java/com/genersoft/iot/vmp/media/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java similarity index 96% rename from src/main/java/com/genersoft/iot/vmp/media/IMediaServerService.java rename to src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 49203d2c2..d1b0eff0b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media; +package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; @@ -6,7 +6,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; -import com.genersoft.iot.vmp.vmanager.bean.RecordFile; import java.util.List; diff --git a/src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java similarity index 99% rename from src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java rename to src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 4a03f1ea2..85969de07 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.impl; +package com.genersoft.iot.vmp.media.service.impl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; @@ -12,12 +12,12 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; -import com.genersoft.iot.vmp.media.IMediaNodeServerService; +import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.*; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 1ac61bd1f..23123331a 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -18,7 +18,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 686649cab..0c15be172 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 7694967b0..650016f7d 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -4,10 +4,9 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; -import com.genersoft.iot.vmp.media.IMediaNodeServerService; +import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @Service("zlm") diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java index c9a09d7bf..fe5dfc98b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.event; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IStreamPushService; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java index e18db682b..aabdb8afe 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.service.ICloudRecordService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index 9a1a5b395..616c7627b 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index cca27e8f6..65fbfe04b 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -7,10 +7,9 @@ import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 3bd01538b..fc2c8fd2e 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -20,7 +20,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.*; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 0bde0cfbc..48910ef7b 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -18,7 +18,7 @@ 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.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 120222461..2eb3da980 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -18,7 +18,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index 51bd3ded7..14f0fe2a9 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index eedc2be4c..fb6f06869 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 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.MediaServerItem; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.utils.redis.RedisUtil; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java index f47bd1f74..f741a1052 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java index 13edaee92..44b168b78 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java @@ -5,7 +5,7 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.utils.DateUtil; import org.slf4j.Logger; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java index b4552b7d9..926d8a678 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.ICloudRecordService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index 04245b169..d24ad372f 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index 5b1589e42..21a19f23c 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index 208c58c19..5b73d0a97 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index 7a417c833..65cb8a650 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.VersionInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index bcc205c86..f69048528 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java index d10a2845b..459f3cc87 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; -import com.genersoft.iot.vmp.media.IMediaServerService; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler; From ad32da0dfd04ca533d363674e007ea6b04eb3c0f Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 19 Mar 2024 18:29:58 +0800 Subject: [PATCH 04/58] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/MediaServerConfig.java | 18 ++++++------ .../media/event/MediaServerChangeEvent.java | 21 ++++++++++++++ .../media/service/IMediaServerService.java | 2 +- .../service/impl/MediaServerServiceImpl.java | 1 + .../vmp/media/zlm/ZLMHttpHookListener.java | 5 +--- .../media/zlm/ZLMMediaNodeServerService.java | 1 + .../media/zlm/ZLMMediaServerStatusManger.java | 29 +++++++++++++++++++ .../vmp/media/zlm/dto/MediaServerItem.java | 1 - .../media/zlm/{ => dto}/ZLMServerConfig.java | 2 +- 9 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java rename src/main/java/com/genersoft/iot/vmp/media/zlm/{ => dto}/ZLMServerConfig.java (99%) diff --git a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java index e578f03a0..937396858 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java @@ -6,8 +6,8 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; +import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForServerStarted; @@ -17,6 +17,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.annotation.Order; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @@ -35,8 +36,8 @@ public class MediaServerConfig implements CommandLineRunner { private Map startGetMedia; -// @Autowired -// private ZLMRESTfulUtils zlmresTfulUtils; + @Autowired + private ApplicationEventPublisher applicationEventPublisher; @Autowired private ZlmHttpHookSubscribe hookSubscribe; @@ -60,16 +61,15 @@ public class MediaServerConfig implements CommandLineRunner { MediaServerItem defaultMediaServer = mediaServerService.getDefaultMediaServer(); if (defaultMediaServer == null) { mediaServerService.addToDatabase(mediaConfig.getMediaSerItem()); - // 发送媒体节点增加事件 }else { MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem(); mediaServerService.updateToDatabase(mediaSerItem); - // 发送媒体节点更新事件 - } + // 发送媒体节点变化事件 mediaServerService.syncCatchFromDatabase(); - - + MediaServerChangeEvent event = new MediaServerChangeEvent(this); + applicationEventPublisher.publishEvent(event); + // TODO 此处以下代码弃用 HookSubscribeForServerStarted hookSubscribeForServerStarted = HookSubscribeFactory.on_server_started(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java new file mode 100644 index 000000000..6cf8bbfc3 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java @@ -0,0 +1,21 @@ +package com.genersoft.iot.vmp.media.event; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import org.springframework.context.ApplicationEvent; + +public class MediaServerChangeEvent extends ApplicationEvent { + + public MediaServerChangeEvent(Object source) { + super(source); + } + + private MediaServerItem mediaServerItem; + + public MediaServerItem getMediaServerItem() { + return mediaServerItem; + } + + public void setMediaServerItem(MediaServerItem mediaServerItem) { + this.mediaServerItem = mediaServerItem; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index d1b0eff0b..0af9ba10b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; +import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 85969de07..2c421bad0 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.*; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData; +import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 23123331a..9bab37210 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -19,10 +19,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.HookType; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; +import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 650016f7d..510a972c0 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -6,6 +6,7 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java new file mode 100644 index 000000000..6799cb7f7 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -0,0 +1,29 @@ +package com.genersoft.iot.vmp.media.zlm; + +import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; + +/** + * 管理zlm流媒体节点的状态 + */ +public class ZLMMediaServerStatusManger { + + private final static Logger logger = LoggerFactory.getLogger(ZLMMediaServerStatusManger.class); + + private final String type = "zlm"; + + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaServerChangeEvent event) { + if (event.getMediaServerItem() == null + || !type.equals(event.getMediaServerItem().getType()) + || event.getMediaServerItem().isStatus()) { + return; + } + logger.info("[ZLM 待上线节点变化] ID:" + event.getMediaServerItem().getId()); + + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java index d00cfbe4a..511b953ab 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.dto; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ZLMServerConfig.java similarity index 99% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java rename to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ZLMServerConfig.java index 80910c026..8f77b6323 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ZLMServerConfig.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm; +package com.genersoft.iot.vmp.media.zlm.dto; import com.alibaba.fastjson2.annotation.JSONField; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; From 4a0e9945b40e237aabd1cc41d180ca35355439ac Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 19 Mar 2024 18:47:55 +0800 Subject: [PATCH 05/58] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../media/zlm/ZLMMediaServerStatusManger.java | 26 +++++++++++++++++++ .../zlm/event/HookZlmServerStartEvent.java | 24 +++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index 6799cb7f7..bf396900a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -1,10 +1,16 @@ package com.genersoft.iot.vmp.media.zlm; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * 管理zlm流媒体节点的状态 @@ -13,6 +19,8 @@ public class ZLMMediaServerStatusManger { private final static Logger logger = LoggerFactory.getLogger(ZLMMediaServerStatusManger.class); + private Map offlineZlmMap = new ConcurrentHashMap<>(); + private final String type = "zlm"; @Async("taskExecutor") @@ -24,6 +32,24 @@ public class ZLMMediaServerStatusManger { return; } logger.info("[ZLM 待上线节点变化] ID:" + event.getMediaServerItem().getId()); + offlineZlmMap.put(event.getMediaServerItem().getId(), event.getMediaServerItem()); + } + + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(HookZlmServerStartEvent event) { + if (event.getMediaServerItem() == null + || !type.equals(event.getMediaServerItem().getType()) + || event.getMediaServerItem().isStatus()) { + return; + } + logger.info("[ZLM-HOOK事件-服务启动] ID:" + event.getMediaServerItem().getId()); + offlineZlmMap.remove(event.getMediaServerItem().getId()); + } + + @Scheduled(fixedDelay = ) //每天的0点执行 + public void execute(){ } + } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java new file mode 100644 index 000000000..cbc5b74b1 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java @@ -0,0 +1,24 @@ +package com.genersoft.iot.vmp.media.zlm.event; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import org.springframework.context.ApplicationEvent; + +/** + * zlm server_start事件 + */ +public class HookZlmServerStartEvent extends ApplicationEvent { + + public HookZlmServerStartEvent(Object source) { + super(source); + } + + private MediaServerItem mediaServerItem; + + public MediaServerItem getMediaServerItem() { + return mediaServerItem; + } + + public void setMediaServerItem(MediaServerItem mediaServerItem) { + this.mediaServerItem = mediaServerItem; + } +} From 5e3073005d286ba7fe9dfced7f4a7a26e5452ebb Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 20 Mar 2024 00:26:04 +0800 Subject: [PATCH 06/58] =?UTF-8?q?=E4=BC=98=E5=8C=96zlm=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/MediaServerConfig.java | 5 + .../service/impl/MediaServerServiceImpl.java | 19 +-- .../media/zlm/ZLMMediaServerStatusManger.java | 146 +++++++++++++++++- .../event/HookZlmServerKeepaliveEvent.java | 24 +++ 4 files changed, 179 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java diff --git a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java index 937396858..4217e140e 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java @@ -57,6 +57,7 @@ public class MediaServerConfig implements CommandLineRunner { @Override public void run(String... strings) throws Exception { + // TODO 获取所有的离线节点信息 mediaServerService.clearMediaServerForOnline(); MediaServerItem defaultMediaServer = mediaServerService.getDefaultMediaServer(); if (defaultMediaServer == null) { @@ -67,7 +68,11 @@ public class MediaServerConfig implements CommandLineRunner { } // 发送媒体节点变化事件 mediaServerService.syncCatchFromDatabase(); + // 获取所有的zlm, 并开启主动连接 + List all = mediaServerService.getAllFromDatabase(); + MediaServerChangeEvent event = new MediaServerChangeEvent(this); + event.setMediaServerItem(); applicationEventPublisher.publishEvent(event); // TODO 此处以下代码弃用 diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 2c421bad0..aa3efceb2 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -264,6 +264,9 @@ public class MediaServerServiceImpl implements IMediaServerService { } String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItemInDataBase.getId(); redisTemplate.opsForValue().set(key, mediaServerItemInDataBase); + if (mediaSerItem.isStatus()) { + resetOnlineServerItem(mediaSerItem); + } } @Override @@ -498,20 +501,18 @@ public class MediaServerServiceImpl implements IMediaServerService { if (redisTemplate.opsForZSet().score(key, serverItem.getId()) == null) { // 不存在则设置默认值 已存在则重置 redisTemplate.opsForZSet().add(key, serverItem.getId(), 0L); // 查询服务流数量 - zlmresTfulUtils.getMediaList(serverItem, null, null, "rtsp",(mediaList ->{ - Integer code = mediaList.getInteger("code"); - if (code == 0) { - JSONArray data = mediaList.getJSONArray("data"); - if (data != null) { - redisTemplate.opsForZSet().add(key, serverItem.getId(), data.size()); - } - } - })); + int count = getMediaList(serverItem); + redisTemplate.opsForZSet().add(key, serverItem.getId(), count); }else { clearRTPServer(serverItem); } } + private int getMediaList(MediaServerItem serverItem) { + + return 0; + } + @Override public void addCount(String mediaServerId) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index bf396900a..ef0c67a21 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -1,13 +1,23 @@ package com.genersoft.iot.vmp.media.zlm; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; +import org.checkerframework.checker.units.qual.A; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -15,11 +25,23 @@ import java.util.concurrent.ConcurrentHashMap; /** * 管理zlm流媒体节点的状态 */ +@Component public class ZLMMediaServerStatusManger { private final static Logger logger = LoggerFactory.getLogger(ZLMMediaServerStatusManger.class); - private Map offlineZlmMap = new ConcurrentHashMap<>(); + private final Map offlineZlmPrimaryMap = new ConcurrentHashMap<>(); + private final Map offlineZlmsecondaryMap = new ConcurrentHashMap<>(); + private final Map offlineZlmTimeMap = new ConcurrentHashMap<>(); + + @Autowired + private ZLMRESTfulUtils zlmresTfulUtils; + + @Autowired + private IMediaServerService mediaServerService; + + @Autowired + private DynamicTask dynamicTask; private final String type = "zlm"; @@ -31,8 +53,9 @@ public class ZLMMediaServerStatusManger { || event.getMediaServerItem().isStatus()) { return; } - logger.info("[ZLM 待上线节点变化] ID:" + event.getMediaServerItem().getId()); - offlineZlmMap.put(event.getMediaServerItem().getId(), event.getMediaServerItem()); + logger.info("[ZLM-添加待上线节点] ID:" + event.getMediaServerItem().getId()); + offlineZlmPrimaryMap.put(event.getMediaServerItem().getId(), event.getMediaServerItem()); + offlineZlmTimeMap.put(event.getMediaServerItem().getId(), System.currentTimeMillis()); } @Async("taskExecutor") @@ -43,13 +66,124 @@ public class ZLMMediaServerStatusManger { || event.getMediaServerItem().isStatus()) { return; } + MediaServerItem serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); + if (serverItem == null) { + return; + } logger.info("[ZLM-HOOK事件-服务启动] ID:" + event.getMediaServerItem().getId()); - offlineZlmMap.remove(event.getMediaServerItem().getId()); + online(serverItem); } - @Scheduled(fixedDelay = ) //每天的0点执行 - public void execute(){ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(HookZlmServerKeepaliveEvent event) { + if (event.getMediaServerItem() == null + || !type.equals(event.getMediaServerItem().getType()) + || event.getMediaServerItem().isStatus()) { + return; + } + MediaServerItem serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); + if (serverItem == null) { + return; + } + logger.info("[ZLM-HOOK事件-心跳] ID:" + event.getMediaServerItem().getId()); + online(serverItem); + } + @Scheduled(fixedDelay = 10*1000) //每隔10秒检查一次 + public void execute(){ + // 初次加入的离线节点会在30分钟内,每间隔十秒尝试一次,30分钟后如果仍然没有上线,则每隔30分钟尝试一次连接 + if (offlineZlmPrimaryMap.isEmpty() && offlineZlmsecondaryMap.isEmpty()) { + return; + } + if (!offlineZlmPrimaryMap.isEmpty()) { + for (MediaServerItem mediaServerItem : offlineZlmPrimaryMap.values()) { + if (offlineZlmTimeMap.get(mediaServerItem.getId()) > 30*60*1000) { + offlineZlmsecondaryMap.put(mediaServerItem.getId(), mediaServerItem); + offlineZlmPrimaryMap.remove(mediaServerItem.getId()); + continue; + } + logger.info("[ZLM-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + JSONObject responseJson = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); + ZLMServerConfig zlmServerConfig = null; + if (responseJson == null) { + logger.info("[ZLM-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + continue; + } + JSONArray data = responseJson.getJSONArray("data"); + if (data == null || data.isEmpty()) { + logger.info("[ZLM-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + }else { + zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); + initPort(mediaServerItem, zlmServerConfig); + online(mediaServerItem); + } + } + } + if (!offlineZlmsecondaryMap.isEmpty()) { + for (MediaServerItem mediaServerItem : offlineZlmsecondaryMap.values()) { + if (offlineZlmTimeMap.get(mediaServerItem.getId()) < 30*60*1000) { + continue; + } + logger.info("[ZLM-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + JSONObject responseJson = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); + ZLMServerConfig zlmServerConfig = null; + if (responseJson == null) { + logger.info("[ZLM-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + offlineZlmTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + continue; + } + JSONArray data = responseJson.getJSONArray("data"); + if (data == null || data.isEmpty()) { + logger.info("[ZLM-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + offlineZlmTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + }else { + zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); + initPort(mediaServerItem, zlmServerConfig); + online(mediaServerItem); + } + } + } + } + + private void online(MediaServerItem mediaServerItem) { + logger.info("[ZLM-连接成功] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + offlineZlmPrimaryMap.remove(mediaServerItem.getId()); + offlineZlmsecondaryMap.remove(mediaServerItem.getId()); + offlineZlmTimeMap.remove(mediaServerItem.getId()); + if (!mediaServerItem.isStatus()) { + mediaServerItem.setStatus(true); + mediaServerService.update(mediaServerItem); + } + // 设置两次心跳未收到则认为zlm离线 + String key = "zlm-keepalive-" + mediaServerItem.getId(); + dynamicTask.startDelay(key, ()->{ + logger.warn("[ZLM-心跳超时] ID:{}", mediaServerItem.getId()); + mediaServerItem.setStatus(false); + offlineZlmPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); + offlineZlmTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + }, (int)(mediaServerItem.getHookAliveInterval() * 2 * 1000)); + } + private void initPort(MediaServerItem mediaServerItem, ZLMServerConfig zlmServerConfig) { + if (mediaServerItem.getHttpSSlPort() == 0) { + mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); + } + if (mediaServerItem.getRtmpPort() == 0) { + mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort()); + } + if (mediaServerItem.getRtmpSSlPort() == 0) { + mediaServerItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); + } + if (mediaServerItem.getRtspPort() == 0) { + mediaServerItem.setRtspPort(zlmServerConfig.getRtspPort()); + } + if (mediaServerItem.getRtspSSLPort() == 0) { + mediaServerItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); + } + if (mediaServerItem.getRtpProxyPort() == 0) { + mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); + } + mediaServerItem.setHookAliveInterval(zlmServerConfig.getHookAliveInterval()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java new file mode 100644 index 000000000..aa6431f52 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java @@ -0,0 +1,24 @@ +package com.genersoft.iot.vmp.media.zlm.event; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import org.springframework.context.ApplicationEvent; + +/** + * zlm 心跳事件 + */ +public class HookZlmServerKeepaliveEvent extends ApplicationEvent { + + public HookZlmServerKeepaliveEvent(Object source) { + super(source); + } + + private MediaServerItem mediaServerItem; + + public MediaServerItem getMediaServerItem() { + return mediaServerItem; + } + + public void setMediaServerItem(MediaServerItem mediaServerItem) { + this.mediaServerItem = mediaServerItem; + } +} From 19e10d0d6a54b2b0c1a8d4f52c84a18c089d0025 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 20 Mar 2024 10:33:43 +0800 Subject: [PATCH 07/58] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/service/impl/MediaServerServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index aa3efceb2..b483e6b6f 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -749,6 +749,7 @@ public class MediaServerServiceImpl implements IMediaServerService { mediaServerItemMap.put(mediaServerItem.getId(), mediaServerItem); } for (MediaServerItem mediaServerItem : allInCatch) { + // 清除数据中不存在但redis缓存数据 if (!mediaServerItemMap.containsKey(mediaServerItem.getId())) { delete(mediaServerItem.getId()); } From 8ae17764fd61c1013eb874018ad078480c025d09 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 20 Mar 2024 11:07:08 +0800 Subject: [PATCH 08/58] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/MediaServerConfig.java | 145 +----------------- .../media/event/MediaServerChangeEvent.java | 21 ++- .../service/impl/MediaServerServiceImpl.java | 24 --- .../media/zlm/ZLMMediaServerStatusManger.java | 19 ++- 4 files changed, 34 insertions(+), 175 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java index 4217e140e..3be8e4c4d 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java @@ -1,63 +1,41 @@ package com.genersoft.iot.vmp.media; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.MediaConfig; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; -import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForServerStarted; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.annotation.Order; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; +/** + * 启动是从配置文件加载节点信息,以及发送个节点状态管理去控制节点状态 + */ @Component @Order(value=12) public class MediaServerConfig implements CommandLineRunner { private final static Logger logger = LoggerFactory.getLogger(MediaServerConfig.class); - private Map startGetMedia; - @Autowired private ApplicationEventPublisher applicationEventPublisher; - @Autowired - private ZlmHttpHookSubscribe hookSubscribe; - - @Autowired - private EventPublisher publisher; - @Autowired private IMediaServerService mediaServerService; @Autowired private MediaConfig mediaConfig; - @Autowired - private DynamicTask dynamicTask; - @Override public void run(String... strings) throws Exception { - // TODO 获取所有的离线节点信息 + // 清理所有在线节点的缓存信息 mediaServerService.clearMediaServerForOnline(); MediaServerItem defaultMediaServer = mediaServerService.getDefaultMediaServer(); if (defaultMediaServer == null) { @@ -70,118 +48,9 @@ public class MediaServerConfig implements CommandLineRunner { mediaServerService.syncCatchFromDatabase(); // 获取所有的zlm, 并开启主动连接 List all = mediaServerService.getAllFromDatabase(); - + logger.info("[媒体节点] 加载节点列表, 共{}个节点", all.size()); MediaServerChangeEvent event = new MediaServerChangeEvent(this); - event.setMediaServerItem(); + event.setMediaServerItemList(all); applicationEventPublisher.publishEvent(event); - // TODO 此处以下代码弃用 - - - HookSubscribeForServerStarted hookSubscribeForServerStarted = HookSubscribeFactory.on_server_started(); - // 订阅 媒体节点启动事件, 新的媒体节点也会从这里进入系统 - hookSubscribe.addSubscribe(hookSubscribeForServerStarted, - (mediaServerItem, hookParam)->{ - ZLMServerConfig zlmServerConfig = (ZLMServerConfig)hookParam; - if (zlmServerConfig !=null ) { - if (startGetMedia != null) { - startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId()); - if (startGetMedia.isEmpty()) { - hookSubscribe.removeSubscribe(HookSubscribeFactory.on_server_started()); - } - } - } - }); - - // 获取zlm信息 - logger.info("[zlm] 等待默认zlm中..."); - - // 获取所有的zlm, 并开启主动连接 - List all = mediaServerService.getAllFromDatabase(); - Map allMap = new HashMap<>(); - mediaServerService.updateVmServer(all); - if (all.size() == 0) { - all.add(mediaConfig.getMediaSerItem()); - } - for (MediaServerItem mediaServerItem : all) { - if (startGetMedia == null) { - startGetMedia = new ConcurrentHashMap<>(); - } - startGetMedia.put(mediaServerItem.getId(), true); - connectZlmServer(mediaServerItem); - allMap.put(mediaServerItem.getId(), mediaServerItem); - } - String taskKey = "zlm-connect-timeout"; - dynamicTask.startDelay(taskKey, ()->{ - if (startGetMedia != null && startGetMedia.size() > 0) { - Set allZlmId = startGetMedia.keySet(); - for (String id : allZlmId) { - logger.error("[ {} ]]主动连接失败,不再尝试连接", id); - } - startGetMedia = null; - } - // 获取redis中所有的zlm - List allInRedis = mediaServerService.getAll(); - for (MediaServerItem mediaServerItem : allInRedis) { - if (!allMap.containsKey(mediaServerItem.getId())) { - mediaServerService.delete(mediaServerItem.getId()); - } - } - }, 60 * 1000 ); - } - - @Async("taskExecutor") - public void connectZlmServer(MediaServerItem mediaServerItem){ - String connectZlmServerTaskKey = "connect-zlm-" + mediaServerItem.getId(); - ZLMServerConfig zlmServerConfigFirst = getMediaServerConfig(mediaServerItem); - if (zlmServerConfigFirst != null) { - zlmServerConfigFirst.setIp(mediaServerItem.getIp()); - zlmServerConfigFirst.setHttpPort(mediaServerItem.getHttpPort()); - startGetMedia.remove(mediaServerItem.getId()); - if (startGetMedia.size() == 0) { - hookSubscribe.removeSubscribe(HookSubscribeFactory.on_server_started()); - } - mediaServerService.zlmServerOnline(zlmServerConfigFirst); - }else { - logger.info("[ {} ]-[ {}:{} ]主动连接失败, 清理相关资源, 开始尝试重试连接", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - publisher.zlmOfflineEventPublish(mediaServerItem.getId()); - } - - dynamicTask.startCron(connectZlmServerTaskKey, ()->{ - ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem); - if (zlmServerConfig != null) { - dynamicTask.stop(connectZlmServerTaskKey); - zlmServerConfig.setIp(mediaServerItem.getIp()); - zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort()); - startGetMedia.remove(mediaServerItem.getId()); - if (startGetMedia.size() == 0) { - hookSubscribe.removeSubscribe(HookSubscribeFactory.on_server_started()); - } - mediaServerService.zlmServerOnline(zlmServerConfig); - } - }, 2000); - } - - public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) { - if (startGetMedia == null) { return null;} - if (!mediaServerItem.isDefaultServer() && mediaServerService.getOne(mediaServerItem.getId()) == null) { - return null; - } - if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) { - return null; - } - JSONObject responseJson = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); - ZLMServerConfig zlmServerConfig = null; - if (responseJson != null) { - JSONArray data = responseJson.getJSONArray("data"); - if (data != null && data.size() > 0) { - zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); - } - } else { - logger.error("[ {} ]-[ {}:{} ]主动连接失败, 2s后重试", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - } - return zlmServerConfig; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java index 6cf8bbfc3..e1d2a94b4 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java @@ -3,19 +3,30 @@ package com.genersoft.iot.vmp.media.event; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.springframework.context.ApplicationEvent; +import java.util.Arrays; +import java.util.List; + public class MediaServerChangeEvent extends ApplicationEvent { public MediaServerChangeEvent(Object source) { super(source); } - private MediaServerItem mediaServerItem; + private List mediaServerItemList; - public MediaServerItem getMediaServerItem() { - return mediaServerItem; + public List getMediaServerItemList() { + return mediaServerItemList; } - public void setMediaServerItem(MediaServerItem mediaServerItem) { - this.mediaServerItem = mediaServerItem; + public void setMediaServerItemList(List mediaServerItemList) { + this.mediaServerItemList = mediaServerItemList; + } + + public void setMediaServerItemList(MediaServerItem... mediaServerItemArray) { + this.mediaServerItemList.addAll(Arrays.asList(mediaServerItemArray)); + } + + public void setMediaServerItem(List mediaServerItemList) { + this.mediaServerItemList = mediaServerItemList; } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index b483e6b6f..be090ec9b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -462,30 +462,6 @@ public class MediaServerServiceImpl implements IMediaServerService { zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); } - class KeepAliveTimeoutRunnable implements Runnable{ - - private MediaServerItem serverItem; - - public KeepAliveTimeoutRunnable(MediaServerItem serverItem) { - this.serverItem = serverItem; - } - - @Override - public void run() { - logger.info("[媒体服务节点心跳到期]:" + serverItem.getId()); - // 发起http请求验证zlm是否确实无法连接,如果确实无法连接则发送离线事件,否则不作处理 - JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(serverItem); - if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) { - logger.info("[媒体服务节点心跳到期]:{}验证后媒体服务节点仍在线,恢复心跳信息,请检查媒体服务节点是否可以正常向wvp发送心跳", serverItem.getId()); - // 添加媒体服务节点信息 - updateMediaServerKeepalive(serverItem.getId(), null); - }else { - publisher.zlmOfflineEventPublish(serverItem.getId()); - } - } - } - - @Override public void zlmServerOffline(String mediaServerId) { delete(mediaServerId); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index ef0c67a21..0637b5314 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -10,7 +10,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; -import org.checkerframework.checker.units.qual.A; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -48,14 +47,18 @@ public class ZLMMediaServerStatusManger { @Async("taskExecutor") @EventListener public void onApplicationEvent(MediaServerChangeEvent event) { - if (event.getMediaServerItem() == null - || !type.equals(event.getMediaServerItem().getType()) - || event.getMediaServerItem().isStatus()) { + if (event.getMediaServerItemList() == null + || event.getMediaServerItemList().isEmpty()) { return; } - logger.info("[ZLM-添加待上线节点] ID:" + event.getMediaServerItem().getId()); - offlineZlmPrimaryMap.put(event.getMediaServerItem().getId(), event.getMediaServerItem()); - offlineZlmTimeMap.put(event.getMediaServerItem().getId(), System.currentTimeMillis()); + for (MediaServerItem mediaServerItem : event.getMediaServerItemList()) { + if (!type.equals(mediaServerItem.getType())) { + continue; + } + logger.info("[ZLM-添加待上线节点] ID:" + mediaServerItem.getId()); + offlineZlmPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); + offlineZlmTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + } } @Async("taskExecutor") @@ -147,11 +150,11 @@ public class ZLMMediaServerStatusManger { } private void online(MediaServerItem mediaServerItem) { - logger.info("[ZLM-连接成功] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); offlineZlmPrimaryMap.remove(mediaServerItem.getId()); offlineZlmsecondaryMap.remove(mediaServerItem.getId()); offlineZlmTimeMap.remove(mediaServerItem.getId()); if (!mediaServerItem.isStatus()) { + logger.info("[ZLM-连接成功] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); mediaServerItem.setStatus(true); mediaServerService.update(mediaServerItem); } From 181bf76862b7d2ccf4382bb782a9dd11cfb10c4e Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 20 Mar 2024 18:54:39 +0800 Subject: [PATCH 09/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/conf/MediaConfig.java | 7 +- .../iot/vmp/gb28181/event/EventPublisher.java | 14 +- .../iot/vmp/media/MediaServerConfig.java | 16 +- .../media/abl/ABLMediaNodeServerService.java | 5 + .../media/event/MediaServerChangeEvent.java | 2 + .../media/event/MediaServerDeleteEvent.java | 11 + .../event/MediaServerEventAbstract.java | 2 +- .../event/MediaServerOfflineEvent.java | 4 +- .../event/MediaServerOnlineEvent.java | 4 +- .../event/MediaServerStatusEventListener.java | 11 +- .../service/IMediaNodeServerService.java | 2 + .../media/service/IMediaServerService.java | 35 +- .../service/impl/MediaServerServiceImpl.java | 349 ++++-------------- .../iot/vmp/media/zlm/SendRtpPortManager.java | 1 + .../vmp/media/zlm/ZLMHttpHookListener.java | 41 +- .../media/zlm/ZLMMediaNodeServerService.java | 40 +- .../media/zlm/ZLMMediaServerStatusManger.java | 129 ++++++- .../vmp/storager/dao/MediaServerMapper.java | 4 + .../cloudRecord/CloudRecordController.java | 4 +- .../vmp/vmanager/server/ServerController.java | 10 +- .../src/components/dialog/MediaServerEdit.vue | 11 +- web_src/src/components/service/MediaServer.js | 3 +- 数据库/abl/更新-mysql-2.7.0.sql | 2 +- 23 files changed, 334 insertions(+), 373 deletions(-) create mode 100755 src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java rename src/main/java/com/genersoft/iot/vmp/media/{zlm => }/event/MediaServerEventAbstract.java (91%) rename src/main/java/com/genersoft/iot/vmp/media/{zlm => }/event/MediaServerOfflineEvent.java (61%) rename src/main/java/com/genersoft/iot/vmp/media/{zlm => }/event/MediaServerOnlineEvent.java (60%) rename src/main/java/com/genersoft/iot/vmp/media/{zlm => }/event/MediaServerStatusEventListener.java (82%) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java index 884036ae9..4664310da 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java @@ -87,6 +87,9 @@ public class MediaConfig{ @Value("${media.record-path:}") private String recordPath; + @Value("${media.type:zlm}") + private String type; + public String getId() { return id; } @@ -217,8 +220,10 @@ public class MediaConfig{ mediaServerItem.setRtpPortRange(rtpPortRange); mediaServerItem.setSendRtpPortRange(rtpSendPortRange); mediaServerItem.setRecordAssistPort(recordAssistPort); - mediaServerItem.setHookAliveInterval(30.00f); + mediaServerItem.setHookAliveInterval(10f); mediaServerItem.setRecordDay(recordDay); + mediaServerItem.setStatus(false); + mediaServerItem.setType(type); if (recordPath != null) { mediaServerItem.setRecordPath(recordPath); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java index c363583a0..ba538f19b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java @@ -1,17 +1,19 @@ package com.genersoft.iot.vmp.gb28181.event; -import com.genersoft.iot.vmp.gb28181.bean.*; +import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.gb28181.bean.GbStream; +import com.genersoft.iot.vmp.gb28181.bean.RecordInfo; +import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent; import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent; import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; -import com.genersoft.iot.vmp.media.zlm.event.MediaServerOfflineEvent; -import com.genersoft.iot.vmp.media.zlm.event.MediaServerOnlineEvent; +import com.genersoft.iot.vmp.media.event.MediaServerOfflineEvent; +import com.genersoft.iot.vmp.media.event.MediaServerOnlineEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; -import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent; - import javax.sip.TimeoutEvent; import java.util.ArrayList; import java.util.HashSet; @@ -39,7 +41,7 @@ public class EventPublisher { applicationEventPublisher.publishEvent(alarmEvent); } - public void zlmOfflineEventPublish(String mediaServerId){ + public void mediaServerOfflineEventPublish(String mediaServerId){ MediaServerOfflineEvent outEvent = new MediaServerOfflineEvent(this); outEvent.setMediaServerId(mediaServerId); applicationEventPublisher.publishEvent(outEvent); diff --git a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java index 3be8e4c4d..761d97091 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java @@ -38,11 +38,19 @@ public class MediaServerConfig implements CommandLineRunner { // 清理所有在线节点的缓存信息 mediaServerService.clearMediaServerForOnline(); MediaServerItem defaultMediaServer = mediaServerService.getDefaultMediaServer(); - if (defaultMediaServer == null) { - mediaServerService.addToDatabase(mediaConfig.getMediaSerItem()); + MediaServerItem mediaSerItemInConfig = mediaConfig.getMediaSerItem(); + if (defaultMediaServer != null && mediaSerItemInConfig.getId().equals(defaultMediaServer.getId())) { + mediaServerService.update(mediaSerItemInConfig); }else { - MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem(); - mediaServerService.updateToDatabase(mediaSerItem); + if (defaultMediaServer != null) { + mediaServerService.delete(defaultMediaServer.getId()); + } + MediaServerItem mediaServerItem = mediaServerService.getOneFromDatabase(mediaSerItemInConfig.getId()); + if (mediaServerItem == null) { + mediaServerService.add(mediaSerItemInConfig); + }else { + mediaServerService.update(mediaSerItemInConfig); + } } // 发送媒体节点变化事件 mediaServerService.syncCatchFromDatabase(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index cbce1d6bb..445e1e6a3 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -42,4 +42,9 @@ public class ABLMediaNodeServerService implements IMediaNodeServerService { public void online(MediaServerItem mediaServerItem) { } + + @Override + public MediaServerItem checkMediaServer(String ip, int port, String secret) { + return null; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java index e1d2a94b4..a880b85c0 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.media.event; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.springframework.context.ApplicationEvent; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -23,6 +24,7 @@ public class MediaServerChangeEvent extends ApplicationEvent { } public void setMediaServerItemList(MediaServerItem... mediaServerItemArray) { + this.mediaServerItemList = new ArrayList<>(); this.mediaServerItemList.addAll(Arrays.asList(mediaServerItemArray)); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java new file mode 100755 index 000000000..10a368b4c --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java @@ -0,0 +1,11 @@ +package com.genersoft.iot.vmp.media.event; + +/** + * zlm在线事件 + */ +public class MediaServerDeleteEvent extends MediaServerEventAbstract { + + public MediaServerDeleteEvent(Object source) { + super(source); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerEventAbstract.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java similarity index 91% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerEventAbstract.java rename to src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java index 66108fc90..91806f8d1 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerEventAbstract.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm.event; +package com.genersoft.iot.vmp.media.event; import org.springframework.context.ApplicationEvent; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOfflineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java similarity index 61% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOfflineEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java index de0ed3344..ce3c5a9d4 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOfflineEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java @@ -1,4 +1,6 @@ -package com.genersoft.iot.vmp.media.zlm.event; +package com.genersoft.iot.vmp.media.event; + +import com.genersoft.iot.vmp.media.event.MediaServerEventAbstract; /** * zlm离线事件类 diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOnlineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java similarity index 60% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOnlineEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java index d3a746a5f..5d9bdc43c 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerOnlineEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java @@ -1,4 +1,6 @@ -package com.genersoft.iot.vmp.media.zlm.event; +package com.genersoft.iot.vmp.media.event; + +import com.genersoft.iot.vmp.media.event.MediaServerEventAbstract; /** * zlm在线事件 diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java similarity index 82% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java rename to src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java index fe5dfc98b..0d8e38c08 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/MediaServerStatusEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java @@ -1,6 +1,5 @@ -package com.genersoft.iot.vmp.media.zlm.event; +package com.genersoft.iot.vmp.media.event; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IStreamPushService; @@ -30,16 +29,13 @@ public class MediaServerStatusEventListener { @Autowired private IStreamProxyService streamProxyService; - @Autowired - private IMediaServerService mediaServerService; - @Autowired private IPlayService playService; @Async("taskExecutor") @EventListener public void onApplicationEvent(MediaServerOnlineEvent event) { - logger.info("[ZLM] 上线 ID:" + event.getMediaServerId()); + logger.info("[媒体节点] 上线 ID:" + event.getMediaServerId()); streamPushService.zlmServerOnline(event.getMediaServerId()); streamProxyService.zlmServerOnline(event.getMediaServerId()); playService.zlmServerOnline(event.getMediaServerId()); @@ -49,9 +45,8 @@ public class MediaServerStatusEventListener { @EventListener public void onApplicationEvent(MediaServerOfflineEvent event) { - logger.info("[ZLM] 离线,ID:" + event.getMediaServerId()); + logger.info("[媒体节点] 离线,ID:" + event.getMediaServerId()); // 处理ZLM离线 - mediaServerService.zlmServerOffline(event.getMediaServerId()); streamProxyService.zlmServerOffline(event.getMediaServerId()); streamPushService.zlmServerOffline(event.getMediaServerId()); playService.zlmServerOffline(event.getMediaServerId()); diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index cc8b66b8c..43f9fc5dd 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -17,4 +17,6 @@ public interface IMediaNodeServerService { boolean checkNodeId(MediaServerItem mediaServerItem); void online(MediaServerItem mediaServerItem); + + MediaServerItem checkMediaServer(String ip, int port, String secret); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 0af9ba10b..d6015e0a8 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -1,9 +1,7 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; -import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -14,6 +12,8 @@ import java.util.List; */ public interface IMediaServerService { + List getAllOnlineList(); + List getAll(); List getAllFromDatabase(); @@ -24,24 +24,8 @@ public interface IMediaServerService { void syncCatchFromDatabase(); - /** - * 新的节点加入 - * @param zlmServerConfig - * @return - */ - void zlmServerOnline(ZLMServerConfig zlmServerConfig); - - /** - * 节点离线 - * @param mediaServerId - * @return - */ - void zlmServerOffline(String mediaServerId); - MediaServerItem getMediaServerForMinimumLoad(Boolean hasAssist); - void setZLMConfig(MediaServerItem mediaServerItem, boolean restart); - void updateVmServer(List mediaServerItemList); SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, @@ -70,30 +54,19 @@ public interface IMediaServerService { void add(MediaServerItem mediaSerItem); - int addToDatabase(MediaServerItem mediaSerItem); - - int updateToDatabase(MediaServerItem mediaSerItem); - void resetOnlineServerItem(MediaServerItem serverItem); - MediaServerItem checkMediaServer(String ip, int port, String secret); + MediaServerItem checkMediaServer(String ip, int port, String secret, String type); boolean checkMediaRecordServer(String ip, int port); void delete(String id); - void deleteDb(String id); - MediaServerItem getDefaultMediaServer(); - void updateMediaServerKeepalive(String mediaServerId, ServerKeepaliveData data); - - /** - * 获取负载信息 - * @return - */ MediaServerLoad getLoad(MediaServerItem mediaServerItem); List getAllWithAssistPort(); + MediaServerItem getOneFromDatabase(String id); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index be090ec9b..a959de78e 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -1,24 +1,17 @@ package com.genersoft.iot.vmp.media.service.impl; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.conf.DynamicTask; -import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; +import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; -import com.genersoft.iot.vmp.media.zlm.*; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData; -import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; -import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -33,15 +26,11 @@ import okhttp3.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.stereotype.Service; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; import org.springframework.util.ObjectUtils; -import java.io.File; import java.time.LocalDateTime; import java.util.*; @@ -54,48 +43,15 @@ public class MediaServerServiceImpl implements IMediaServerService { private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); - private final String zlmKeepaliveKeyPrefix = "zlm-keepalive_"; - - @Autowired - private SipConfig sipConfig; - @Autowired private SSRCFactory ssrcFactory; - @Value("${server.ssl.enabled:false}") - private boolean sslEnabled; - - @Value("${server.port}") - private Integer serverPort; - @Autowired private UserSetting userSetting; - @Autowired - private SendRtpPortManager sendRtpPortManager; - - @Autowired - private AssistRESTfulUtils assistRESTfulUtils; - @Autowired private MediaServerMapper mediaServerMapper; - @Autowired - private DataSourceTransactionManager dataSourceTransactionManager; - - @Autowired - private TransactionDefinition transactionDefinition; - - - @Autowired - private ZLMServerFactory zlmServerFactory; - - @Autowired - private EventPublisher publisher; - - @Autowired - private DynamicTask dynamicTask; - @Autowired private IRedisCatchStorage redisCatchStorage; @@ -108,6 +64,9 @@ public class MediaServerServiceImpl implements IMediaServerService { @Autowired private Map nodeServerServiceMap; + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + /** * 初始化 @@ -259,18 +218,28 @@ public class MediaServerServiceImpl implements IMediaServerService { mediaServerMapper.update(mediaSerItem); MediaServerItem mediaServerItemInRedis = getOne(mediaSerItem.getId()); MediaServerItem mediaServerItemInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId()); - if (mediaServerItemInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaSerItem.getId())) { + if (mediaServerItemInDataBase == null) { + return; + } + mediaServerItemInDataBase.setStatus(mediaSerItem.isStatus()); + if (mediaServerItemInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerItemInDataBase.getId())) { ssrcFactory.initMediaServerSSRC(mediaServerItemInDataBase.getId(),null); } String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItemInDataBase.getId(); redisTemplate.opsForValue().set(key, mediaServerItemInDataBase); - if (mediaSerItem.isStatus()) { - resetOnlineServerItem(mediaSerItem); + if (mediaServerItemInDataBase.isStatus()) { + resetOnlineServerItem(mediaServerItemInDataBase); + }else { + // 发送事件 + MediaServerChangeEvent event = new MediaServerChangeEvent(this); + event.setMediaServerItemList(mediaServerItemInDataBase); + applicationEventPublisher.publishEvent(event); } } + @Override - public List getAll() { + public List getAllOnlineList() { List result = new ArrayList<>(); List mediaServerKeys = RedisUtil.scan(redisTemplate, String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX+ userSetting.getServerId() + "_" )); String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); @@ -298,6 +267,21 @@ public class MediaServerServiceImpl implements IMediaServerService { return result; } + @Override + public List getAll() { + List mediaServerList = mediaServerMapper.queryAll(); + if (mediaServerList.isEmpty()) { + return new ArrayList<>(); + } + for (MediaServerItem mediaServerItem : mediaServerList) { + MediaServerItem mediaServerItemInRedis = getOne(mediaServerItem.getId()); + if (mediaServerItemInRedis != null) { + mediaServerItem.setStatus(mediaServerItemInRedis.isStatus()); + } + } + return mediaServerList; + } + @Override public List getAllFromDatabase() { @@ -351,12 +335,15 @@ public class MediaServerServiceImpl implements IMediaServerService { public void add(MediaServerItem mediaServerItem) { mediaServerItem.setCreateTime(DateUtil.getNow()); mediaServerItem.setUpdateTime(DateUtil.getNow()); - mediaServerItem.setHookAliveInterval(30f); + if (mediaServerItem.getHookAliveInterval() == null || mediaServerItem.getHookAliveInterval() == 0F) { + mediaServerItem.setHookAliveInterval(10F); + } if (mediaServerItem.getType() == null) { logger.info("[添加媒体节点] 失败, mediaServerItem的类型:为空"); return; } if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) { + logger.info("[添加媒体节点] 失败, 媒体服务ID已存在,请修改媒体服务器配置, {}", mediaServerItem.getId()); throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败,媒体服务ID [ " + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); } IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); @@ -364,111 +351,17 @@ public class MediaServerServiceImpl implements IMediaServerService { logger.info("[添加媒体节点] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); return; } - if (mediaNodeServerService.checkNodeId(mediaServerItem)) { - mediaServerMapper.add(mediaServerItem); + mediaServerMapper.add(mediaServerItem); + if (mediaServerItem.isStatus()) { mediaNodeServerService.online(mediaServerItem); }else { - throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败,媒体服务ID [ " + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); + // 发送事件 + MediaServerChangeEvent event = new MediaServerChangeEvent(this); + event.setMediaServerItemList(mediaServerItem); + applicationEventPublisher.publishEvent(event); } } - @Override - public int addToDatabase(MediaServerItem mediaSerItem) { - return mediaServerMapper.add(mediaSerItem); - } - - @Override - public int updateToDatabase(MediaServerItem mediaSerItem) { - int result = 0; - if (mediaSerItem.isDefaultServer()) { - TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition); - int delResult = mediaServerMapper.delDefault(); - if (delResult == 0) { - logger.error("移除数据库默认媒体服务节点节点失败"); - //事务回滚 - dataSourceTransactionManager.rollback(transactionStatus); - return 0; - } - result = mediaServerMapper.add(mediaSerItem); - dataSourceTransactionManager.commit(transactionStatus); //手动提交 - }else { - result = mediaServerMapper.update(mediaSerItem); - } - return result; - } - - /** - * 处理媒体服务节点上线 - * @param zlmServerConfig 媒体服务节点上线携带的参数 - */ - @Override - public void zlmServerOnline(ZLMServerConfig zlmServerConfig) { - - MediaServerItem serverItem = mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()); - if (serverItem == null) { - logger.warn("[未注册的媒体服务节点] 拒接接入:{}来自{}:{}", zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(),zlmServerConfig.getHttpPort() ); - logger.warn("请检查媒体服务节点的ID配置是否与WVP的一致"); - return; - }else { - logger.info("[媒体服务节点] 正在连接 : {} -> {}:{}", - zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); - } - serverItem.setHookAliveInterval(zlmServerConfig.getHookAliveInterval()); - if (serverItem.getHttpPort() == 0) { - serverItem.setHttpPort(zlmServerConfig.getHttpPort()); - } - if (serverItem.getHttpSSlPort() == 0) { - serverItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); - } - if (serverItem.getRtmpPort() == 0) { - serverItem.setRtmpPort(zlmServerConfig.getRtmpPort()); - } - if (serverItem.getRtmpSSlPort() == 0) { - serverItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); - } - if (serverItem.getRtspPort() == 0) { - serverItem.setRtspPort(zlmServerConfig.getRtspPort()); - } - if (serverItem.getRtspSSLPort() == 0) { - serverItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); - } - if (serverItem.getRtpProxyPort() == 0) { - serverItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); - } - serverItem.setStatus(true); - - if (ObjectUtils.isEmpty(serverItem.getId())) { - logger.warn("[未注册的媒体服务节点] serverItem缺少ID, 无法接入:{}:{}", zlmServerConfig.getIp(),zlmServerConfig.getHttpPort() ); - return; - } - mediaServerMapper.update(serverItem); - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + zlmServerConfig.getGeneralMediaServerId(); - if (!ssrcFactory.hasMediaServerSSRC(serverItem.getId())) { - ssrcFactory.initMediaServerSSRC(zlmServerConfig.getGeneralMediaServerId(), null); - } - redisTemplate.opsForValue().set(key, serverItem); - resetOnlineServerItem(serverItem); - - - if (serverItem.isAutoConfig()) { - setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable())); - } - final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId(); - dynamicTask.stop(zlmKeepaliveKey); - dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(serverItem), (serverItem.getHookAliveInterval().intValue() + 5) * 1000); - publisher.mediaServerOnlineEventPublish(serverItem.getId()); - - logger.info("[媒体服务节点] 连接成功 {} - {}:{} ", - zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); - } - - @Override - public void zlmServerOffline(String mediaServerId) { - delete(mediaServerId); - final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerId; - dynamicTask.stop(zlmKeepaliveKey); - } - @Override public void resetOnlineServerItem(MediaServerItem serverItem) { // 更新缓存 @@ -549,111 +442,23 @@ public class MediaServerServiceImpl implements IMediaServerService { return mediaServerItem; } - /** - * 对媒体服务节点服务器进行基础配置 - * @param mediaServerItem 服务ID - * @param restart 是否重启媒体服务节点 - */ @Override - public void setZLMConfig(MediaServerItem mediaServerItem, boolean restart) { - logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - String protocol = sslEnabled ? "https" : "http"; - String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); - - Map param = new HashMap<>(); - param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline - if (mediaServerItem.getRtspPort() != 0) { - param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); - } - param.put("hook.enable","1"); - param.put("hook.on_flow_report",""); - param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); - param.put("hook.on_http_access",""); - param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); - param.put("hook.on_record_ts",""); - param.put("hook.on_rtsp_auth",""); - param.put("hook.on_rtsp_realm",""); - param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); - param.put("hook.on_shell_login",""); - param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); - param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); - param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); - param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); - param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); - param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); - param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); - param.put("hook.timeoutSec","20"); - // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 - // 置0关闭此特性(推流断开会导致立即断开播放器) - // 此参数不应大于播放器超时时间 - // 优化此消息以更快的收到流注销事件 - param.put("protocol.continue_push_ms", "3000" ); - // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, - // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 - if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { - param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); - } - - if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { - File recordPathFile = new File(mediaServerItem.getRecordPath()); - param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); - param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); - param.put("record.appName", recordPathFile.getName()); - } - - JSONObject responseJSON = zlmresTfulUtils.setServerConfig(mediaServerItem, param); - - if (responseJSON != null && responseJSON.getInteger("code") == 0) { - if (restart) { - logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - zlmresTfulUtils.restartServer(mediaServerItem); - }else { - logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - } - - - }else { - logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - } - - - } - - - @Override - public MediaServerItem checkMediaServer(String ip, int port, String secret) { + public MediaServerItem checkMediaServer(String ip, int port, String secret, String type) { if (mediaServerMapper.queryOneByHostAndPort(ip, port) != null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "此连接已存在"); } - MediaServerItem mediaServerItem = new MediaServerItem(); - mediaServerItem.setIp(ip); - mediaServerItem.setHttpPort(port); - mediaServerItem.setSecret(secret); - JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); - if (responseJSON == null) { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接失败"); + + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(type); + if (mediaNodeServerService == null) { + logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", type); + return null; } - JSONArray data = responseJSON.getJSONArray("data"); - ZLMServerConfig zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); - if (zlmServerConfig == null) { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败"); + MediaServerItem mediaServerItem = mediaNodeServerService.checkMediaServer(ip, port, secret); + if (mediaServerItem != null) { + if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体服务ID [" + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); + } } - if (mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()) != null) { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体服务ID [" + zlmServerConfig.getGeneralMediaServerId() + " ] 已存在,请修改媒体服务器配置"); - } - mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpPort()); - mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort()); - mediaServerItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); - mediaServerItem.setRtspPort(zlmServerConfig.getRtspPort()); - mediaServerItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); - mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); - mediaServerItem.setStreamIp(ip); - mediaServerItem.setHookIp(sipConfig.getIp().split(",")[0]); - mediaServerItem.setSdpIp(ip); return mediaServerItem; } @@ -678,46 +483,24 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public void delete(String id) { + mediaServerMapper.delOne(id); redisTemplate.opsForZSet().remove(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), id); String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + id; redisTemplate.delete(key); - } - @Override - public void deleteDb(String id){ - //同步删除数据库中的数据 - mediaServerMapper.delOne(id); + // 发送节点移除通知 + MediaServerDeleteEvent event = new MediaServerDeleteEvent(this); + event.setMediaServerId(id); + applicationEventPublisher.publishEvent(event); } @Override - public void updateMediaServerKeepalive(String mediaServerId, ServerKeepaliveData data) { - MediaServerItem mediaServerItem = getOne(mediaServerId); - if (mediaServerItem == null) { - // 缓存不存在,从数据库查询,如果数据库不存在则是错误的 - mediaServerItem = getOneFromDatabase(mediaServerId); - if (mediaServerItem == null) { - logger.warn("[更新媒体服务节点 保活信息] 流媒体{}尚未加入使用,请检查节点中是否含有此流媒体 ", mediaServerId); - return; - } - // 媒体服务节点连接重试 - logger.warn("[更新媒体服务节点 保活信息]尝试链接zml id {}", mediaServerId); - ssrcFactory.initMediaServerSSRC(mediaServerItem.getId(), null); - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(); - redisTemplate.opsForValue().set(key, mediaServerItem); - resetOnlineServerItem(mediaServerItem); - clearRTPServer(mediaServerItem); - } - final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId(); - dynamicTask.stop(zlmKeepaliveKey); - dynamicTask.startDelay(zlmKeepaliveKey, new KeepAliveTimeoutRunnable(mediaServerItem), (mediaServerItem.getHookAliveInterval().intValue() + 5) * 1000); - } - - private MediaServerItem getOneFromDatabase(String mediaServerId) { + public MediaServerItem getOneFromDatabase(String mediaServerId) { return mediaServerMapper.queryOne(mediaServerId); } @Override public void syncCatchFromDatabase() { - List allInCatch = getAll(); + List allInCatch = getAllOnlineList(); List allInDatabase = mediaServerMapper.queryAll(); Map mediaServerItemMap = new HashMap<>(); @@ -748,4 +531,6 @@ public class MediaServerServiceImpl implements IMediaServerService { public List getAllWithAssistPort() { return mediaServerMapper.queryAllWithAssistPort(); } + + } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java index 3f28d02ad..fda2e67c8 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java @@ -83,6 +83,7 @@ public class SendRtpPortManager { } private synchronized int getSendPort(int startPort, int endPort, String sendIndexKey, Map sendRtpItemMap){ + // TODO 这里改为只取偶数端口 RedisAtomicInteger redisAtomicInteger = new RedisAtomicInteger(sendIndexKey , redisTemplate.getConnectionFactory()); if (redisAtomicInteger.get() < startPort) { redisAtomicInteger.set(startPort); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 9bab37210..4b2557def 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -10,8 +10,8 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; +import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; @@ -21,6 +21,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -35,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.util.ObjectUtils; @@ -70,9 +73,6 @@ public class ZLMHttpHookListener { @Autowired private AudioBroadcastManager audioBroadcastManager; - @Autowired - private ZLMServerFactory zlmServerFactory; - @Autowired private IPlayService playService; @@ -121,9 +121,6 @@ public class ZLMHttpHookListener { @Autowired private VideoStreamSessionManager sessionManager; - @Autowired - private AssistRESTfulUtils assistRESTfulUtils; - @Autowired private SSRCFactory ssrcFactory; @@ -134,6 +131,9 @@ public class ZLMHttpHookListener { @Autowired private RedisTemplate redisTemplate; + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + /** * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 */ @@ -141,8 +141,6 @@ public class ZLMHttpHookListener { @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { - - taskExecutor.execute(() -> { List subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); if (subscribes != null && subscribes.size() > 0) { @@ -151,8 +149,16 @@ public class ZLMHttpHookListener { } } }); - mediaServerService.updateMediaServerKeepalive(param.getMediaServerId(), param.getData()); - + try { + HookZlmServerKeepaliveEvent event = new HookZlmServerKeepaliveEvent(this); + MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServerItem(mediaServerItem); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ZLM-HOOK-心跳] 发送通知失败 ", e); + } return HookResult.SUCCESS(); } @@ -160,7 +166,6 @@ public class ZLMHttpHookListener { * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。 */ @ResponseBody - @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") public HookResult onPlay(@RequestBody OnPlayHookParam param) { if (logger.isDebugEnabled()) { @@ -199,6 +204,7 @@ public class ZLMHttpHookListener { JSONObject json = (JSONObject) JSON.toJSON(param); logger.info("[ZLM HOOK]推流鉴权:{}->{}", param.getMediaServerId(), param); + // TODO 加快处理速度 String mediaServerId = json.getString("mediaServerId"); MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); @@ -801,8 +807,17 @@ public class ZLMHttpHookListener { subscribe.response(null, zlmServerConfig); } } - mediaServerService.zlmServerOnline(zlmServerConfig); }); + try { + HookZlmServerStartEvent event = new HookZlmServerStartEvent(this); + MediaServerItem mediaServerItem = mediaServerService.getOne(zlmServerConfig.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServerItem(mediaServerItem); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ZLM-HOOK-ZLM启动] 发送通知失败 ", e); + } return HookResult.SUCCESS(); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 510a972c0..de330c300 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -4,10 +4,13 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; +import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service("zlm") @@ -19,9 +22,12 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { @Autowired private ZLMServerFactory zlmServerFactory; + @Value("${sip.ip}") + private String sipIp; + @Override public int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { - return zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode);; + return zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode); } @Override @@ -68,4 +74,36 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { public void online(MediaServerItem mediaServerItem) { } + + @Override + public MediaServerItem checkMediaServer(String ip, int port, String secret) { + MediaServerItem mediaServerItem = new MediaServerItem(); + mediaServerItem.setIp(ip); + mediaServerItem.setHttpPort(port); + mediaServerItem.setSecret(secret); + JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); + if (responseJSON == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接失败"); + } + JSONArray data = responseJSON.getJSONArray("data"); + if (data == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败"); + } + ZLMServerConfig zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); + if (zlmServerConfig == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败"); + } + mediaServerItem.setId(zlmServerConfig.getGeneralMediaServerId()); + mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpPort()); + mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort()); + mediaServerItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); + mediaServerItem.setRtspPort(zlmServerConfig.getRtspPort()); + mediaServerItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); + mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); + mediaServerItem.setStreamIp(ip); + mediaServerItem.setHookIp(sipIp.split(",")[0]); + mediaServerItem.setSdpIp(ip); + mediaServerItem.setType("zlm"); + return mediaServerItem; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index 0637b5314..6f97558da 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -4,7 +4,9 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.DynamicTask; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; @@ -13,12 +15,17 @@ import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import java.io.File; +import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; /** @@ -42,6 +49,15 @@ public class ZLMMediaServerStatusManger { @Autowired private DynamicTask dynamicTask; + @Value("${server.ssl.enabled:false}") + private boolean sslEnabled; + + @Value("${server.port}") + private Integer serverPort; + + @Autowired + private UserSetting userSetting; + private final String type = "zlm"; @Async("taskExecutor") @@ -74,15 +90,13 @@ public class ZLMMediaServerStatusManger { return; } logger.info("[ZLM-HOOK事件-服务启动] ID:" + event.getMediaServerItem().getId()); - online(serverItem); + online(serverItem, null); } @Async("taskExecutor") @EventListener public void onApplicationEvent(HookZlmServerKeepaliveEvent event) { - if (event.getMediaServerItem() == null - || !type.equals(event.getMediaServerItem().getType()) - || event.getMediaServerItem().isStatus()) { + if (event.getMediaServerItem() == null) { return; } MediaServerItem serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); @@ -90,7 +104,19 @@ public class ZLMMediaServerStatusManger { return; } logger.info("[ZLM-HOOK事件-心跳] ID:" + event.getMediaServerItem().getId()); - online(serverItem); + online(serverItem, null); + } + + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaServerDeleteEvent event) { + if (event.getMediaServerId() == null) { + return; + } + logger.info("[ZLM-节点被移除] ID:" + event.getMediaServerId()); + offlineZlmPrimaryMap.remove(event.getMediaServerId()); + offlineZlmsecondaryMap.remove(event.getMediaServerId()); + offlineZlmTimeMap.remove(event.getMediaServerId()); } @Scheduled(fixedDelay = 10*1000) //每隔10秒检查一次 @@ -101,7 +127,7 @@ public class ZLMMediaServerStatusManger { } if (!offlineZlmPrimaryMap.isEmpty()) { for (MediaServerItem mediaServerItem : offlineZlmPrimaryMap.values()) { - if (offlineZlmTimeMap.get(mediaServerItem.getId()) > 30*60*1000) { + if (offlineZlmTimeMap.get(mediaServerItem.getId()) < System.currentTimeMillis() - 30*60*1000) { offlineZlmsecondaryMap.put(mediaServerItem.getId(), mediaServerItem); offlineZlmPrimaryMap.remove(mediaServerItem.getId()); continue; @@ -119,13 +145,13 @@ public class ZLMMediaServerStatusManger { }else { zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); initPort(mediaServerItem, zlmServerConfig); - online(mediaServerItem); + online(mediaServerItem, zlmServerConfig); } } } if (!offlineZlmsecondaryMap.isEmpty()) { for (MediaServerItem mediaServerItem : offlineZlmsecondaryMap.values()) { - if (offlineZlmTimeMap.get(mediaServerItem.getId()) < 30*60*1000) { + if (offlineZlmTimeMap.get(mediaServerItem.getId()) < System.currentTimeMillis() - 30*60*1000) { continue; } logger.info("[ZLM-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); @@ -143,20 +169,34 @@ public class ZLMMediaServerStatusManger { }else { zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); initPort(mediaServerItem, zlmServerConfig); - online(mediaServerItem); + online(mediaServerItem, zlmServerConfig); } } } } - private void online(MediaServerItem mediaServerItem) { + private void online(MediaServerItem mediaServerItem, ZLMServerConfig config) { offlineZlmPrimaryMap.remove(mediaServerItem.getId()); offlineZlmsecondaryMap.remove(mediaServerItem.getId()); offlineZlmTimeMap.remove(mediaServerItem.getId()); if (!mediaServerItem.isStatus()) { logger.info("[ZLM-连接成功] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); mediaServerItem.setStatus(true); + mediaServerItem.setHookAliveInterval(10F); mediaServerService.update(mediaServerItem); + if(mediaServerItem.isAutoConfig()) { + if (config == null) { + JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); + JSONArray data = responseJSON.getJSONArray("data"); + if (data != null && !data.isEmpty()) { + config = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); + } + } + if (config != null) { + setZLMConfig(mediaServerItem, "0".equals(config.getHookEnable()) + || !Objects.equals(mediaServerItem.getHookAliveInterval(), config.getHookAliveInterval())); + } + } } // 设置两次心跳未收到则认为zlm离线 String key = "zlm-keepalive-" + mediaServerItem.getId(); @@ -165,6 +205,8 @@ public class ZLMMediaServerStatusManger { mediaServerItem.setStatus(false); offlineZlmPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); offlineZlmTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + // TODO 发送离线通知 + mediaServerService.update(mediaServerItem); }, (int)(mediaServerItem.getHookAliveInterval() * 2 * 1000)); } private void initPort(MediaServerItem mediaServerItem, ZLMServerConfig zlmServerConfig) { @@ -186,7 +228,72 @@ public class ZLMMediaServerStatusManger { if (mediaServerItem.getRtpProxyPort() == 0) { mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); } - mediaServerItem.setHookAliveInterval(zlmServerConfig.getHookAliveInterval()); + mediaServerItem.setHookAliveInterval(10F); + } + + public void setZLMConfig(MediaServerItem mediaServerItem, boolean restart) { + logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + String protocol = sslEnabled ? "https" : "http"; + String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); + + Map param = new HashMap<>(); + param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline + if (mediaServerItem.getRtspPort() != 0) { + param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); + } + param.put("hook.enable","1"); + param.put("hook.on_flow_report",""); + param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); + param.put("hook.on_http_access",""); + param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); + param.put("hook.on_record_ts",""); + param.put("hook.on_rtsp_auth",""); + param.put("hook.on_rtsp_realm",""); + param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); + param.put("hook.on_shell_login",""); + param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); + param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); + param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); + param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); + param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); + param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); + param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); + param.put("hook.timeoutSec","30"); + param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); + // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 + // 置0关闭此特性(推流断开会导致立即断开播放器) + // 此参数不应大于播放器超时时间 + // 优化此消息以更快的收到流注销事件 + param.put("protocol.continue_push_ms", "3000" ); + // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, + // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 + if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { + param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); + } + + if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { + File recordPathFile = new File(mediaServerItem.getRecordPath()); + param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); + param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); + param.put("record.appName", recordPathFile.getName()); + } + + JSONObject responseJSON = zlmresTfulUtils.setServerConfig(mediaServerItem, param); + + if (responseJSON != null && responseJSON.getInteger("code") == 0) { + if (restart) { + logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + zlmresTfulUtils.restartServer(mediaServerItem); + }else { + logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + } + }else { + logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + } } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java index 46785911a..131b8a521 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java @@ -34,6 +34,7 @@ public interface MediaServerMapper { "record_day,"+ "record_path,"+ "default_server,"+ + "type,"+ "create_time,"+ "update_time,"+ "hook_alive_interval"+ @@ -60,6 +61,7 @@ public interface MediaServerMapper { "#{recordDay}, " + "#{recordPath}, " + "#{defaultServer}, " + + "#{type}, " + "#{createTime}, " + "#{updateTime}, " + "#{hookAliveInterval})") @@ -88,6 +90,7 @@ public interface MediaServerMapper { ", hook_alive_interval=#{hookAliveInterval}" + ", record_day=#{recordDay}" + ", record_path=#{recordPath}" + + ", type=#{type}" + "WHERE id=#{id}"+ " "}) int update(MediaServerItem mediaServerItem); @@ -113,6 +116,7 @@ public interface MediaServerMapper { ", record_assist_port=#{recordAssistPort}" + ", record_day=#{recordDay}" + ", record_path=#{recordPath}" + + ", type=#{type}" + ", hook_alive_interval=#{hookAliveInterval}" + "WHERE ip=#{ip} and http_port=#{httpPort}"+ " "}) diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java index 926d8a678..bf9cf4fed 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -76,7 +76,7 @@ public class CloudRecordController { } mediaServerItems.add(mediaServerItem); } else { - mediaServerItems = mediaServerService.getAll(); + mediaServerItems = mediaServerService.getAllOnlineList(); } if (mediaServerItems.isEmpty()) { return new ArrayList<>(); @@ -119,7 +119,7 @@ public class CloudRecordController { } mediaServerItems.add(mediaServerItem); } else { - mediaServerItems = mediaServerService.getAll(); + mediaServerItems = mediaServerService.getAllOnlineList(); } if (mediaServerItems.isEmpty()) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "当前无流媒体"); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index 65cb8a650..09f0abb9d 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -108,8 +108,8 @@ public class ServerController { @Parameter(name = "secret", description = "流媒体服务secret", required = true) @GetMapping(value = "/media_server/check") @ResponseBody - public MediaServerItem checkMediaServer(@RequestParam String ip, @RequestParam int port, @RequestParam String secret) { - return mediaServerService.checkMediaServer(ip, port, secret); + public MediaServerItem checkMediaServer(@RequestParam String ip, @RequestParam int port, @RequestParam String secret, @RequestParam String type) { + return mediaServerService.checkMediaServer(ip, port, secret, type); } @Operation(summary = "测试流媒体录像管理服务", security = @SecurityRequirement(name = JwtUtils.HEADER)) @@ -129,7 +129,7 @@ public class ServerController { @PostMapping(value = "/media_server/save") @ResponseBody public void saveMediaServer(@RequestBody MediaServerItem mediaServerItem) { - MediaServerItem mediaServerItemInDatabase = mediaServerService.getOne(mediaServerItem.getId()); + MediaServerItem mediaServerItemInDatabase = mediaServerService.getOneFromDatabase(mediaServerItem.getId()); if (mediaServerItemInDatabase != null) { mediaServerService.update(mediaServerItem); @@ -143,11 +143,7 @@ public class ServerController { @DeleteMapping(value = "/media_server/delete") @ResponseBody public void deleteMediaServer(@RequestParam String id) { - if (mediaServerService.getOne(id) == null) { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到此节点"); - } mediaServerService.delete(id); - mediaServerService.deleteDb(id); } diff --git a/web_src/src/components/dialog/MediaServerEdit.vue b/web_src/src/components/dialog/MediaServerEdit.vue index 9808a1c2e..9d8491eb1 100755 --- a/web_src/src/components/dialog/MediaServerEdit.vue +++ b/web_src/src/components/dialog/MediaServerEdit.vue @@ -20,6 +20,12 @@ + + + + + +
下一步 @@ -170,7 +176,7 @@ export default { hookIp: "", sdpIp: "", streamIp: "", - secret: "035c73f7-bb6b-4889-a715-d9eb2d1925cc", + secret: "", httpPort: "", httpSSlPort: "", recordAssistPort: "", @@ -182,6 +188,7 @@ export default { rtpProxyPort: "", rtspPort: "", rtspSSLPort: "", + type: "zlm", }, rtpPortRange1:30000, rtpPortRange2:30500, @@ -330,7 +337,7 @@ export default { hookIp: "", sdpIp: "", streamIp: "", - secret: "035c73f7-bb6b-4889-a715-d9eb2d1925cc", + secret: "", httpPort: "", httpSSlPort: "", recordAssistPort: "", diff --git a/web_src/src/components/service/MediaServer.js b/web_src/src/components/service/MediaServer.js index d4446f06f..b04953730 100755 --- a/web_src/src/components/service/MediaServer.js +++ b/web_src/src/components/service/MediaServer.js @@ -45,7 +45,8 @@ class MediaServer{ params: { ip: param.ip, port: param.httpPort, - secret: param.secret + secret: param.secret, + type: param.type } }).then(function (res) { if (typeof (callback) == "function") callback(res.data) diff --git a/数据库/abl/更新-mysql-2.7.0.sql b/数据库/abl/更新-mysql-2.7.0.sql index 2b38f06dd..de92cb2cd 100644 --- a/数据库/abl/更新-mysql-2.7.0.sql +++ b/数据库/abl/更新-mysql-2.7.0.sql @@ -1,2 +1,2 @@ alter table wvp_media_server - add type character varying(50) default 'zlm',; + add type character varying(50) default 'zlm'; From c7ca9703c196c5ac39de5594049171f3a1bf067c Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 20 Mar 2024 23:50:30 +0800 Subject: [PATCH 10/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=9C=8D=E5=8A=A1=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/StreamInfo.java | 11 +-- .../iot/vmp/conf/CloudRecordTimer.java | 9 +- .../iot/vmp/gb28181/task/SipRunner.java | 12 +-- .../genersoft/iot/vmp/media/bean/Track.java | 80 +++++++++++++++++ .../service/IMediaNodeServerService.java | 9 ++ .../media/service/IMediaServerService.java | 7 ++ .../service/impl/MediaServerServiceImpl.java | 31 +++++++ .../vmp/media/zlm/ZLMHttpHookListener.java | 37 +++++++- .../vmp/media/zlm/ZLMMediaListManager.java | 7 -- .../media/zlm/ZLMMediaNodeServerService.java | 86 +++++++++++++++++++ .../iot/vmp/media/zlm/ZLMServerFactory.java | 2 +- .../dto/hook/OnStreamChangedHookParam.java | 6 +- .../iot/vmp/service/IMediaService.java | 5 +- .../vmp/service/impl/DeviceServiceImpl.java | 11 +-- .../vmp/service/impl/MediaServiceImpl.java | 32 +++---- .../iot/vmp/service/impl/PlayServiceImpl.java | 37 +++++++- .../iot/vmp/vmanager/bean/StreamContent.java | 5 +- 17 files changed, 320 insertions(+), 67 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/bean/Track.java diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index 979f54a51..1cd09bb0f 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.common; +import com.genersoft.iot.vmp.media.bean.Track; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import io.swagger.v3.oas.annotations.media.Schema; @@ -70,7 +71,7 @@ public class StreamInfo implements Serializable, Cloneable{ @Schema(description = "流媒体ID") private String mediaServerId; @Schema(description = "流编码信息") - private Object tracks; + private Track track; @Schema(description = "开始时间") private String startTime; @Schema(description = "结束时间") @@ -473,12 +474,12 @@ public class StreamInfo implements Serializable, Cloneable{ this.mediaServerId = mediaServerId; } - public Object getTracks() { - return tracks; + public Track getTrack() { + return track; } - public void setTracks(Object tracks) { - this.tracks = tracks; + public void setTrack(Track track) { + this.track = track; } public String getStartTime() { diff --git a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java index e5ab4cf29..496e639af 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java @@ -32,9 +32,6 @@ public class CloudRecordTimer { @Autowired private CloudRecordServiceMapper cloudRecordServiceMapper; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - /** * 定时查询待删除的录像文件 */ @@ -66,10 +63,10 @@ public class CloudRecordTimer { // TODO 后续可以删除空了的过期日期文件夹 for (CloudRecordItem cloudRecordItem : cloudRecordItemList) { String date = new File(cloudRecordItem.getFilePath()).getParentFile().getName(); - JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServerItem, cloudRecordItem.getApp(), + boolean deleteResult = mediaServerService.deleteRecordDirectory(mediaServerItem, cloudRecordItem.getApp(), cloudRecordItem.getStream(), date, cloudRecordItem.getFileName()); - if (jsonObject.getInteger("code") != 0) { - logger.warn("[录像文件定时清理] 删除磁盘文件错误: {}:{}", cloudRecordItem.getFilePath(), jsonObject); + if (deleteResult) { + logger.warn("[录像文件定时清理] 删除磁盘文件成功: {}", cloudRecordItem.getFilePath()); } } result += cloudRecordServiceMapper.deleteList(cloudRecordItemList); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java index 852db420c..495c8fe8d 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java @@ -53,9 +53,6 @@ public class SipRunner implements CommandLineRunner { @Autowired private IDeviceService deviceService; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Autowired private IMediaServerService mediaServerService; @@ -109,13 +106,8 @@ public class SipRunner implements CommandLineRunner { redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(),sendRtpItem.getChannelId(), sendRtpItem.getCallId(),sendRtpItem.getStream()); if (mediaServerItem != null) { ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); - Map param = new HashMap<>(); - param.put("vhost","__defaultVhost__"); - param.put("app",sendRtpItem.getApp()); - param.put("stream",sendRtpItem.getStream()); - param.put("ssrc",sendRtpItem.getSsrc()); - JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { + boolean stopResult = mediaServerService.stopSendRtp(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc()); + if (stopResult) { ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getPlatformId()); if (platform != null) { try { diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java b/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java new file mode 100644 index 000000000..e95e7954d --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java @@ -0,0 +1,80 @@ +package com.genersoft.iot.vmp.media.bean; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * 视频信息 + */ +@Schema(description = "视频信息") +public class Track { + @Schema(description = "观看人数") + private Integer readerCount; + @Schema(description = "视频编码类型") + private String videoCodec; + @Schema(description = "视频宽度") + private Integer width; + @Schema(description = "视频高度") + private Integer height; + @Schema(description = "音频编码类型") + private String audioCodec; + @Schema(description = "音频通道数") + private Integer audioChannels; + @Schema(description = "音频采样率") + private Integer audioSampleRate; + + public Integer getReaderCount() { + return readerCount; + } + + public void setReaderCount(Integer readerCount) { + this.readerCount = readerCount; + } + + public String getVideoCodec() { + return videoCodec; + } + + public void setVideoCodec(String videoCodec) { + this.videoCodec = videoCodec; + } + + public Integer getWidth() { + return width; + } + + public void setWidth(Integer width) { + this.width = width; + } + + public Integer getHeight() { + return height; + } + + public void setHeight(Integer height) { + this.height = height; + } + + public String getAudioCodec() { + return audioCodec; + } + + public void setAudioCodec(String audioCodec) { + this.audioCodec = audioCodec; + } + + public Integer getAudioChannels() { + return audioChannels; + } + + public void setAudioChannels(Integer audioChannels) { + this.audioChannels = audioChannels; + } + + public Integer getAudioSampleRate() { + return audioSampleRate; + } + + public void setAudioSampleRate(Integer audioSampleRate) { + this.audioSampleRate = audioSampleRate; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 43f9fc5dd..971f48a60 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -1,8 +1,11 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import java.util.List; + public interface IMediaNodeServerService { int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); @@ -19,4 +22,10 @@ public interface IMediaNodeServerService { void online(MediaServerItem mediaServerItem); MediaServerItem checkMediaServer(String ip, int port, String secret); + + boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc); + + boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName); + + List getMediaList(MediaServerItem mediaServerItem, String app, String stream); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index d6015e0a8..ceaafc4bb 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -69,4 +70,10 @@ public interface IMediaServerService { List getAllWithAssistPort(); MediaServerItem getOneFromDatabase(String id); + + boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc); + + boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName); + + List getMediaList(MediaServerItem mediaInfo, String app, String stream); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index a959de78e..54e3330c1 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -1,7 +1,9 @@ package com.genersoft.iot.vmp.media.service.impl; +import com.alibaba.fastjson2.JSONObject; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.CommonCallback; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; @@ -533,4 +535,33 @@ public class MediaServerServiceImpl implements IMediaServerService { } + @Override + public boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaInfo.getType()); + if (mediaNodeServerService == null) { + logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaInfo.getType()); + return false; + } + return mediaNodeServerService.stopSendRtp(mediaInfo, app, stream, ssrc); + } + + @Override + public boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return false; + } + return mediaNodeServerService.deleteRecordDirectory(mediaServerItem, app, stream, date, fileName); + } + + @Override + public List getMediaList(MediaServerItem mediaServerItem, String app, String stream) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[getMediaList] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return new ArrayList<>(); + } + return mediaNodeServerService.getMediaList(mediaServerItem, app, stream); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 4b2557def..3ecfc6ced 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; +import com.genersoft.iot.vmp.media.bean.Track; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; @@ -33,6 +34,7 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; +import org.apache.poi.ss.formula.functions.T; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -368,6 +370,39 @@ public class ZLMHttpHookListener { } List tracks = param.getTracks(); + Track track = new Track(); + track.setReaderCount(param.getTotalReaderCount()); + for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { + switch (mediaTrack.getCodec_id()) { + case 0: + track.setVideoCodec("H264"); + break; + case 1: + track.setVideoCodec("H265"); + break; + case 2: + track.setAudioCodec("AAC"); + break; + case 3: + track.setAudioCodec("G711A"); + break; + case 4: + track.setAudioCodec("G711U"); + break; + } + if (mediaTrack.getSample_rate() > 0) { + track.setAudioSampleRate(mediaTrack.getSample_rate()); + } + if (mediaTrack.getChannels() > 0) { + track.setAudioChannels(mediaTrack.getChannels()); + } + if (mediaTrack.getHeight() > 0) { + track.setHeight(mediaTrack.getHeight()); + } + if (mediaTrack.getWidth() > 0) { + track.setWidth(mediaTrack.getWidth()); + } + } // TODO 重构此处逻辑 if (param.isRegist()) { // 处理流注册的鉴权信息, 流注销这里不再删除鉴权信息,下次来了新的鉴权信息会对就的进行覆盖 @@ -471,7 +506,7 @@ public class ZLMHttpHookListener { callId = streamAuthorityInfo.getCallId(); } StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo, - param.getApp(), param.getStream(), tracks, callId); + param.getApp(), param.getStream(), track, callId); param.setStreamInfo(new StreamContent(streamInfoByAppAndStream)); redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param); if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 0c15be172..0a0b6072f 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -7,7 +7,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IStreamPushService; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; @@ -30,12 +29,6 @@ public class ZLMMediaListManager { private Logger logger = LoggerFactory.getLogger("ZLMMediaListManager"); - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - - @Autowired - private IRedisCatchStorage redisCatchStorage; - @Autowired private IVideoManagerStorage storager; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index de330c300..55161a928 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -4,18 +4,31 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; +import com.genersoft.iot.vmp.media.bean.Track; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; +import com.genersoft.iot.vmp.service.impl.DeviceServiceImpl; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @Service("zlm") public class ZLMMediaNodeServerService implements IMediaNodeServerService { + private final static Logger logger = LoggerFactory.getLogger(ZLMMediaNodeServerService.class); + @Autowired private ZLMRESTfulUtils zlmresTfulUtils; @@ -106,4 +119,77 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { mediaServerItem.setType("zlm"); return mediaServerItem; } + + @Override + public boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc) { + Map param = new HashMap<>(); + param.put("vhost", "__defaultVhost__"); + param.put("app", app); + param.put("stream", stream); + if (!ObjectUtils.isEmpty(ssrc)) { + param.put("ssrc", ssrc); + } + JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaInfo, param); + return (jsonObject != null && jsonObject.getInteger("code") == 0); + + } + + @Override + public boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) { + logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件, server: {} {}:{}->{}/{}", mediaServerItem.getId(), app, stream, date, fileName); + JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServerItem, app, + stream, date, fileName); + if (jsonObject.getInteger("code") == 0) { + return true; + }else { + logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件错误, server: {} {}:{}->{}/{}, 结果: {}", mediaServerItem.getId(), app, stream, date, fileName, jsonObject); + return false; + } + } + + @Override + public List getMediaList(MediaServerItem mediaServerItem, String app, String stream) { + List streamInfoList = new ArrayList<>(); + JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream); + if (mediaList != null) { + if (mediaList.getInteger("code") == 0) { + JSONArray data = mediaList.getJSONArray("data"); + if (data == null) { + return null; + } + JSONObject mediaJSON = data.getJSONObject(0); + JSONArray tracks = mediaJSON.getJSONArray("tracks"); + + if (authority) { + streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, tracks, null, calld, true); + }else { + streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, tracks, null,null, true); + } + } + } + return streamInfoList; + } + + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String addr, String callId, boolean isPlay) { + StreamInfo streamInfoResult = new StreamInfo(); + streamInfoResult.setStream(stream); + streamInfoResult.setApp(app); + if (addr == null) { + addr = mediaInfo.getStreamIp(); + } + + streamInfoResult.setIp(addr); + streamInfoResult.setMediaServerId(mediaInfo.getId()); + String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; + streamInfoResult.setRtmp(addr, mediaInfo.getRtmpPort(),mediaInfo.getRtmpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtsp(addr, mediaInfo.getRtspPort(),mediaInfo.getRtspSSLPort(), app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setFmp4(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setHls(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setTs(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam, isPlay); + + streamInfoResult.setTrack(track); + return streamInfoResult; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java index 24222069d..15a1d7d98 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java @@ -17,7 +17,7 @@ import java.util.Map; @Component public class ZLMServerFactory { - private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory"); + private Logger logger = LoggerFactory.getLogger("ZLMServerFactory"); @Autowired private ZLMRESTfulUtils zlmresTfulUtils; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java index ffca0d5a7..efd14545e 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java @@ -32,7 +32,7 @@ public class OnStreamChangedHookParam extends HookParam{ /** * 观看总人数,包括hls/rtsp/rtmp/http-flv/ws-flv */ - private String totalReaderCount; + private int totalReaderCount; /** * 协议 包括hls/rtsp/rtmp/http-flv/ws-flv @@ -374,11 +374,11 @@ public class OnStreamChangedHookParam extends HookParam{ this.stream = stream; } - public String getTotalReaderCount() { + public int getTotalReaderCount() { return totalReaderCount; } - public void setTotalReaderCount(String totalReaderCount) { + public void setTotalReaderCount(int totalReaderCount) { this.totalReaderCount = totalReaderCount; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java index 82de3bb0f..b1261c77a 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service; import com.alibaba.fastjson2.JSONArray; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.media.bean.Track; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; /** @@ -32,7 +33,7 @@ public interface IMediaService { * @param stream * @return */ - StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Object tracks, String callId); + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Track track, String callId); /** * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 @@ -40,5 +41,5 @@ public interface IMediaService { * @param stream * @return */ - StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr, String callId, boolean isPlay); + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String addr, String callId, boolean isPlay); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index 616c7627b..65bd9f5d9 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.service.IDeviceService; @@ -54,6 +53,7 @@ public class DeviceServiceImpl implements IDeviceService { @Autowired private SIPCommander cmder; + @Autowired private DynamicTask dynamicTask; @@ -102,9 +102,6 @@ public class DeviceServiceImpl implements IDeviceService { @Autowired private AudioBroadcastManager audioBroadcastManager; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Override public void online(Device device, SipTransactionInfo sipTransactionInfo) { logger.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort()); @@ -245,11 +242,7 @@ public class DeviceServiceImpl implements IDeviceService { if (sendRtpItem != null) { redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Map param = new HashMap<>(); - param.put("vhost", "__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStream()); - zlmresTfulUtils.stopSendRtp(mediaInfo, param); + mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream()); } audioBroadcastManager.del(deviceId, audioBroadcastCatch.getChannelId()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 65fbfe04b..67c46b325 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaConfig; +import com.genersoft.iot.vmp.media.bean.Track; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; @@ -14,6 +15,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; +import java.util.List; + @Service public class MediaServiceImpl implements IMediaService { @@ -31,8 +34,8 @@ public class MediaServiceImpl implements IMediaService { @Override - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String callId) { - return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null, callId, true); + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String callId) { + return getStreamInfoByAppAndStream(mediaInfo, app, stream, track, null, callId, true); } @Override @@ -50,23 +53,12 @@ public class MediaServiceImpl implements IMediaService { if (streamAuthorityInfo != null) { calld = streamAuthorityInfo.getCallId(); } - JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, app, stream); - if (mediaList != null) { - if (mediaList.getInteger("code") == 0) { - JSONArray data = mediaList.getJSONArray("data"); - if (data == null) { - return null; - } - JSONObject mediaJSON = data.getJSONObject(0); - JSONArray tracks = mediaJSON.getJSONArray("tracks"); - if (authority) { - streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, addr, calld, true); - }else { - streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, addr,null, true); - } - } + List streamInfoList = mediaServerService.getMediaList(mediaInfo, app, stream); + if (streamInfoList.isEmpty()) { + return null; + }else { + return streamInfoList.get(0); } - return streamInfo; } @@ -77,7 +69,7 @@ public class MediaServiceImpl implements IMediaService { } @Override - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr, String callId, boolean isPlay) { + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String addr, String callId, boolean isPlay) { StreamInfo streamInfoResult = new StreamInfo(); streamInfoResult.setStream(stream); streamInfoResult.setApp(app); @@ -96,7 +88,7 @@ public class MediaServiceImpl implements IMediaService { streamInfoResult.setTs(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam, isPlay); - streamInfoResult.setTracks(tracks); + streamInfoResult.setTrack(track); return streamInfoResult; } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 48910ef7b..eae1dde96 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -18,6 +18,7 @@ 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.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.bean.Track; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; @@ -1048,7 +1049,41 @@ public class PlayServiceImpl implements IPlayService { public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, OnStreamChangedHookParam hookParam, String deviceId, String channelId) { - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", hookParam.getStream(), hookParam.getTracks(), null); + List tracks = hookParam.getTracks(); + Track track = new Track(); + track.setReaderCount(hookParam.getTotalReaderCount()); + for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { + switch (mediaTrack.getCodec_id()) { + case 0: + track.setVideoCodec("H264"); + break; + case 1: + track.setVideoCodec("H265"); + break; + case 2: + track.setAudioCodec("AAC"); + break; + case 3: + track.setAudioCodec("G711A"); + break; + case 4: + track.setAudioCodec("G711U"); + break; + } + if (mediaTrack.getSample_rate() > 0) { + track.setAudioSampleRate(mediaTrack.getSample_rate()); + } + if (mediaTrack.getChannels() > 0) { + track.setAudioChannels(mediaTrack.getChannels()); + } + if (mediaTrack.getHeight() > 0) { + track.setHeight(mediaTrack.getHeight()); + } + if (mediaTrack.getWidth() > 0) { + track.setWidth(mediaTrack.getWidth()); + } + } + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", hookParam.getStream(), track, null); streamInfo.setDeviceID(deviceId); streamInfo.setChannelId(channelId); return streamInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java index 4974209a5..2252a2524 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.vmanager.bean; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.media.bean.Track; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import io.swagger.v3.oas.annotations.media.Schema; @@ -86,7 +87,7 @@ public class StreamContent { private String mediaServerId; @Schema(description = "流编码信息") - private Object tracks; + private Track track; @Schema(description = "开始时间") private String startTime; @@ -170,7 +171,7 @@ public class StreamContent { } this.mediaServerId = streamInfo.getMediaServerId(); - this.tracks = streamInfo.getTracks(); + this.track = streamInfo.getTracks(); this.startTime = streamInfo.getStartTime(); this.endTime = streamInfo.getEndTime(); this.progress = streamInfo.getProgress(); From 913099291bbcf2607c17a51e7372fdee266c26c9 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Thu, 21 Mar 2024 18:21:30 +0800 Subject: [PATCH 11/58] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/service/IMediaNodeServerService.java | 2 +- .../iot/vmp/media/service/IMediaServerService.java | 2 +- .../vmp/media/service/impl/MediaServerServiceImpl.java | 5 ++--- .../iot/vmp/media/zlm/ZLMMediaNodeServerService.java | 9 ++++----- .../iot/vmp/service/impl/DeviceServiceImpl.java | 2 +- .../iot/vmp/service/impl/MediaServiceImpl.java | 6 ++---- .../iot/vmp/service/impl/StreamPushServiceImpl.java | 2 +- .../vmp/service/redisMsg/RedisStreamMsgListener.java | 2 +- .../genersoft/iot/vmp/vmanager/bean/StreamContent.java | 10 +++++----- 9 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 971f48a60..2f8983b5e 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -27,5 +27,5 @@ public interface IMediaNodeServerService { boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName); - List getMediaList(MediaServerItem mediaServerItem, String app, String stream); + List getMediaList(MediaServerItem mediaServerItem, String app, String stream, String callId); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index ceaafc4bb..2e5ab1f83 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -75,5 +75,5 @@ public interface IMediaServerService { boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName); - List getMediaList(MediaServerItem mediaInfo, String app, String stream); + List getMediaList(MediaServerItem mediaInfo, String app, String stream, String callId); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 54e3330c1..af5f1c556 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.media.service.impl; -import com.alibaba.fastjson2.JSONObject; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; @@ -556,12 +555,12 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public List getMediaList(MediaServerItem mediaServerItem, String app, String stream) { + public List getMediaList(MediaServerItem mediaServerItem, String app, String stream, String callId) { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); if (mediaNodeServerService == null) { logger.info("[getMediaList] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); return new ArrayList<>(); } - return mediaNodeServerService.getMediaList(mediaServerItem, app, stream); + return mediaNodeServerService.getMediaList(mediaServerItem, app, stream, callId); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 55161a928..6d55ac05d 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -148,7 +148,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public List getMediaList(MediaServerItem mediaServerItem, String app, String stream) { + public List getMediaList(MediaServerItem mediaServerItem, String app, String stream, String callId) { List streamInfoList = new ArrayList<>(); JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream); if (mediaList != null) { @@ -160,10 +160,9 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { JSONObject mediaJSON = data.getJSONObject(0); JSONArray tracks = mediaJSON.getJSONArray("tracks"); - if (authority) { - streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, tracks, null, calld, true); - }else { - streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, tracks, null,null, true); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, tracks, null, callId, true); + if (streamInfo != null) { + streamInfoList.add(streamInfo); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index a1c56ee87..dbf1a9141 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -242,7 +242,7 @@ public class DeviceServiceImpl implements IDeviceService { if (sendRtpItem != null) { redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream()); + mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), null); } audioBroadcastManager.del(deviceId, audioBroadcastCatch.getChannelId()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 67c46b325..b568ae237 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -1,14 +1,12 @@ package com.genersoft.iot.vmp.service.impl; -import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.media.bean.Track; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import org.springframework.beans.factory.annotation.Autowired; @@ -53,7 +51,7 @@ public class MediaServiceImpl implements IMediaService { if (streamAuthorityInfo != null) { calld = streamAuthorityInfo.getCallId(); } - List streamInfoList = mediaServerService.getMediaList(mediaInfo, app, stream); + List streamInfoList = mediaServerService.getMediaList(mediaInfo, app, stream, calld); if (streamInfoList.isEmpty()) { return null; }else { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index 14f0fe2a9..b9fd1dfaa 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -122,7 +122,7 @@ public class StreamPushServiceImpl implements IStreamPushService { streamPushItem.setStream(item.getStream()); streamPushItem.setAliveSecond(item.getAliveSecond()); streamPushItem.setOriginSock(item.getOriginSock()); - streamPushItem.setTotalReaderCount(item.getTotalReaderCount()); + streamPushItem.setTotalReaderCount(item.getTotalReaderCount() + ""); streamPushItem.setOriginType(item.getOriginType()); streamPushItem.setOriginTypeStr(item.getOriginTypeStr()); streamPushItem.setOriginUrl(item.getOriginUrl()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java index f5f29487e..5c332fd0c 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java @@ -72,7 +72,7 @@ public class RedisStreamMsgListener implements MessageListener { onStreamChangedHookParam.setMediaServerId(mediaServerId); onStreamChangedHookParam.setCreateStamp(System.currentTimeMillis()/1000); onStreamChangedHookParam.setAliveSecond(0L); - onStreamChangedHookParam.setTotalReaderCount("0"); + onStreamChangedHookParam.setTotalReaderCount(0); onStreamChangedHookParam.setOriginType(0); onStreamChangedHookParam.setOriginTypeStr("0"); onStreamChangedHookParam.setOriginTypeStr("unknown"); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java index 2252a2524..f1872ca79 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java @@ -171,7 +171,7 @@ public class StreamContent { } this.mediaServerId = streamInfo.getMediaServerId(); - this.track = streamInfo.getTracks(); + this.track = streamInfo.getTrack(); this.startTime = streamInfo.getStartTime(); this.endTime = streamInfo.getEndTime(); this.progress = streamInfo.getProgress(); @@ -389,12 +389,12 @@ public class StreamContent { this.mediaServerId = mediaServerId; } - public Object getTracks() { - return tracks; + public Track getTrack() { + return track; } - public void setTracks(Object tracks) { - this.tracks = tracks; + public void setTrack(Track track) { + this.track = track; } public String getStartTime() { From 4134c73745ff63d44186ed608735ea432b244755 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Thu, 21 Mar 2024 22:38:56 +0800 Subject: [PATCH 12/58] =?UTF-8?q?=E4=BC=98=E5=8C=96Track=E7=9A=84=E6=9E=84?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../media/abl/ABLMediaNodeServerService.java | 18 ++++ .../genersoft/iot/vmp/media/bean/Track.java | 96 +++++++++++++++++++ .../vmp/media/zlm/ZLMHttpHookListener.java | 36 +------ .../media/zlm/ZLMMediaNodeServerService.java | 12 +-- src/main/resources/application.yml | 2 +- 5 files changed, 120 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index 445e1e6a3..bd2a7be64 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -1,10 +1,13 @@ package com.genersoft.iot.vmp.media.abl; import com.genersoft.iot.vmp.common.CommonCallback; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.springframework.stereotype.Service; +import java.util.List; + @Service("abl") public class ABLMediaNodeServerService implements IMediaNodeServerService { @@ -47,4 +50,19 @@ public class ABLMediaNodeServerService implements IMediaNodeServerService { public MediaServerItem checkMediaServer(String ip, int port, String secret) { return null; } + + @Override + public boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc) { + return false; + } + + @Override + public boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) { + return false; + } + + @Override + public List getMediaList(MediaServerItem mediaServerItem, String app, String stream, String callId) { + return null; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java b/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java index e95e7954d..963474ea1 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java @@ -1,7 +1,12 @@ package com.genersoft.iot.vmp.media.bean; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + /** * 视频信息 */ @@ -22,6 +27,97 @@ public class Track { @Schema(description = "音频采样率") private Integer audioSampleRate; + public static Track getInstance(JSONObject jsonObject) { + Track track = new Track(); + Integer totalReaderCount = jsonObject.getInteger("totalReaderCount"); + if (totalReaderCount != null) { + track.setReaderCount(totalReaderCount); + } + JSONArray jsonArray = jsonObject.getJSONArray("tracks"); + if (jsonArray.isEmpty()) { + return null; + } + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject trackJson = jsonArray.getJSONObject(i); + Integer channels = trackJson.getInteger("channels"); + Integer codecId = trackJson.getInteger("codec_id"); + Integer codecType = trackJson.getInteger("codec_type"); + Integer sampleRate = trackJson.getInteger("sample_rate"); + Integer height = trackJson.getInteger("height"); + Integer width = trackJson.getInteger("height"); + if (channels != null) { + track.setAudioChannels(channels); + } + if (sampleRate != null) { + track.setAudioSampleRate(sampleRate); + } + if (height != null) { + track.setHeight(height); + } + if (width != null) { + track.setWidth(width); + } + if (codecId != null) { + switch (codecId) { + case 0: + track.setVideoCodec("H264"); + break; + case 1: + track.setVideoCodec("H265"); + break; + case 2: + track.setAudioCodec("AAC"); + break; + case 3: + track.setAudioCodec("G711A"); + break; + case 4: + track.setAudioCodec("G711U"); + break; + } + } + } + return track; + } + + public static Track getInstance(OnStreamChangedHookParam param) { + List tracks = param.getTracks(); + Track track = new Track(); + track.setReaderCount(param.getTotalReaderCount()); + for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { + switch (mediaTrack.getCodec_id()) { + case 0: + track.setVideoCodec("H264"); + break; + case 1: + track.setVideoCodec("H265"); + break; + case 2: + track.setAudioCodec("AAC"); + break; + case 3: + track.setAudioCodec("G711A"); + break; + case 4: + track.setAudioCodec("G711U"); + break; + } + if (mediaTrack.getSample_rate() > 0) { + track.setAudioSampleRate(mediaTrack.getSample_rate()); + } + if (mediaTrack.getChannels() > 0) { + track.setAudioChannels(mediaTrack.getChannels()); + } + if (mediaTrack.getHeight() > 0) { + track.setHeight(mediaTrack.getHeight()); + } + if (mediaTrack.getWidth() > 0) { + track.setWidth(mediaTrack.getWidth()); + } + } + return track; + } + public Integer getReaderCount() { return readerCount; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index ac68bfea1..f5d664af5 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -369,40 +369,6 @@ public class ZLMHttpHookListener { subscribe.response(mediaInfo, param); } - List tracks = param.getTracks(); - Track track = new Track(); - track.setReaderCount(param.getTotalReaderCount()); - for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { - switch (mediaTrack.getCodec_id()) { - case 0: - track.setVideoCodec("H264"); - break; - case 1: - track.setVideoCodec("H265"); - break; - case 2: - track.setAudioCodec("AAC"); - break; - case 3: - track.setAudioCodec("G711A"); - break; - case 4: - track.setAudioCodec("G711U"); - break; - } - if (mediaTrack.getSample_rate() > 0) { - track.setAudioSampleRate(mediaTrack.getSample_rate()); - } - if (mediaTrack.getChannels() > 0) { - track.setAudioChannels(mediaTrack.getChannels()); - } - if (mediaTrack.getHeight() > 0) { - track.setHeight(mediaTrack.getHeight()); - } - if (mediaTrack.getWidth() > 0) { - track.setWidth(mediaTrack.getWidth()); - } - } // TODO 重构此处逻辑 if (param.isRegist()) { // 处理流注册的鉴权信息, 流注销这里不再删除鉴权信息,下次来了新的鉴权信息会对就的进行覆盖 @@ -506,7 +472,7 @@ public class ZLMHttpHookListener { callId = streamAuthorityInfo.getCallId(); } StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo, - param.getApp(), param.getStream(), track, callId); + param.getApp(), param.getStream(), Track.getInstance(param), callId); param.setStreamInfo(new StreamContent(streamInfoByAppAndStream)); redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param); if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 6d55ac05d..686981e62 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -158,9 +158,8 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { return null; } JSONObject mediaJSON = data.getJSONObject(0); - JSONArray tracks = mediaJSON.getJSONArray("tracks"); - - StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, tracks, null, callId, true); + Track track = Track.getInstance(mediaJSON); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, track, callId, true); if (streamInfo != null) { streamInfoList.add(streamInfo); } @@ -169,14 +168,11 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { return streamInfoList; } - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String addr, String callId, boolean isPlay) { + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String callId, boolean isPlay) { StreamInfo streamInfoResult = new StreamInfo(); streamInfoResult.setStream(stream); streamInfoResult.setApp(app); - if (addr == null) { - addr = mediaInfo.getStreamIp(); - } - + String addr = mediaInfo.getStreamIp(); streamInfoResult.setIp(addr); streamInfoResult.setMediaServerId(mediaInfo.getId()); String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3f478442e..3d36b8474 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,4 +2,4 @@ spring: application: name: wvp profiles: - active: local \ No newline at end of file + active: abl \ No newline at end of file From b90dc789b429c31674c26bb3ff309b987afaa77a Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Thu, 21 Mar 2024 23:39:32 +0800 Subject: [PATCH 13/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=9C=8D=E5=8A=A1=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/StreamInfo.java | 12 +- .../iot/vmp/common/VideoManagerConstants.java | 2 +- .../iot/vmp/conf/CloudRecordTimer.java | 8 +- .../genersoft/iot/vmp/conf/MediaConfig.java | 6 +- .../iot/vmp/conf/ProxyServletConfig.java | 22 +-- .../vmp/gb28181/bean/AudioBroadcastCatch.java | 10 +- .../vmp/gb28181/bean/InviteStreamInfo.java | 10 +- .../iot/vmp/gb28181/task/SipRunner.java | 6 +- .../gb28181/transmit/cmd/ISIPCommander.java | 14 +- .../cmd/ISIPCommanderForPlatform.java | 4 +- .../transmit/cmd/impl/SIPCommander.java | 16 +- .../cmd/impl/SIPCommanderFroPlatform.java | 8 +- .../request/impl/AckRequestProcessor.java | 6 +- .../request/impl/ByeRequestProcessor.java | 10 +- .../request/impl/InviteRequestProcessor.java | 20 +- .../cmd/BroadcastNotifyMessageHandler.java | 4 +- .../iot/vmp/media/MediaServerConfig.java | 10 +- .../media/abl/ABLMediaNodeServerService.java | 40 ++-- .../media/bean/{Track.java => MediaInfo.java} | 68 ++++--- .../media/event/MediaServerChangeEvent.java | 12 +- .../service/IMediaNodeServerService.java | 35 ++-- .../media/service/IMediaServerService.java | 61 +++--- .../service/impl/MediaServerServiceImpl.java | 149 +++++++++----- .../iot/vmp/media/zlm/AssistRESTfulUtils.java | 12 +- .../iot/vmp/media/zlm/SendRtpPortManager.java | 4 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 17 +- .../vmp/media/zlm/ZLMMediaListManager.java | 2 +- .../media/zlm/ZLMMediaNodeServerService.java | 88 ++++++--- .../media/zlm/ZLMMediaServerStatusManger.java | 22 +-- .../iot/vmp/media/zlm/ZLMRESTfulUtils.java | 68 +++---- .../iot/vmp/media/zlm/ZLMServerFactory.java | 30 +-- .../vmp/media/zlm/ZlmHttpHookSubscribe.java | 4 +- ...{MediaServerItem.java => MediaServer.java} | 6 +- .../media/zlm/dto/MediaServerItemLite.java | 2 +- .../event/HookZlmServerKeepaliveEvent.java | 8 +- .../zlm/event/HookZlmServerStartEvent.java | 8 +- .../iot/vmp/service/ICloudRecordService.java | 8 +- .../iot/vmp/service/IMediaService.java | 9 +- .../iot/vmp/service/IPlatformService.java | 6 +- .../iot/vmp/service/IPlayService.java | 18 +- .../iot/vmp/service/IStreamProxyService.java | 4 +- .../iot/vmp/service/IStreamPushService.java | 4 +- .../iot/vmp/service/bean/PlayBackResult.java | 8 +- .../vmp/service/bean/ResponseSendItemMsg.java | 8 +- .../service/impl/CloudRecordServiceImpl.java | 18 +- .../vmp/service/impl/DeviceServiceImpl.java | 4 +- .../vmp/service/impl/MediaServiceImpl.java | 36 ++-- .../vmp/service/impl/PlatformServiceImpl.java | 24 +-- .../iot/vmp/service/impl/PlayServiceImpl.java | 185 +++++------------- .../service/impl/StreamProxyServiceImpl.java | 18 +- .../service/impl/StreamPushServiceImpl.java | 10 +- .../redisMsg/RedisGbPlayMsgListener.java | 10 +- .../RedisPushStreamCloseResponseListener.java | 4 +- .../iot/vmp/storager/IRedisCatchStorage.java | 4 +- .../dao/CloudRecordServiceMapper.java | 6 +- .../vmp/storager/dao/MediaServerMapper.java | 18 +- .../storager/impl/RedisCatchStorageImpl.java | 4 +- .../iot/vmp/utils/CloudRecordUtils.java | 4 +- .../iot/vmp/vmanager/bean/StreamContent.java | 14 +- .../cloudRecord/CloudRecordController.java | 12 +- .../vmanager/gb28181/play/PlayController.java | 8 +- .../iot/vmp/vmanager/ps/PsController.java | 12 +- .../iot/vmp/vmanager/rtp/RtpController.java | 10 +- .../vmp/vmanager/server/ServerController.java | 18 +- .../streamProxy/StreamProxyController.java | 4 +- .../vmp/web/gb28181/ApiStreamController.java | 4 +- 66 files changed, 667 insertions(+), 629 deletions(-) rename src/main/java/com/genersoft/iot/vmp/media/bean/{Track.java => MediaInfo.java} (69%) rename src/main/java/com/genersoft/iot/vmp/media/zlm/dto/{MediaServerItem.java => MediaServer.java} (98%) diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index 1cd09bb0f..979797d3b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.common; -import com.genersoft.iot.vmp.media.bean.Track; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import io.swagger.v3.oas.annotations.media.Schema; @@ -71,7 +71,7 @@ public class StreamInfo implements Serializable, Cloneable{ @Schema(description = "流媒体ID") private String mediaServerId; @Schema(description = "流编码信息") - private Track track; + private MediaInfo mediaInfo; @Schema(description = "开始时间") private String startTime; @Schema(description = "结束时间") @@ -474,12 +474,12 @@ public class StreamInfo implements Serializable, Cloneable{ this.mediaServerId = mediaServerId; } - public Track getTrack() { - return track; + public MediaInfo getMediaInfo() { + return mediaInfo; } - public void setTrack(Track track) { - this.track = track; + public void setMediaInfo(MediaInfo mediaInfo) { + this.mediaInfo = mediaInfo; } public String getStartTime() { diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index d19b8f051..bfd39c25d 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -12,7 +12,7 @@ public class VideoManagerConstants { public static final String WVP_SERVER_STREAM_PREFIX = "VMP_SIGNALLING_STREAM_"; - public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_"; + public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_INFO_"; public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_"; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java index 496e639af..b2cd1211f 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java @@ -1,9 +1,7 @@ package com.genersoft.iot.vmp.conf; -import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper; @@ -40,12 +38,12 @@ public class CloudRecordTimer { public void execute(){ logger.info("[录像文件定时清理] 开始清理过期录像文件"); // 获取配置了assist的流媒体节点 - List mediaServerItemList = mediaServerService.getAllOnline(); + List mediaServerItemList = mediaServerService.getAllOnline(); if (mediaServerItemList.isEmpty()) { return; } long result = 0; - for (MediaServerItem mediaServerItem : mediaServerItemList) { + for (MediaServer mediaServerItem : mediaServerItemList) { Calendar lastCalendar = Calendar.getInstance(); if (mediaServerItem.getRecordDay() > 0) { diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java index 4664310da..baf819fb7 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.conf; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.utils.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -199,8 +199,8 @@ public class MediaConfig{ return sipDomain; } - public MediaServerItem getMediaSerItem(){ - MediaServerItem mediaServerItem = new MediaServerItem(); + public MediaServer getMediaSerItem(){ + MediaServer mediaServerItem = new MediaServer(); mediaServerItem.setId(id); mediaServerItem.setIp(ip); mediaServerItem.setDefaultServer(true); diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java index 560cae21f..aaa99fca8 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.conf; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; @@ -54,7 +54,7 @@ public class ProxyServletConfig { @Override protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); - MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); + MediaServer mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); if (mediaInfo != null) { if (!ObjectUtils.isEmpty(queryStr)) { queryStr += "&secret=" + mediaInfo.getSecret(); @@ -103,7 +103,7 @@ public class ProxyServletConfig { @Override protected String getTargetUri(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServer mediaInfo = getMediaInfoByUri(requestURI); String uri = null; if (mediaInfo != null) { @@ -121,7 +121,7 @@ public class ProxyServletConfig { @Override protected HttpHost getTargetHost(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServer mediaInfo = getMediaInfoByUri(requestURI); HttpHost host; if (mediaInfo != null) { host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort()); @@ -135,7 +135,7 @@ public class ProxyServletConfig { /** * 根据uri获取流媒体信息 */ - MediaServerItem getMediaInfoByUri(String uri){ + MediaServer getMediaInfoByUri(String uri){ String[] split = uri.split("/"); String mediaServerId = split[2]; if ("default".equalsIgnoreCase(mediaServerId)) { @@ -151,7 +151,7 @@ public class ProxyServletConfig { @Override protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServer mediaInfo = getMediaInfoByUri(requestURI); String url = super.rewriteUrlFromRequest(servletRequest); if (mediaInfo == null) { logger.error("[ZLM服务访问代理],错误:处理url信息时未找到流媒体信息=>{}", requestURI); @@ -181,7 +181,7 @@ public class ProxyServletConfig { @Override protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); - MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); + MediaServer mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); if (mediaInfo == null) { return null; } @@ -238,7 +238,7 @@ public class ProxyServletConfig { @Override protected String getTargetUri(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServer mediaInfo = getMediaInfoByUri(requestURI); String uri = null; if (mediaInfo != null) { @@ -256,7 +256,7 @@ public class ProxyServletConfig { @Override protected HttpHost getTargetHost(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServer mediaInfo = getMediaInfoByUri(requestURI); HttpHost host; if (mediaInfo != null) { host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort()); @@ -270,7 +270,7 @@ public class ProxyServletConfig { /** * 根据uri获取流媒体信息 */ - MediaServerItem getMediaInfoByUri(String uri){ + MediaServer getMediaInfoByUri(String uri){ String[] split = uri.split("/"); String mediaServerId = split[2]; if ("default".equalsIgnoreCase(mediaServerId)) { @@ -287,7 +287,7 @@ public class ProxyServletConfig { @Override protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServer mediaInfo = getMediaInfoByUri(requestURI); String url = super.rewriteUrlFromRequest(servletRequest); if (mediaInfo == null) { logger.error("[录像服务访问代理],错误:处理url信息时未找到流媒体信息=>{}", requestURI); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/AudioBroadcastCatch.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/AudioBroadcastCatch.java index 814d9847a..237be7e49 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/AudioBroadcastCatch.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/AudioBroadcastCatch.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.gb28181.bean; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent; import gov.nist.javax.sip.message.SIPResponse; @@ -15,7 +15,7 @@ public class AudioBroadcastCatch { public AudioBroadcastCatch( String deviceId, String channelId, - MediaServerItem mediaServerItem, + MediaServer mediaServerItem, String app, String stream, AudioBroadcastEvent event, @@ -48,7 +48,7 @@ public class AudioBroadcastCatch { /** * 流媒体信息 */ - private MediaServerItem mediaServerItem; + private MediaServer mediaServerItem; /** * 关联的流APP @@ -109,11 +109,11 @@ public class AudioBroadcastCatch { return sipTransactionInfo; } - public MediaServerItem getMediaServerItem() { + public MediaServer getMediaServerItem() { return mediaServerItem; } - public void setMediaServerItem(MediaServerItem mediaServerItem) { + public void setMediaServerItem(MediaServer mediaServerItem) { this.mediaServerItem = mediaServerItem; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java index 134930b33..005994139 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java @@ -1,11 +1,11 @@ package com.genersoft.iot.vmp.gb28181.bean; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; public class InviteStreamInfo { - public InviteStreamInfo(MediaServerItem mediaServerItem, JSONObject response, String callId, String app, String stream) { + public InviteStreamInfo(MediaServer mediaServerItem, JSONObject response, String callId, String app, String stream) { this.mediaServerItem = mediaServerItem; this.response = response; this.callId = callId; @@ -13,17 +13,17 @@ public class InviteStreamInfo { this.stream = stream; } - private MediaServerItem mediaServerItem; + private MediaServer mediaServerItem; private JSONObject response; private String callId; private String app; private String stream; - public MediaServerItem getMediaServerItem() { + public MediaServer getMediaServerItem() { return mediaServerItem; } - public void setMediaServerItem(MediaServerItem mediaServerItem) { + public void setMediaServerItem(MediaServer mediaServerItem) { this.mediaServerItem = mediaServerItem; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java index 495c8fe8d..234e268bc 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java @@ -1,14 +1,12 @@ package com.genersoft.iot.vmp.gb28181.task; -import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; @@ -102,7 +100,7 @@ public class SipRunner implements CommandLineRunner { List sendRtpItems = redisCatchStorage.queryAllSendRTPServer(); if (sendRtpItems.size() > 0) { for (SendRtpItem sendRtpItem : sendRtpItems) { - MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(),sendRtpItem.getChannelId(), sendRtpItem.getCallId(),sendRtpItem.getStream()); if (mediaServerItem != null) { ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index d48e3a8b2..f30ead17d 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import gov.nist.javax.sip.message.SIPRequest; @@ -100,7 +100,7 @@ public interface ISIPCommander { * @param device 视频设备 * @param channel 预览通道 */ - void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; + void playStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; /** * 请求回放视频流 @@ -110,7 +110,7 @@ public interface ISIPCommander { * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss */ - void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; + void playbackStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; /** * 请求历史媒体下载 @@ -121,9 +121,9 @@ public interface ISIPCommander { * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss * @param downloadSpeed 下载倍速参数 */ - void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, - String startTime, String endTime, int downloadSpeed, ZlmHttpHookSubscribe.Event hookEvent, - SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; + void downloadStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, + String startTime, String endTime, int downloadSpeed, ZlmHttpHookSubscribe.Event hookEvent, + SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; /** @@ -131,7 +131,7 @@ public interface ISIPCommander { */ void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException; - void talkStreamCmd(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem, Device device, String channelId, String callId, ZlmHttpHookSubscribe.Event event, ZlmHttpHookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; + void talkStreamCmd(MediaServer mediaServerItem, SendRtpItem sendRtpItem, Device device, String channelId, String callId, ZlmHttpHookSubscribe.Event event, ZlmHttpHookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; void streamByeCmd(Device device, String channelId, String stream, String callId) throws InvalidArgumentException, ParseException, SipException, SsrcTransactionNotFoundException; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java index a412a6c74..5c088d50e 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -154,7 +154,7 @@ public interface ISIPCommanderForPlatform { void streamByeCmd(ParentPlatform platform, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException; - void broadcastInviteCmd(ParentPlatform platform, String channelId, MediaServerItem mediaServerItem, + void broadcastInviteCmd(ParentPlatform platform, String channelId, MediaServer mediaServerItem, SSRCInfo ssrcInfo, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws ParseException, SipException, InvalidArgumentException; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index cb156a8c8..fcbe6d4c4 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -23,7 +23,7 @@ import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 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.HookSubscribeForStreamPush; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -274,7 +274,7 @@ public class SIPCommander implements ISIPCommander { * @param errorEvent sip错误订阅 */ @Override - public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, + public void playStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { String stream = ssrcInfo.getStream(); @@ -284,7 +284,7 @@ public class SIPCommander implements ISIPCommander { logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { + subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> { if (event != null) { event.response(mediaServerItemInUse, hookParam); subscribe.removeSubscribe(hookSubscribe); @@ -383,7 +383,7 @@ public class SIPCommander implements ISIPCommander { * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss */ @Override - public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, + public void playbackStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { @@ -459,7 +459,7 @@ public class SIPCommander implements ISIPCommander { HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); // 添加订阅 - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { + subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> { if (hookEvent != null) { hookEvent.response(mediaServerItemInUse, hookParam); } @@ -485,10 +485,10 @@ public class SIPCommander implements ISIPCommander { * @param downloadSpeed 下载倍速参数 */ @Override - public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, + public void downloadStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, int downloadSpeed, ZlmHttpHookSubscribe.Event hookEvent, - SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { + SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); String sdpIp; @@ -594,7 +594,7 @@ public class SIPCommander implements ISIPCommander { } @Override - public void talkStreamCmd(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem, Device device, String channelId, String callId, ZlmHttpHookSubscribe.Event event, ZlmHttpHookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { + public void talkStreamCmd(MediaServer mediaServerItem, SendRtpItem sendRtpItem, Device device, String channelId, String callId, ZlmHttpHookSubscribe.Event event, ZlmHttpHookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { String stream = sendRtpItem.getStream(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index f2869855f..20d78e857 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -17,7 +17,7 @@ import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 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.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; @@ -844,7 +844,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { } logger.info("[向上级发送BYE], {}/{}", platform.getServerGBId(), sendRtpItem.getChannelId()); String mediaServerId = sendRtpItem.getMediaServerId(); - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); if (mediaServerItem != null) { mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc()); zlmServerFactory.closeRtpServer(mediaServerItem, sendRtpItem.getStream()); @@ -895,7 +895,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { } @Override - public void broadcastInviteCmd(ParentPlatform platform, String channelId, MediaServerItem mediaServerItem, + public void broadcastInviteCmd(ParentPlatform platform, String channelId, MediaServer mediaServerItem, SSRCInfo ssrcInfo, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws ParseException, SipException, InvalidArgumentException { String stream = ssrcInfo.getStream(); @@ -906,7 +906,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { + subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> { if (event != null) { event.response(mediaServerItemInUse, hookParam); subscribe.removeSubscribe(hookSubscribe); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index e6d8fc127..a27ad44a7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlayService; @@ -104,7 +104,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In logger.info("收到ACK,rtp/{} TCP主动方式后续处理", sendRtpItem.getStream()); return; } - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); logger.info("收到ACK,rtp/{}开始向上级推流, 目标={}:{},SSRC={}, 协议:{}", sendRtpItem.getStream(), sendRtpItem.getIp(), @@ -173,7 +173,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In return param; } - private JSONObject sendRtp(SendRtpItem sendRtpItem, MediaServerItem mediaInfo, Map param){ + private JSONObject sendRtp(SendRtpItem sendRtpItem, MediaServer mediaInfo, Map param){ JSONObject startSendRtpStreamResult = null; if (sendRtpItem.getLocalPort() != 0) { if (sendRtpItem.isTcpActive()) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java index 5f51fb26f..3b1788545 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java @@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; @@ -146,7 +146,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In redisGbPlayMsgListener.sendMsgForStopSendRtpStream(sendRtpItem.getServerId(), streamMsg); } }else { - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), callIdHeader.getCallId(), null); zlmServerFactory.stopSendRtpStream(mediaInfo, param); @@ -166,7 +166,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In } } }else { - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), callIdHeader.getCallId(), null); zlmServerFactory.stopSendRtpStream(mediaInfo, param); @@ -174,7 +174,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In mediaServerService.releaseSsrc(mediaInfo.getId(), sendRtpItem.getSsrc()); } } - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); if (mediaInfo != null) { AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); if (audioBroadcastCatch != null && audioBroadcastCatch.getSipTransactionInfo().getCallId().equals(callIdHeader.getCallId())) { @@ -246,7 +246,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In } } // 释放ssrc - MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); if (mediaServerItem != null) { mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransaction.getSsrc()); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 4157fc83f..0f83bd8fb 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -192,7 +192,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); PlatformCatalog catalog = storager.getCatalog(requesterId, channelId); - MediaServerItem mediaServerItem = null; + MediaServer mediaServerItem = null; StreamPushItem streamPushItem = null; StreamProxyItem proxyByAppAndStream = null; // 不是通道可能是直播流 @@ -398,7 +398,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements Long finalStopTime = stopTime; ErrorCallback hookEvent = (code, msg, data) -> { StreamInfo streamInfo = (StreamInfo)data; - MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId()); + MediaServer mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId()); logger.info("[上级Invite]下级已经开始推流。 回复200OK(SDP), {}/{}", streamInfo.getApp(), streamInfo.getStream()); // * 0 等待设备推流上来 // * 1 下级已经推流,等待上级平台回复ack @@ -452,7 +452,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements responseSdpAck(request, content.toString(), platform); // tcp主动模式,回复sdp后开启监听 if (sendRtpItem.isTcpActive()) { - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); Map param = new HashMap<>(12); param.put("vhost","__defaultVhost__"); param.put("app",sendRtpItem.getApp()); @@ -624,7 +624,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements * 安排推流 */ private void pushProxyStream(RequestEvent evt, SIPRequest request, GbStream gbStream, ParentPlatform platform, - CallIdHeader callIdHeader, MediaServerItem mediaServerItem, + CallIdHeader callIdHeader, MediaServer mediaServerItem, int port, Boolean tcpActive, boolean mediaTransmissionTCP, String channelId, String addressStr, String ssrc, String requesterId) { Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); @@ -662,7 +662,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements } private void pushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, - CallIdHeader callIdHeader, MediaServerItem mediaServerItem, + CallIdHeader callIdHeader, MediaServer mediaServerItem, int port, Boolean tcpActive, boolean mediaTransmissionTCP, String channelId, String addressStr, String ssrc, String requesterId) { // 推流 @@ -714,7 +714,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements * 通知流上线 */ private void notifyStreamOnline(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, - CallIdHeader callIdHeader, MediaServerItem mediaServerItem, + CallIdHeader callIdHeader, MediaServer mediaServerItem, int port, Boolean tcpActive, boolean mediaTransmissionTCP, String channelId, String addressStr, String ssrc, String requesterId) { if ("proxy".equals(gbStream.getStreamType())) { @@ -837,7 +837,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements * 来自其他wvp的推流 */ private void otherWvpPushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform, - CallIdHeader callIdHeader, MediaServerItem mediaServerItem, + CallIdHeader callIdHeader, MediaServer mediaServerItem, int port, Boolean tcpActive, boolean mediaTransmissionTCP, String channelId, String addressStr, String ssrc, String requesterId) { logger.info("[级联点播]直播流来自其他平台,发送redis消息"); @@ -900,7 +900,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements }); } - public SIPResponse sendStreamAck(MediaServerItem mediaServerItem, SIPRequest request, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) { + public SIPResponse sendStreamAck(MediaServer mediaServerItem, SIPRequest request, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) { StringBuffer content = new StringBuffer(200); content.append("v=0\r\n"); @@ -1042,7 +1042,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}, {}", requesterId, addressStr, port, gb28181Sdp.getSsrc(), mediaTransmissionTCP ? (tcpActive ? "TCP主动" : "TCP被动") : "UDP"); - MediaServerItem mediaServerItem = broadcastCatch.getMediaServerItem(); + MediaServer mediaServerItem = broadcastCatch.getMediaServerItem(); if (mediaServerItem == null) { logger.warn("未找到语音喊话使用的zlm"); try { @@ -1119,7 +1119,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements } } - SIPResponse sendOk(Device device, SendRtpItem sendRtpItem, SessionDescription sdp, SIPRequest request, MediaServerItem mediaServerItem, boolean mediaTransmissionTCP, String ssrc) { + SIPResponse sendOk(Device device, SendRtpItem sendRtpItem, SessionDescription sdp, SIPRequest request, MediaServer mediaServerItem, boolean mediaTransmissionTCP, String ssrc) { SIPResponse sipResponse = null; try { sendRtpItem.setStatus(2); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java index fe19ec622..57b76829e 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -120,7 +120,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp return; } - MediaServerItem mediaServerForMinimumLoad = mediaServerService.getMediaServerForMinimumLoad(null); + MediaServer mediaServerForMinimumLoad = mediaServerService.getMediaServerForMinimumLoad(null); commanderForPlatform.broadcastResultCmd(platform, deviceChannel, sn, true, eventResult->{ logger.info("[国标级联] 语音喊话 回复失败 platform: {}, 错误:{}/{}", platform.getServerGBId(), eventResult.statusCode, eventResult.msg); }, eventResult->{ diff --git a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java index 761d97091..942f63a95 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.media; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -37,15 +37,15 @@ public class MediaServerConfig implements CommandLineRunner { public void run(String... strings) throws Exception { // 清理所有在线节点的缓存信息 mediaServerService.clearMediaServerForOnline(); - MediaServerItem defaultMediaServer = mediaServerService.getDefaultMediaServer(); - MediaServerItem mediaSerItemInConfig = mediaConfig.getMediaSerItem(); + MediaServer defaultMediaServer = mediaServerService.getDefaultMediaServer(); + MediaServer mediaSerItemInConfig = mediaConfig.getMediaSerItem(); if (defaultMediaServer != null && mediaSerItemInConfig.getId().equals(defaultMediaServer.getId())) { mediaServerService.update(mediaSerItemInConfig); }else { if (defaultMediaServer != null) { mediaServerService.delete(defaultMediaServer.getId()); } - MediaServerItem mediaServerItem = mediaServerService.getOneFromDatabase(mediaSerItemInConfig.getId()); + MediaServer mediaServerItem = mediaServerService.getOneFromDatabase(mediaSerItemInConfig.getId()); if (mediaServerItem == null) { mediaServerService.add(mediaSerItemInConfig); }else { @@ -55,7 +55,7 @@ public class MediaServerConfig implements CommandLineRunner { // 发送媒体节点变化事件 mediaServerService.syncCatchFromDatabase(); // 获取所有的zlm, 并开启主动连接 - List all = mediaServerService.getAllFromDatabase(); + List all = mediaServerService.getAllFromDatabase(); logger.info("[媒体节点] 加载节点列表, 共{}个节点", all.size()); MediaServerChangeEvent event = new MediaServerChangeEvent(this); event.setMediaServerItemList(all); diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index bd2a7be64..59b1c8d95 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -2,8 +2,9 @@ package com.genersoft.iot.vmp.media.abl; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.springframework.stereotype.Service; import java.util.List; @@ -12,57 +13,72 @@ import java.util.List; public class ABLMediaNodeServerService implements IMediaNodeServerService { @Override - public int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { + public int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { return 0; } @Override - public void closeRtpServer(MediaServerItem mediaServerItem, String streamId) { + public void closeRtpServer(MediaServer mediaServerItem, String streamId) { } @Override - public void closeRtpServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback) { + public void closeRtpServer(MediaServer mediaServerItem, String streamId, CommonCallback callback) { } @Override - public void closeStreams(MediaServerItem mediaServerItem, String rtp, String streamId) { + public void closeStreams(MediaServer mediaServerItem, String rtp, String streamId) { } @Override - public Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) { + public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { return null; } @Override - public boolean checkNodeId(MediaServerItem mediaServerItem) { + public boolean checkNodeId(MediaServer mediaServerItem) { return false; } @Override - public void online(MediaServerItem mediaServerItem) { + public void online(MediaServer mediaServerItem) { } @Override - public MediaServerItem checkMediaServer(String ip, int port, String secret) { + public MediaServer checkMediaServer(String ip, int port, String secret) { return null; } @Override - public boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc) { + public boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) { return false; } @Override - public boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) { + public boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { return false; } @Override - public List getMediaList(MediaServerItem mediaServerItem, String app, String stream, String callId) { + public List getMediaList(MediaServer mediaServerItem, String app, String stream, String callId) { + return null; + } + + @Override + public Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream) { + return null; + } + + @Override + public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { + + } + + @Override + public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { return null; } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java similarity index 69% rename from src/main/java/com/genersoft/iot/vmp/media/bean/Track.java rename to src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java index 963474ea1..d808772b2 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/Track.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java @@ -11,7 +11,7 @@ import java.util.List; * 视频信息 */ @Schema(description = "视频信息") -public class Track { +public class MediaInfo { @Schema(description = "观看人数") private Integer readerCount; @Schema(description = "视频编码类型") @@ -26,12 +26,14 @@ public class Track { private Integer audioChannels; @Schema(description = "音频采样率") private Integer audioSampleRate; + @Schema(description = "音频采样率") + private Long duration; - public static Track getInstance(JSONObject jsonObject) { - Track track = new Track(); + public static MediaInfo getInstance(JSONObject jsonObject) { + MediaInfo mediaInfo = new MediaInfo(); Integer totalReaderCount = jsonObject.getInteger("totalReaderCount"); if (totalReaderCount != null) { - track.setReaderCount(totalReaderCount); + mediaInfo.setReaderCount(totalReaderCount); } JSONArray jsonArray = jsonObject.getJSONArray("tracks"); if (jsonArray.isEmpty()) { @@ -45,77 +47,81 @@ public class Track { Integer sampleRate = trackJson.getInteger("sample_rate"); Integer height = trackJson.getInteger("height"); Integer width = trackJson.getInteger("height"); + Long duration = trackJson.getLongValue("duration"); if (channels != null) { - track.setAudioChannels(channels); + mediaInfo.setAudioChannels(channels); } if (sampleRate != null) { - track.setAudioSampleRate(sampleRate); + mediaInfo.setAudioSampleRate(sampleRate); } if (height != null) { - track.setHeight(height); + mediaInfo.setHeight(height); } if (width != null) { - track.setWidth(width); + mediaInfo.setWidth(width); + } + if (duration > 0L) { + mediaInfo.setDuration(duration); } if (codecId != null) { switch (codecId) { case 0: - track.setVideoCodec("H264"); + mediaInfo.setVideoCodec("H264"); break; case 1: - track.setVideoCodec("H265"); + mediaInfo.setVideoCodec("H265"); break; case 2: - track.setAudioCodec("AAC"); + mediaInfo.setAudioCodec("AAC"); break; case 3: - track.setAudioCodec("G711A"); + mediaInfo.setAudioCodec("G711A"); break; case 4: - track.setAudioCodec("G711U"); + mediaInfo.setAudioCodec("G711U"); break; } } } - return track; + return mediaInfo; } - public static Track getInstance(OnStreamChangedHookParam param) { + public static MediaInfo getInstance(OnStreamChangedHookParam param) { List tracks = param.getTracks(); - Track track = new Track(); - track.setReaderCount(param.getTotalReaderCount()); + MediaInfo mediaInfo = new MediaInfo(); + mediaInfo.setReaderCount(param.getTotalReaderCount()); for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { switch (mediaTrack.getCodec_id()) { case 0: - track.setVideoCodec("H264"); + mediaInfo.setVideoCodec("H264"); break; case 1: - track.setVideoCodec("H265"); + mediaInfo.setVideoCodec("H265"); break; case 2: - track.setAudioCodec("AAC"); + mediaInfo.setAudioCodec("AAC"); break; case 3: - track.setAudioCodec("G711A"); + mediaInfo.setAudioCodec("G711A"); break; case 4: - track.setAudioCodec("G711U"); + mediaInfo.setAudioCodec("G711U"); break; } if (mediaTrack.getSample_rate() > 0) { - track.setAudioSampleRate(mediaTrack.getSample_rate()); + mediaInfo.setAudioSampleRate(mediaTrack.getSample_rate()); } if (mediaTrack.getChannels() > 0) { - track.setAudioChannels(mediaTrack.getChannels()); + mediaInfo.setAudioChannels(mediaTrack.getChannels()); } if (mediaTrack.getHeight() > 0) { - track.setHeight(mediaTrack.getHeight()); + mediaInfo.setHeight(mediaTrack.getHeight()); } if (mediaTrack.getWidth() > 0) { - track.setWidth(mediaTrack.getWidth()); + mediaInfo.setWidth(mediaTrack.getWidth()); } } - return track; + return mediaInfo; } public Integer getReaderCount() { @@ -173,4 +179,12 @@ public class Track { public void setAudioSampleRate(Integer audioSampleRate) { this.audioSampleRate = audioSampleRate; } + + public Long getDuration() { + return duration; + } + + public void setDuration(Long duration) { + this.duration = duration; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java index a880b85c0..0da054fe9 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.event; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.springframework.context.ApplicationEvent; import java.util.ArrayList; @@ -13,22 +13,22 @@ public class MediaServerChangeEvent extends ApplicationEvent { super(source); } - private List mediaServerItemList; + private List mediaServerItemList; - public List getMediaServerItemList() { + public List getMediaServerItemList() { return mediaServerItemList; } - public void setMediaServerItemList(List mediaServerItemList) { + public void setMediaServerItemList(List mediaServerItemList) { this.mediaServerItemList = mediaServerItemList; } - public void setMediaServerItemList(MediaServerItem... mediaServerItemArray) { + public void setMediaServerItemList(MediaServer... mediaServerItemArray) { this.mediaServerItemList = new ArrayList<>(); this.mediaServerItemList.addAll(Arrays.asList(mediaServerItemArray)); } - public void setMediaServerItem(List mediaServerItemList) { + public void setMediaServerItem(List mediaServerItemList) { this.mediaServerItemList = mediaServerItemList; } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 2f8983b5e..504e35c14 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -2,30 +2,41 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import java.util.List; public interface IMediaNodeServerService { - int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); + int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); - void closeRtpServer(MediaServerItem mediaServerItem, String streamId); + void closeRtpServer(MediaServer mediaServerItem, String streamId); - void closeRtpServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback); + void closeRtpServer(MediaServer mediaServerItem, String streamId, CommonCallback callback); - void closeStreams(MediaServerItem mediaServerItem, String app, String stream); + void closeStreams(MediaServer mediaServerItem, String app, String stream); - Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String stream, String ssrc); + Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String stream, String ssrc); - boolean checkNodeId(MediaServerItem mediaServerItem); + boolean checkNodeId(MediaServer mediaServerItem); - void online(MediaServerItem mediaServerItem); + void online(MediaServer mediaServerItem); - MediaServerItem checkMediaServer(String ip, int port, String secret); + MediaServer checkMediaServer(String ip, int port, String secret); - boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc); + boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc); - boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName); + boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName); - List getMediaList(MediaServerItem mediaServerItem, String app, String stream, String callId); + List getMediaList(MediaServer mediaServerItem, String app, String stream, String callId); + + Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream); + + void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName); + + MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream); + + Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey); + + Boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 2e5ab1f83..4127d7ba3 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -2,7 +2,8 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -13,37 +14,37 @@ import java.util.List; */ public interface IMediaServerService { - List getAllOnlineList(); + List getAllOnlineList(); - List getAll(); + List getAll(); - List getAllFromDatabase(); + List getAllFromDatabase(); - List getAllOnline(); + List getAllOnline(); - MediaServerItem getOne(String generalMediaServerId); + MediaServer getOne(String generalMediaServerId); void syncCatchFromDatabase(); - MediaServerItem getMediaServerForMinimumLoad(Boolean hasAssist); + MediaServer getMediaServerForMinimumLoad(Boolean hasAssist); - void updateVmServer(List mediaServerItemList); + void updateVmServer(List mediaServerItemList); - SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, + SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); - SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto); + SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto); - void closeRTPServer(MediaServerItem mediaServerItem, String streamId); + void closeRTPServer(MediaServer mediaServerItem, String streamId); - void closeRTPServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback); - Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc); + void closeRTPServer(MediaServer mediaServerItem, String streamId, CommonCallback callback); + Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc); void closeRTPServer(String mediaServerId, String streamId); - void clearRTPServer(MediaServerItem mediaServerItem); + void clearRTPServer(MediaServer mediaServerItem); - void update(MediaServerItem mediaSerItem); + void update(MediaServer mediaSerItem); void addCount(String mediaServerId); @@ -53,27 +54,37 @@ public interface IMediaServerService { void clearMediaServerForOnline(); - void add(MediaServerItem mediaSerItem); + void add(MediaServer mediaSerItem); - void resetOnlineServerItem(MediaServerItem serverItem); + void resetOnlineServerItem(MediaServer serverItem); - MediaServerItem checkMediaServer(String ip, int port, String secret, String type); + MediaServer checkMediaServer(String ip, int port, String secret, String type); boolean checkMediaRecordServer(String ip, int port); void delete(String id); - MediaServerItem getDefaultMediaServer(); + MediaServer getDefaultMediaServer(); - MediaServerLoad getLoad(MediaServerItem mediaServerItem); + MediaServerLoad getLoad(MediaServer mediaServerItem); - List getAllWithAssistPort(); + List getAllWithAssistPort(); - MediaServerItem getOneFromDatabase(String id); + MediaServer getOneFromDatabase(String id); - boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc); + boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc); - boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName); + boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName); - List getMediaList(MediaServerItem mediaInfo, String app, String stream, String callId); + List getMediaList(MediaServer mediaInfo, String app, String stream, String callId); + + Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream); + + void getSnap(MediaServer mediaServerItemInuse, String streamUrl, int timeoutSec, int expireSec, String path, String fileName); + + MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream); + + Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey); + + boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index af5f1c556..d4723793b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -7,11 +7,12 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -73,9 +74,9 @@ public class MediaServerServiceImpl implements IMediaServerService { * 初始化 */ @Override - public void updateVmServer(List mediaServerItemList) { + public void updateVmServer(List mediaServerItemList) { logger.info("[媒体服务节点] 缓存初始化 "); - for (MediaServerItem mediaServerItem : mediaServerItemList) { + for (MediaServer mediaServerItem : mediaServerItemList) { if (ObjectUtils.isEmpty(mediaServerItem.getId())) { continue; } @@ -94,7 +95,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override - public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, + public SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { if (mediaServerItem == null || mediaServerItem.getId() == null) { logger.info("[openRTPServer] 失败, mediaServerItem == null || mediaServerItem.getId() == null"); @@ -134,13 +135,13 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto) { + public SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto) { return openRTPServer(mediaServerItem, streamId, ssrc, ssrcCheck, isPlayback, port, onlyAuto, null, 0); } @Override - public void closeRTPServer(MediaServerItem mediaServerItem, String streamId) { + public void closeRTPServer(MediaServer mediaServerItem, String streamId) { if (mediaServerItem == null) { return; } @@ -153,7 +154,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public void closeRTPServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback) { + public void closeRTPServer(MediaServer mediaServerItem, String streamId, CommonCallback callback) { if (mediaServerItem == null) { callback.run(false); return; @@ -168,7 +169,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public void closeRTPServer(String mediaServerId, String streamId) { - MediaServerItem mediaServerItem = this.getOne(mediaServerId); + MediaServer mediaServerItem = this.getOne(mediaServerId); if (mediaServerItem == null) { return; } @@ -184,7 +185,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) { + public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { if (mediaServerItem == null) { return false; } @@ -198,7 +199,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public void releaseSsrc(String mediaServerItemId, String ssrc) { - MediaServerItem mediaServerItem = getOne(mediaServerItemId); + MediaServer mediaServerItem = getOne(mediaServerItemId); if (mediaServerItem == null || ssrc == null) { return; } @@ -209,21 +210,21 @@ public class MediaServerServiceImpl implements IMediaServerService { * 媒体服务节点 重启后重置他的推流信息, TODO 给正在使用的设备发送停止命令 */ @Override - public void clearRTPServer(MediaServerItem mediaServerItem) { + public void clearRTPServer(MediaServer mediaServerItem) { ssrcFactory.reset(mediaServerItem.getId()); } @Override - public void update(MediaServerItem mediaSerItem) { + public void update(MediaServer mediaSerItem) { mediaServerMapper.update(mediaSerItem); - MediaServerItem mediaServerItemInRedis = getOne(mediaSerItem.getId()); - MediaServerItem mediaServerItemInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId()); + MediaServer mediaServerInRedis = getOne(mediaSerItem.getId()); + MediaServer mediaServerItemInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId()); if (mediaServerItemInDataBase == null) { return; } mediaServerItemInDataBase.setStatus(mediaSerItem.isStatus()); - if (mediaServerItemInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerItemInDataBase.getId())) { + if (mediaServerInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerItemInDataBase.getId())) { ssrcFactory.initMediaServerSSRC(mediaServerItemInDataBase.getId(),null); } String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItemInDataBase.getId(); @@ -240,13 +241,13 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override - public List getAllOnlineList() { - List result = new ArrayList<>(); + public List getAllOnlineList() { + List result = new ArrayList<>(); List mediaServerKeys = RedisUtil.scan(redisTemplate, String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX+ userSetting.getServerId() + "_" )); String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); for (Object mediaServerKey : mediaServerKeys) { String key = (String) mediaServerKey; - MediaServerItem mediaServerItem = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServerItem.class); + MediaServer mediaServerItem = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServer.class); if (Objects.isNull(mediaServerItem)) { continue; } @@ -269,13 +270,13 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public List getAll() { - List mediaServerList = mediaServerMapper.queryAll(); + public List getAll() { + List mediaServerList = mediaServerMapper.queryAll(); if (mediaServerList.isEmpty()) { return new ArrayList<>(); } - for (MediaServerItem mediaServerItem : mediaServerList) { - MediaServerItem mediaServerItemInRedis = getOne(mediaServerItem.getId()); + for (MediaServer mediaServerItem : mediaServerList) { + MediaServer mediaServerItemInRedis = getOne(mediaServerItem.getId()); if (mediaServerItemInRedis != null) { mediaServerItem.setStatus(mediaServerItemInRedis.isStatus()); } @@ -285,21 +286,21 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override - public List getAllFromDatabase() { + public List getAllFromDatabase() { return mediaServerMapper.queryAll(); } @Override - public List getAllOnline() { + public List getAllOnline() { String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); Set mediaServerIdSet = redisTemplate.opsForZSet().reverseRange(key, 0, -1); - List result = new ArrayList<>(); + List result = new ArrayList<>(); if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) { for (Object mediaServerId : mediaServerIdSet) { String mediaServerIdStr = (String) mediaServerId; String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerIdStr; - result.add((MediaServerItem) redisTemplate.opsForValue().get(serverKey)); + result.add((MediaServer) redisTemplate.opsForValue().get(serverKey)); } } Collections.reverse(result); @@ -312,17 +313,17 @@ public class MediaServerServiceImpl implements IMediaServerService { * @return MediaServerItem */ @Override - public MediaServerItem getOne(String mediaServerId) { + public MediaServer getOne(String mediaServerId) { if (mediaServerId == null) { return null; } String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerId; - return JsonUtil.redisJsonToObject(redisTemplate, key, MediaServerItem.class); + return JsonUtil.redisJsonToObject(redisTemplate, key, MediaServer.class); } @Override - public MediaServerItem getDefaultMediaServer() { + public MediaServer getDefaultMediaServer() { return mediaServerMapper.queryDefault(); } @@ -333,7 +334,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public void add(MediaServerItem mediaServerItem) { + public void add(MediaServer mediaServerItem) { mediaServerItem.setCreateTime(DateUtil.getNow()); mediaServerItem.setUpdateTime(DateUtil.getNow()); if (mediaServerItem.getHookAliveInterval() == null || mediaServerItem.getHookAliveInterval() == 0F) { @@ -364,7 +365,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public void resetOnlineServerItem(MediaServerItem serverItem) { + public void resetOnlineServerItem(MediaServer serverItem) { // 更新缓存 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); // 使用zset的分数作为当前并发量, 默认值设置为0 @@ -378,7 +379,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } } - private int getMediaList(MediaServerItem serverItem) { + private int getMediaList(MediaServer serverItem) { return 0; } @@ -405,7 +406,7 @@ public class MediaServerServiceImpl implements IMediaServerService { * @return MediaServerItem */ @Override - public MediaServerItem getMediaServerForMinimumLoad(Boolean hasAssist) { + public MediaServer getMediaServerForMinimumLoad(Boolean hasAssist) { String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); Long size = redisTemplate.opsForZSet().zCard(key); if (size == null || size == 0) { @@ -416,14 +417,14 @@ public class MediaServerServiceImpl implements IMediaServerService { // 获取分数最低的,及并发最低的 Set objects = redisTemplate.opsForZSet().range(key, 0, -1); ArrayList mediaServerObjectS = new ArrayList<>(objects); - MediaServerItem mediaServerItem = null; + MediaServer mediaServerItem = null; if (hasAssist == null) { String mediaServerId = (String)mediaServerObjectS.get(0); mediaServerItem = getOne(mediaServerId); }else if (hasAssist) { for (Object mediaServerObject : mediaServerObjectS) { String mediaServerId = (String)mediaServerObject; - MediaServerItem serverItem = getOne(mediaServerId); + MediaServer serverItem = getOne(mediaServerId); if (serverItem.getRecordAssistPort() > 0) { mediaServerItem = serverItem; break; @@ -432,7 +433,7 @@ public class MediaServerServiceImpl implements IMediaServerService { }else if (!hasAssist) { for (Object mediaServerObject : mediaServerObjectS) { String mediaServerId = (String)mediaServerObject; - MediaServerItem serverItem = getOne(mediaServerId); + MediaServer serverItem = getOne(mediaServerId); if (serverItem.getRecordAssistPort() == 0) { mediaServerItem = serverItem; break; @@ -444,7 +445,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public MediaServerItem checkMediaServer(String ip, int port, String secret, String type) { + public MediaServer checkMediaServer(String ip, int port, String secret, String type) { if (mediaServerMapper.queryOneByHostAndPort(ip, port) != null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "此连接已存在"); } @@ -454,7 +455,7 @@ public class MediaServerServiceImpl implements IMediaServerService { logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", type); return null; } - MediaServerItem mediaServerItem = mediaNodeServerService.checkMediaServer(ip, port, secret); + MediaServer mediaServerItem = mediaNodeServerService.checkMediaServer(ip, port, secret); if (mediaServerItem != null) { if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体服务ID [" + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); @@ -495,20 +496,20 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public MediaServerItem getOneFromDatabase(String mediaServerId) { + public MediaServer getOneFromDatabase(String mediaServerId) { return mediaServerMapper.queryOne(mediaServerId); } @Override public void syncCatchFromDatabase() { - List allInCatch = getAllOnlineList(); - List allInDatabase = mediaServerMapper.queryAll(); - Map mediaServerItemMap = new HashMap<>(); + List allInCatch = getAllOnlineList(); + List allInDatabase = mediaServerMapper.queryAll(); + Map mediaServerItemMap = new HashMap<>(); - for (MediaServerItem mediaServerItem : allInDatabase) { + for (MediaServer mediaServerItem : allInDatabase) { mediaServerItemMap.put(mediaServerItem.getId(), mediaServerItem); } - for (MediaServerItem mediaServerItem : allInCatch) { + for (MediaServer mediaServerItem : allInCatch) { // 清除数据中不存在但redis缓存数据 if (!mediaServerItemMap.containsKey(mediaServerItem.getId())) { delete(mediaServerItem.getId()); @@ -517,7 +518,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public MediaServerLoad getLoad(MediaServerItem mediaServerItem) { + public MediaServerLoad getLoad(MediaServer mediaServerItem) { MediaServerLoad result = new MediaServerLoad(); result.setId(mediaServerItem.getId()); result.setPush(redisCatchStorage.getPushStreamCount(mediaServerItem.getId())); @@ -529,13 +530,13 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public List getAllWithAssistPort() { + public List getAllWithAssistPort() { return mediaServerMapper.queryAllWithAssistPort(); } @Override - public boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc) { + public boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaInfo.getType()); if (mediaNodeServerService == null) { logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaInfo.getType()); @@ -545,7 +546,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) { + public boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); if (mediaNodeServerService == null) { logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); @@ -555,7 +556,7 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public List getMediaList(MediaServerItem mediaServerItem, String app, String stream, String callId) { + public List getMediaList(MediaServer mediaServerItem, String app, String stream, String callId) { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); if (mediaNodeServerService == null) { logger.info("[getMediaList] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); @@ -563,4 +564,54 @@ public class MediaServerServiceImpl implements IMediaServerService { } return mediaNodeServerService.getMediaList(mediaServerItem, app, stream, callId); } + + @Override + public Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[connectRtpServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return false; + } + return mediaNodeServerService.connectRtpServer(mediaServerItem, address, port, stream); + } + + @Override + public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[getSnap] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return; + } + mediaNodeServerService.getSnap(mediaServerItem, streamUrl, timeoutSec, expireSec, path, fileName); + } + + @Override + public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[getMediaInfo] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return null; + } + return mediaNodeServerService.getMediaInfo(mediaServerItem, app, stream); + } + + @Override + public Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[pauseRtpCheck] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return false; + } + return mediaNodeServerService.pauseRtpCheck(mediaServerItem, streamKey); + } + + @Override + public boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[pauseRtpCheck] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return false; + } + return mediaNodeServerService.resumeRtpCheck(mediaServerItem, streamKey); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java index 5735f37fd..9c473a33c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.utils.SSLSocketClientUtil; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; @@ -70,7 +70,7 @@ public class AssistRESTfulUtils { } - public JSONObject sendGet(MediaServerItem mediaServerItem, String api, Map param, RequestCallback callback) { + public JSONObject sendGet(MediaServer mediaServerItem, String api, Map param, RequestCallback callback) { OkHttpClient client = getClient(); if (mediaServerItem == null) { @@ -155,7 +155,7 @@ public class AssistRESTfulUtils { return responseJSON; } - public JSONObject sendPost(MediaServerItem mediaServerItem, String url, + public JSONObject sendPost(MediaServer mediaServerItem, String url, JSONObject param, ZLMRESTfulUtils.RequestCallback callback, Integer readTimeOut) { OkHttpClient client = getClient(readTimeOut); @@ -244,12 +244,12 @@ public class AssistRESTfulUtils { return responseJSON; } - public JSONObject getInfo(MediaServerItem mediaServerItem, RequestCallback callback){ + public JSONObject getInfo(MediaServer mediaServerItem, RequestCallback callback){ Map param = new HashMap<>(); return sendGet(mediaServerItem, "api/record/info",param, callback); } - public JSONObject addTask(MediaServerItem mediaServerItem, String app, String stream, String startTime, + public JSONObject addTask(MediaServer mediaServerItem, String app, String stream, String startTime, String endTime, String callId, List filePathList, String remoteHost) { JSONObject videoTaskInfoJSON = new JSONObject(); @@ -266,7 +266,7 @@ public class AssistRESTfulUtils { return sendPost(mediaServerItem, urlStr, videoTaskInfoJSON, null, 30); } - public JSONObject queryTaskList(MediaServerItem mediaServerItem, String app, String stream, String callId, + public JSONObject queryTaskList(MediaServer mediaServerItem, String app, String stream, String callId, String taskId, Boolean isEnd, String scheme) { Map param = new HashMap<>(); if (!ObjectUtils.isEmpty(app)) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java index fda2e67c8..cb63365bb 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.apache.commons.lang3.math.NumberUtils; import org.slf4j.Logger; @@ -30,7 +30,7 @@ public class SendRtpPortManager { private final String KEY = "VM_MEDIA_SEND_RTP_PORT_"; - public synchronized int getNextPort(MediaServerItem mediaServer) { + public synchronized int getNextPort(MediaServer mediaServer) { if (mediaServer == null) { logger.warn("[发送端口管理] 参数错误,mediaServer为NULL"); return -1; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index f5d664af5..336c56f82 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -18,7 +18,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.bean.Track; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; @@ -34,7 +34,6 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; -import org.apache.poi.ss.formula.functions.T; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -153,7 +152,7 @@ public class ZLMHttpHookListener { }); try { HookZlmServerKeepaliveEvent event = new HookZlmServerKeepaliveEvent(this); - MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); if (mediaServerItem != null) { event.setMediaServerItem(mediaServerItem); applicationEventPublisher.publishEvent(event); @@ -179,7 +178,7 @@ public class ZLMHttpHookListener { JSONObject json = (JSONObject) JSON.toJSON(param); ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); if (subscribe != null) { - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { subscribe.response(mediaInfo, param); } @@ -209,7 +208,7 @@ public class ZLMHttpHookListener { // TODO 加快处理速度 String mediaServerId = json.getString("mediaServerId"); - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo == null) { return new HookResultForOnPublish(200, "success"); } @@ -360,7 +359,7 @@ public class ZLMHttpHookListener { JSONObject json = (JSONObject) JSON.toJSON(param); taskExecutor.execute(() -> { ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); - MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); if (mediaInfo == null) { logger.info("[ZLM HOOK] 流变化未找到ZLM, {}", param.getMediaServerId()); return; @@ -472,7 +471,7 @@ public class ZLMHttpHookListener { callId = streamAuthorityInfo.getCallId(); } StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo, - param.getApp(), param.getStream(), Track.getInstance(param), callId); + param.getApp(), param.getStream(), MediaInfo.getInstance(param), callId); param.setStreamInfo(new StreamContent(streamInfoByAppAndStream)); redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param); if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() @@ -680,7 +679,7 @@ public class ZLMHttpHookListener { DeferredResult defaultResult = new DeferredResult<>(); - MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); if (!userSetting.isAutoApplyPlay() || mediaInfo == null) { defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); return defaultResult; @@ -811,7 +810,7 @@ public class ZLMHttpHookListener { }); try { HookZlmServerStartEvent event = new HookZlmServerStartEvent(this); - MediaServerItem mediaServerItem = mediaServerService.getOne(zlmServerConfig.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(zlmServerConfig.getMediaServerId()); if (mediaServerItem != null) { event.setMediaServerItem(mediaServerItem); applicationEventPublisher.publishEvent(event); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 0a0b6072f..5223be8cf 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -88,7 +88,7 @@ public class ZLMMediaListManager { } public void sendStreamEvent(String app, String stream, String mediaServerId) { - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); // 查看推流状态 Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, app, stream); if (streamReady != null && streamReady) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 686981e62..23b26dbc9 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -6,11 +6,10 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; -import com.genersoft.iot.vmp.media.bean.Track; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; -import com.genersoft.iot.vmp.service.impl.DeviceServiceImpl; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,32 +38,32 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { private String sipIp; @Override - public int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { + public int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { return zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode); } @Override - public void closeRtpServer(MediaServerItem mediaServerItem, String streamId) { + public void closeRtpServer(MediaServer mediaServerItem, String streamId) { zlmresTfulUtils.closeStreams(mediaServerItem, "rtp", streamId); } @Override - public void closeRtpServer(MediaServerItem mediaServerItem, String streamId, CommonCallback callback) { + public void closeRtpServer(MediaServer mediaServerItem, String streamId, CommonCallback callback) { zlmServerFactory.closeRtpServer(mediaServerItem, streamId, callback); } @Override - public void closeStreams(MediaServerItem mediaServerItem, String app, String stream) { + public void closeStreams(MediaServer mediaServerItem, String app, String stream) { zlmresTfulUtils.closeStreams(mediaServerItem, app, stream); } @Override - public Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) { + public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { return zlmServerFactory.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); } @Override - public boolean checkNodeId(MediaServerItem mediaServerItem) { + public boolean checkNodeId(MediaServer mediaServerItem) { if (mediaServerItem == null) { return false; } @@ -84,13 +83,13 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public void online(MediaServerItem mediaServerItem) { + public void online(MediaServer mediaServerItem) { } @Override - public MediaServerItem checkMediaServer(String ip, int port, String secret) { - MediaServerItem mediaServerItem = new MediaServerItem(); + public MediaServer checkMediaServer(String ip, int port, String secret) { + MediaServer mediaServerItem = new MediaServer(); mediaServerItem.setIp(ip); mediaServerItem.setHttpPort(port); mediaServerItem.setSecret(secret); @@ -121,7 +120,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc) { + public boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) { Map param = new HashMap<>(); param.put("vhost", "__defaultVhost__"); param.put("app", app); @@ -135,7 +134,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) { + public boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件, server: {} {}:{}->{}/{}", mediaServerItem.getId(), app, stream, date, fileName); JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServerItem, app, stream, date, fileName); @@ -148,7 +147,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public List getMediaList(MediaServerItem mediaServerItem, String app, String stream, String callId) { + public List getMediaList(MediaServer mediaServerItem, String app, String stream, String callId) { List streamInfoList = new ArrayList<>(); JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream); if (mediaList != null) { @@ -158,8 +157,8 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { return null; } JSONObject mediaJSON = data.getJSONObject(0); - Track track = Track.getInstance(mediaJSON); - StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, track, callId, true); + MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, mediaInfo, callId, true); if (streamInfo != null) { streamInfoList.add(streamInfo); } @@ -168,23 +167,56 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { return streamInfoList; } - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String callId, boolean isPlay) { + public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId, boolean isPlay) { StreamInfo streamInfoResult = new StreamInfo(); streamInfoResult.setStream(stream); streamInfoResult.setApp(app); - String addr = mediaInfo.getStreamIp(); + String addr = mediaServerItem.getStreamIp(); streamInfoResult.setIp(addr); - streamInfoResult.setMediaServerId(mediaInfo.getId()); + streamInfoResult.setMediaServerId(mediaServerItem.getId()); String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; - streamInfoResult.setRtmp(addr, mediaInfo.getRtmpPort(),mediaInfo.getRtmpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtsp(addr, mediaInfo.getRtspPort(),mediaInfo.getRtspSSLPort(), app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setFmp4(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setHls(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setTs(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam, isPlay); + streamInfoResult.setRtmp(addr, mediaServerItem.getRtmpPort(),mediaServerItem.getRtmpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtsp(addr, mediaServerItem.getRtspPort(),mediaServerItem.getRtspSSLPort(), app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setFmp4(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setHls(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setTs(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtc(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam, isPlay); - streamInfoResult.setTrack(track); + streamInfoResult.setMediaInfo(mediaInfo); return streamInfoResult; } + + @Override + public Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream) { + JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, address, port, stream); + logger.info("[TCP主动连接对方] 结果: {}", jsonObject); + return jsonObject.getInteger("code") == 0; + } + + @Override + public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { + zlmresTfulUtils.getSnap(mediaServerItem, streamUrl, timeoutSec, expireSec, path, fileName); + } + + @Override + public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { + JSONObject jsonObject = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtsp", stream); + if (jsonObject.getInteger("code") != 0) { + return null; + } + return MediaInfo.getInstance(jsonObject); + } + + @Override + public Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey) { + JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServerItem, streamKey); + return jsonObject.getInteger("code") == 0; + } + + @Override + public Boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey) { + JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServerItem, streamKey); + return jsonObject.getInteger("code") == 0; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index 6f97558da..b2bfaf1b0 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; @@ -36,8 +36,8 @@ public class ZLMMediaServerStatusManger { private final static Logger logger = LoggerFactory.getLogger(ZLMMediaServerStatusManger.class); - private final Map offlineZlmPrimaryMap = new ConcurrentHashMap<>(); - private final Map offlineZlmsecondaryMap = new ConcurrentHashMap<>(); + private final Map offlineZlmPrimaryMap = new ConcurrentHashMap<>(); + private final Map offlineZlmsecondaryMap = new ConcurrentHashMap<>(); private final Map offlineZlmTimeMap = new ConcurrentHashMap<>(); @Autowired @@ -67,7 +67,7 @@ public class ZLMMediaServerStatusManger { || event.getMediaServerItemList().isEmpty()) { return; } - for (MediaServerItem mediaServerItem : event.getMediaServerItemList()) { + for (MediaServer mediaServerItem : event.getMediaServerItemList()) { if (!type.equals(mediaServerItem.getType())) { continue; } @@ -85,7 +85,7 @@ public class ZLMMediaServerStatusManger { || event.getMediaServerItem().isStatus()) { return; } - MediaServerItem serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); + MediaServer serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); if (serverItem == null) { return; } @@ -99,7 +99,7 @@ public class ZLMMediaServerStatusManger { if (event.getMediaServerItem() == null) { return; } - MediaServerItem serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); + MediaServer serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); if (serverItem == null) { return; } @@ -126,7 +126,7 @@ public class ZLMMediaServerStatusManger { return; } if (!offlineZlmPrimaryMap.isEmpty()) { - for (MediaServerItem mediaServerItem : offlineZlmPrimaryMap.values()) { + for (MediaServer mediaServerItem : offlineZlmPrimaryMap.values()) { if (offlineZlmTimeMap.get(mediaServerItem.getId()) < System.currentTimeMillis() - 30*60*1000) { offlineZlmsecondaryMap.put(mediaServerItem.getId(), mediaServerItem); offlineZlmPrimaryMap.remove(mediaServerItem.getId()); @@ -150,7 +150,7 @@ public class ZLMMediaServerStatusManger { } } if (!offlineZlmsecondaryMap.isEmpty()) { - for (MediaServerItem mediaServerItem : offlineZlmsecondaryMap.values()) { + for (MediaServer mediaServerItem : offlineZlmsecondaryMap.values()) { if (offlineZlmTimeMap.get(mediaServerItem.getId()) < System.currentTimeMillis() - 30*60*1000) { continue; } @@ -175,7 +175,7 @@ public class ZLMMediaServerStatusManger { } } - private void online(MediaServerItem mediaServerItem, ZLMServerConfig config) { + private void online(MediaServer mediaServerItem, ZLMServerConfig config) { offlineZlmPrimaryMap.remove(mediaServerItem.getId()); offlineZlmsecondaryMap.remove(mediaServerItem.getId()); offlineZlmTimeMap.remove(mediaServerItem.getId()); @@ -209,7 +209,7 @@ public class ZLMMediaServerStatusManger { mediaServerService.update(mediaServerItem); }, (int)(mediaServerItem.getHookAliveInterval() * 2 * 1000)); } - private void initPort(MediaServerItem mediaServerItem, ZLMServerConfig zlmServerConfig) { + private void initPort(MediaServer mediaServerItem, ZLMServerConfig zlmServerConfig) { if (mediaServerItem.getHttpSSlPort() == 0) { mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); } @@ -231,7 +231,7 @@ public class ZLMMediaServerStatusManger { mediaServerItem.setHookAliveInterval(10F); } - public void setZLMConfig(MediaServerItem mediaServerItem, boolean restart) { + public void setZLMConfig(MediaServer mediaServerItem, boolean restart) { logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); String protocol = sslEnabled ? "https" : "http"; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 044f9f30b..5cddd5e22 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; import org.jetbrains.annotations.NotNull; @@ -60,12 +60,12 @@ public class ZLMRESTfulUtils { } - public JSONObject sendPost(MediaServerItem mediaServerItem, String api, Map param, RequestCallback callback) { + public JSONObject sendPost(MediaServer mediaServerItem, String api, Map param, RequestCallback callback) { return sendPost(mediaServerItem, api, param, callback, null); } - public JSONObject sendPost(MediaServerItem mediaServerItem, String api, Map param, RequestCallback callback, Integer readTimeOut) { + public JSONObject sendPost(MediaServer mediaServerItem, String api, Map param, RequestCallback callback, Integer readTimeOut) { OkHttpClient client = getClient(readTimeOut); if (mediaServerItem == null) { @@ -164,7 +164,7 @@ public class ZLMRESTfulUtils { return responseJSON; } - public void sendGetForImg(MediaServerItem mediaServerItem, String api, Map params, String targetPath, String fileName) { + public void sendGetForImg(MediaServer mediaServerItem, String api, Map params, String targetPath, String fileName) { String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); HttpUrl parseUrl = HttpUrl.parse(url); if (parseUrl == null) { @@ -216,7 +216,7 @@ public class ZLMRESTfulUtils { } } - public JSONObject isMediaOnline(MediaServerItem mediaServerItem, String app, String stream, String schema){ + public JSONObject isMediaOnline(MediaServer mediaServerItem, String app, String stream, String schema){ Map param = new HashMap<>(); if (app != null) { param.put("app",app); @@ -231,7 +231,7 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "isMediaOnline", param, null); } - public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream, String schema, RequestCallback callback){ + public JSONObject getMediaList(MediaServer mediaServerItem, String app, String stream, String schema, RequestCallback callback){ Map param = new HashMap<>(); if (app != null) { param.put("app",app); @@ -246,15 +246,15 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "getMediaList",param, callback); } - public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream){ + public JSONObject getMediaList(MediaServer mediaServerItem, String app, String stream){ return getMediaList(mediaServerItem, app, stream,null, null); } - public JSONObject getMediaList(MediaServerItem mediaServerItem, RequestCallback callback){ + public JSONObject getMediaList(MediaServer mediaServerItem, RequestCallback callback){ return sendPost(mediaServerItem, "getMediaList",null, callback); } - public JSONObject getMediaInfo(MediaServerItem mediaServerItem, String app, String schema, String stream){ + public JSONObject getMediaInfo(MediaServer mediaServerItem, String app, String schema, String stream){ Map param = new HashMap<>(); param.put("app",app); param.put("schema",schema); @@ -263,13 +263,13 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "getMediaInfo",param, null); } - public JSONObject getRtpInfo(MediaServerItem mediaServerItem, String stream_id){ + public JSONObject getRtpInfo(MediaServer mediaServerItem, String stream_id){ Map param = new HashMap<>(); param.put("stream_id",stream_id); return sendPost(mediaServerItem, "getRtpInfo",param, null); } - public JSONObject addFFmpegSource(MediaServerItem mediaServerItem, String src_url, String dst_url, String timeout_ms, + public JSONObject addFFmpegSource(MediaServer mediaServerItem, String src_url, String dst_url, String timeout_ms, boolean enable_audio, boolean enable_mp4, String ffmpeg_cmd_key){ logger.info(src_url); logger.info(dst_url); @@ -282,63 +282,63 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "addFFmpegSource",param, null); } - public JSONObject delFFmpegSource(MediaServerItem mediaServerItem, String key){ + public JSONObject delFFmpegSource(MediaServer mediaServerItem, String key){ Map param = new HashMap<>(); param.put("key", key); return sendPost(mediaServerItem, "delFFmpegSource",param, null); } - public JSONObject delStreamProxy(MediaServerItem mediaServerItem, String key){ + public JSONObject delStreamProxy(MediaServer mediaServerItem, String key){ Map param = new HashMap<>(); param.put("key", key); return sendPost(mediaServerItem, "delStreamProxy",param, null); } - public JSONObject getMediaServerConfig(MediaServerItem mediaServerItem){ + public JSONObject getMediaServerConfig(MediaServer mediaServerItem){ return sendPost(mediaServerItem, "getServerConfig",null, null); } - public JSONObject setServerConfig(MediaServerItem mediaServerItem, Map param){ + public JSONObject setServerConfig(MediaServer mediaServerItem, Map param){ return sendPost(mediaServerItem,"setServerConfig",param, null); } - public JSONObject openRtpServer(MediaServerItem mediaServerItem, Map param){ + public JSONObject openRtpServer(MediaServer mediaServerItem, Map param){ return sendPost(mediaServerItem, "openRtpServer",param, null); } - public JSONObject closeRtpServer(MediaServerItem mediaServerItem, Map param) { + public JSONObject closeRtpServer(MediaServer mediaServerItem, Map param) { return sendPost(mediaServerItem, "closeRtpServer",param, null); } - public void closeRtpServer(MediaServerItem mediaServerItem, Map param, RequestCallback callback) { + public void closeRtpServer(MediaServer mediaServerItem, Map param, RequestCallback callback) { sendPost(mediaServerItem, "closeRtpServer",param, callback); } - public JSONObject listRtpServer(MediaServerItem mediaServerItem) { + public JSONObject listRtpServer(MediaServer mediaServerItem) { return sendPost(mediaServerItem, "listRtpServer",null, null); } - public JSONObject startSendRtp(MediaServerItem mediaServerItem, Map param) { + public JSONObject startSendRtp(MediaServer mediaServerItem, Map param) { return sendPost(mediaServerItem, "startSendRtp",param, null); } - public JSONObject startSendRtpPassive(MediaServerItem mediaServerItem, Map param) { + public JSONObject startSendRtpPassive(MediaServer mediaServerItem, Map param) { return sendPost(mediaServerItem, "startSendRtpPassive",param, null); } - public JSONObject startSendRtpPassive(MediaServerItem mediaServerItem, Map param, RequestCallback callback) { + public JSONObject startSendRtpPassive(MediaServer mediaServerItem, Map param, RequestCallback callback) { return sendPost(mediaServerItem, "startSendRtpPassive",param, callback); } - public JSONObject stopSendRtp(MediaServerItem mediaServerItem, Map param) { + public JSONObject stopSendRtp(MediaServer mediaServerItem, Map param) { return sendPost(mediaServerItem, "stopSendRtp",param, null); } - public JSONObject restartServer(MediaServerItem mediaServerItem) { + public JSONObject restartServer(MediaServer mediaServerItem) { return sendPost(mediaServerItem, "restartServer",null, null); } - public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_audio, boolean enable_mp4, String rtp_type) { + public JSONObject addStreamProxy(MediaServer mediaServerItem, String app, String stream, String url, boolean enable_audio, boolean enable_mp4, String rtp_type) { Map param = new HashMap<>(); param.put("vhost", "__defaultVhost__"); param.put("app", app); @@ -350,7 +350,7 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "addStreamProxy",param, null, 20); } - public JSONObject closeStreams(MediaServerItem mediaServerItem, String app, String stream) { + public JSONObject closeStreams(MediaServer mediaServerItem, String app, String stream) { Map param = new HashMap<>(); param.put("vhost", "__defaultVhost__"); param.put("app", app); @@ -359,17 +359,17 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "close_streams",param, null); } - public JSONObject getAllSession(MediaServerItem mediaServerItem) { + public JSONObject getAllSession(MediaServer mediaServerItem) { return sendPost(mediaServerItem, "getAllSession",null, null); } - public void kickSessions(MediaServerItem mediaServerItem, String localPortSStr) { + public void kickSessions(MediaServer mediaServerItem, String localPortSStr) { Map param = new HashMap<>(); param.put("local_port", localPortSStr); sendPost(mediaServerItem, "kick_sessions",param, null); } - public void getSnap(MediaServerItem mediaServerItem, String streamUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { + public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { Map param = new HashMap<>(3); param.put("url", streamUrl); param.put("timeout_sec", timeout_sec); @@ -377,19 +377,19 @@ public class ZLMRESTfulUtils { sendGetForImg(mediaServerItem, "getSnap", param, targetPath, fileName); } - public JSONObject pauseRtpCheck(MediaServerItem mediaServerItem, String streamId) { + public JSONObject pauseRtpCheck(MediaServer mediaServerItem, String streamId) { Map param = new HashMap<>(1); param.put("stream_id", streamId); return sendPost(mediaServerItem, "pauseRtpCheck",param, null); } - public JSONObject resumeRtpCheck(MediaServerItem mediaServerItem, String streamId) { + public JSONObject resumeRtpCheck(MediaServer mediaServerItem, String streamId) { Map param = new HashMap<>(1); param.put("stream_id", streamId); return sendPost(mediaServerItem, "resumeRtpCheck",param, null); } - public JSONObject connectRtpServer(MediaServerItem mediaServerItem, String dst_url, int dst_port, String stream_id) { + public JSONObject connectRtpServer(MediaServer mediaServerItem, String dst_url, int dst_port, String stream_id) { Map param = new HashMap<>(1); param.put("dst_url", dst_url); param.put("dst_port", dst_port); @@ -397,14 +397,14 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "connectRtpServer",param, null); } - public JSONObject updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) { + public JSONObject updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { Map param = new HashMap<>(1); param.put("ssrc", ssrc); param.put("stream_id", streamId); return sendPost(mediaServerItem, "updateRtpServerSSRC",param, null); } - public JSONObject deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) { + public JSONObject deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { Map param = new HashMap<>(1); param.put("vhost", "__defaultVhost__"); param.put("app", app); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java index 737427e6c..ccb5b355e 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java @@ -5,7 +5,7 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -42,7 +42,7 @@ public class ZLMServerFactory { * @param tcpMode 0/null udp 模式,1 tcp 被动模式, 2 tcp 主动模式。 * @return */ - public int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { + public int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { int result = -1; // 查询此rtp server 是否已经存在 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaServerItem, streamId); @@ -108,7 +108,7 @@ public class ZLMServerFactory { return result; } - public boolean closeRtpServer(MediaServerItem serverItem, String streamId) { + public boolean closeRtpServer(MediaServer serverItem, String streamId) { boolean result = false; if (serverItem !=null){ Map param = new HashMap<>(); @@ -129,7 +129,7 @@ public class ZLMServerFactory { return result; } - public void closeRtpServer(MediaServerItem serverItem, String streamId, CommonCallback callback) { + public void closeRtpServer(MediaServer serverItem, String streamId, CommonCallback callback) { if (serverItem == null) { callback.run(false); return; @@ -165,7 +165,7 @@ public class ZLMServerFactory { * @param tcp 是否为tcp * @return SendRtpItem */ - public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, + public SendRtpItem createSendRtpItem(MediaServer serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp, boolean rtcp){ int localPort = sendRtpPortManager.getNextPort(serverItem); @@ -198,7 +198,7 @@ public class ZLMServerFactory { * @param tcp 是否为tcp * @return SendRtpItem */ - public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, + public SendRtpItem createSendRtpItem(MediaServer serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp, boolean rtcp){ int localPort = sendRtpPortManager.getNextPort(serverItem); @@ -224,25 +224,25 @@ public class ZLMServerFactory { /** * 调用zlm RESTFUL API —— startSendRtp */ - public JSONObject startSendRtpStream(MediaServerItem mediaServerItem, Mapparam) { + public JSONObject startSendRtpStream(MediaServer mediaServerItem, Mapparam) { return zlmresTfulUtils.startSendRtp(mediaServerItem, param); } /** * 调用zlm RESTFUL API —— startSendRtpPassive */ - public JSONObject startSendRtpPassive(MediaServerItem mediaServerItem, Mapparam) { + public JSONObject startSendRtpPassive(MediaServer mediaServerItem, Mapparam) { return zlmresTfulUtils.startSendRtpPassive(mediaServerItem, param); } - public JSONObject startSendRtpPassive(MediaServerItem mediaServerItem, Mapparam, ZLMRESTfulUtils.RequestCallback callback) { + public JSONObject startSendRtpPassive(MediaServer mediaServerItem, Mapparam, ZLMRESTfulUtils.RequestCallback callback) { return zlmresTfulUtils.startSendRtpPassive(mediaServerItem, param, callback); } /** * 查询待转推的流是否就绪 */ - public Boolean isRtpReady(MediaServerItem mediaServerItem, String streamId) { + public Boolean isRtpReady(MediaServer mediaServerItem, String streamId) { JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtsp", streamId); if (mediaInfo.getInteger("code") == -2) { return null; @@ -253,7 +253,7 @@ public class ZLMServerFactory { /** * 查询待转推的流是否就绪 */ - public Boolean isStreamReady(MediaServerItem mediaServerItem, String app, String streamId) { + public Boolean isStreamReady(MediaServer mediaServerItem, String app, String streamId) { JSONObject mediaInfo = zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId); if (mediaInfo == null || (mediaInfo.getInteger("code") == -2)) { return null; @@ -268,7 +268,7 @@ public class ZLMServerFactory { * @param streamId * @return */ - public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) { + public int totalReaderCount(MediaServer mediaServerItem, String app, String streamId) { JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtsp", streamId); if (mediaInfo == null) { return 0; @@ -288,7 +288,7 @@ public class ZLMServerFactory { /** * 调用zlm RESTful API —— stopSendRtp */ - public Boolean stopSendRtpStream(MediaServerItem mediaServerItem, Mapparam) { + public Boolean stopSendRtpStream(MediaServer mediaServerItem, Mapparam) { if (mediaServerItem == null) { logger.error("[停止RTP推流] 失败: 媒体节点为NULL"); return false; @@ -306,7 +306,7 @@ public class ZLMServerFactory { return result; } - public JSONObject startSendRtp(MediaServerItem mediaInfo, SendRtpItem sendRtpItem) { + public JSONObject startSendRtp(MediaServer mediaInfo, SendRtpItem sendRtpItem) { String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; logger.info("rtp/{}开始推流, 目标={}:{},SSRC={}", sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc()); Map param = new HashMap<>(12); @@ -351,7 +351,7 @@ public class ZLMServerFactory { return startSendRtpStreamResult; } - public Boolean updateRtpServerSSRC(MediaServerItem mediaServerItem, String streamId, String ssrc) { + public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { boolean result = false; JSONObject jsonObject = zlmresTfulUtils.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); if (jsonObject == null) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java index 5e46f55ce..4d1762af0 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,7 +27,7 @@ public class ZlmHttpHookSubscribe { @FunctionalInterface public interface Event{ - void response(MediaServerItem mediaServerItem, HookParam hookParam); + void response(MediaServer mediaServerItem, HookParam hookParam); } private Map> allSubscribes = new ConcurrentHashMap<>(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServer.java similarity index 98% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java rename to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServer.java index 511b953ab..a53924f31 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServer.java @@ -5,7 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.util.ObjectUtils; @Schema(description = "流媒体服务信息") -public class MediaServerItem{ +public class MediaServer { @Schema(description = "ID") private String id; @@ -87,10 +87,10 @@ public class MediaServerItem{ @Schema(description = "类型: zlm/abl") private String type; - public MediaServerItem() { + public MediaServer() { } - public MediaServerItem(ZLMServerConfig zlmServerConfig, String sipIp) { + public MediaServer(ZLMServerConfig zlmServerConfig, String sipIp) { id = zlmServerConfig.getGeneralMediaServerId(); ip = zlmServerConfig.getIp(); hookIp = ObjectUtils.isEmpty(zlmServerConfig.getHookIp())? sipIp: zlmServerConfig.getHookIp(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItemLite.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItemLite.java index 4e0ffe93b..c803185b0 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItemLite.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItemLite.java @@ -36,7 +36,7 @@ public class MediaServerItemLite { - public MediaServerItemLite(MediaServerItem mediaServerItem) { + public MediaServerItemLite(MediaServer mediaServerItem) { this.id = mediaServerItem.getId(); this.ip = mediaServerItem.getIp(); this.hookIp = mediaServerItem.getHookIp(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java index aa6431f52..8ac53fff2 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.event; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.springframework.context.ApplicationEvent; /** @@ -12,13 +12,13 @@ public class HookZlmServerKeepaliveEvent extends ApplicationEvent { super(source); } - private MediaServerItem mediaServerItem; + private MediaServer mediaServerItem; - public MediaServerItem getMediaServerItem() { + public MediaServer getMediaServerItem() { return mediaServerItem; } - public void setMediaServerItem(MediaServerItem mediaServerItem) { + public void setMediaServerItem(MediaServer mediaServerItem) { this.mediaServerItem = mediaServerItem; } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java index cbc5b74b1..4d89c7089 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.event; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.springframework.context.ApplicationEvent; /** @@ -12,13 +12,13 @@ public class HookZlmServerStartEvent extends ApplicationEvent { super(source); } - private MediaServerItem mediaServerItem; + private MediaServer mediaServerItem; - public MediaServerItem getMediaServerItem() { + public MediaServer getMediaServerItem() { return mediaServerItem; } - public void setMediaServerItem(MediaServerItem mediaServerItem) { + public void setMediaServerItem(MediaServer mediaServerItem) { this.mediaServerItem = mediaServerItem; } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java index c10313e8e..bffd25b5c 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.service; import com.alibaba.fastjson2.JSONArray; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; @@ -18,7 +18,7 @@ public interface ICloudRecordService { /** * 分页回去云端录像列表 */ - PageInfo getList(int page, int count, String query, String app, String stream, String startTime, String endTime, List mediaServerItems); + PageInfo getList(int page, int count, String query, String app, String stream, String startTime, String endTime, List mediaServerItems); /** * 根据hook消息增加一条记录 @@ -28,12 +28,12 @@ public interface ICloudRecordService { /** * 获取所有的日期 */ - List getDateList(String app, String stream, int year, int month, List mediaServerItems); + List getDateList(String app, String stream, int year, int month, List mediaServerItems); /** * 添加合并任务 */ - String addTask(String app, String stream, MediaServerItem mediaServerItem, String startTime, + String addTask(String app, String stream, MediaServer mediaServerItem, String startTime, String endTime, String callId, String remoteHost, boolean filterMediaServer); diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java index b1261c77a..338814c51 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java @@ -1,9 +1,8 @@ package com.genersoft.iot.vmp.service; -import com.alibaba.fastjson2.JSONArray; import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.bean.Track; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; /** * 媒体信息业务 @@ -33,7 +32,7 @@ public interface IMediaService { * @param stream * @return */ - StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, Track track, String callId); + StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId); /** * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 @@ -41,5 +40,5 @@ public interface IMediaService { * @param stream * @return */ - StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String addr, String callId, boolean isPlay); + StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java index f8486a87d..fb5ffdda0 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; import com.github.pagehelper.PageInfo; @@ -73,13 +73,13 @@ public interface IPlatformService { * @param errorEvent 信令错误事件 * @param timeoutCallback 超时事件 */ - void broadcastInvite(ParentPlatform platform, String channelId, MediaServerItem mediaServerItem, ZlmHttpHookSubscribe.Event hookEvent, + void broadcastInvite(ParentPlatform platform, String channelId, MediaServer mediaServerItem, ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, InviteTimeOutCallback timeoutCallback) throws InvalidArgumentException, ParseException, SipException; /** * 语音喊话回复BYE */ - void stopBroadcast(ParentPlatform platform, DeviceChannel channel, String stream,boolean sendBye, MediaServerItem mediaServerItem); + void stopBroadcast(ParentPlatform platform, DeviceChannel channel, String stream,boolean sendBye, MediaServer mediaServerItem); void addSimulatedSubscribeInfo(ParentPlatform parentPlatform); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java index 77525e880..88cac66c1 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -26,20 +26,20 @@ import java.util.Map; */ public interface IPlayService { - void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channelId, + void play(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channelId, ErrorCallback callback); - SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback callback); + SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback callback); - StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId); + StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, HookParam hookParam, String deviceId, String channelId); - MediaServerItem getNewMediaServerItem(Device device); + MediaServer getNewMediaServerItem(Device device); void playBack(String deviceId, String channelId, String startTime, String endTime, ErrorCallback callback); - void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback callback); + void playBack(MediaServer mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback callback); void zlmServerOffline(String mediaServerId); void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback callback); - void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback callback); + void download(MediaServer mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback callback); StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream); @@ -47,7 +47,7 @@ public interface IPlayService { AudioBroadcastResult audioBroadcast(Device device, String channelId, Boolean broadcastMode); - boolean audioBroadcastCmd(Device device, String channelId, MediaServerItem mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException; + boolean audioBroadcastCmd(Device device, String channelId, MediaServer mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException; boolean audioBroadcastInUse(Device device, String channelId); @@ -62,7 +62,7 @@ public interface IPlayService { void startSendRtpStreamHand(SendRtpItem sendRtpItem, Object correlationInfo, JSONObject jsonObject, Map param, CallIdHeader callIdHeader); - void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioBroadcastEvent event); + void talkCmd(Device device, String channelId, MediaServer mediaServerItem, String stream, AudioBroadcastEvent event); void stopTalk(Device device, String channelId, Boolean streamIsReady); diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java index c4968a745..775e91d7c 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.service; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.GeneralCallback; import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; import com.github.pagehelper.PageInfo; @@ -75,7 +75,7 @@ public interface IStreamProxyService { * 获取ffmpeg.cmd模板 * @return */ - JSONObject getFFmpegCMDs(MediaServerItem mediaServerItem); + JSONObject getFFmpegCMDs(MediaServer mediaServerItem); /** * 根据app与stream获取streamProxy diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java index 10b1eff1c..49c1087f7 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; @@ -16,7 +16,7 @@ import java.util.Map; */ public interface IStreamPushService { - List handleJSON(String json, MediaServerItem mediaServerItem); + List handleJSON(String json, MediaServer mediaServerItem); /** * 将应用名和流ID加入国标关联 diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java index 0a332ef09..8aa5dce27 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service.bean; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import java.util.EventObject; @@ -15,7 +15,7 @@ public class PlayBackResult { private String msg; private T data; - private MediaServerItem mediaServerItem; + private MediaServer mediaServerItem; private JSONObject response; private SipSubscribe.EventResult event; @@ -35,11 +35,11 @@ public class PlayBackResult { this.data = data; } - public MediaServerItem getMediaServerItem() { + public MediaServer getMediaServerItem() { return mediaServerItem; } - public void setMediaServerItem(MediaServerItem mediaServerItem) { + public void setMediaServerItem(MediaServer mediaServerItem) { this.mediaServerItem = mediaServerItem; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/ResponseSendItemMsg.java b/src/main/java/com/genersoft/iot/vmp/service/bean/ResponseSendItemMsg.java index 501621bb4..80b0d7d60 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/ResponseSendItemMsg.java +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/ResponseSendItemMsg.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.service.bean; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; /** * redis消息:下级回复推送信息 @@ -11,7 +11,7 @@ public class ResponseSendItemMsg { private SendRtpItem sendRtpItem; - private MediaServerItem mediaServerItem; + private MediaServer mediaServerItem; public SendRtpItem getSendRtpItem() { return sendRtpItem; @@ -21,11 +21,11 @@ public class ResponseSendItemMsg { this.sendRtpItem = sendRtpItem; } - public MediaServerItem getMediaServerItem() { + public MediaServer getMediaServerItem() { return mediaServerItem; } - public void setMediaServerItem(MediaServerItem mediaServerItem) { + public void setMediaServerItem(MediaServer mediaServerItem) { this.mediaServerItem = mediaServerItem; } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java index aabdb8afe..de4af6c53 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java @@ -6,7 +6,7 @@ import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.service.ICloudRecordService; @@ -51,7 +51,7 @@ public class CloudRecordServiceImpl implements ICloudRecordService { private VideoStreamSessionManager streamSession; @Override - public PageInfo getList(int page, int count, String query, String app, String stream, String startTime, String endTime, List mediaServerItems) { + public PageInfo getList(int page, int count, String query, String app, String stream, String startTime, String endTime, List mediaServerItems) { // 开始时间和结束时间在数据库中都是以秒为单位的 Long startTimeStamp = null; Long endTimeStamp = null; @@ -76,7 +76,7 @@ public class CloudRecordServiceImpl implements ICloudRecordService { } @Override - public List getDateList(String app, String stream, int year, int month, List mediaServerItems) { + public List getDateList(String app, String stream, int year, int month, List mediaServerItems) { LocalDate startDate = LocalDate.of(year, month, 1); LocalDate endDate; if (month == 12) { @@ -111,7 +111,7 @@ public class CloudRecordServiceImpl implements ICloudRecordService { } @Override - public String addTask(String app, String stream, MediaServerItem mediaServerItem, String startTime, String endTime, + public String addTask(String app, String stream, MediaServer mediaServerItem, String startTime, String endTime, String callId, String remoteHost, boolean filterMediaServer) { // 参数校验 assert app != null; @@ -128,7 +128,7 @@ public class CloudRecordServiceImpl implements ICloudRecordService { endTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime); } - List mediaServers = new ArrayList<>(); + List mediaServers = new ArrayList<>(); mediaServers.add(mediaServerItem); // 检索相关的录像文件 List filePathList = cloudRecordServiceMapper.queryRecordFilePathList(app, stream, startTimeStamp, @@ -146,7 +146,7 @@ public class CloudRecordServiceImpl implements ICloudRecordService { @Override public JSONArray queryTask(String app, String stream, String callId, String taskId, String mediaServerId, Boolean isEnd, String scheme) { - MediaServerItem mediaServerItem = null; + MediaServer mediaServerItem = null; if (mediaServerId == null) { mediaServerItem = mediaServerService.getDefaultMediaServer(); }else { @@ -183,10 +183,10 @@ public class CloudRecordServiceImpl implements ICloudRecordService { } - List mediaServerItems; + List mediaServerItems; if (!ObjectUtils.isEmpty(mediaServerId)) { mediaServerItems = new ArrayList<>(); - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); if (mediaServerItem == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId); } @@ -229,7 +229,7 @@ public class CloudRecordServiceImpl implements ICloudRecordService { throw new ControllerException(ErrorCode.ERROR400.getCode(), "资源不存在"); } String filePath = recordItem.getFilePath(); - MediaServerItem mediaServerItem = mediaServerService.getOne(recordItem.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(recordItem.getMediaServerId()); return CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index dbf1a9141..0d864ad84 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IInviteStreamService; @@ -241,7 +241,7 @@ public class DeviceServiceImpl implements IDeviceService { SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null); if (sendRtpItem != null) { redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), null); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index b568ae237..07a28a3be 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -2,10 +2,9 @@ package com.genersoft.iot.vmp.service.impl; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaConfig; -import com.genersoft.iot.vmp.media.bean.Track; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -27,13 +26,10 @@ public class MediaServiceImpl implements IMediaService { @Autowired private MediaConfig mediaConfig; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Override - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String callId) { - return getStreamInfoByAppAndStream(mediaInfo, app, stream, track, null, callId, true); + public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId) { + return getStreamInfoByAppAndStream(mediaServerItem, app, stream, mediaInfo, null, callId, true); } @Override @@ -42,7 +38,7 @@ public class MediaServiceImpl implements IMediaService { if (mediaServerId == null) { mediaServerId = mediaConfig.getId(); } - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo == null) { return null; } @@ -67,26 +63,26 @@ public class MediaServiceImpl implements IMediaService { } @Override - public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String addr, String callId, boolean isPlay) { + public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay) { StreamInfo streamInfoResult = new StreamInfo(); streamInfoResult.setStream(stream); streamInfoResult.setApp(app); if (addr == null) { - addr = mediaInfo.getStreamIp(); + addr = mediaServer.getStreamIp(); } streamInfoResult.setIp(addr); - streamInfoResult.setMediaServerId(mediaInfo.getId()); + streamInfoResult.setMediaServerId(mediaServer.getId()); String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; - streamInfoResult.setRtmp(addr, mediaInfo.getRtmpPort(),mediaInfo.getRtmpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtsp(addr, mediaInfo.getRtspPort(),mediaInfo.getRtspSSLPort(), app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setFmp4(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setHls(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setTs(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam, isPlay); + streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); - streamInfoResult.setTrack(track); + streamInfoResult.setMediaInfo(mediaInfo); return streamInfoResult; } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index fc2c8fd2e..4de8420e8 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.service.impl; -import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.InviteInfo; import com.genersoft.iot.vmp.common.InviteSessionStatus; import com.genersoft.iot.vmp.common.InviteSessionType; @@ -13,11 +12,10 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -96,16 +94,12 @@ public class PlatformServiceImpl implements IPlatformService { @Autowired private VideoStreamSessionManager streamSession; - @Autowired private IPlayService playService; @Autowired private IInviteStreamService inviteStreamService; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Override public ParentPlatform queryPlatformByServerGBId(String platformGbId) { @@ -392,7 +386,7 @@ public class PlatformServiceImpl implements IPlatformService { for (SendRtpItem sendRtpItem : sendRtpItems) { ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), null, null); - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); Map param = new HashMap<>(3); param.put("vhost", "__defaultVhost__"); param.put("app", sendRtpItem.getApp()); @@ -455,7 +449,7 @@ public class PlatformServiceImpl implements IPlatformService { } @Override - public void broadcastInvite(ParentPlatform platform, String channelId, MediaServerItem mediaServerItem, ZlmHttpHookSubscribe.Event hookEvent, + public void broadcastInvite(ParentPlatform platform, String channelId, MediaServer mediaServerItem, ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, InviteTimeOutCallback timeoutCallback) throws InvalidArgumentException, ParseException, SipException { if (mediaServerItem == null) { @@ -466,7 +460,7 @@ public class PlatformServiceImpl implements IPlatformService { if (inviteInfoForOld != null && inviteInfoForOld.getStreamInfo() != null) { // 如果zlm不存在这个流,则删除数据即可 - MediaServerItem mediaServerItemForStreamInfo = mediaServerService.getOne(inviteInfoForOld.getStreamInfo().getMediaServerId()); + MediaServer mediaServerItemForStreamInfo = mediaServerService.getOne(inviteInfoForOld.getStreamInfo().getMediaServerId()); if (mediaServerItemForStreamInfo != null) { Boolean ready = zlmServerFactory.isStreamReady(mediaServerItemForStreamInfo, inviteInfoForOld.getStreamInfo().getApp(), inviteInfoForOld.getStreamInfo().getStream()); if (!ready) { @@ -596,7 +590,7 @@ public class PlatformServiceImpl implements IPlatformService { }); } - private void inviteOKHandler(SipSubscribe.EventResult eventResult, SSRCInfo ssrcInfo, int tcpMode, boolean ssrcCheck, MediaServerItem mediaServerItem, + private void inviteOKHandler(SipSubscribe.EventResult eventResult, SSRCInfo ssrcInfo, int tcpMode, boolean ssrcCheck, MediaServer mediaServerItem, ParentPlatform platform, String channelId, String timeOutTaskKey, ErrorCallback callback, InviteInfo inviteInfo, InviteSessionType inviteSessionType){ inviteInfo.setStatus(InviteSessionStatus.ok); @@ -701,7 +695,7 @@ public class PlatformServiceImpl implements IPlatformService { private void tcpActiveHandler(ParentPlatform platform, String channelId, String contentString, - MediaServerItem mediaServerItem, int tcpMode, boolean ssrcCheck, + MediaServer mediaServerItem, int tcpMode, boolean ssrcCheck, String timeOutTaskKey, SSRCInfo ssrcInfo, ErrorCallback callback){ if (tcpMode != 2) { return; @@ -729,8 +723,8 @@ public class PlatformServiceImpl implements IPlatformService { } logger.info("[TCP主动连接对方] serverGbId: {}, channelId: {}, 连接对方的地址:{}:{}, SSRC: {}, SSRC校验:{}", platform.getServerGBId(), channelId, sdp.getConnection().getAddress(), port, ssrcInfo.getSsrc(), ssrcCheck); - JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream()); - logger.info("[TCP主动连接对方] 结果: {}", jsonObject); + Boolean result = mediaServerService.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream()); + logger.info("[TCP主动连接对方] 结果: {}", result); } catch (SdpException e) { logger.error("[TCP主动连接对方] serverGbId: {}, channelId: {}, 解析200OK的SDP信息失败", platform.getServerGBId(), channelId, e); dynamicTask.stop(timeOutTaskKey); @@ -749,7 +743,7 @@ public class PlatformServiceImpl implements IPlatformService { } @Override - public void stopBroadcast(ParentPlatform platform, DeviceChannel channel, String stream, boolean sendBye, MediaServerItem mediaServerItem) { + public void stopBroadcast(ParentPlatform platform, DeviceChannel channel, String stream, boolean sendBye, MediaServer mediaServerItem) { try { if (sendBye) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index eae1dde96..ee84dc819 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -1,11 +1,9 @@ package com.genersoft.iot.vmp.service.impl; -import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.*; import com.genersoft.iot.vmp.conf.DynamicTask; -import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.exception.ServiceException; @@ -18,16 +16,15 @@ 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.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.bean.Track; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; @@ -36,7 +33,6 @@ import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper; import com.genersoft.iot.vmp.utils.CloudRecordUtils; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; @@ -47,9 +43,6 @@ import gov.nist.javax.sip.message.SIPResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; @@ -101,9 +94,6 @@ public class PlayServiceImpl implements IPlayService { @Autowired private SendRtpPortManager sendRtpPortManager; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Autowired private IMediaService mediaService; @@ -119,38 +109,21 @@ public class PlayServiceImpl implements IPlayService { @Autowired private IDeviceChannelService channelService; - @Autowired - private SipConfig sipConfig; - @Autowired private DynamicTask dynamicTask; - @Autowired - private CloudRecordServiceMapper cloudRecordServiceMapper; - @Autowired private ISIPCommanderForPlatform commanderForPlatform; - - @Qualifier("taskExecutor") - @Autowired - private ThreadPoolTaskExecutor taskExecutor; - @Autowired private RedisGbPlayMsgListener redisGbPlayMsgListener; - @Autowired - private ZlmHttpHookSubscribe hookSubscribe; - @Autowired private SSRCFactory ssrcFactory; - @Autowired - private RedisTemplate redisTemplate; - @Override - public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback callback) { + public SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback callback) { if (mediaServerItem == null) { logger.warn("[点播] 未找到可用的zlm deviceId: {},channelId:{}", deviceId, channelId); throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm"); @@ -185,7 +158,7 @@ public class PlayServiceImpl implements IPlayService { return inviteInfo.getSsrcInfo(); } String mediaServerId = streamInfo.getMediaServerId(); - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); Boolean ready = zlmServerFactory.isStreamReady(mediaInfo, "rtp", streamId); if (ready != null && ready) { @@ -204,7 +177,7 @@ public class PlayServiceImpl implements IPlayService { } } } - String streamId = String.format("%s_%s", device.getDeviceId(), channelId);; + String streamId = String.format("%s_%s", device.getDeviceId(), channelId); SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); @@ -218,7 +191,7 @@ public class PlayServiceImpl implements IPlayService { return ssrcInfo; } - private void talk(MediaServerItem mediaServerItem, Device device, String channelId, String stream, + private void talk(MediaServer mediaServerItem, Device device, String channelId, String stream, ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, Runnable timeoutCallback, AudioBroadcastEvent audioEvent) { @@ -361,7 +334,7 @@ public class PlayServiceImpl implements IPlayService { @Override - public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, + public void play(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, ErrorCallback callback) { if (mediaServerItem == null || ssrcInfo == null) { @@ -495,7 +468,7 @@ public class PlayServiceImpl implements IPlayService { } private void tcpActiveHandler(Device device, String channelId, String contentString, - MediaServerItem mediaServerItem, + MediaServer mediaServerItem, String timeOutTaskKey, SSRCInfo ssrcInfo, ErrorCallback callback){ if (!device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) { return; @@ -522,9 +495,9 @@ public class PlayServiceImpl implements IPlayService { } } logger.info("[TCP主动连接对方] deviceId: {}, channelId: {}, 连接对方的地址:{}:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, sdp.getConnection().getAddress(), port, device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck()); - JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream()); - logger.info("[TCP主动连接对方] 结果: {}" , jsonObject); - if (jsonObject.getInteger("code") != 0) { + Boolean result = mediaServerService.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream()); + logger.info("[TCP主动连接对方] 结果: {}" , result); + if (!result) { // 主动连接失败,结束流程, 清理数据 dynamicTask.stop(timeOutTaskKey); mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); @@ -564,7 +537,7 @@ public class PlayServiceImpl implements IPlayService { * @param channelId 通道 ID * @param stream ssrc */ - private void snapOnPlay(MediaServerItem mediaServerItemInuse, String deviceId, String channelId, String stream) { + private void snapOnPlay(MediaServer mediaServerItemInuse, String deviceId, String channelId, String stream) { String streamUrl; if (mediaServerItemInuse.getRtspPort() != 0) { streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", stream); @@ -575,10 +548,10 @@ public class PlayServiceImpl implements IPlayService { String fileName = deviceId + "_" + channelId + ".jpg"; // 请求截图 logger.info("[请求截图]: " + fileName); - zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); + mediaServerService.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); } - public StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId) { + public StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, HookParam hookParam, String deviceId, String channelId) { StreamInfo streamInfo = null; Device device = redisCatchStorage.getDevice(deviceId); OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam; @@ -600,7 +573,7 @@ public class PlayServiceImpl implements IPlayService { } - private StreamInfo onPublishHandlerForPlayback(MediaServerItem mediaServerItem, HookParam param, String deviceId, String channelId, String startTime, String endTime) { + private StreamInfo onPublishHandlerForPlayback(MediaServer mediaServerItem, HookParam param, String deviceId, String channelId, String startTime, String endTime) { OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) param; StreamInfo streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId); if (streamInfo != null) { @@ -624,11 +597,11 @@ public class PlayServiceImpl implements IPlayService { } @Override - public MediaServerItem getNewMediaServerItem(Device device) { + public MediaServer getNewMediaServerItem(Device device) { if (device == null) { return null; } - MediaServerItem mediaServerItem; + MediaServer mediaServerItem; if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) { mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null); } else { @@ -649,7 +622,7 @@ public class PlayServiceImpl implements IPlayService { throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到设备:" + deviceId); } - MediaServerItem newMediaServerItem = getNewMediaServerItem(device); + MediaServer newMediaServerItem = getNewMediaServerItem(device); if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE") && ! newMediaServerItem.isRtpEnable()) { logger.warn("[录像回放] 单端口收流时不支持TCP主动方式收流 deviceId: {},channelId:{}", deviceId, channelId); throw new ControllerException(ErrorCode.ERROR100.getCode(), "单端口收流时不支持TCP主动方式收流"); @@ -666,7 +639,7 @@ public class PlayServiceImpl implements IPlayService { } @Override - public void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, + public void playBack(MediaServer mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback callback) { if (mediaServerItem == null || ssrcInfo == null) { @@ -750,7 +723,7 @@ public class PlayServiceImpl implements IPlayService { } - private void InviteOKHandler(SipSubscribe.EventResult eventResult, SSRCInfo ssrcInfo, MediaServerItem mediaServerItem, + private void InviteOKHandler(SipSubscribe.EventResult eventResult, SSRCInfo ssrcInfo, MediaServer mediaServerItem, Device device, String channelId, String timeOutTaskKey, ErrorCallback callback, InviteInfo inviteInfo, InviteSessionType inviteSessionType){ inviteInfo.setStatus(InviteSessionStatus.ok); @@ -846,7 +819,7 @@ public class PlayServiceImpl implements IPlayService { if (device == null) { return; } - MediaServerItem newMediaServerItem = this.getNewMediaServerItem(device); + MediaServer newMediaServerItem = this.getNewMediaServerItem(device); if (newMediaServerItem == null) { callback.run(InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getCode(), InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getMsg(), @@ -860,7 +833,7 @@ public class PlayServiceImpl implements IPlayService { @Override - public void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback callback) { + public void download(MediaServer mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback callback) { if (mediaServerItem == null || ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(), @@ -973,7 +946,7 @@ public class PlayServiceImpl implements IPlayService { // 获取当前已下载时长 String mediaServerId = inviteInfo.getStreamInfo().getMediaServerId(); - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); if (mediaServerItem == null) { logger.warn("[获取下载进度] 查询录像信息时发现节点不存在"); return null; @@ -984,30 +957,13 @@ public class PlayServiceImpl implements IPlayService { logger.warn("[获取下载进度] 下载已结束"); return null; } - - JSONObject mediaListJson= zlmresTfulUtils.getMediaList(mediaServerItem, "rtp", stream); - if (mediaListJson == null) { - logger.warn("[获取下载进度] 从zlm查询进度失败"); + String app = "rtp"; + MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServerItem, app, stream); + if (mediaInfo == null) { + logger.warn("[获取下载进度] 查询进度失败, 节点Id: {}, {}/{}", mediaServerId, app, stream); return null; } - if (mediaListJson.getInteger("code") != 0) { - logger.warn("[获取下载进度] 从zlm查询进度出现错误: {}", mediaListJson.getString("msg")); - return null; - } - JSONArray data = mediaListJson.getJSONArray("data"); - if (data == null) { - logger.warn("[获取下载进度] 从zlm查询进度时未返回数据"); - return null; - } - JSONObject mediaJSON = data.getJSONObject(0); - JSONArray tracks = mediaJSON.getJSONArray("tracks"); - if (tracks.isEmpty()) { - logger.warn("[获取下载进度] 从zlm查询进度时未返回数据"); - return null; - } - JSONObject jsonObject = tracks.getJSONObject(0); - long duration = jsonObject.getLongValue("duration"); - if (duration == 0) { + if (mediaInfo.getDuration() == 0) { inviteInfo.getStreamInfo().setProgress(0); } else { String startTime = inviteInfo.getStreamInfo().getStartTime(); @@ -1016,7 +972,7 @@ public class PlayServiceImpl implements IPlayService { long start = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime); long end = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime); - BigDecimal currentCount = new BigDecimal(duration); + BigDecimal currentCount = new BigDecimal(mediaInfo.getDuration()); BigDecimal totalCount = new BigDecimal((end - start) * 1000); BigDecimal divide = currentCount.divide(totalCount, 2, RoundingMode.HALF_UP); double process = divide.doubleValue(); @@ -1029,7 +985,7 @@ public class PlayServiceImpl implements IPlayService { return inviteInfo.getStreamInfo(); } - private StreamInfo onPublishHandlerForDownload(MediaServerItem mediaServerItemInuse, HookParam hookParam, String deviceId, String channelId, String startTime, String endTime) { + private StreamInfo onPublishHandlerForDownload(MediaServer mediaServerItemInuse, HookParam hookParam, String deviceId, String channelId, String startTime, String endTime) { OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) hookParam; StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, streamChangedHookParam, deviceId, channelId); if (streamInfo != null) { @@ -1048,42 +1004,9 @@ public class PlayServiceImpl implements IPlayService { } - public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, OnStreamChangedHookParam hookParam, String deviceId, String channelId) { - List tracks = hookParam.getTracks(); - Track track = new Track(); - track.setReaderCount(hookParam.getTotalReaderCount()); - for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { - switch (mediaTrack.getCodec_id()) { - case 0: - track.setVideoCodec("H264"); - break; - case 1: - track.setVideoCodec("H265"); - break; - case 2: - track.setAudioCodec("AAC"); - break; - case 3: - track.setAudioCodec("G711A"); - break; - case 4: - track.setAudioCodec("G711U"); - break; - } - if (mediaTrack.getSample_rate() > 0) { - track.setAudioSampleRate(mediaTrack.getSample_rate()); - } - if (mediaTrack.getChannels() > 0) { - track.setAudioChannels(mediaTrack.getChannels()); - } - if (mediaTrack.getHeight() > 0) { - track.setHeight(mediaTrack.getHeight()); - } - if (mediaTrack.getWidth() > 0) { - track.setWidth(mediaTrack.getWidth()); - } - } - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", hookParam.getStream(), track, null); + public StreamInfo onPublishHandler(MediaServer mediaServerItem, OnStreamChangedHookParam hookParam, String deviceId, String channelId) { + MediaInfo mediaInfo = MediaInfo.getInstance(hookParam); + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", hookParam.getStream(), mediaInfo, null); streamInfo.setDeviceID(deviceId); streamInfo.setChannelId(channelId); return streamInfo; @@ -1139,7 +1062,7 @@ public class PlayServiceImpl implements IPlayService { logger.warn("开启语音广播的时候未找到通道: {}", channelId); return null; } - MediaServerItem mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null); + MediaServer mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null); if (broadcastMode == null) { broadcastMode = true; } @@ -1154,7 +1077,7 @@ public class PlayServiceImpl implements IPlayService { } @Override - public boolean audioBroadcastCmd(Device device, String channelId, MediaServerItem mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException { + public boolean audioBroadcastCmd(Device device, String channelId, MediaServer mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException { if (device == null || channelId == null) { return false; } @@ -1222,7 +1145,7 @@ public class PlayServiceImpl implements IPlayService { SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 查询流是否存在,不存在则认为是异常状态 - MediaServerItem mediaServerServiceOne = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaServerServiceOne = mediaServerService.getOne(sendRtpItem.getMediaServerId()); Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerServiceOne, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("语音广播通道使用中: {}", channelId); @@ -1252,12 +1175,8 @@ public class PlayServiceImpl implements IPlayService { SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null); if (sendRtpItem != null) { redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Map param = new HashMap<>(); - param.put("vhost", "__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStream()); - zlmresTfulUtils.stopSendRtp(mediaInfo, param); + MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + mediaServerService.stopSendRtp(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream(), null); try { cmder.streamByeCmdForDeviceInvite(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); } catch (InvalidArgumentException | ParseException | SipException | @@ -1333,7 +1252,7 @@ public class PlayServiceImpl implements IPlayService { } inviteInfo.getStreamInfo().setPause(true); inviteStreamService.updateInviteInfo(inviteInfo); - MediaServerItem mediaServerItem = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); if (null == mediaServerItem) { logger.warn("mediaServer 不存在!"); throw new ServiceException("mediaServer不存在"); @@ -1344,8 +1263,8 @@ public class PlayServiceImpl implements IPlayService { if (!mediaServerItem.isRtpEnable()) { streamKey = Long.toHexString(Long.parseLong(inviteInfo.getSsrcInfo().getSsrc())).toUpperCase(); } - JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServerItem, streamKey); - if (jsonObject == null || jsonObject.getInteger("code") != 0) { + Boolean result = mediaServerService.pauseRtpCheck(mediaServerItem, streamKey); + if (!result) { throw new ServiceException("暂停RTP接收失败"); } Device device = storager.queryVideoDevice(inviteInfo.getDeviceId()); @@ -1361,7 +1280,7 @@ public class PlayServiceImpl implements IPlayService { } inviteInfo.getStreamInfo().setPause(false); inviteStreamService.updateInviteInfo(inviteInfo); - MediaServerItem mediaServerItem = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); if (null == mediaServerItem) { logger.warn("mediaServer 不存在!"); throw new ServiceException("mediaServer不存在"); @@ -1372,8 +1291,8 @@ public class PlayServiceImpl implements IPlayService { if (!mediaServerItem.isRtpEnable()) { streamKey = Long.toHexString(Long.parseLong(inviteInfo.getSsrcInfo().getSsrc())).toUpperCase(); } - JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServerItem, streamKey); - if (jsonObject == null || jsonObject.getInteger("code") != 0) { + boolean result = mediaServerService.resumeRtpCheck(mediaServerItem, streamKey); + if (!result) { throw new ServiceException("继续RTP接收失败"); } Device device = storager.queryVideoDevice(inviteInfo.getDeviceId()); @@ -1384,7 +1303,7 @@ public class PlayServiceImpl implements IPlayService { public void startPushStream(SendRtpItem sendRtpItem, SIPResponse sipResponse, ParentPlatform platform, CallIdHeader callIdHeader) { // 开始发流 String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); logger.info("[开始推流] rtp/{}, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); Map param = new HashMap<>(12); @@ -1481,7 +1400,7 @@ public class PlayServiceImpl implements IPlayService { } @Override - public void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioBroadcastEvent event) { + public void talkCmd(Device device, String channelId, MediaServer mediaServerItem, String stream, AudioBroadcastEvent event) { if (device == null || channelId == null) { return; } @@ -1498,7 +1417,7 @@ public class PlayServiceImpl implements IPlayService { SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 查询流是否存在,不存在则认为是异常状态 - MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("[语音对讲] 正在语音广播,无法开启语音通话: {}", channelId); @@ -1512,7 +1431,7 @@ public class PlayServiceImpl implements IPlayService { SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, stream, null); if (sendRtpItem != null) { - MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream()); if (streamReady) { logger.warn("[语音对讲] 进行中: {}", channelId); @@ -1557,7 +1476,7 @@ public class PlayServiceImpl implements IPlayService { return; } - MediaServerItem mediaServer = mediaServerService.getOne(mediaServerId); + MediaServer mediaServer = mediaServerService.getOne(mediaServerId); if (streamIsReady == null || streamIsReady) { Map param = new HashMap<>(); @@ -1592,7 +1511,7 @@ public class PlayServiceImpl implements IPlayService { if (inviteInfo != null) { if (inviteInfo.getStreamInfo() != null) { // 已存在线直接截图 - MediaServerItem mediaServerItemInuse = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); + MediaServer mediaServerItemInuse = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); String streamUrl; if (mediaServerItemInuse.getRtspPort() != 0) { streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", inviteInfo.getStreamInfo().getStream()); @@ -1602,7 +1521,7 @@ public class PlayServiceImpl implements IPlayService { String path = "snap"; // 请求截图 logger.info("[请求截图]: " + fileName); - zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); + mediaServerService.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); File snapFile = new File(path + File.separator + fileName); if (snapFile.exists()) { errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), snapFile.getAbsoluteFile()); @@ -1613,7 +1532,7 @@ public class PlayServiceImpl implements IPlayService { } } - MediaServerItem newMediaServerItem = getNewMediaServerItem(device); + MediaServer newMediaServerItem = getNewMediaServerItem(device); play(newMediaServerItem, deviceId, channelId, null, (code, msg, data)->{ if (code == InviteErrorCode.SUCCESS.getCode()) { InviteInfo inviteInfoForPlay = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 2eb3da980..4a44093e8 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 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.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; @@ -108,7 +108,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @Override public void save(StreamProxyItem param, GeneralCallback callback) { - MediaServerItem mediaInfo; + MediaServer mediaInfo; if (ObjectUtils.isEmpty(param.getMediaServerId()) || "auto".equals(param.getMediaServerId())){ mediaInfo = mediaServerService.getMediaServerForMinimumLoad(null); }else { @@ -310,7 +310,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @Override public JSONObject addStreamProxyToZlm(StreamProxyItem param) { JSONObject result = null; - MediaServerItem mediaServerItem = null; + MediaServer mediaServerItem = null; if (param.getMediaServerId() == null) { logger.warn("添加代理时MediaServerId 为null"); return null; @@ -355,7 +355,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { if (param ==null) { return null; } - MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); JSONObject result = null; if ("ffmpeg".equalsIgnoreCase(param.getType())){ result = zlmresTfulUtils.delFFmpegSource(mediaServerItem, param.getStreamKey()); @@ -428,7 +428,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } @Override - public JSONObject getFFmpegCMDs(MediaServerItem mediaServerItem) { + public JSONObject getFFmpegCMDs(MediaServer mediaServerItem) { JSONObject result = new JSONObject(); JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0 @@ -518,7 +518,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } private void syncPullStream(String mediaServerId){ - MediaServerItem mediaServer = mediaServerService.getOne(mediaServerId); + MediaServer mediaServer = mediaServerService.getOne(mediaServerId); if (mediaServer != null) { List allPullStream = redisCatchStorage.getStreams(mediaServerId, "PULL"); if (allPullStream.size() > 0) { @@ -571,13 +571,13 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @Scheduled(cron = "* 0/10 * * * ?") public void asyncCheckStreamProxyStatus() { - List all = mediaServerService.getAllOnline(); + List all = mediaServerService.getAllOnline(); if (CollectionUtils.isEmpty(all)){ return; } - Map serverItemMap = all.stream().collect(Collectors.toMap(MediaServerItem::getId, Function.identity(), (m1, m2) -> m1)); + Map serverItemMap = all.stream().collect(Collectors.toMap(MediaServer::getId, Function.identity(), (m1, m2) -> m1)); List list = videoManagerStorager.getStreamProxyListForEnable(true); @@ -587,7 +587,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { for (StreamProxyItem streamProxyItem : list) { - MediaServerItem mediaServerItem = serverItemMap.get(streamProxyItem.getMediaServerId()); + MediaServer mediaServerItem = serverItemMap.get(streamProxyItem.getMediaServerId()); // TODO 支持其他 schema JSONObject mediaInfo = zlmresTfulUtils.isMediaOnline(mediaServerItem, streamProxyItem.getApp(), streamProxyItem.getStream(), "rtsp"); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index b9fd1dfaa..ea560550f 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -89,7 +89,7 @@ public class StreamPushServiceImpl implements IStreamPushService { @Override - public List handleJSON(String jsonData, MediaServerItem mediaServerItem) { + public List handleJSON(String jsonData, MediaServer mediaServerItem) { if (jsonData == null) { return null; } @@ -164,7 +164,7 @@ public class StreamPushServiceImpl implements IStreamPushService { gbStreamService.sendCatalogMsg(stream, CatalogEvent.DEL); platformGbStreamMapper.delByAppAndStream(stream.getApp(), stream.getStream()); int del = gbStreamMapper.del(stream.getApp(), stream.getStream()); - MediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream()); if (mediaList != null) { if (mediaList.getInteger("code") == 0) { @@ -195,7 +195,7 @@ public class StreamPushServiceImpl implements IStreamPushService { gbStreamMapper.del(app, streamId); int delStream = streamPushMapper.del(app, streamId); if (delStream > 0) { - MediaServerItem mediaServerItem = mediaServerService.getOne(streamPushItem.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(streamPushItem.getMediaServerId()); zlmresTfulUtils.closeStreams(mediaServerItem,app, streamId); } return true; @@ -204,7 +204,7 @@ public class StreamPushServiceImpl implements IStreamPushService { @Override public void zlmServerOnline(String mediaServerId) { // 同步zlm推流信息 - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); if (mediaServerItem == null) { return; } @@ -470,7 +470,7 @@ public class StreamPushServiceImpl implements IStreamPushService { int delStream = streamPushMapper.delAllForGbStream(gbStreams); if (delStream > 0) { for (GbStream gbStream : gbStreams) { - MediaServerItem mediaServerItem = mediaServerService.getOne(gbStream.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(gbStream.getMediaServerId()); zlmresTfulUtils.closeStreams(mediaServerItem, gbStream.getApp(), gbStream.getStream()); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index 29bd734e2..b5b1b3cad 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 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.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -219,7 +219,7 @@ public class RedisGbPlayMsgListener implements MessageListener { * 处理收到的请求推流的请求 */ private void requestPushStreamMsgHand(RequestPushStreamMsg requestPushStreamMsg, String fromId, String serial) { - MediaServerItem mediaInfo = mediaServerService.getOne(requestPushStreamMsg.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(requestPushStreamMsg.getMediaServerId()); if (mediaInfo == null) { // TODO 回复错误 return; @@ -258,7 +258,7 @@ public class RedisGbPlayMsgListener implements MessageListener { * 处理收到的请求sendItem的请求 */ private void requestSendItemMsgHand(RequestSendItemMsg content, String toId, String serial) { - MediaServerItem mediaServerItem = mediaServerService.getOne(content.getMediaServerId()); + MediaServer mediaServerItem = mediaServerService.getOne(content.getMediaServerId()); if (mediaServerItem == null) { logger.info("[回复推流信息] 流媒体{}不存在 ", content.getMediaServerId()); @@ -317,7 +317,7 @@ public class RedisGbPlayMsgListener implements MessageListener { /** * 将获取到的sendItem发送出去 */ - private void responseSendItem(MediaServerItem mediaServerItem, RequestSendItemMsg content, String toId, String serial) { + private void responseSendItem(MediaServer mediaServerItem, RequestSendItemMsg content, String toId, String serial) { SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, content.getIp(), content.getPort(), content.getSsrc(), content.getPlatformId(), content.getApp(), content.getStream(), content.getChannelId(), @@ -449,7 +449,7 @@ public class RedisGbPlayMsgListener implements MessageListener { logger.info("[REDIS 执行其他平台的请求停止推流] 失败: sendRtpItem为NULL"); return; } - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); if (mediaInfo == null) { // TODO 回复错误 return; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java index 8620e13b2..ecab51f5f 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; @@ -95,7 +95,7 @@ public class RedisPushStreamCloseResponseListener implements MessageListener { param.put("stream",streamId); param.put("ssrc",sendRtpItem.getSsrc()); logger.info("[REDIS消息-推流结束] 停止向上级推流:{}", streamId); - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), sendRtpItem.getCallId(), sendRtpItem.getStream()); zlmServerFactory.stopSendRtpStream(mediaInfo, param); if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) { diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index 78fd28016..2a48a4969 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.AlarmChannelMessage; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; @@ -89,7 +89,7 @@ public interface IRedisCatchStorage { * @param app * @param streamId */ - void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, OnStreamChangedHookParam item); + void addStream(MediaServer mediaServerItem, String type, String app, String streamId, OnStreamChangedHookParam item); /** * 移除流信息从redis diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java index 08f67ba94..7db1dfbf9 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.storager.dao; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import org.apache.ibatis.annotations.*; @@ -55,7 +55,7 @@ public interface CloudRecordServiceMapper { " ") List getList(@Param("query") String query, @Param("app") String app, @Param("stream") String stream, @Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp, - @Param("callId")String callId, List mediaServerItemList); + @Param("callId")String callId, List mediaServerItemList); @Select(" ") List queryRecordFilePathList(@Param("app") String app, @Param("stream") String stream, @Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp, - @Param("callId")String callId, List mediaServerItemList); + @Param("callId")String callId, List mediaServerItemList); @Update(" "}) - int update(MediaServerItem mediaServerItem); + int update(MediaServer mediaServerItem); @Update(value = {" "}) - int updateByHostAndPort(MediaServerItem mediaServerItem); + int updateByHostAndPort(MediaServer mediaServerItem); @Select("SELECT * FROM wvp_media_server WHERE id=#{id}") - MediaServerItem queryOne(String id); + MediaServer queryOne(String id); @Select("SELECT * FROM wvp_media_server") - List queryAll(); + List queryAll(); @Delete("DELETE FROM wvp_media_server WHERE id=#{id}") void delOne(String id); @@ -138,12 +138,12 @@ public interface MediaServerMapper { int delDefault(); @Select("SELECT * FROM wvp_media_server WHERE ip=#{host} and http_port=#{port}") - MediaServerItem queryOneByHostAndPort(@Param("host") String host, @Param("port") int port); + MediaServer queryOneByHostAndPort(@Param("host") String host, @Param("port") int port); @Select("SELECT * FROM wvp_media_server WHERE default_server=true") - MediaServerItem queryDefault(); + MediaServer queryDefault(); @Select("SELECT * FROM wvp_media_server WHERE record_assist_port > 0") - List queryAllWithAssistPort(); + List queryAllWithAssistPort(); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 18a037dd6..4fc16fc40 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.AlarmChannelMessage; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; @@ -313,7 +313,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { } @Override - public void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, OnStreamChangedHookParam onStreamChangedHookParam) { + public void addStream(MediaServer mediaServerItem, String type, String app, String streamId, OnStreamChangedHookParam onStreamChangedHookParam) { // 查找是否使用了callID StreamAuthorityInfo streamAuthorityInfo = getStreamAuthorityInfo(app, streamId); String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_" + type + "_" + app + "_" + streamId + "_" + mediaServerItem.getId(); diff --git a/src/main/java/com/genersoft/iot/vmp/utils/CloudRecordUtils.java b/src/main/java/com/genersoft/iot/vmp/utils/CloudRecordUtils.java index 8954bd7f9..2df9bea31 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/CloudRecordUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/CloudRecordUtils.java @@ -1,11 +1,11 @@ package com.genersoft.iot.vmp.utils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; public class CloudRecordUtils { - public static DownloadFileInfo getDownloadFilePath(MediaServerItem mediaServerItem, String filePath) { + public static DownloadFileInfo getDownloadFilePath(MediaServer mediaServerItem, String filePath) { DownloadFileInfo downloadFileInfo = new DownloadFileInfo(); String pathTemplate = "%s://%s:%s/index/api/downloadFile?file_path=" + filePath; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java index f1872ca79..193c95d4a 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.vmanager.bean; import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.bean.Track; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import io.swagger.v3.oas.annotations.media.Schema; @@ -87,7 +87,7 @@ public class StreamContent { private String mediaServerId; @Schema(description = "流编码信息") - private Track track; + private MediaInfo mediaInfo; @Schema(description = "开始时间") private String startTime; @@ -171,7 +171,7 @@ public class StreamContent { } this.mediaServerId = streamInfo.getMediaServerId(); - this.track = streamInfo.getTrack(); + this.mediaInfo = streamInfo.getMediaInfo(); this.startTime = streamInfo.getStartTime(); this.endTime = streamInfo.getEndTime(); this.progress = streamInfo.getProgress(); @@ -389,12 +389,12 @@ public class StreamContent { this.mediaServerId = mediaServerId; } - public Track getTrack() { - return track; + public MediaInfo getMediaInfo() { + return mediaInfo; } - public void setTrack(Track track) { - this.track = track; + public void setMediaInfo(MediaInfo mediaInfo) { + this.mediaInfo = mediaInfo; } public String getStartTime() { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java index bf9cf4fed..6c111597a 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.vmanager.cloudRecord; import com.alibaba.fastjson2.JSONArray; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.ICloudRecordService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; @@ -67,10 +67,10 @@ public class CloudRecordController { if (ObjectUtils.isEmpty(month)) { month = calendar.get(Calendar.MONTH) + 1; } - List mediaServerItems; + List mediaServerItems; if (!ObjectUtils.isEmpty(mediaServerId)) { mediaServerItems = new ArrayList<>(); - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); if (mediaServerItem == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId); } @@ -110,10 +110,10 @@ public class CloudRecordController { logger.info("[云端录像] 查询 app->{}, stream->{}, mediaServerId->{}, page->{}, count->{}, startTime->{}, endTime->{}", app, stream, mediaServerId, page, count, startTime, endTime); - List mediaServerItems; + List mediaServerItems; if (!ObjectUtils.isEmpty(mediaServerId)) { mediaServerItems = new ArrayList<>(); - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); if (mediaServerItem == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId); } @@ -162,7 +162,7 @@ public class CloudRecordController { @RequestParam(required = false) String callId, @RequestParam(required = false) String remoteHost ){ - MediaServerItem mediaServerItem; + MediaServer mediaServerItem; if (mediaServerId == null) { mediaServerItem = mediaServerService.getDefaultMediaServer(); }else { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index d24ad372f..ece3349b9 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -17,7 +17,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; @@ -104,7 +104,7 @@ public class PlayController { logger.info("[开始点播] deviceId:{}, channelId:{}, ", deviceId, channelId); // 获取可用的zlm Device device = storager.queryVideoDevice(deviceId); - MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); + MediaServer newMediaServerItem = playService.getNewMediaServerItem(device); RequestMessage requestMessage = new RequestMessage(); String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; @@ -218,7 +218,7 @@ public class PlayController { logger.warn("视频转码API调用失败!, 视频流已经停止!"); throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到视频流信息, 视频流可能已经停止"); } - MediaServerItem mediaInfo = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); if (!rtpInfo.getBoolean("exist")) { logger.warn("视频转码API调用失败!, 视频流已停止推流!"); @@ -257,7 +257,7 @@ public class PlayController { if (mediaServerId == null) { throw new ControllerException(ErrorCode.ERROR400.getCode(), "流媒体:" + mediaServerId + "不存在" ); } - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "使用的流媒体已经停止运行" ); }else { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index 21a19f23c..4566ddae0 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.utils.redis.RedisUtil; @@ -83,7 +83,7 @@ public class PsController { logger.info("[第三方PS服务对接->开启收流和获取发流信息] isSend->{}, ssrc->{}, callId->{}, stream->{}, tcpMode->{}, callBack->{}", isSend, ssrc, callId, stream, tcpMode==0?"UDP":"TCP被动", callBack); - MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); if (mediaServerItem == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(),"没有可用的MediaServer"); } @@ -158,7 +158,7 @@ public class PsController { @Parameter(name = "stream", description = "流的ID", required = true) public void closeRtpServer(String stream) { logger.info("[第三方PS服务对接->关闭收流] stream->{}", stream); - MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); zlmServerFactory.closeRtpServer(mediaServerItem,stream); String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_PS_INFO + userSetting.getServerId() + "_*_" + stream; List scan = RedisUtil.scan(redisTemplate, receiveKey); @@ -201,7 +201,7 @@ public class PsController { app, stream, callId); - MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); String key = VideoManagerConstants.WVP_OTHER_SEND_PS_INFO + userSetting.getServerId() + "_" + callId; OtherPsSendInfo sendInfo = (OtherPsSendInfo)redisTemplate.opsForValue().get(key); if (sendInfo == null) { @@ -290,7 +290,7 @@ public class PsController { param.put("app",sendInfo.getPushApp()); param.put("stream",sendInfo.getPushStream()); param.put("ssrc",sendInfo.getPushSSRC()); - MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); Boolean result = zlmServerFactory.stopSendRtpStream(mediaServerItem, param); if (!result) { logger.info("[第三方PS服务对接->关闭发送流] 失败 callId->{}", callId); @@ -305,7 +305,7 @@ public class PsController { @GetMapping(value = "/getTestPort") @ResponseBody public int getTestPort() { - MediaServerItem defaultMediaServer = mediaServerService.getDefaultMediaServer(); + MediaServer defaultMediaServer = mediaServerService.getDefaultMediaServer(); // for (int i = 0; i <300; i++) { // new Thread(() -> { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index 5b73d0a97..ac51bc575 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.utils.redis.RedisUtil; @@ -83,7 +83,7 @@ public class RtpController { logger.info("[第三方服务对接->开启收流和获取发流信息] isSend->{}, ssrc->{}, callId->{}, stream->{}, tcpMode->{}, callBack->{}", isSend, ssrc, callId, stream, tcpMode==0?"UDP":"TCP被动", callBack); - MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); if (mediaServerItem == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(),"没有可用的MediaServer"); } @@ -162,7 +162,7 @@ public class RtpController { @Parameter(name = "stream", description = "流的ID", required = true) public void closeRtpServer(String stream) { logger.info("[第三方服务对接->关闭收流] stream->{}", stream); - MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); zlmServerFactory.closeRtpServer(mediaServerItem,stream); zlmServerFactory.closeRtpServer(mediaServerItem,stream + "_a"); String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_*_" + stream; @@ -225,7 +225,7 @@ public class RtpController { if (!((dstPortForAudio > 0 && !ObjectUtils.isEmpty(dstPortForAudio) || (dstPortForVideo > 0 && !ObjectUtils.isEmpty(dstIpForVideo))))) { throw new ControllerException(ErrorCode.ERROR400.getCode(), "至少应该存在一组音频或视频发送参数"); } - MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + "_" + callId; OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key); if (sendInfo == null) { @@ -367,7 +367,7 @@ public class RtpController { param.put("app",sendInfo.getPushApp()); param.put("stream",sendInfo.getPushStream()); param.put("ssrc",sendInfo.getPushSSRC()); - MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); Boolean result = zlmServerFactory.stopSendRtpStream(mediaServerItem, param); if (!result) { logger.info("[第三方服务对接->关闭发送流] 失败 callId->{}", callId); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index 09f0abb9d..c6c024e1e 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -83,14 +83,14 @@ public class ServerController { @GetMapping(value = "/media_server/list") @ResponseBody @Operation(summary = "流媒体服务列表", security = @SecurityRequirement(name = JwtUtils.HEADER)) - public List getMediaServerList() { + public List getMediaServerList() { return mediaServerService.getAll(); } @GetMapping(value = "/media_server/online/list") @ResponseBody @Operation(summary = "在线流媒体服务列表", security = @SecurityRequirement(name = JwtUtils.HEADER)) - public List getOnlineMediaServerList() { + public List getOnlineMediaServerList() { return mediaServerService.getAllOnline(); } @@ -98,7 +98,7 @@ public class ServerController { @ResponseBody @Operation(summary = "停止视频回放", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "id", description = "流媒体服务ID", required = true) - public MediaServerItem getMediaServer(@PathVariable String id) { + public MediaServer getMediaServer(@PathVariable String id) { return mediaServerService.getOne(id); } @@ -108,7 +108,7 @@ public class ServerController { @Parameter(name = "secret", description = "流媒体服务secret", required = true) @GetMapping(value = "/media_server/check") @ResponseBody - public MediaServerItem checkMediaServer(@RequestParam String ip, @RequestParam int port, @RequestParam String secret, @RequestParam String type) { + public MediaServer checkMediaServer(@RequestParam String ip, @RequestParam int port, @RequestParam String secret, @RequestParam String type) { return mediaServerService.checkMediaServer(ip, port, secret, type); } @@ -128,8 +128,8 @@ public class ServerController { @Parameter(name = "mediaServerItem", description = "流媒体信息", required = true) @PostMapping(value = "/media_server/save") @ResponseBody - public void saveMediaServer(@RequestBody MediaServerItem mediaServerItem) { - MediaServerItem mediaServerItemInDatabase = mediaServerService.getOneFromDatabase(mediaServerItem.getId()); + public void saveMediaServer(@RequestBody MediaServer mediaServerItem) { + MediaServer mediaServerItemInDatabase = mediaServerService.getOneFromDatabase(mediaServerItem.getId()); if (mediaServerItemInDatabase != null) { mediaServerService.update(mediaServerItem); @@ -238,11 +238,11 @@ public class ServerController { @Operation(summary = "获取负载信息") public List getMediaLoad() { List result = new ArrayList<>(); - List allOnline = mediaServerService.getAllOnline(); + List allOnline = mediaServerService.getAllOnline(); if (allOnline.size() == 0) { return result; }else { - for (MediaServerItem mediaServerItem : allOnline) { + for (MediaServer mediaServerItem : allOnline) { result.add(mediaServerService.getLoad(mediaServerItem)); } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index f69048528..5f17cbd5c 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; @@ -138,7 +138,7 @@ public class StreamProxyController { public JSONObject getFFmpegCMDs(@RequestParam String mediaServerId){ logger.debug("获取节点[ {} ]ffmpeg.cmd模板", mediaServerId ); - MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); if (mediaServerItem == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "流媒体: " + mediaServerId + "未找到"); } diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java index 63d9f310d..8a5c96ef5 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.IPlayService; @@ -114,7 +114,7 @@ public class ApiStreamController { result.setResult(resultJSON); return result; } - MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); + MediaServer newMediaServerItem = playService.getNewMediaServerItem(device); playService.play(newMediaServerItem, serial, code, null, (errorCode, msg, data) -> { if (errorCode == InviteErrorCode.SUCCESS.getCode()) { From 150e7a31997f590eba879c3515f21821e9e68eb6 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 22 Mar 2024 16:45:18 +0800 Subject: [PATCH 14/58] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/StreamInfo.java | 11 + .../iot/vmp/media/bean/MediaInfo.java | 60 +++ .../service/IMediaNodeServerService.java | 42 ++- .../media/service/IMediaServerService.java | 17 + .../service/impl/MediaServerServiceImpl.java | 343 +++++++++++------- .../media/zlm/ZLMMediaNodeServerService.java | 196 +++++++--- .../iot/vmp/media/zlm/ZLMRESTfulUtils.java | 2 +- .../iot/vmp/media/zlm/dto/StreamPushItem.java | 22 ++ .../iot/vmp/service/IStreamProxyService.java | 13 +- .../iot/vmp/service/IStreamPushService.java | 5 +- .../service/impl/StreamProxyServiceImpl.java | 189 ++++------ .../service/impl/StreamPushServiceImpl.java | 164 ++++----- .../vmanager/gb28181/play/PlayController.java | 70 +--- .../streamProxy/StreamProxyController.java | 3 +- 14 files changed, 644 insertions(+), 493 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index 979797d3b..b8d5f186c 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -84,6 +84,9 @@ public class StreamInfo implements Serializable, Cloneable{ @Schema(description = "是否暂停(录像回放使用)") private boolean pause; + @Schema(description = "产生源类型,包括 unknown = 0,rtmp_push=1,rtsp_push=2,rtp_push=3,pull=4,ffmpeg_pull=5,mp4_vod=6,device_chn=7") + private int originType; + public void setFlv(StreamURL flv) { this.flv = flv; } @@ -616,4 +619,12 @@ public class StreamInfo implements Serializable, Cloneable{ public void setDownLoadFilePath(DownloadFileInfo downLoadFilePath) { this.downLoadFilePath = downLoadFilePath; } + + public int getOriginType() { + return originType; + } + + public void setOriginType(int originType) { + this.originType = originType; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java index d808772b2..2cc9943e7 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java @@ -28,13 +28,37 @@ public class MediaInfo { private Integer audioSampleRate; @Schema(description = "音频采样率") private Long duration; + @Schema(description = "在线") + private Boolean online; + @Schema(description = "unknown = 0,rtmp_push=1,rtsp_push=2,rtp_push=3,pull=4,ffmpeg_pull=5,mp4_vod=6,device_chn=7") + private Integer originType; + @Schema(description = "存活时间,单位秒") + private Long aliveSecond; + @Schema(description = "数据产生速度,单位byte/s") + private Long bytesSpeed; public static MediaInfo getInstance(JSONObject jsonObject) { MediaInfo mediaInfo = new MediaInfo(); Integer totalReaderCount = jsonObject.getInteger("totalReaderCount"); + Boolean online = jsonObject.getBoolean("online"); + Integer originType = jsonObject.getInteger("originType"); + Long aliveSecond = jsonObject.getLong("aliveSecond"); + Long bytesSpeed = jsonObject.getLong("bytesSpeed"); if (totalReaderCount != null) { mediaInfo.setReaderCount(totalReaderCount); } + if (online != null) { + mediaInfo.setOnline(online); + } + if (originType != null) { + mediaInfo.setOriginType(originType); + } + if (aliveSecond != null) { + mediaInfo.setAliveSecond(aliveSecond); + } + if (bytesSpeed != null) { + mediaInfo.setBytesSpeed(bytesSpeed); + } JSONArray jsonArray = jsonObject.getJSONArray("tracks"); if (jsonArray.isEmpty()) { return null; @@ -90,6 +114,10 @@ public class MediaInfo { List tracks = param.getTracks(); MediaInfo mediaInfo = new MediaInfo(); mediaInfo.setReaderCount(param.getTotalReaderCount()); + mediaInfo.setOnline(param.isRegist()); + mediaInfo.setOriginType(param.getOriginType()); + mediaInfo.setAliveSecond(param.getAliveSecond()); + mediaInfo.setBytesSpeed(param.getBytesSpeed()); for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { switch (mediaTrack.getCodec_id()) { case 0: @@ -187,4 +215,36 @@ public class MediaInfo { public void setDuration(Long duration) { this.duration = duration; } + + public Boolean getOnline() { + return online; + } + + public void setOnline(Boolean online) { + this.online = online; + } + + public Integer getOriginType() { + return originType; + } + + public void setOriginType(Integer originType) { + this.originType = originType; + } + + public Long getAliveSecond() { + return aliveSecond; + } + + public void setAliveSecond(Long aliveSecond) { + this.aliveSecond = aliveSecond; + } + + public Long getBytesSpeed() { + return bytesSpeed; + } + + public void setBytesSpeed(Long bytesSpeed) { + this.bytesSpeed = bytesSpeed; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 504e35c14..9ecedd97f 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -4,39 +4,53 @@ import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import java.util.List; +import java.util.Map; public interface IMediaNodeServerService { - int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); + int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); - void closeRtpServer(MediaServer mediaServerItem, String streamId); + void closeRtpServer(MediaServer mediaServer, String streamId); - void closeRtpServer(MediaServer mediaServerItem, String streamId, CommonCallback callback); + void closeRtpServer(MediaServer mediaServer, String streamId, CommonCallback callback); - void closeStreams(MediaServer mediaServerItem, String app, String stream); + void closeStreams(MediaServer mediaServer, String app, String stream); - Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String stream, String ssrc); + Boolean updateRtpServerSSRC(MediaServer mediaServer, String stream, String ssrc); - boolean checkNodeId(MediaServer mediaServerItem); + boolean checkNodeId(MediaServer mediaServer); - void online(MediaServer mediaServerItem); + void online(MediaServer mediaServer); MediaServer checkMediaServer(String ip, int port, String secret); boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc); - boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName); + boolean deleteRecordDirectory(MediaServer mediaServer, String app, String stream, String date, String fileName); - List getMediaList(MediaServer mediaServerItem, String app, String stream, String callId); + List getMediaList(MediaServer mediaServer, String app, String stream, String callId); - Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream); + Boolean connectRtpServer(MediaServer mediaServer, String address, int port, String stream); - void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName); + void getSnap(MediaServer mediaServer, String streamUrl, int timeoutSec, int expireSec, String path, String fileName); - MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream); + MediaInfo getMediaInfo(MediaServer mediaServer, String app, String stream); - Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey); + Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey); - Boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey); + Boolean resumeRtpCheck(MediaServer mediaServer, String streamKey); + + String getFfmpegCmd(MediaServer mediaServer, String cmdKey); + + WVPResult addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey); + + WVPResult addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType); + + Boolean delFFmpegSource(MediaServer mediaServer, String streamKey); + + Boolean delStreamProxy(MediaServer mediaServer, String streamKey); + + Map getFFmpegCMDs(MediaServer mediaServer); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 4127d7ba3..de095eacc 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -6,8 +6,10 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import java.util.List; +import java.util.Map; /** * 媒体服务节点 @@ -87,4 +89,19 @@ public interface IMediaServerService { Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey); boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey); + + String getFfmpegCmd(MediaServer mediaServer, String cmdKey); + + void closeStreams(MediaServer mediaServerItem, String app, String stream); + + WVPResult addFFmpegSource(MediaServer mediaServerItem, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey); + + WVPResult addStreamProxy(MediaServer mediaServerItem, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType); + + Boolean delFFmpegSource(MediaServer mediaServerItem, String streamKey); + + Boolean delStreamProxy(MediaServer mediaServerItem, String streamKey); + + Map getFFmpegCMDs(MediaServer mediaServer); + } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index d4723793b..c5367fb1d 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -22,6 +22,7 @@ import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.JsonUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -74,31 +75,31 @@ public class MediaServerServiceImpl implements IMediaServerService { * 初始化 */ @Override - public void updateVmServer(List mediaServerItemList) { + public void updateVmServer(List mediaServerList) { logger.info("[媒体服务节点] 缓存初始化 "); - for (MediaServer mediaServerItem : mediaServerItemList) { - if (ObjectUtils.isEmpty(mediaServerItem.getId())) { + for (MediaServer mediaServer : mediaServerList) { + if (ObjectUtils.isEmpty(mediaServer.getId())) { continue; } // 更新 - if (!ssrcFactory.hasMediaServerSSRC(mediaServerItem.getId())) { - ssrcFactory.initMediaServerSSRC(mediaServerItem.getId(), null); + if (!ssrcFactory.hasMediaServerSSRC(mediaServer.getId())) { + ssrcFactory.initMediaServerSSRC(mediaServer.getId(), null); } // 查询redis是否存在此mediaServer - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(); + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServer.getId(); Boolean hasKey = redisTemplate.hasKey(key); if (hasKey != null && ! hasKey) { - redisTemplate.opsForValue().set(key, mediaServerItem); + redisTemplate.opsForValue().set(key, mediaServer); } } } @Override - public SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, + public SSRCInfo openRTPServer(MediaServer mediaServer, String streamId, String presetSsrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { - if (mediaServerItem == null || mediaServerItem.getId() == null) { - logger.info("[openRTPServer] 失败, mediaServerItem == null || mediaServerItem.getId() == null"); + if (mediaServer == null || mediaServer.getId() == null) { + logger.info("[openRTPServer] 失败, mediaServer == null || mediaServer.getId() == null"); return null; } // 获取mediaServer可用的ssrc @@ -107,9 +108,9 @@ public class MediaServerServiceImpl implements IMediaServerService { ssrc = presetSsrc; }else { if (isPlayback) { - ssrc = ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); + ssrc = ssrcFactory.getPlayBackSsrc(mediaServer.getId()); }else { - ssrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId()); + ssrc = ssrcFactory.getPlaySsrc(mediaServer.getId()); } } @@ -121,97 +122,97 @@ public class MediaServerServiceImpl implements IMediaServerService { logger.warn("[openRTPServer] 平台对接时下级可能自定义ssrc,但是tcp模式zlm收流目前无法更新ssrc,可能收流超时,此时请使用udp收流或者关闭ssrc校验"); } int rtpServerPort; - if (mediaServerItem.isRtpEnable()) { - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaServer.isRtpEnable()) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[openRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[openRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return null; } - rtpServerPort = mediaNodeServerService.createRTPServer(mediaServerItem, streamId, ssrcCheck ? Long.parseLong(ssrc) : 0, port, onlyAuto, reUsePort, tcpMode); + rtpServerPort = mediaNodeServerService.createRTPServer(mediaServer, streamId, ssrcCheck ? Long.parseLong(ssrc) : 0, port, onlyAuto, reUsePort, tcpMode); } else { - rtpServerPort = mediaServerItem.getRtpProxyPort(); + rtpServerPort = mediaServer.getRtpProxyPort(); } return new SSRCInfo(rtpServerPort, ssrc, streamId); } @Override - public SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto) { - return openRTPServer(mediaServerItem, streamId, ssrc, ssrcCheck, isPlayback, port, onlyAuto, null, 0); + public SSRCInfo openRTPServer(MediaServer mediaServer, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto) { + return openRTPServer(mediaServer, streamId, ssrc, ssrcCheck, isPlayback, port, onlyAuto, null, 0); } @Override - public void closeRTPServer(MediaServer mediaServerItem, String streamId) { - if (mediaServerItem == null) { + public void closeRTPServer(MediaServer mediaServer, String streamId) { + if (mediaServer == null) { return; } - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[closeRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return; } - mediaNodeServerService.closeRtpServer(mediaServerItem, streamId); + mediaNodeServerService.closeRtpServer(mediaServer, streamId); } @Override - public void closeRTPServer(MediaServer mediaServerItem, String streamId, CommonCallback callback) { - if (mediaServerItem == null) { + public void closeRTPServer(MediaServer mediaServer, String streamId, CommonCallback callback) { + if (mediaServer == null) { callback.run(false); return; } - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[closeRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return; } - mediaNodeServerService.closeRtpServer(mediaServerItem, streamId, callback); + mediaNodeServerService.closeRtpServer(mediaServer, streamId, callback); } @Override public void closeRTPServer(String mediaServerId, String streamId) { - MediaServer mediaServerItem = this.getOne(mediaServerId); - if (mediaServerItem == null) { + MediaServer mediaServer = this.getOne(mediaServerId); + if (mediaServer == null) { return; } - if (mediaServerItem.isRtpEnable()) { - closeRTPServer(mediaServerItem, streamId); + if (mediaServer.isRtpEnable()) { + closeRTPServer(mediaServer, streamId); } - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[closeRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return; } - mediaNodeServerService.closeStreams(mediaServerItem, "rtp", streamId); + mediaNodeServerService.closeStreams(mediaServer, "rtp", streamId); } @Override - public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { - if (mediaServerItem == null) { + public Boolean updateRtpServerSSRC(MediaServer mediaServer, String streamId, String ssrc) { + if (mediaServer == null) { return false; } - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[updateRtpServerSSRC] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[updateRtpServerSSRC] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return false; } - return mediaNodeServerService.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); + return mediaNodeServerService.updateRtpServerSSRC(mediaServer, streamId, ssrc); } @Override - public void releaseSsrc(String mediaServerItemId, String ssrc) { - MediaServer mediaServerItem = getOne(mediaServerItemId); - if (mediaServerItem == null || ssrc == null) { + public void releaseSsrc(String mediaServerId, String ssrc) { + MediaServer mediaServer = getOne(mediaServerId); + if (mediaServer == null || ssrc == null) { return; } - ssrcFactory.releaseSsrc(mediaServerItemId, ssrc); + ssrcFactory.releaseSsrc(mediaServerId, ssrc); } /** * 媒体服务节点 重启后重置他的推流信息, TODO 给正在使用的设备发送停止命令 */ @Override - public void clearRTPServer(MediaServer mediaServerItem) { - ssrcFactory.reset(mediaServerItem.getId()); + public void clearRTPServer(MediaServer mediaServer) { + ssrcFactory.reset(mediaServer.getId()); } @@ -219,22 +220,22 @@ public class MediaServerServiceImpl implements IMediaServerService { public void update(MediaServer mediaSerItem) { mediaServerMapper.update(mediaSerItem); MediaServer mediaServerInRedis = getOne(mediaSerItem.getId()); - MediaServer mediaServerItemInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId()); - if (mediaServerItemInDataBase == null) { + MediaServer mediaServerInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId()); + if (mediaServerInDataBase == null) { return; } - mediaServerItemInDataBase.setStatus(mediaSerItem.isStatus()); - if (mediaServerInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerItemInDataBase.getId())) { - ssrcFactory.initMediaServerSSRC(mediaServerItemInDataBase.getId(),null); + mediaServerInDataBase.setStatus(mediaSerItem.isStatus()); + if (mediaServerInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerInDataBase.getId())) { + ssrcFactory.initMediaServerSSRC(mediaServerInDataBase.getId(),null); } - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItemInDataBase.getId(); - redisTemplate.opsForValue().set(key, mediaServerItemInDataBase); - if (mediaServerItemInDataBase.isStatus()) { - resetOnlineServerItem(mediaServerItemInDataBase); + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerInDataBase.getId(); + redisTemplate.opsForValue().set(key, mediaServerInDataBase); + if (mediaServerInDataBase.isStatus()) { + resetOnlineServerItem(mediaServerInDataBase); }else { // 发送事件 MediaServerChangeEvent event = new MediaServerChangeEvent(this); - event.setMediaServerItemList(mediaServerItemInDataBase); + event.setMediaServerItemList(mediaServerInDataBase); applicationEventPublisher.publishEvent(event); } } @@ -247,16 +248,16 @@ public class MediaServerServiceImpl implements IMediaServerService { String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); for (Object mediaServerKey : mediaServerKeys) { String key = (String) mediaServerKey; - MediaServer mediaServerItem = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServer.class); - if (Objects.isNull(mediaServerItem)) { + MediaServer mediaServer = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServer.class); + if (Objects.isNull(mediaServer)) { continue; } // 检查状态 - Double aDouble = redisTemplate.opsForZSet().score(onlineKey, mediaServerItem.getId()); + Double aDouble = redisTemplate.opsForZSet().score(onlineKey, mediaServer.getId()); if (aDouble != null) { - mediaServerItem.setStatus(true); + mediaServer.setStatus(true); } - result.add(mediaServerItem); + result.add(mediaServer); } result.sort((serverItem1, serverItem2)->{ int sortResult = 0; @@ -275,10 +276,10 @@ public class MediaServerServiceImpl implements IMediaServerService { if (mediaServerList.isEmpty()) { return new ArrayList<>(); } - for (MediaServer mediaServerItem : mediaServerList) { - MediaServer mediaServerItemInRedis = getOne(mediaServerItem.getId()); - if (mediaServerItemInRedis != null) { - mediaServerItem.setStatus(mediaServerItemInRedis.isStatus()); + for (MediaServer mediaServer : mediaServerList) { + MediaServer mediaServerInRedis = getOne(mediaServer.getId()); + if (mediaServerInRedis != null) { + mediaServer.setStatus(mediaServerInRedis.isStatus()); } } return mediaServerList; @@ -310,7 +311,7 @@ public class MediaServerServiceImpl implements IMediaServerService { /** * 获取单个媒体服务节点服务器 * @param mediaServerId 服务id - * @return MediaServerItem + * @return mediaServer */ @Override public MediaServer getOne(String mediaServerId) { @@ -334,32 +335,32 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public void add(MediaServer mediaServerItem) { - mediaServerItem.setCreateTime(DateUtil.getNow()); - mediaServerItem.setUpdateTime(DateUtil.getNow()); - if (mediaServerItem.getHookAliveInterval() == null || mediaServerItem.getHookAliveInterval() == 0F) { - mediaServerItem.setHookAliveInterval(10F); + public void add(MediaServer mediaServer) { + mediaServer.setCreateTime(DateUtil.getNow()); + mediaServer.setUpdateTime(DateUtil.getNow()); + if (mediaServer.getHookAliveInterval() == null || mediaServer.getHookAliveInterval() == 0F) { + mediaServer.setHookAliveInterval(10F); } - if (mediaServerItem.getType() == null) { - logger.info("[添加媒体节点] 失败, mediaServerItem的类型:为空"); + if (mediaServer.getType() == null) { + logger.info("[添加媒体节点] 失败, mediaServer的类型:为空"); return; } - if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) { - logger.info("[添加媒体节点] 失败, 媒体服务ID已存在,请修改媒体服务器配置, {}", mediaServerItem.getId()); - throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败,媒体服务ID [ " + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); + if (mediaServerMapper.queryOne(mediaServer.getId()) != null) { + logger.info("[添加媒体节点] 失败, 媒体服务ID已存在,请修改媒体服务器配置, {}", mediaServer.getId()); + throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败,媒体服务ID [ " + mediaServer.getId() + " ] 已存在,请修改媒体服务器配置"); } - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[添加媒体节点] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[添加媒体节点] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return; } - mediaServerMapper.add(mediaServerItem); - if (mediaServerItem.isStatus()) { - mediaNodeServerService.online(mediaServerItem); + mediaServerMapper.add(mediaServer); + if (mediaServer.isStatus()) { + mediaNodeServerService.online(mediaServer); }else { // 发送事件 MediaServerChangeEvent event = new MediaServerChangeEvent(this); - event.setMediaServerItemList(mediaServerItem); + event.setMediaServerItemList(mediaServer); applicationEventPublisher.publishEvent(event); } } @@ -403,7 +404,7 @@ public class MediaServerServiceImpl implements IMediaServerService { /** * 获取负载最低的节点 - * @return MediaServerItem + * @return mediaServer */ @Override public MediaServer getMediaServerForMinimumLoad(Boolean hasAssist) { @@ -417,16 +418,16 @@ public class MediaServerServiceImpl implements IMediaServerService { // 获取分数最低的,及并发最低的 Set objects = redisTemplate.opsForZSet().range(key, 0, -1); ArrayList mediaServerObjectS = new ArrayList<>(objects); - MediaServer mediaServerItem = null; + MediaServer mediaServer = null; if (hasAssist == null) { String mediaServerId = (String)mediaServerObjectS.get(0); - mediaServerItem = getOne(mediaServerId); + mediaServer = getOne(mediaServerId); }else if (hasAssist) { for (Object mediaServerObject : mediaServerObjectS) { String mediaServerId = (String)mediaServerObject; MediaServer serverItem = getOne(mediaServerId); if (serverItem.getRecordAssistPort() > 0) { - mediaServerItem = serverItem; + mediaServer = serverItem; break; } } @@ -435,13 +436,13 @@ public class MediaServerServiceImpl implements IMediaServerService { String mediaServerId = (String)mediaServerObject; MediaServer serverItem = getOne(mediaServerId); if (serverItem.getRecordAssistPort() == 0) { - mediaServerItem = serverItem; + mediaServer = serverItem; break; } } } - return mediaServerItem; + return mediaServer; } @Override @@ -452,16 +453,16 @@ public class MediaServerServiceImpl implements IMediaServerService { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(type); if (mediaNodeServerService == null) { - logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", type); + logger.info("[closeRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", type); return null; } - MediaServer mediaServerItem = mediaNodeServerService.checkMediaServer(ip, port, secret); - if (mediaServerItem != null) { - if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体服务ID [" + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); + MediaServer mediaServer = mediaNodeServerService.checkMediaServer(ip, port, secret); + if (mediaServer != null) { + if (mediaServerMapper.queryOne(mediaServer.getId()) != null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体服务ID [" + mediaServer.getId() + " ] 已存在,请修改媒体服务器配置"); } } - return mediaServerItem; + return mediaServer; } @Override @@ -504,28 +505,28 @@ public class MediaServerServiceImpl implements IMediaServerService { public void syncCatchFromDatabase() { List allInCatch = getAllOnlineList(); List allInDatabase = mediaServerMapper.queryAll(); - Map mediaServerItemMap = new HashMap<>(); + Map mediaServerMap = new HashMap<>(); - for (MediaServer mediaServerItem : allInDatabase) { - mediaServerItemMap.put(mediaServerItem.getId(), mediaServerItem); + for (MediaServer mediaServer : allInDatabase) { + mediaServerMap.put(mediaServer.getId(), mediaServer); } - for (MediaServer mediaServerItem : allInCatch) { + for (MediaServer mediaServer : allInCatch) { // 清除数据中不存在但redis缓存数据 - if (!mediaServerItemMap.containsKey(mediaServerItem.getId())) { - delete(mediaServerItem.getId()); + if (!mediaServerMap.containsKey(mediaServer.getId())) { + delete(mediaServer.getId()); } } } @Override - public MediaServerLoad getLoad(MediaServer mediaServerItem) { + public MediaServerLoad getLoad(MediaServer mediaServer) { MediaServerLoad result = new MediaServerLoad(); - result.setId(mediaServerItem.getId()); - result.setPush(redisCatchStorage.getPushStreamCount(mediaServerItem.getId())); - result.setProxy(redisCatchStorage.getProxyStreamCount(mediaServerItem.getId())); + result.setId(mediaServer.getId()); + result.setPush(redisCatchStorage.getPushStreamCount(mediaServer.getId())); + result.setProxy(redisCatchStorage.getProxyStreamCount(mediaServer.getId())); - result.setGbReceive(inviteStreamService.getStreamInfoCount(mediaServerItem.getId())); - result.setGbSend(redisCatchStorage.getGbSendCount(mediaServerItem.getId())); + result.setGbReceive(inviteStreamService.getStreamInfoCount(mediaServer.getId())); + result.setGbSend(redisCatchStorage.getGbSendCount(mediaServer.getId())); return result; } @@ -539,79 +540,149 @@ public class MediaServerServiceImpl implements IMediaServerService { public boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaInfo.getType()); if (mediaNodeServerService == null) { - logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaInfo.getType()); + logger.info("[stopSendRtp] 失败, mediaServer的类型: {},未找到对应的实现类", mediaInfo.getType()); return false; } return mediaNodeServerService.stopSendRtp(mediaInfo, app, stream, ssrc); } @Override - public boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + public boolean deleteRecordDirectory(MediaServer mediaServer, String app, String stream, String date, String fileName) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[stopSendRtp] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return false; } - return mediaNodeServerService.deleteRecordDirectory(mediaServerItem, app, stream, date, fileName); + return mediaNodeServerService.deleteRecordDirectory(mediaServer, app, stream, date, fileName); } @Override - public List getMediaList(MediaServer mediaServerItem, String app, String stream, String callId) { - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + public List getMediaList(MediaServer mediaServer, String app, String stream, String callId) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[getMediaList] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[getMediaList] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return new ArrayList<>(); } - return mediaNodeServerService.getMediaList(mediaServerItem, app, stream, callId); + return mediaNodeServerService.getMediaList(mediaServer, app, stream, callId); } @Override - public Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream) { - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + public Boolean connectRtpServer(MediaServer mediaServer, String address, int port, String stream) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[connectRtpServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[connectRtpServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return false; } - return mediaNodeServerService.connectRtpServer(mediaServerItem, address, port, stream); + return mediaNodeServerService.connectRtpServer(mediaServer, address, port, stream); } @Override - public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + public void getSnap(MediaServer mediaServer, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[getSnap] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[getSnap] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return; } - mediaNodeServerService.getSnap(mediaServerItem, streamUrl, timeoutSec, expireSec, path, fileName); + mediaNodeServerService.getSnap(mediaServer, streamUrl, timeoutSec, expireSec, path, fileName); } @Override - public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + public MediaInfo getMediaInfo(MediaServer mediaServer, String app, String stream) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[getMediaInfo] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[getMediaInfo] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return null; } - return mediaNodeServerService.getMediaInfo(mediaServerItem, app, stream); + return mediaNodeServerService.getMediaInfo(mediaServer, app, stream); } @Override - public Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey) { - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + public Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[pauseRtpCheck] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[pauseRtpCheck] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return false; } - return mediaNodeServerService.pauseRtpCheck(mediaServerItem, streamKey); + return mediaNodeServerService.pauseRtpCheck(mediaServer, streamKey); } @Override - public boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey) { - IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + public boolean resumeRtpCheck(MediaServer mediaServer, String streamKey) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { - logger.info("[pauseRtpCheck] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); + logger.info("[pauseRtpCheck] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return false; } - return mediaNodeServerService.resumeRtpCheck(mediaServerItem, streamKey); + return mediaNodeServerService.resumeRtpCheck(mediaServer, streamKey); + } + + @Override + public String getFfmpegCmd(MediaServer mediaServer, String cmdKey) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[getFfmpegCmd] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + return null; + } + return mediaNodeServerService.getFfmpegCmd(mediaServer, cmdKey); + } + + @Override + public void closeStreams(MediaServer mediaServer, String app, String stream) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[closeStreams] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + return; + } + mediaNodeServerService.closeStreams(mediaServer, app, stream); + } + + @Override + public WVPResult addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[addFFmpegSource] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + return WVPResult.fail(ErrorCode.ERROR400); + } + return mediaNodeServerService.addFFmpegSource(mediaServer, srcUrl, dstUrl, timeoutMs, enableAudio, enableMp4, ffmpegCmdKey); + } + + @Override + public WVPResult addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[addStreamProxy] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + return WVPResult.fail(ErrorCode.ERROR400); + } + return mediaNodeServerService.addStreamProxy(mediaServer, app, stream, url, enableAudio, enableMp4, rtpType); + } + + @Override + public Boolean delFFmpegSource(MediaServer mediaServer, String streamKey) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[delFFmpegSource] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + return false; + } + return mediaNodeServerService.delFFmpegSource(mediaServer, streamKey); + } + + @Override + public Boolean delStreamProxy(MediaServer mediaServerItem, String streamKey) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); + if (mediaNodeServerService == null) { + logger.info("[delStreamProxy] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServerItem.getType()); + return false; + } + return mediaNodeServerService.delStreamProxy(mediaServerItem, streamKey); + } + + @Override + public Map getFFmpegCMDs(MediaServer mediaServer) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[getFFmpegCMDs] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + return new HashMap<>(); + } + return mediaNodeServerService.getFFmpegCMDs(mediaServer); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 23b26dbc9..60327ebfb 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -38,41 +39,41 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { private String sipIp; @Override - public int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { - return zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode); + public int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { + return zlmServerFactory.createRTPServer(mediaServer, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode); } @Override - public void closeRtpServer(MediaServer mediaServerItem, String streamId) { - zlmresTfulUtils.closeStreams(mediaServerItem, "rtp", streamId); + public void closeRtpServer(MediaServer mediaServer, String streamId) { + zlmresTfulUtils.closeStreams(mediaServer, "rtp", streamId); } @Override - public void closeRtpServer(MediaServer mediaServerItem, String streamId, CommonCallback callback) { - zlmServerFactory.closeRtpServer(mediaServerItem, streamId, callback); + public void closeRtpServer(MediaServer mediaServer, String streamId, CommonCallback callback) { + zlmServerFactory.closeRtpServer(mediaServer, streamId, callback); } @Override - public void closeStreams(MediaServer mediaServerItem, String app, String stream) { - zlmresTfulUtils.closeStreams(mediaServerItem, app, stream); + public void closeStreams(MediaServer mediaServer, String app, String stream) { + zlmresTfulUtils.closeStreams(mediaServer, app, stream); } @Override - public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { - return zlmServerFactory.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); + public Boolean updateRtpServerSSRC(MediaServer mediaServer, String streamId, String ssrc) { + return zlmServerFactory.updateRtpServerSSRC(mediaServer, streamId, ssrc); } @Override - public boolean checkNodeId(MediaServer mediaServerItem) { - if (mediaServerItem == null) { + public boolean checkNodeId(MediaServer mediaServer) { + if (mediaServer == null) { return false; } - JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); + JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServer); if (responseJSON != null) { JSONArray data = responseJSON.getJSONArray("data"); if (data != null && !data.isEmpty()) { ZLMServerConfig zlmServerConfig= JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); - return zlmServerConfig.getGeneralMediaServerId().equals(mediaServerItem.getId()); + return zlmServerConfig.getGeneralMediaServerId().equals(mediaServer.getId()); }else { return false; } @@ -83,17 +84,17 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public void online(MediaServer mediaServerItem) { + public void online(MediaServer mediaServer) { } @Override public MediaServer checkMediaServer(String ip, int port, String secret) { - MediaServer mediaServerItem = new MediaServer(); - mediaServerItem.setIp(ip); - mediaServerItem.setHttpPort(port); - mediaServerItem.setSecret(secret); - JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); + MediaServer mediaServer = new MediaServer(); + mediaServer.setIp(ip); + mediaServer.setHttpPort(port); + mediaServer.setSecret(secret); + JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServer); if (responseJSON == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接失败"); } @@ -105,18 +106,18 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { if (zlmServerConfig == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败"); } - mediaServerItem.setId(zlmServerConfig.getGeneralMediaServerId()); - mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpPort()); - mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort()); - mediaServerItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); - mediaServerItem.setRtspPort(zlmServerConfig.getRtspPort()); - mediaServerItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); - mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); - mediaServerItem.setStreamIp(ip); - mediaServerItem.setHookIp(sipIp.split(",")[0]); - mediaServerItem.setSdpIp(ip); - mediaServerItem.setType("zlm"); - return mediaServerItem; + mediaServer.setId(zlmServerConfig.getGeneralMediaServerId()); + mediaServer.setHttpSSlPort(zlmServerConfig.getHttpPort()); + mediaServer.setRtmpPort(zlmServerConfig.getRtmpPort()); + mediaServer.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); + mediaServer.setRtspPort(zlmServerConfig.getRtspPort()); + mediaServer.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); + mediaServer.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); + mediaServer.setStreamIp(ip); + mediaServer.setHookIp(sipIp.split(",")[0]); + mediaServer.setSdpIp(ip); + mediaServer.setType("zlm"); + return mediaServer; } @Override @@ -134,22 +135,22 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { - logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件, server: {} {}:{}->{}/{}", mediaServerItem.getId(), app, stream, date, fileName); - JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServerItem, app, + public boolean deleteRecordDirectory(MediaServer mediaServer, String app, String stream, String date, String fileName) { + logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件, server: {} {}:{}->{}/{}", mediaServer.getId(), app, stream, date, fileName); + JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServer, app, stream, date, fileName); if (jsonObject.getInteger("code") == 0) { return true; }else { - logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件错误, server: {} {}:{}->{}/{}, 结果: {}", mediaServerItem.getId(), app, stream, date, fileName, jsonObject); + logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件错误, server: {} {}:{}->{}/{}, 结果: {}", mediaServer.getId(), app, stream, date, fileName, jsonObject); return false; } } @Override - public List getMediaList(MediaServer mediaServerItem, String app, String stream, String callId) { + public List getMediaList(MediaServer mediaServer, String app, String stream, String callId) { List streamInfoList = new ArrayList<>(); - JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream); + JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServer, app, stream); if (mediaList != null) { if (mediaList.getInteger("code") == 0) { JSONArray data = mediaList.getJSONArray("data"); @@ -158,7 +159,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } JSONObject mediaJSON = data.getJSONObject(0); MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON); - StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, mediaInfo, callId, true); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, app, stream, mediaInfo, callId, true); if (streamInfo != null) { streamInfoList.add(streamInfo); } @@ -167,41 +168,42 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { return streamInfoList; } - public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId, boolean isPlay) { + public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String callId, boolean isPlay) { StreamInfo streamInfoResult = new StreamInfo(); streamInfoResult.setStream(stream); streamInfoResult.setApp(app); - String addr = mediaServerItem.getStreamIp(); + String addr = mediaServer.getStreamIp(); streamInfoResult.setIp(addr); - streamInfoResult.setMediaServerId(mediaServerItem.getId()); + streamInfoResult.setMediaServerId(mediaServer.getId()); String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; - streamInfoResult.setRtmp(addr, mediaServerItem.getRtmpPort(),mediaServerItem.getRtmpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtsp(addr, mediaServerItem.getRtspPort(),mediaServerItem.getRtspSSLPort(), app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setFmp4(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setHls(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setTs(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtc(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam, isPlay); + streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); streamInfoResult.setMediaInfo(mediaInfo); + streamInfoResult.setOriginType(mediaInfo.getOriginType()); return streamInfoResult; } @Override - public Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream) { - JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, address, port, stream); + public Boolean connectRtpServer(MediaServer mediaServer, String address, int port, String stream) { + JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServer, address, port, stream); logger.info("[TCP主动连接对方] 结果: {}", jsonObject); return jsonObject.getInteger("code") == 0; } @Override - public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { - zlmresTfulUtils.getSnap(mediaServerItem, streamUrl, timeoutSec, expireSec, path, fileName); + public void getSnap(MediaServer mediaServer, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { + zlmresTfulUtils.getSnap(mediaServer, streamUrl, timeoutSec, expireSec, path, fileName); } @Override - public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { - JSONObject jsonObject = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtsp", stream); + public MediaInfo getMediaInfo(MediaServer mediaServer, String app, String stream) { + JSONObject jsonObject = zlmresTfulUtils.getMediaInfo(mediaServer, app, "rtsp", stream); if (jsonObject.getInteger("code") != 0) { return null; } @@ -209,14 +211,90 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey) { - JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServerItem, streamKey); + public Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey) { + JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServer, streamKey); return jsonObject.getInteger("code") == 0; } @Override - public Boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey) { - JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServerItem, streamKey); + public Boolean resumeRtpCheck(MediaServer mediaServer, String streamKey) { + JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServer, streamKey); return jsonObject.getInteger("code") == 0; } + + @Override + public String getFfmpegCmd(MediaServer mediaServer, String cmdKey) { + JSONObject jsonObject = zlmresTfulUtils.getMediaServerConfig(mediaServer); + if (jsonObject.getInteger("code") != 0) { + logger.warn("[getFfmpegCmd] 获取流媒体配置失败"); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取流媒体配置失败"); + } + JSONArray dataArray = jsonObject.getJSONArray("data"); + JSONObject mediaServerConfig = dataArray.getJSONObject(0); + if (ObjectUtils.isEmpty(cmdKey)) { + cmdKey = "ffmpeg.cmd"; + } + return mediaServerConfig.getString(cmdKey); + } + + @Override + public WVPResult addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey) { + JSONObject jsonObject = zlmresTfulUtils.addFFmpegSource(mediaServer, srcUrl, dstUrl, timeoutMs, enableAudio, enableMp4, ffmpegCmdKey); + if (jsonObject.getInteger("code") != 0) { + logger.warn("[getFfmpegCmd] 添加FFMPEG代理失败"); + return WVPResult.fail(ErrorCode.ERROR100.getCode(), "添加FFMPEG代理失败"); + }else { + JSONObject data = jsonObject.getJSONObject("data"); + if (data == null) { + return WVPResult.fail(ErrorCode.ERROR100.getCode(), "代理结果异常: " + jsonObject); + }else { + return WVPResult.success(data.getString("key")); + } + } + } + + @Override + public WVPResult addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType) { + JSONObject jsonObject = zlmresTfulUtils.addStreamProxy(mediaServer, app, stream, url, enableAudio, enableMp4, rtpType); + if (jsonObject.getInteger("code") != 0) { + logger.warn("[addStreamProxy] 添加代理失败"); + return WVPResult.fail(ErrorCode.ERROR100.getCode(), "添加代理失败"); + }else { + JSONObject data = jsonObject.getJSONObject("data"); + if (data == null) { + return WVPResult.fail(ErrorCode.ERROR100.getCode(), "代理结果异常: " + jsonObject); + }else { + return WVPResult.success(""); + } + } + } + + @Override + public Boolean delFFmpegSource(MediaServer mediaServer, String streamKey) { + JSONObject jsonObject = zlmresTfulUtils.delFFmpegSource(mediaServer, streamKey); + return jsonObject.getInteger("code") == 0; + } + + @Override + public Boolean delStreamProxy(MediaServer mediaServer, String streamKey) { + JSONObject jsonObject = zlmresTfulUtils.delStreamProxy(mediaServer, streamKey); + return jsonObject.getInteger("code") == 0; + } + + @Override + public Map getFFmpegCMDs(MediaServer mediaServer) { + Map result = new HashMap<>(); + JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServer); + if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0 + && mediaServerConfigResuly.getJSONArray("data").size() > 0){ + JSONObject mediaServerConfig = mediaServerConfigResuly.getJSONArray("data").getJSONObject(0); + + for (String key : mediaServerConfig.keySet()) { + if (key.startsWith("ffmpeg.cmd")){ + result.put(key, mediaServerConfig.getString(key)); + } + } + } + return result; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 5cddd5e22..49200545d 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -269,7 +269,7 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "getRtpInfo",param, null); } - public JSONObject addFFmpegSource(MediaServer mediaServerItem, String src_url, String dst_url, String timeout_ms, + public JSONObject addFFmpegSource(MediaServer mediaServerItem, String src_url, String dst_url, Integer timeout_ms, boolean enable_audio, boolean enable_mp4, String ffmpeg_cmd_key){ logger.info(src_url); logger.info(dst_url); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java index 6befe46fa..85d481a2c 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.dto; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.utils.DateUtil; @@ -150,6 +151,27 @@ public class StreamPushItem extends GbStream implements Comparable addStreamProxyToZlm(StreamProxyItem param); /** * 从zlm移除视频代理 + * * @param param * @return */ - JSONObject removeStreamProxyFromZlm(StreamProxyItem param); + Boolean removeStreamProxyFromZlm(StreamProxyItem param); /** * 分页查询 @@ -73,9 +77,10 @@ public interface IStreamProxyService { /** * 获取ffmpeg.cmd模板 + * * @return */ - JSONObject getFFmpegCMDs(MediaServer mediaServerItem); + Map getFFmpegCMDs(MediaServer mediaServerItem); /** * 根据app与stream获取streamProxy diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java index 49c1087f7..1507331f3 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java @@ -1,9 +1,8 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.gb28181.bean.GbStream; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; import com.github.pagehelper.PageInfo; @@ -16,8 +15,6 @@ import java.util.Map; */ public interface IStreamPushService { - List handleJSON(String json, MediaServer mediaServerItem); - /** * 将应用名和流ID加入国标关联 * @param stream diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 4a44093e8..ea824ffef 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.service.impl; -import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.GeneralCallback; @@ -9,7 +8,8 @@ import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; @@ -18,7 +18,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -29,6 +28,7 @@ import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,9 +63,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @Autowired private IMediaService mediaService; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Autowired private ZLMServerFactory zlmServerFactory; @@ -108,28 +105,21 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @Override public void save(StreamProxyItem param, GeneralCallback callback) { - MediaServer mediaInfo; + MediaServer mediaServer; if (ObjectUtils.isEmpty(param.getMediaServerId()) || "auto".equals(param.getMediaServerId())){ - mediaInfo = mediaServerService.getMediaServerForMinimumLoad(null); + mediaServer = mediaServerService.getMediaServerForMinimumLoad(null); }else { - mediaInfo = mediaServerService.getOne(param.getMediaServerId()); + mediaServer = mediaServerService.getOne(param.getMediaServerId()); } - if (mediaInfo == null) { + if (mediaServer == null) { logger.warn("保存代理未找到在线的ZLM..."); throw new ControllerException(ErrorCode.ERROR100.getCode(), "保存代理未找到在线的ZLM"); } String dstUrl; if ("ffmpeg".equalsIgnoreCase(param.getType())) { - JSONObject jsonObject = zlmresTfulUtils.getMediaServerConfig(mediaInfo); - if (jsonObject.getInteger("code") != 0) { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取流媒体配置失败"); - } - JSONArray dataArray = jsonObject.getJSONArray("data"); - JSONObject mediaServerConfig = dataArray.getJSONObject(0); - if (ObjectUtils.isEmpty(param.getFfmpegCmdKey())) { - param.setFfmpegCmdKey("ffmpeg.cmd"); - } - String ffmpegCmd = mediaServerConfig.getString(param.getFfmpegCmdKey()); + + String ffmpegCmd = mediaServerService.getFfmpegCmd(mediaServer, param.getFfmpegCmdKey()); + if (ffmpegCmd == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg拉流代理无法获取ffmpeg cmd"); } @@ -140,25 +130,25 @@ public class StreamProxyServiceImpl implements IStreamProxyService { int port; String schemaForUri; if (schema.equalsIgnoreCase("rtsp")) { - port = mediaInfo.getRtspPort(); + port = mediaServer.getRtspPort(); schemaForUri = schema; }else if (schema.equalsIgnoreCase("flv")) { - port = mediaInfo.getRtmpPort(); + port = mediaServer.getRtmpPort(); schemaForUri = schema; }else { - port = mediaInfo.getRtmpPort(); + port = mediaServer.getRtmpPort(); schemaForUri = schema; } dstUrl = String.format("%s://%s:%s/%s/%s", schemaForUri, "127.0.0.1", port, param.getApp(), param.getStream()); }else { - dstUrl = String.format("rtsp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtspPort(), param.getApp(), + dstUrl = String.format("rtsp://%s:%s/%s/%s", "127.0.0.1", mediaServer.getRtspPort(), param.getApp(), param.getStream()); } param.setDstUrl(dstUrl); logger.info("[拉流代理] 输出地址为:{}", dstUrl); - param.setMediaServerId(mediaInfo.getId()); + param.setMediaServerId(mediaServer.getId()); boolean saveResult; // 更新 if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) { @@ -170,17 +160,17 @@ public class StreamProxyServiceImpl implements IStreamProxyService { callback.run(ErrorCode.ERROR100.getCode(), "保存失败", null); return; } - HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(param.getApp(), param.getStream(), true, "rtsp", mediaInfo.getId()); + HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(param.getApp(), param.getStream(), true, "rtsp", mediaServer.getId()); hookSubscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItem, response) -> { StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( - mediaInfo, param.getApp(), param.getStream(), null, null); + mediaServer, param.getApp(), param.getStream(), null, null); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); }); if (param.isEnable()) { String talkKey = UUID.randomUUID().toString(); String delayTalkKey = UUID.randomUUID().toString(); dynamicTask.startDelay(delayTalkKey, ()->{ - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaInfo.getId(), false); + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaServer.getId(), false); if (streamInfo != null) { callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); }else { @@ -188,12 +178,12 @@ public class StreamProxyServiceImpl implements IStreamProxyService { callback.run(ErrorCode.ERROR100.getCode(), "超时", null); } }, 7000); - JSONObject jsonObject = addStreamProxyToZlm(param); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { + WVPResult result = addStreamProxyToZlm(param); + if (result != null && result.getCode() == 0) { hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); dynamicTask.stop(talkKey); StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( - mediaInfo, param.getApp(), param.getStream(), null, null); + mediaServer, param.getApp(), param.getStream(), null, null); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); }else { param.setEnable(false); @@ -203,16 +193,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService { }else { updateStreamProxy(param); } - if (jsonObject == null){ + if (result == null){ callback.run(ErrorCode.ERROR100.getCode(), "记录已保存,启用失败", null); }else { - callback.run(ErrorCode.ERROR100.getCode(), jsonObject.getString("msg"), null); + callback.run(ErrorCode.ERROR100.getCode(), result.getMsg(), null); } } } else{ StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( - mediaInfo, param.getApp(), param.getStream(), null, null); + mediaServer, param.getApp(), param.getStream(), null, null); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); } } @@ -308,40 +298,36 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } @Override - public JSONObject addStreamProxyToZlm(StreamProxyItem param) { - JSONObject result = null; - MediaServer mediaServerItem = null; + public WVPResult addStreamProxyToZlm(StreamProxyItem param) { + WVPResult result = null; + MediaServer mediaServer = null; if (param.getMediaServerId() == null) { logger.warn("添加代理时MediaServerId 为null"); return null; }else { - mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + mediaServer = mediaServerService.getOne(param.getMediaServerId()); } - if (mediaServerItem == null) { + if (mediaServer == null) { return null; } - if (zlmServerFactory.isStreamReady(mediaServerItem, param.getApp(), param.getStream())) { - zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream()); + if (zlmServerFactory.isStreamReady(mediaServer, param.getApp(), param.getStream())) { + mediaServerService.closeStreams(mediaServer, param.getApp(), param.getStream()); } + String msgResult; if ("ffmpeg".equalsIgnoreCase(param.getType())){ - result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrcUrl().trim(), param.getDstUrl(), - param.getTimeoutMs() + "", param.isEnableAudio(), param.isEnableMp4(), + result = mediaServerService.addFFmpegSource(mediaServer, param.getSrcUrl().trim(), param.getDstUrl(), + param.getTimeoutMs(), param.isEnableAudio(), param.isEnableMp4(), param.getFfmpegCmdKey()); }else { - result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl().trim(), + result = mediaServerService.addStreamProxy(mediaServer, param.getApp(), param.getStream(), param.getUrl().trim(), param.isEnableAudio(), param.isEnableMp4(), param.getRtpType()); } System.out.println("addStreamProxyToZlm===="); System.out.println(result); - if (result != null && result.getInteger("code") == 0) { - JSONObject data = result.getJSONObject("data"); - if (data == null) { - logger.warn("[获取拉流代理的结果数据Data] 失败: {}", result ); - return result; - } - String key = data.getString("key"); + if (result != null && result.getCode() == 0) { + String key = result.getData(); if (key == null) { - logger.warn("[获取拉流代理的结果数据Data中的KEY] 失败: {}", result ); + logger.warn("[获取拉流代理的结果数据Data] 失败: {}", result ); return result; } param.setStreamKey(key); @@ -351,16 +337,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } @Override - public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) { + public Boolean removeStreamProxyFromZlm(StreamProxyItem param) { if (param ==null) { return null; } - MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); - JSONObject result = null; + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + Boolean result = false; if ("ffmpeg".equalsIgnoreCase(param.getType())){ - result = zlmresTfulUtils.delFFmpegSource(mediaServerItem, param.getStreamKey()); + result = mediaServerService.delFFmpegSource(mediaServer, param.getStreamKey()); }else { - result = zlmresTfulUtils.delStreamProxy(mediaServerItem, param.getStreamKey()); + result = mediaServerService.delStreamProxy(mediaServer, param.getStreamKey()); } return result; } @@ -381,8 +367,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService { gbStreamMapper.del(app, stream); videoManagerStorager.deleteStreamProxy(app, stream); redisCatchStorage.removeStream(streamProxyItem.getMediaServerId(), "PULL", app, stream); - JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyItem); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { + Boolean result = removeStreamProxyFromZlm(streamProxyItem); + if (result != null && result) { logger.info("[移除代理]: 代理: {}/{}, 从zlm移除成功", app, stream); }else { logger.info("[移除代理]: 代理: {}/{}, 从zlm移除失败", app, stream); @@ -395,16 +381,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService { boolean result = false; StreamProxyItem streamProxy = videoManagerStorager.queryStreamProxy(app, stream); if (streamProxy != null && !streamProxy.isEnable() ) { - JSONObject jsonObject = addStreamProxyToZlm(streamProxy); - if (jsonObject == null) { + WVPResult wvpResult = addStreamProxyToZlm(streamProxy); + if (wvpResult == null) { return false; } - if (jsonObject.getInteger("code") == 0) { + if (wvpResult.getCode() == 0) { result = true; streamProxy.setEnable(true); updateStreamProxy(streamProxy); }else { - logger.info("启用代理失败: {}/{}->{}({})", app, stream, jsonObject.getString("msg"), + logger.info("启用代理失败: {}/{}->{}({})", app, stream, wvpResult.getMsg(), streamProxy.getSrcUrl() == null? streamProxy.getUrl():streamProxy.getSrcUrl()); } } else if (streamProxy != null && streamProxy.isEnable()) { @@ -418,8 +404,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService { boolean result = false; StreamProxyItem streamProxyDto = videoManagerStorager.queryStreamProxy(app, stream); if (streamProxyDto != null && streamProxyDto.isEnable()) { - JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyDto); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { + Boolean removed = removeStreamProxyFromZlm(streamProxyDto); + if (removed != null && removed) { streamProxyDto.setEnable(false); result = updateStreamProxy(streamProxyDto); } @@ -428,20 +414,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } @Override - public JSONObject getFFmpegCMDs(MediaServer mediaServerItem) { - JSONObject result = new JSONObject(); - JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); - if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0 - && mediaServerConfigResuly.getJSONArray("data").size() > 0){ - JSONObject mediaServerConfig = mediaServerConfigResuly.getJSONArray("data").getJSONObject(0); - - for (String key : mediaServerConfig.keySet()) { - if (key.startsWith("ffmpeg.cmd")){ - result.put(key, mediaServerConfig.getString(key)); - } - } - } - return result; + public Map getFFmpegCMDs(MediaServer mediaServer) { + return mediaServerService.getFFmpegCMDs(mediaServer); } @@ -467,8 +441,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService { mediaServerId, true); for (StreamProxyItem streamProxyDto : streamProxyListForEnable) { logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream()); - JSONObject jsonObject = addStreamProxyToZlm(streamProxyDto); - if (jsonObject == null) { + WVPResult wvpResult = addStreamProxyToZlm(streamProxyDto); + if (wvpResult == null) { // 设置为离线 logger.info("恢复流代理失败" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream()); updateStatus(false, streamProxyDto.getApp(), streamProxyDto.getStream()); @@ -521,41 +495,27 @@ public class StreamProxyServiceImpl implements IStreamProxyService { MediaServer mediaServer = mediaServerService.getOne(mediaServerId); if (mediaServer != null) { List allPullStream = redisCatchStorage.getStreams(mediaServerId, "PULL"); - if (allPullStream.size() > 0) { - zlmresTfulUtils.getMediaList(mediaServer, jsonObject->{ - Map stringStreamInfoMap = new HashMap<>(); - if (jsonObject.getInteger("code") == 0) { - JSONArray data = jsonObject.getJSONArray("data"); - if(data != null && data.size() > 0) { - for (int i = 0; i < data.size(); i++) { - JSONObject streamJSONObj = data.getJSONObject(i); - if ("rtsp".equals(streamJSONObj.getString("schema"))) { - StreamInfo streamInfo = new StreamInfo(); - String app = streamJSONObj.getString("app"); - String stream = streamJSONObj.getString("stream"); - streamInfo.setApp(app); - streamInfo.setStream(stream); - stringStreamInfoMap.put(app+stream, streamInfo); - } - } + if (!allPullStream.isEmpty()) { + List mediaList = mediaServerService.getMediaList(mediaServer, null, null, null); + Map stringStreamInfoMap = new HashMap<>(); + if (mediaList != null && !mediaList.isEmpty()) { + for (StreamInfo streamInfo : mediaList) { + stringStreamInfoMap.put(streamInfo.getApp() + streamInfo.getStream(), streamInfo); + } + } + if (stringStreamInfoMap.isEmpty()) { + redisCatchStorage.removeStream(mediaServerId, "PULL"); + }else { + for (String key : stringStreamInfoMap.keySet()) { + StreamInfo streamInfo = stringStreamInfoMap.get(key); + if (stringStreamInfoMap.get(streamInfo.getApp() + streamInfo.getStream()) == null) { + redisCatchStorage.removeStream(mediaServerId, "PULL", streamInfo.getApp(), + streamInfo.getStream()); } } - if (stringStreamInfoMap.size() == 0) { - redisCatchStorage.removeStream(mediaServerId, "PULL"); - }else { - for (String key : stringStreamInfoMap.keySet()) { - StreamInfo streamInfo = stringStreamInfoMap.get(key); - if (stringStreamInfoMap.get(streamInfo.getApp() + streamInfo.getStream()) == null) { - redisCatchStorage.removeStream(mediaServerId, "PULL", streamInfo.getApp(), - streamInfo.getStream()); - } - } - } - }); + } } - } - } @Override @@ -589,13 +549,12 @@ public class StreamProxyServiceImpl implements IStreamProxyService { MediaServer mediaServerItem = serverItemMap.get(streamProxyItem.getMediaServerId()); - // TODO 支持其他 schema - JSONObject mediaInfo = zlmresTfulUtils.isMediaOnline(mediaServerItem, streamProxyItem.getApp(), streamProxyItem.getStream(), "rtsp"); + MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServerItem, streamProxyItem.getApp(), streamProxyItem.getStream()); if (mediaInfo == null){ streamProxyItem.setStatus(false); } else { - if (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")) { + if (mediaInfo.getOnline() != null && mediaInfo.getOnline()) { streamProxyItem.setStatus(true); } else { streamProxyItem.setStatus(false); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index ea560550f..c5b7f58e2 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -1,21 +1,22 @@ package com.genersoft.iot.vmp.service.impl; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import com.alibaba.fastjson2.TypeReference; import com.baomidou.dynamic.datasource.annotation.DS; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.gb28181.bean.*; +import com.genersoft.iot.vmp.gb28181.bean.GbStream; +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; +import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.*; +import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -66,9 +67,6 @@ public class StreamPushServiceImpl implements IStreamPushService { @Autowired private EventPublisher eventPublisher; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Autowired private IRedisCatchStorage redisCatchStorage; @@ -88,32 +86,27 @@ public class StreamPushServiceImpl implements IStreamPushService { private MediaConfig mediaConfig; - @Override - public List handleJSON(String jsonData, MediaServer mediaServerItem) { - if (jsonData == null) { + private List handleJSON(List streamInfoList) { + if (streamInfoList == null || streamInfoList.isEmpty()) { return null; } - Map result = new HashMap<>(); - - List onStreamChangedHookParams = JSON.parseObject(jsonData, new TypeReference>() {}); - for (OnStreamChangedHookParam item : onStreamChangedHookParams) { - + for (StreamInfo streamInfo : streamInfoList) { // 不保存国标推理以及拉流代理的流 - if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal() - || item.getOriginType() == OriginType.RTMP_PUSH.ordinal() - || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) { - String key = item.getApp() + "_" + item.getStream(); + if (streamInfo.getOriginType() == OriginType.RTSP_PUSH.ordinal() + || streamInfo.getOriginType() == OriginType.RTMP_PUSH.ordinal() + || streamInfo.getOriginType() == OriginType.RTC_PUSH.ordinal() ) { + String key = streamInfo.getApp() + "_" + streamInfo.getStream(); StreamPushItem streamPushItem = result.get(key); if (streamPushItem == null) { - streamPushItem = transform(item); + streamPushItem = streamPushItem.instance(streamInfo); result.put(key, streamPushItem); } } } - return new ArrayList<>(result.values()); } + @Override public StreamPushItem transform(OnStreamChangedHookParam item) { StreamPushItem streamPushItem = new StreamPushItem(); @@ -165,14 +158,9 @@ public class StreamPushServiceImpl implements IStreamPushService { platformGbStreamMapper.delByAppAndStream(stream.getApp(), stream.getStream()); int del = gbStreamMapper.del(stream.getApp(), stream.getStream()); MediaServer mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); - JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream()); - if (mediaList != null) { - if (mediaList.getInteger("code") == 0) { - JSONArray data = mediaList.getJSONArray("data"); - if (data == null) { - streamPushMapper.del(stream.getApp(), stream.getStream()); - } - } + List mediaList = mediaServerService.getMediaList(mediaInfo, stream.getApp(), stream.getStream(), null); + if (mediaList != null && mediaList.isEmpty()) { + streamPushMapper.del(stream.getApp(), stream.getStream()); } return del > 0; } @@ -196,7 +184,7 @@ public class StreamPushServiceImpl implements IStreamPushService { int delStream = streamPushMapper.del(app, streamId); if (delStream > 0) { MediaServer mediaServerItem = mediaServerService.getOne(streamPushItem.getMediaServerId()); - zlmresTfulUtils.closeStreams(mediaServerItem,app, streamId); + mediaServerService.closeStreams(mediaServerItem,app, streamId); } return true; } @@ -232,71 +220,61 @@ public class StreamPushServiceImpl implements IStreamPushService { for (StreamAuthorityInfo streamAuthorityInfo : allStreamAuthorityInfo) { streamAuthorityInfoInfoMap.put(streamAuthorityInfo.getApp() + streamAuthorityInfo.getStream(), streamAuthorityInfo); } - zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{ - if (mediaList == null) { - return; + List mediaList = mediaServerService.getMediaList(mediaServerItem, null, null, null); + if (mediaList == null) { + return; + } + List streamPushItems = handleJSON(mediaList); + if (streamPushItems != null) { + for (StreamPushItem streamPushItem : streamPushItems) { + pushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream()); + streamInfoPushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream()); + streamAuthorityInfoInfoMap.remove(streamPushItem.getApp() + streamPushItem.getStream()); } - String dataStr = mediaList.getString("data"); - - Integer code = mediaList.getInteger("code"); - List streamPushItems = null; - if (code == 0 ) { - if (dataStr != null) { - streamPushItems = handleJSON(dataStr, mediaServerItem); - } - } - - if (streamPushItems != null) { - for (StreamPushItem streamPushItem : streamPushItems) { - pushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream()); - streamInfoPushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream()); - streamAuthorityInfoInfoMap.remove(streamPushItem.getApp() + streamPushItem.getStream()); - } - } - List offlinePushItems = new ArrayList<>(pushItemMap.values()); - if (offlinePushItems.size() > 0) { - String type = "PUSH"; - int runLimit = 300; - if (offlinePushItems.size() > runLimit) { - for (int i = 0; i < offlinePushItems.size(); i += runLimit) { - int toIndex = i + runLimit; - if (i + runLimit > offlinePushItems.size()) { - toIndex = offlinePushItems.size(); - } - List streamPushItemsSub = offlinePushItems.subList(i, toIndex); - streamPushMapper.delAll(streamPushItemsSub); + } + List offlinePushItems = new ArrayList<>(pushItemMap.values()); + if (offlinePushItems.size() > 0) { + String type = "PUSH"; + int runLimit = 300; + if (offlinePushItems.size() > runLimit) { + for (int i = 0; i < offlinePushItems.size(); i += runLimit) { + int toIndex = i + runLimit; + if (i + runLimit > offlinePushItems.size()) { + toIndex = offlinePushItems.size(); } - }else { - streamPushMapper.delAll(offlinePushItems); - } - - } - Collection offlineOnStreamChangedHookParamList = streamInfoPushItemMap.values(); - if (offlineOnStreamChangedHookParamList.size() > 0) { - String type = "PUSH"; - for (OnStreamChangedHookParam offlineOnStreamChangedHookParam : offlineOnStreamChangedHookParamList) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("serverId", userSetting.getServerId()); - jsonObject.put("app", offlineOnStreamChangedHookParam.getApp()); - jsonObject.put("stream", offlineOnStreamChangedHookParam.getStream()); - jsonObject.put("register", false); - jsonObject.put("mediaServerId", mediaServerId); - redisCatchStorage.sendStreamChangeMsg(type, jsonObject); - // 移除redis内流的信息 - redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream()); - // 冗余数据,自己系统中自用 - redisCatchStorage.removePushListItem(offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream(), mediaServerItem.getId()); + List streamPushItemsSub = offlinePushItems.subList(i, toIndex); + streamPushMapper.delAll(streamPushItemsSub); } + }else { + streamPushMapper.delAll(offlinePushItems); } - Collection streamAuthorityInfos = streamAuthorityInfoInfoMap.values(); - if (streamAuthorityInfos.size() > 0) { - for (StreamAuthorityInfo streamAuthorityInfo : streamAuthorityInfos) { - // 移除redis内流的信息 - redisCatchStorage.removeStreamAuthorityInfo(streamAuthorityInfo.getApp(), streamAuthorityInfo.getStream()); - } + } + Collection offlineOnStreamChangedHookParamList = streamInfoPushItemMap.values(); + if (offlineOnStreamChangedHookParamList.size() > 0) { + String type = "PUSH"; + for (OnStreamChangedHookParam offlineOnStreamChangedHookParam : offlineOnStreamChangedHookParamList) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("serverId", userSetting.getServerId()); + jsonObject.put("app", offlineOnStreamChangedHookParam.getApp()); + jsonObject.put("stream", offlineOnStreamChangedHookParam.getStream()); + jsonObject.put("register", false); + jsonObject.put("mediaServerId", mediaServerId); + redisCatchStorage.sendStreamChangeMsg(type, jsonObject); + // 移除redis内流的信息 + redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream()); + // 冗余数据,自己系统中自用 + redisCatchStorage.removePushListItem(offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream(), mediaServerItem.getId()); } - })); + } + + Collection streamAuthorityInfos = streamAuthorityInfoInfoMap.values(); + if (streamAuthorityInfos.size() > 0) { + for (StreamAuthorityInfo streamAuthorityInfo : streamAuthorityInfos) { + // 移除redis内流的信息 + redisCatchStorage.removeStreamAuthorityInfo(streamAuthorityInfo.getApp(), streamAuthorityInfo.getStream()); + } + } } @Override @@ -471,7 +449,7 @@ public class StreamPushServiceImpl implements IStreamPushService { if (delStream > 0) { for (GbStream gbStream : gbStreams) { MediaServer mediaServerItem = mediaServerService.getOne(gbStream.getMediaServerId()); - zlmresTfulUtils.closeStreams(mediaServerItem, gbStream.getApp(), gbStream.getStream()); + mediaServerService.closeStreams(mediaServerItem, gbStream.getApp(), gbStream.getStream()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index ece3349b9..c32c3e5cd 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -16,17 +16,14 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; -import com.genersoft.iot.vmp.vmanager.bean.*; +import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; @@ -70,24 +67,15 @@ public class PlayController { @Autowired private IVideoManagerStorage storager; - @Autowired - private IRedisCatchStorage redisCatchStorage; - @Autowired private IInviteStreamService inviteStreamService; - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; - @Autowired private DeferredResultHolder resultHolder; @Autowired private IPlayService playService; - @Autowired - private IMediaService mediaService; - @Autowired private IMediaServerService mediaServerService; @@ -202,50 +190,6 @@ public class PlayController { json.put("isSubStream", isSubStream); return json; } - - /** - * 将不是h264的视频通过ffmpeg 转码为h264 + aac - * @param streamId 流ID - */ - @Operation(summary = "将不是h264的视频通过ffmpeg 转码为h264 + aac", security = @SecurityRequirement(name = JwtUtils.HEADER)) - @Parameter(name = "streamId", description = "视频流ID", required = true) - @PostMapping("/convert/{streamId}") - public JSONObject playConvert(@PathVariable String streamId) { -// StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); - - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, streamId); - if (inviteInfo == null || inviteInfo.getStreamInfo() == null) { - logger.warn("视频转码API调用失败!, 视频流已经停止!"); - throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到视频流信息, 视频流可能已经停止"); - } - MediaServer mediaInfo = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId()); - JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); - if (!rtpInfo.getBoolean("exist")) { - logger.warn("视频转码API调用失败!, 视频流已停止推流!"); - throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到视频流信息, 视频流可能已停止推流"); - } else { - String dstUrl = String.format("rtmp://%s:%s/convert/%s", "127.0.0.1", mediaInfo.getRtmpPort(), - streamId ); - String srcUrl = String.format("rtsp://%s:%s/rtp/%s", "127.0.0.1", mediaInfo.getRtspPort(), streamId); - JSONObject jsonObject = zlmresTfulUtils.addFFmpegSource(mediaInfo, srcUrl, dstUrl, "1000000", true, false, null); - logger.info(jsonObject.toJSONString()); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { - JSONObject data = jsonObject.getJSONObject("data"); - if (data != null) { - JSONObject result = new JSONObject(); - result.put("key", data.getString("key")); - StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStreamWithCheck("convert", streamId, mediaInfo.getId(), false); - result.put("StreamInfo", streamInfoResult); - return result; - }else { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "转码失败"); - } - }else { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "转码失败"); - } - } - } - /** * 结束转码 */ @@ -261,14 +205,8 @@ public class PlayController { if (mediaInfo == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "使用的流媒体已经停止运行" ); }else { - JSONObject jsonObject = zlmresTfulUtils.delFFmpegSource(mediaInfo, key); - logger.info(jsonObject.toJSONString()); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { - JSONObject data = jsonObject.getJSONObject("data"); - if (data == null || data.getBoolean("flag") == null || !data.getBoolean("flag")) { - throw new ControllerException(ErrorCode.ERROR100 ); - } - }else { + Boolean deleted = mediaServerService.delFFmpegSource(mediaInfo, key); + if (!deleted) { throw new ControllerException(ErrorCode.ERROR100 ); } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index 5f17cbd5c..89a5f906f 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -27,6 +27,7 @@ import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; +import java.util.Map; import java.util.UUID; @SuppressWarnings("rawtypes") @@ -135,7 +136,7 @@ public class StreamProxyController { @ResponseBody @Operation(summary = "获取ffmpeg.cmd模板", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "mediaServerId", description = "流媒体ID", required = true) - public JSONObject getFFmpegCMDs(@RequestParam String mediaServerId){ + public Map getFFmpegCMDs(@RequestParam String mediaServerId){ logger.debug("获取节点[ {} ]ffmpeg.cmd模板", mediaServerId ); MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); From 63a35ffaaf248f1c6eb7d660e9d3dba5d664eed7 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 22 Mar 2024 17:44:42 +0800 Subject: [PATCH 15/58] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../media/abl/ABLMediaNodeServerService.java | 42 +++++++++++++++++++ .../media/zlm/ZLMMediaServerStatusManger.java | 12 +++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index 59b1c8d95..9c2bb904f 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -5,9 +5,11 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Map; @Service("abl") public class ABLMediaNodeServerService implements IMediaNodeServerService { @@ -81,4 +83,44 @@ public class ABLMediaNodeServerService implements IMediaNodeServerService { public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { return null; } + + @Override + public Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey) { + return null; + } + + @Override + public Boolean resumeRtpCheck(MediaServer mediaServer, String streamKey) { + return null; + } + + @Override + public String getFfmpegCmd(MediaServer mediaServer, String cmdKey) { + return null; + } + + @Override + public WVPResult addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey) { + return null; + } + + @Override + public WVPResult addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType) { + return null; + } + + @Override + public Boolean delFFmpegSource(MediaServer mediaServer, String streamKey) { + return null; + } + + @Override + public Boolean delStreamProxy(MediaServer mediaServer, String streamKey) { + return null; + } + + @Override + public Map getFFmpegCMDs(MediaServer mediaServer) { + return null; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index b2bfaf1b0..86faa256b 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -210,22 +210,22 @@ public class ZLMMediaServerStatusManger { }, (int)(mediaServerItem.getHookAliveInterval() * 2 * 1000)); } private void initPort(MediaServer mediaServerItem, ZLMServerConfig zlmServerConfig) { - if (mediaServerItem.getHttpSSlPort() == 0) { + if (mediaServerItem.getHttpSSlPort() != 0) { mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); } - if (mediaServerItem.getRtmpPort() == 0) { + if (mediaServerItem.getRtmpPort() != 0) { mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort()); } - if (mediaServerItem.getRtmpSSlPort() == 0) { + if (mediaServerItem.getRtmpSSlPort() != 0) { mediaServerItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); } - if (mediaServerItem.getRtspPort() == 0) { + if (mediaServerItem.getRtspPort() != 0) { mediaServerItem.setRtspPort(zlmServerConfig.getRtspPort()); } - if (mediaServerItem.getRtspSSLPort() == 0) { + if (mediaServerItem.getRtspSSLPort() != 0) { mediaServerItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); } - if (mediaServerItem.getRtpProxyPort() == 0) { + if (mediaServerItem.getRtpProxyPort() != 0) { mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); } mediaServerItem.setHookAliveInterval(10F); From 23f0aba0ed87f1a788b764c1cce16d8cca78871c Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 22 Mar 2024 17:48:21 +0800 Subject: [PATCH 16/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E7=AB=AF=E5=8F=A3=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/zlm/ZLMMediaServerStatusManger.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index 86faa256b..6d6332983 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -193,10 +193,12 @@ public class ZLMMediaServerStatusManger { } } if (config != null) { + initPort(mediaServerItem, config); setZLMConfig(mediaServerItem, "0".equals(config.getHookEnable()) || !Objects.equals(mediaServerItem.getHookAliveInterval(), config.getHookAliveInterval())); } } + mediaServerService.update(mediaServerItem); } // 设置两次心跳未收到则认为zlm离线 String key = "zlm-keepalive-" + mediaServerItem.getId(); @@ -210,22 +212,23 @@ public class ZLMMediaServerStatusManger { }, (int)(mediaServerItem.getHookAliveInterval() * 2 * 1000)); } private void initPort(MediaServer mediaServerItem, ZLMServerConfig zlmServerConfig) { - if (mediaServerItem.getHttpSSlPort() != 0) { + // 端口只会从配置中读取一次,一旦自己配置或者读取过了将不在配置 + if (mediaServerItem.getHttpSSlPort() == 0) { mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); } - if (mediaServerItem.getRtmpPort() != 0) { + if (mediaServerItem.getRtmpPort() == 0) { mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort()); } - if (mediaServerItem.getRtmpSSlPort() != 0) { + if (mediaServerItem.getRtmpSSlPort() == 0) { mediaServerItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); } - if (mediaServerItem.getRtspPort() != 0) { + if (mediaServerItem.getRtspPort() == 0) { mediaServerItem.setRtspPort(zlmServerConfig.getRtspPort()); } - if (mediaServerItem.getRtspSSLPort() != 0) { + if (mediaServerItem.getRtspSSLPort() == 0) { mediaServerItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); } - if (mediaServerItem.getRtpProxyPort() != 0) { + if (mediaServerItem.getRtpProxyPort() == 0) { mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); } mediaServerItem.setHookAliveInterval(10F); From c1ac16bf620d09a94a0cfe184cbe1c9cb531a01b Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Sat, 23 Mar 2024 15:38:54 +0800 Subject: [PATCH 17/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=9C=8D=E5=8A=A1=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/abl/ABLHttpHookListener.java | 906 ++++++++++++++++++ .../media/abl/ABLMediaServerStatusManger.java | 305 ++++++ .../iot/vmp/media/abl/ABLRESTfulUtils.java | 403 ++++++++ .../vmp/media/abl/bean/AblServerConfig.java | 4 + .../event/HookAblServerKeepaliveEvent.java | 24 + .../abl/event/HookAblServerStartEvent.java | 24 + .../vmp/media/zlm/ZLMHttpHookListener.java | 17 +- 7 files changed, 1671 insertions(+), 12 deletions(-) create mode 100755 src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java create mode 100755 src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java new file mode 100755 index 000000000..026134acb --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java @@ -0,0 +1,906 @@ +package com.genersoft.iot.vmp.media.abl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +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.common.VideoManagerConstants; +import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; +import com.genersoft.iot.vmp.gb28181.bean.*; +import com.genersoft.iot.vmp.gb28181.event.EventPublisher; +import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; +import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; +import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.dto.*; +import com.genersoft.iot.vmp.media.zlm.dto.hook.*; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; +import com.genersoft.iot.vmp.service.*; +import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.utils.DateUtil; +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; +import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; +import com.genersoft.iot.vmp.vmanager.bean.StreamContent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.util.ObjectUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; + +import javax.servlet.http.HttpServletRequest; +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import java.text.ParseException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * ABL服务Hook事件 + */ +@RestController +@RequestMapping("/index/hook") +public class ABLHttpHookListener { + + private final static Logger logger = LoggerFactory.getLogger(ABLHttpHookListener.class); + + @Autowired + private SIPCommander cmder; + + @Autowired + private ISIPCommanderForPlatform commanderFroPlatform; + + @Autowired + private AudioBroadcastManager audioBroadcastManager; + + @Autowired + private IPlayService playService; + + @Autowired + private IVideoManagerStorage storager; + + @Autowired + private IRedisCatchStorage redisCatchStorage; + + @Autowired + private IInviteStreamService inviteStreamService; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IMediaServerService mediaServerService; + + @Autowired + private IStreamProxyService streamProxyService; + + @Autowired + private DeferredResultHolder resultHolder; + + @Autowired + private IMediaService mediaService; + + @Autowired + private EventPublisher eventPublisher; + + @Autowired + private ZLMMediaListManager zlmMediaListManager; + + @Autowired + private ZlmHttpHookSubscribe subscribe; + + @Autowired + private UserSetting userSetting; + + @Autowired + private IUserService userService; + + @Autowired + private ICloudRecordService cloudRecordService; + + @Autowired + private VideoStreamSessionManager sessionManager; + + @Autowired + private SSRCFactory ssrcFactory; + + @Qualifier("taskExecutor") + @Autowired + private ThreadPoolTaskExecutor taskExecutor; + + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + /** + * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 + */ + @ResponseBody + + @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") + public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { + try { + HookAblServerKeepaliveEvent event = new HookAblServerKeepaliveEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServerItem(mediaServerItem); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ZLM-HOOK-心跳] 发送通知失败 ", e); + } + return HookResult.SUCCESS(); + } + + /** + * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。 + */ + @ResponseBody + @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") + public HookResult onPlay(@RequestBody OnPlayHookParam param) { + if (logger.isDebugEnabled()) { + logger.debug("[ZLM HOOK] 播放鉴权:{}->{}", param.getMediaServerId(), param); + } + String mediaServerId = param.getMediaServerId(); + + taskExecutor.execute(() -> { + JSONObject json = (JSONObject) JSON.toJSON(param); + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); + if (subscribe != null) { + MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); + if (mediaInfo != null) { + subscribe.response(mediaInfo, param); + } + } + }); + if (!"rtp".equals(param.getApp())) { + Map paramMap = urlParamToMap(param.getParams()); + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); + if (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(paramMap.get("callId"))) { + return new HookResult(401, "Unauthorized"); + } + } + + return HookResult.SUCCESS(); + } + + /** + * rtsp/rtmp/rtp推流鉴权事件。 + */ + @ResponseBody + @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8") + public HookResultForOnPublish onPublish(@RequestBody OnPublishHookParam param) { + + JSONObject json = (JSONObject) JSON.toJSON(param); + + logger.info("[ABL HOOK]推流鉴权:{}->{}", param.getMediaServerId(), param); + // TODO 加快处理速度 + + String mediaServerId = json.getString("mediaServerId"); + MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); + if (mediaInfo == null) { + return new HookResultForOnPublish(200, "success"); + } + // 推流鉴权的处理 + if (!"rtp".equals(param.getApp())) { + StreamProxyItem stream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); + if (stream != null) { + HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); + result.setEnable_audio(stream.isEnableAudio()); + result.setEnable_mp4(stream.isEnableMp4()); + return result; + } + if (userSetting.getPushAuthority()) { + // 推流鉴权 + if (param.getParams() == null) { + logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); + return new HookResultForOnPublish(401, "Unauthorized"); + } + Map paramMap = urlParamToMap(param.getParams()); + String sign = paramMap.get("sign"); + if (sign == null) { + logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); + return new HookResultForOnPublish(401, "Unauthorized"); + } + // 推流自定义播放鉴权码 + String callId = paramMap.get("callId"); + // 鉴权配置 + boolean hasAuthority = userService.checkPushAuthority(callId, sign); + if (!hasAuthority) { + logger.info("推流鉴权失败: sign 无权限: callId={}. sign={}", callId, sign); + return new HookResultForOnPublish(401, "Unauthorized"); + } + StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); + streamAuthorityInfo.setCallId(callId); + streamAuthorityInfo.setSign(sign); + // 鉴权通过 + redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); + } + } else { + zlmMediaListManager.sendStreamEvent(param.getApp(), param.getStream(), param.getMediaServerId()); + } + + + HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); + result.setEnable_audio(true); + taskExecutor.execute(() -> { + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); + if (subscribe != null) { + subscribe.response(mediaInfo, param); + } + }); + + // 是否录像 + if ("rtp".equals(param.getApp())) { + result.setEnable_mp4(userSetting.getRecordSip()); + } else { + result.setEnable_mp4(userSetting.isRecordPushLive()); + } + // 国标流 + if ("rtp".equals(param.getApp())) { + + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); + + // 单端口模式下修改流 ID + if (!mediaInfo.isRtpEnable() && inviteInfo == null) { + String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16)); + inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc); + if (inviteInfo != null) { + result.setStream_replace(inviteInfo.getStream()); + logger.info("[ABL HOOK]推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream()); + } + } + + // 设置音频信息及录制信息 + List ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream()); + if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) { + + // 为录制国标模拟一个鉴权信息, 方便后续写入录像文件时使用 + StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); + streamAuthorityInfo.setApp(param.getApp()); + streamAuthorityInfo.setStream(ssrcTransactionForAll.get(0).getStream()); + streamAuthorityInfo.setCallId(ssrcTransactionForAll.get(0).getSipTransactionInfo().getCallId()); + + redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), ssrcTransactionForAll.get(0).getStream(), streamAuthorityInfo); + + String deviceId = ssrcTransactionForAll.get(0).getDeviceId(); + String channelId = ssrcTransactionForAll.get(0).getChannelId(); + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); + if (deviceChannel != null) { + result.setEnable_audio(deviceChannel.isHasAudio()); + } + // 如果是录像下载就设置视频间隔十秒 + if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) { + // 获取录像的总时长,然后设置为这个视频的时长 + InviteInfo inviteInfoForDownload = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, param.getStream()); + if (inviteInfoForDownload != null && inviteInfoForDownload.getStreamInfo() != null) { + String startTime = inviteInfoForDownload.getStreamInfo().getStartTime(); + String endTime = inviteInfoForDownload.getStreamInfo().getEndTime(); + long difference = DateUtil.getDifference(startTime, endTime) / 1000; + result.setMp4_max_second((int) difference); + result.setEnable_mp4(true); + // 设置为2保证得到的mp4的时长是正常的 + result.setModify_stamp(2); + } + } + // 如果是talk对讲,则默认获取声音 + if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.TALK) { + result.setEnable_audio(true); + } + } + } else if (param.getApp().equals("broadcast")) { + result.setEnable_audio(true); + } else if (param.getApp().equals("talk")) { + result.setEnable_audio(true); + } + if (param.getApp().equalsIgnoreCase("rtp")) { + String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_" + param.getStream(); + OtherRtpSendInfo otherRtpSendInfo = (OtherRtpSendInfo) redisTemplate.opsForValue().get(receiveKey); + + String receiveKeyForPS = VideoManagerConstants.WVP_OTHER_RECEIVE_PS_INFO + userSetting.getServerId() + "_" + param.getStream(); + OtherPsSendInfo otherPsSendInfo = (OtherPsSendInfo) redisTemplate.opsForValue().get(receiveKeyForPS); + if (otherRtpSendInfo != null || otherPsSendInfo != null) { + result.setEnable_mp4(true); + } + } + logger.info("[ABL HOOK]推流鉴权 响应:{}->{}->>>>{}", param.getMediaServerId(), param, result); + return result; + } + + + /** + * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 + */ + @ResponseBody + @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8") + public HookResult onStreamChanged(@RequestBody OnStreamChangedHookParam param) { + + if (param.isRegist()) { + logger.info("[ABL HOOK] 流注册, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + } else { + logger.info("[ABL HOOK] 流注销, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + } + + JSONObject json = (JSONObject) JSON.toJSON(param); + taskExecutor.execute(() -> { + ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); + MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); + if (mediaInfo == null) { + logger.info("[ABL HOOK] 流变化未找到ABL, {}", param.getMediaServerId()); + return; + } + if (subscribe != null) { + subscribe.response(mediaInfo, param); + } + + // TODO 重构此处逻辑 + if (param.isRegist()) { + // 处理流注册的鉴权信息, 流注销这里不再删除鉴权信息,下次来了新的鉴权信息会对就的进行覆盖 + if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal() + || param.getOriginType() == OriginType.RTSP_PUSH.ordinal() + || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); + if (streamAuthorityInfo == null) { + streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); + } else { + streamAuthorityInfo.setOriginType(param.getOriginType()); + streamAuthorityInfo.setOriginTypeStr(param.getOriginTypeStr()); + } + redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); + } + } + if ("rtsp".equals(param.getSchema())) { + logger.info("流变化:注册->{}, app->{}, stream->{}", param.isRegist(), param.getApp(), param.getStream()); + if (param.isRegist()) { + mediaServerService.addCount(param.getMediaServerId()); + } else { + mediaServerService.removeCount(param.getMediaServerId()); + } + + int updateStatusResult = streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream()); + if (updateStatusResult > 0) { + + } + + if ("rtp".equals(param.getApp()) && !param.isRegist()) { + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); + if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) { + inviteStreamService.removeInviteInfo(inviteInfo); + storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); + } + } else if ("broadcast".equals(param.getApp())) { + // 语音对讲推流 stream需要满足格式deviceId_channelId + if (param.getStream().indexOf("_") > 0) { + String[] streamArray = param.getStream().split("_"); + if (streamArray.length == 2) { + String deviceId = streamArray[0]; + String channelId = streamArray[1]; + Device device = deviceService.getDevice(deviceId); + if (device != null) { + if (param.isRegist()) { + if (audioBroadcastManager.exit(deviceId, channelId)) { + playService.stopAudioBroadcast(deviceId, channelId); + } + // 开启语音对讲通道 + try { + playService.audioBroadcastCmd(device, channelId, mediaInfo, param.getApp(), param.getStream(), 60, false, (msg) -> { + logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); + }); + } catch (InvalidArgumentException | ParseException | SipException e) { + logger.error("[命令发送失败] 语音对讲: {}", e.getMessage()); + } + } else { + // 流注销 + playService.stopAudioBroadcast(deviceId, channelId); + } + } else { + logger.info("[语音对讲] 未找到设备:{}", deviceId); + } + } + } + } else if ("talk".equals(param.getApp())) { + // 语音对讲推流 stream需要满足格式deviceId_channelId + if (param.getStream().indexOf("_") > 0) { + String[] streamArray = param.getStream().split("_"); + if (streamArray.length == 2) { + String deviceId = streamArray[0]; + String channelId = streamArray[1]; + Device device = deviceService.getDevice(deviceId); + if (device != null) { + if (param.isRegist()) { + if (audioBroadcastManager.exit(deviceId, channelId)) { + playService.stopAudioBroadcast(deviceId, channelId); + } + // 开启语音对讲通道 + playService.talkCmd(device, channelId, mediaInfo, param.getStream(), (msg) -> { + logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); + }); + } else { + // 流注销 + playService.stopTalk(device, channelId, param.isRegist()); + } + } else { + logger.info("[语音对讲] 未找到设备:{}", deviceId); + } + } + } + + } else { + if (!"rtp".equals(param.getApp())) { + String type = OriginType.values()[param.getOriginType()].getType(); + if (param.isRegist()) { + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo( + param.getApp(), param.getStream()); + String callId = null; + if (streamAuthorityInfo != null) { + callId = streamAuthorityInfo.getCallId(); + } + StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo, + param.getApp(), param.getStream(), MediaInfo.getInstance(param), callId); + param.setStreamInfo(new StreamContent(streamInfoByAppAndStream)); + redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param); + if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() + || param.getOriginType() == OriginType.RTMP_PUSH.ordinal() + || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { + param.setSeverId(userSetting.getServerId()); + zlmMediaListManager.addPush(param); + + // 冗余数据,自己系统中自用 + redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param); + } + } else { + // 兼容流注销时类型从redis记录获取 + OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo( + param.getApp(), param.getStream(), param.getMediaServerId()); + if (onStreamChangedHookParam != null) { + type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType(); + redisCatchStorage.removeStream(mediaInfo.getId(), type, param.getApp(), param.getStream()); + if ("PUSH".equalsIgnoreCase(type)) { + // 冗余数据,自己系统中自用 + redisCatchStorage.removePushListItem(param.getApp(), param.getStream(), param.getMediaServerId()); + } + } + GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream()); + if (gbStream != null) { +// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); + } + zlmMediaListManager.removeMedia(param.getApp(), param.getStream()); + } + GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream()); + if (gbStream != null) { + if (userSetting.isUsePushingAsStatus()) { + eventPublisher.catalogEventPublishForStream(null, gbStream, param.isRegist() ? CatalogEvent.ON : CatalogEvent.OFF); + } + } + if (type != null) { + // 发送流变化redis消息 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("serverId", userSetting.getServerId()); + jsonObject.put("app", param.getApp()); + jsonObject.put("stream", param.getStream()); + jsonObject.put("register", param.isRegist()); + jsonObject.put("mediaServerId", param.getMediaServerId()); + redisCatchStorage.sendStreamChangeMsg(type, jsonObject); + } + } + } + if (!param.isRegist()) { + List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream()); + if (!sendRtpItems.isEmpty()) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + if (sendRtpItem != null && sendRtpItem.getApp().equals(param.getApp())) { + String platformId = sendRtpItem.getPlatformId(); + ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); + Device device = deviceService.getDevice(platformId); + + try { + if (platform != null) { + commanderFroPlatform.streamByeCmd(platform, sendRtpItem); + redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), + sendRtpItem.getCallId(), sendRtpItem.getStream()); + } else { + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), param.getStream(), sendRtpItem.getCallId()); + if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) + || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + if (audioBroadcastCatch != null) { + // 来自上级平台的停止对讲 + logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + } + } + } + } catch (SipException | InvalidArgumentException | ParseException | + SsrcTransactionNotFoundException e) { + logger.error("[命令发送失败] 发送BYE: {}", e.getMessage()); + } + } + } + } + } + } + }); + return HookResult.SUCCESS(); + } + + /** + * 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 + */ + @ResponseBody + @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") + public JSONObject onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) { + + logger.info("[ABL HOOK]流无人观看:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), + param.getApp(), param.getStream()); + JSONObject ret = new JSONObject(); + ret.put("code", 0); + // 国标类型的流 + if ("rtp".equals(param.getApp())) { + ret.put("close", userSetting.getStreamOnDemand()); + // 国标流, 点播/录像回放/录像下载 + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); + // 点播 + if (inviteInfo != null) { + // 录像下载 + if (inviteInfo.getType() == InviteSessionType.DOWNLOAD) { + ret.put("close", false); + return ret; + } + // 收到无人观看说明流也没有在往上级推送 + if (redisCatchStorage.isChannelSendingRTP(inviteInfo.getChannelId())) { + List sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId( + inviteInfo.getChannelId()); + if (!sendRtpItems.isEmpty()) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); + try { + commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); + } + redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(), + sendRtpItem.getCallId(), sendRtpItem.getStream()); + if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) { + MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, + sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), + sendRtpItem.getPlatformId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); + messageForPushChannel.setPlatFormIndex(parentPlatform.getId()); + redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); + } + } + } + } + Device device = deviceService.getDevice(inviteInfo.getDeviceId()); + if (device != null) { + try { + // 多查询一次防止已经被处理了 + InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(), + inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream()); + if (info != null) { + cmder.streamByeCmd(device, inviteInfo.getChannelId(), + inviteInfo.getStream(), null); + } else { + logger.info("[无人观看] 未找到设备的点播信息: {}, 流:{}", inviteInfo.getDeviceId(), param.getStream()); + } + } catch (InvalidArgumentException | ParseException | SipException | + SsrcTransactionNotFoundException e) { + logger.error("[无人观看]点播, 发送BYE失败 {}", e.getMessage()); + } + } else { + logger.info("[无人观看] 未找到设备: {},流:{}", inviteInfo.getDeviceId(), param.getStream()); + } + + inviteStreamService.removeInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), + inviteInfo.getChannelId(), inviteInfo.getStream()); + storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); + return ret; + } + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null); + if (sendRtpItem != null && "talk".equals(sendRtpItem.getApp())) { + ret.put("close", false); + return ret; + } + } else if ("talk".equals(param.getApp()) || "broadcast".equals(param.getApp())) { + ret.put("close", false); + } else { + // 非国标流 推流/拉流代理 + // 拉流代理 + StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); + if (streamProxyItem != null) { + if (streamProxyItem.isEnableRemoveNoneReader()) { + // 无人观看自动移除 + ret.put("close", true); + streamProxyService.del(param.getApp(), param.getStream()); + String url = streamProxyItem.getUrl() != null ? streamProxyItem.getUrl() : streamProxyItem.getSrcUrl(); + logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", param.getApp(), param.getStream(), url); + } else if (streamProxyItem.isEnableDisableNoneReader()) { + // 无人观看停用 + ret.put("close", true); + // 修改数据 + streamProxyService.stop(param.getApp(), param.getStream()); + } else { + // 无人观看不做处理 + ret.put("close", false); + } + return ret; + } + // TODO 推流具有主动性,暂时不做处理 +// StreamPushItem streamPushItem = streamPushService.getPush(app, streamId); +// if (streamPushItem != null) { +// // TODO 发送停止 +// +// } + } + return ret; + } + + /** + * 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感。 + */ + @ResponseBody + @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") + public DeferredResult onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param) { + logger.info("[ABL HOOK] 流未找到:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + + DeferredResult defaultResult = new DeferredResult<>(); + + MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); + if (!userSetting.isAutoApplyPlay() || mediaInfo == null) { + defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); + return defaultResult; + } + + if ("rtp".equals(param.getApp())) { + String[] s = param.getStream().split("_"); + if ((s.length != 2 && s.length != 4)) { + defaultResult.setResult(HookResult.SUCCESS()); + return defaultResult; + } + String deviceId = s[0]; + String channelId = s[1]; + Device device = redisCatchStorage.getDevice(deviceId); + if (device == null || !device.isOnLine()) { + defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); + return defaultResult; + } + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); + if (deviceChannel == null) { + defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); + return defaultResult; + } + if (s.length == 2) { + logger.info("[ABL HOOK] 预览流未找到, 发起自动点播:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + + RequestMessage msg = new RequestMessage(); + String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; + boolean exist = resultHolder.exist(key, null); + msg.setKey(key); + String uuid = UUID.randomUUID().toString(); + msg.setId(uuid); + DeferredResult result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); + + result.onTimeout(() -> { + logger.info("[ABL HOOK] 预览流自动点播, 等待超时"); + msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时")); + resultHolder.invokeAllResult(msg); + inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); + storager.stopPlay(deviceId, channelId); + }); + + resultHolder.put(key, uuid, result); + + if (!exist) { + playService.play(mediaInfo, deviceId, channelId, null, (code, message, data) -> { + msg.setData(new HookResult(code, message)); + resultHolder.invokeResult(msg); + }); + } + return result; + } else if (s.length == 4) { + // 此时为录像回放, 录像回放格式为> 设备ID_通道ID_开始时间_结束时间 + String startTimeStr = s[2]; + String endTimeStr = s[3]; + if (startTimeStr == null || endTimeStr == null || startTimeStr.length() != 14 || endTimeStr.length() != 14) { + defaultResult.setResult(HookResult.SUCCESS()); + return defaultResult; + } + String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr); + String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr); + logger.info("[ABL HOOK] 回放流未找到, 发起自动点播:{}->{}->{}/{}-{}-{}", + param.getMediaServerId(), param.getSchema(), + param.getApp(), param.getStream(), + startTime, endTime + ); + RequestMessage msg = new RequestMessage(); + String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId; + boolean exist = resultHolder.exist(key, null); + msg.setKey(key); + String uuid = UUID.randomUUID().toString(); + msg.setId(uuid); + DeferredResult result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); + + result.onTimeout(() -> { + logger.info("[ABL HOOK] 回放流自动点播, 等待超时"); + // 释放rtpserver + msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时")); + resultHolder.invokeResult(msg); + }); + + resultHolder.put(key, uuid, result); + + if (!exist) { + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaInfo, param.getStream(), null, + device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); + playService.playBack(mediaInfo, ssrcInfo, deviceId, channelId, startTime, endTime, (code, message, data) -> { + msg.setData(new HookResult(code, message)); + resultHolder.invokeResult(msg); + }); + } + return result; + } else { + defaultResult.setResult(HookResult.SUCCESS()); + return defaultResult; + } + + } else { + // 拉流代理 + StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); + if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnableDisableNoneReader()) { + streamProxyService.start(param.getApp(), param.getStream()); + } + DeferredResult result = new DeferredResult<>(); + result.setResult(HookResult.SUCCESS()); + return result; + } + } + + /** + * 服务器启动事件,可以用于监听服务器崩溃重启;此事件对回复不敏感。 + */ + @ResponseBody + @PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8") + public HookResult onServerStarted(HttpServletRequest request, @RequestBody JSONObject jsonObject) { + + jsonObject.put("ip", request.getRemoteAddr()); + ZLMServerConfig zlmServerConfig = JSON.to(ZLMServerConfig.class, jsonObject); + zlmServerConfig.setIp(request.getRemoteAddr()); + logger.info("[ABL HOOK] ABL 启动 " + zlmServerConfig.getGeneralMediaServerId()); + taskExecutor.execute(() -> { + List subscribes = this.subscribe.getSubscribes(HookType.on_server_started); + if (subscribes != null && !subscribes.isEmpty()) { + for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { + subscribe.response(null, zlmServerConfig); + } + } + }); + try { + HookZlmServerStartEvent event = new HookZlmServerStartEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(zlmServerConfig.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServerItem(mediaServerItem); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ABL-HOOK-ABL启动] 发送通知失败 ", e); + } + + return HookResult.SUCCESS(); + } + + /** + * 发送rtp(startSendRtp)被动关闭时回调 + */ + @ResponseBody + @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8") + public HookResult onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param) { + + logger.info("[ABL HOOK] rtp发送关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); + + // 查找对应的上级推流,发送停止 + if (!"rtp".equals(param.getApp())) { + return HookResult.SUCCESS(); + } + taskExecutor.execute(() -> { + List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream()); + if (sendRtpItems.size() > 0) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); + ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); + try { + commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); + } + redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(), + sendRtpItem.getCallId(), sendRtpItem.getStream()); + } + } + }); + + return HookResult.SUCCESS(); + } + + /** + * rtpServer收流超时 + */ + @ResponseBody + @PostMapping(value = "/on_rtp_server_timeout", produces = "application/json;charset=UTF-8") + public HookResult onRtpServerTimeout(@RequestBody OnRtpServerTimeoutHookParam + param) { + logger.info("[ABL HOOK] rtpServer收流超时:{}->{}({})", param.getMediaServerId(), param.getStream_id(), param.getSsrc()); + + taskExecutor.execute(() -> { + List subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); + if (subscribes != null && !subscribes.isEmpty()) { + for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { + subscribe.response(null, param); + } + } + }); + + return HookResult.SUCCESS(); + } + + /** + * 录像完成事件 + */ + @ResponseBody + @PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8") + public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4HookParam param) { + logger.info("[AB HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path()); + + taskExecutor.execute(() -> { + List subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4); + if (subscribes != null && !subscribes.isEmpty()) { + for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { + subscribe.response(null, param); + } + } + cloudRecordService.addRecord(param); + + }); + + return HookResult.SUCCESS(); + } + + private Map urlParamToMap(String params) { + HashMap map = new HashMap<>(); + if (ObjectUtils.isEmpty(params)) { + return map; + } + String[] paramsArray = params.split("&"); + if (paramsArray.length == 0) { + return map; + } + for (String param : paramsArray) { + String[] paramArray = param.split("="); + if (paramArray.length == 2) { + map.put(paramArray[0], paramArray[1]); + } + } + return map; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java new file mode 100644 index 000000000..28181e89e --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java @@ -0,0 +1,305 @@ +package com.genersoft.iot.vmp.media.abl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.conf.DynamicTask; +import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.media.abl.bean.AblServerConfig; +import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; +import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent; +import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; +import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 管理zlm流媒体节点的状态 + */ +@Component +public class ABLMediaServerStatusManger { + + private final static Logger logger = LoggerFactory.getLogger(ABLMediaServerStatusManger.class); + + private final Map offlineABLPrimaryMap = new ConcurrentHashMap<>(); + private final Map offlineAblsecondaryMap = new ConcurrentHashMap<>(); + private final Map offlineAblTimeMap = new ConcurrentHashMap<>(); + + @Autowired + private ABLRESTfulUtils ablResTfulUtils; + + @Autowired + private IMediaServerService mediaServerService; + + @Autowired + private DynamicTask dynamicTask; + + @Value("${server.ssl.enabled:false}") + private boolean sslEnabled; + + @Value("${server.port}") + private Integer serverPort; + + @Autowired + private UserSetting userSetting; + + private final String type = "abl"; + + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaServerChangeEvent event) { + if (event.getMediaServerItemList() == null + || event.getMediaServerItemList().isEmpty()) { + return; + } + for (MediaServer mediaServerItem : event.getMediaServerItemList()) { + if (!type.equals(mediaServerItem.getType())) { + continue; + } + logger.info("[ABL-添加待上线节点] ID:" + mediaServerItem.getId()); + offlineABLPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); + offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + } + } + + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(HookAblServerStartEvent event) { + if (event.getMediaServerItem() == null + || !type.equals(event.getMediaServerItem().getType()) + || event.getMediaServerItem().isStatus()) { + return; + } + MediaServer serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); + if (serverItem == null) { + return; + } + logger.info("[ABL-HOOK事件-服务启动] ID:" + event.getMediaServerItem().getId()); + online(serverItem, null); + } + + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(HookAblServerKeepaliveEvent event) { + if (event.getMediaServerItem() == null) { + return; + } + MediaServer serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); + if (serverItem == null) { + return; + } + logger.info("[ABL-HOOK事件-心跳] ID:" + event.getMediaServerItem().getId()); + online(serverItem, null); + } + + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaServerDeleteEvent event) { + if (event.getMediaServerId() == null) { + return; + } + logger.info("[ABL-节点被移除] ID:" + event.getMediaServerId()); + offlineABLPrimaryMap.remove(event.getMediaServerId()); + offlineAblsecondaryMap.remove(event.getMediaServerId()); + offlineAblTimeMap.remove(event.getMediaServerId()); + } + + @Scheduled(fixedDelay = 10*1000) //每隔10秒检查一次 + public void execute(){ + // 初次加入的离线节点会在30分钟内,每间隔十秒尝试一次,30分钟后如果仍然没有上线,则每隔30分钟尝试一次连接 + if (offlineABLPrimaryMap.isEmpty() && offlineAblsecondaryMap.isEmpty()) { + return; + } + if (!offlineABLPrimaryMap.isEmpty()) { + for (MediaServer mediaServerItem : offlineABLPrimaryMap.values()) { + if (offlineAblTimeMap.get(mediaServerItem.getId()) < System.currentTimeMillis() - 30*60*1000) { + offlineAblsecondaryMap.put(mediaServerItem.getId(), mediaServerItem); + offlineABLPrimaryMap.remove(mediaServerItem.getId()); + continue; + } + logger.info("[ABL-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + JSONObject responseJson = ablResTfulUtils.getMediaServerConfig(mediaServerItem); + AblServerConfig ablServerConfig = null; + if (responseJson == null) { + logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + continue; + } + JSONArray data = responseJson.getJSONArray("data"); + if (data == null || data.isEmpty()) { + logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + }else { + ablServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), AblServerConfig.class); + initPort(mediaServerItem, ablServerConfig); + online(mediaServerItem, ablServerConfig); + } + } + } + if (!offlineAblsecondaryMap.isEmpty()) { + for (MediaServer mediaServerItem : offlineAblsecondaryMap.values()) { + if (offlineAblTimeMap.get(mediaServerItem.getId()) < System.currentTimeMillis() - 30*60*1000) { + continue; + } + logger.info("[ABL-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + JSONObject responseJson = ablResTfulUtils.getMediaServerConfig(mediaServerItem); + ZLMServerConfig zlmServerConfig = null; + if (responseJson == null) { + logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + continue; + } + JSONArray data = responseJson.getJSONArray("data"); + if (data == null || data.isEmpty()) { + logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + }else { + zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); + initPort(mediaServerItem, zlmServerConfig); + online(mediaServerItem, zlmServerConfig); + } + } + } + } + + private void online(MediaServer mediaServerItem, AblServerConfig config) { + offlineABLPrimaryMap.remove(mediaServerItem.getId()); + offlineAblsecondaryMap.remove(mediaServerItem.getId()); + offlineAblTimeMap.remove(mediaServerItem.getId()); + if (!mediaServerItem.isStatus()) { + logger.info("[ABL-连接成功] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + mediaServerItem.setStatus(true); + mediaServerItem.setHookAliveInterval(10F); + mediaServerService.update(mediaServerItem); + if(mediaServerItem.isAutoConfig()) { + if (config == null) { + JSONObject responseJSON = ablResTfulUtils.getMediaServerConfig(mediaServerItem); + JSONArray data = responseJSON.getJSONArray("data"); + if (data != null && !data.isEmpty()) { + config = JSON.parseObject(JSON.toJSONString(data.get(0)), AblServerConfig.class); + } + } + if (config != null) { + initPort(mediaServerItem, config); + setZLMConfig(mediaServerItem, "0".equals(config.getHookEnable()) + || !Objects.equals(mediaServerItem.getHookAliveInterval(), config.getHookAliveInterval())); + } + } + mediaServerService.update(mediaServerItem); + } + // 设置两次心跳未收到则认为zlm离线 + String key = "ABL-keepalive-" + mediaServerItem.getId(); + dynamicTask.startDelay(key, ()->{ + logger.warn("[ABL-心跳超时] ID:{}", mediaServerItem.getId()); + mediaServerItem.setStatus(false); + offlineABLPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); + offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + // TODO 发送离线通知 + mediaServerService.update(mediaServerItem); + }, (int)(mediaServerItem.getHookAliveInterval() * 2 * 1000)); + } + private void initPort(MediaServer mediaServerItem, AblServerConfig ablServerConfig) { + // 端口只会从配置中读取一次,一旦自己配置或者读取过了将不在配置 + if (mediaServerItem.getHttpSSlPort() == 0) { + mediaServerItem.setHttpSSlPort(ablServerConfig.getHttpSSLport()); + } + if (mediaServerItem.getRtmpPort() == 0) { + mediaServerItem.setRtmpPort(ablServerConfig.getRtmpPort()); + } + if (mediaServerItem.getRtmpSSlPort() == 0) { + mediaServerItem.setRtmpSSlPort(ablServerConfig.getRtmpSslPort()); + } + if (mediaServerItem.getRtspPort() == 0) { + mediaServerItem.setRtspPort(ablServerConfig.getRtspPort()); + } + if (mediaServerItem.getRtspSSLPort() == 0) { + mediaServerItem.setRtspSSLPort(ablServerConfig.getRtspSSlport()); + } + if (mediaServerItem.getRtpProxyPort() == 0) { + mediaServerItem.setRtpProxyPort(ablServerConfig.getRtpProxyPort()); + } + mediaServerItem.setHookAliveInterval(10F); + } + + public void setZLMConfig(MediaServer mediaServerItem, boolean restart) { + logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + String protocol = sslEnabled ? "https" : "http"; + String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); + + Map param = new HashMap<>(); + param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline + if (mediaServerItem.getRtspPort() != 0) { + param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); + } + param.put("hook.enable","1"); + param.put("hook.on_flow_report",""); + param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); + param.put("hook.on_http_access",""); + param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); + param.put("hook.on_record_ts",""); + param.put("hook.on_rtsp_auth",""); + param.put("hook.on_rtsp_realm",""); + param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); + param.put("hook.on_shell_login",""); + param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); + param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); + param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); + param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); + param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); + param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); + param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); + param.put("hook.timeoutSec","30"); + param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); + // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 + // 置0关闭此特性(推流断开会导致立即断开播放器) + // 此参数不应大于播放器超时时间 + // 优化此消息以更快的收到流注销事件 + param.put("protocol.continue_push_ms", "3000" ); + // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, + // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 + if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { + param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); + } + + if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { + File recordPathFile = new File(mediaServerItem.getRecordPath()); + param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); + param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); + param.put("record.appName", recordPathFile.getName()); + } + + JSONObject responseJSON = ablResTfulUtils.setServerConfig(mediaServerItem, param); + + if (responseJSON != null && responseJSON.getInteger("code") == 0) { + if (restart) { + logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + ablResTfulUtils.restartServer(mediaServerItem); + }else { + logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + } + }else { + logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + } + } + +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java new file mode 100755 index 000000000..ce9432494 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java @@ -0,0 +1,403 @@ +package com.genersoft.iot.vmp.media.abl; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import okhttp3.*; +import okhttp3.logging.HttpLoggingInterceptor; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +@Component +public class ABLRESTfulUtils { + + private final static Logger logger = LoggerFactory.getLogger(ABLRESTfulUtils.class); + + private OkHttpClient client; + + public interface RequestCallback{ + void run(JSONObject response); + } + + private OkHttpClient getClient(){ + return getClient(null); + } + + private OkHttpClient getClient(Integer readTimeOut){ + if (client == null) { + if (readTimeOut == null) { + readTimeOut = 10; + } + OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); + //todo 暂时写死超时时间 均为5s + // 设置连接超时时间 + httpClientBuilder.connectTimeout(8,TimeUnit.SECONDS); + // 设置读取超时时间 + httpClientBuilder.readTimeout(readTimeOut,TimeUnit.SECONDS); + // 设置连接池 + httpClientBuilder.connectionPool(new ConnectionPool(16, 5, TimeUnit.MINUTES)); + if (logger.isDebugEnabled()) { + HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> { + logger.debug("http请求参数:" + message); + }); + logging.setLevel(HttpLoggingInterceptor.Level.BASIC); + // OkHttp進行添加攔截器loggingInterceptor + httpClientBuilder.addInterceptor(logging); + } + client = httpClientBuilder.build(); + } + return client; + + } + + public JSONObject sendPost(MediaServer mediaServerItem, String api, Map param, RequestCallback callback) { + return sendPost(mediaServerItem, api, param, callback, null); + } + + + public JSONObject sendPost(MediaServer mediaServerItem, String api, Map param, RequestCallback callback, Integer readTimeOut) { + OkHttpClient client = getClient(readTimeOut); + + if (mediaServerItem == null) { + return null; + } + String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); + JSONObject responseJSON = new JSONObject(); + //-2自定义流媒体 调用错误码 + responseJSON.put("code",-2); + responseJSON.put("msg","流媒体调用失败"); + + FormBody.Builder builder = new FormBody.Builder(); + builder.add("secret",mediaServerItem.getSecret()); + if (param != null && param.keySet().size() > 0) { + for (String key : param.keySet()){ + if (param.get(key) != null) { + builder.add(key, param.get(key).toString()); + } + } + } + + FormBody body = builder.build(); + + Request request = new Request.Builder() + .post(body) + .url(url) + .build(); + if (callback == null) { + try { + Response response = client.newCall(request).execute(); + + if (response.isSuccessful()) { + ResponseBody responseBody = response.body(); + if (responseBody != null) { + String responseStr = responseBody.string(); + responseJSON = JSON.parseObject(responseStr); + } + }else { + System.out.println( 2222); + System.out.println( response.code()); + response.close(); + Objects.requireNonNull(response.body()).close(); + } + }catch (IOException e) { + logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); + + if(e instanceof SocketTimeoutException){ + //读取超时超时异常 + logger.error(String.format("读取ZLM数据超时失败: %s, %s", url, e.getMessage())); + } + if(e instanceof ConnectException){ + //判断连接异常,我这里是报Failed to connect to 10.7.5.144 + logger.error(String.format("连接ZLM连接失败: %s, %s", url, e.getMessage())); + } + + }catch (Exception e){ + logger.error(String.format("访问ZLM失败: %s, %s", url, e.getMessage())); + } + }else { + client.newCall(request).enqueue(new Callback(){ + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response){ + if (response.isSuccessful()) { + try { + String responseStr = Objects.requireNonNull(response.body()).string(); + callback.run(JSON.parseObject(responseStr)); + } catch (IOException e) { + logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); + } + + }else { + response.close(); + Objects.requireNonNull(response.body()).close(); + } + } + + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + logger.error(String.format("连接ZLM失败: %s, %s", call.request().toString(), e.getMessage())); + + if(e instanceof SocketTimeoutException){ + //读取超时超时异常 + logger.error(String.format("读取ZLM数据失败: %s, %s", call.request().toString(), e.getMessage())); + } + if(e instanceof ConnectException){ + //判断连接异常,我这里是报Failed to connect to 10.7.5.144 + logger.error(String.format("连接ZLM失败: %s, %s", call.request().toString(), e.getMessage())); + } + } + }); + } + + + + return responseJSON; + } + + public void sendGetForImg(MediaServer mediaServerItem, String api, Map params, String targetPath, String fileName) { + String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); + HttpUrl parseUrl = HttpUrl.parse(url); + if (parseUrl == null) { + return; + } + HttpUrl.Builder httpBuilder = parseUrl.newBuilder(); + + httpBuilder.addQueryParameter("secret", mediaServerItem.getSecret()); + if (params != null) { + for (Map.Entry param : params.entrySet()) { + httpBuilder.addQueryParameter(param.getKey(), param.getValue().toString()); + } + } + + Request request = new Request.Builder() + .url(httpBuilder.build()) + .build(); + logger.info(request.toString()); + try { + OkHttpClient client = getClient(); + Response response = client.newCall(request).execute(); + if (response.isSuccessful()) { + if (targetPath != null) { + File snapFolder = new File(targetPath); + if (!snapFolder.exists()) { + if (!snapFolder.mkdirs()) { + logger.warn("{}路径创建失败", snapFolder.getAbsolutePath()); + } + + } + File snapFile = new File(targetPath + File.separator + fileName); + FileOutputStream outStream = new FileOutputStream(snapFile); + + outStream.write(Objects.requireNonNull(response.body()).bytes()); + outStream.flush(); + outStream.close(); + } else { + logger.error(String.format("[ %s ]请求失败: %s %s", url, response.code(), response.message())); + } + } else { + logger.error(String.format("[ %s ]请求失败: %s %s", url, response.code(), response.message())); + } + Objects.requireNonNull(response.body()).close(); + } catch (ConnectException e) { + logger.error(String.format("连接ZLM失败: %s, %s", e.getCause().getMessage(), e.getMessage())); + logger.info("请检查media配置并确认ZLM已启动..."); + } catch (IOException e) { + logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); + } + } + + public JSONObject getMediaList(MediaServer mediaServerItem, String app, String stream, String schema, RequestCallback callback){ + Map param = new HashMap<>(); + if (app != null) { + param.put("app",app); + } + if (stream != null) { + param.put("stream",stream); + } + if (schema != null) { + param.put("schema",schema); + } + param.put("vhost","__defaultVhost__"); + return sendPost(mediaServerItem, "getMediaList",param, callback); + } + + public JSONObject getMediaList(MediaServer mediaServerItem, String app, String stream){ + return getMediaList(mediaServerItem, app, stream,null, null); + } + + public JSONObject getMediaList(MediaServer mediaServerItem, RequestCallback callback){ + return sendPost(mediaServerItem, "getMediaList",null, callback); + } + + public JSONObject getMediaInfo(MediaServer mediaServerItem, String app, String schema, String stream){ + Map param = new HashMap<>(); + param.put("app",app); + param.put("schema",schema); + param.put("stream",stream); + param.put("vhost","__defaultVhost__"); + return sendPost(mediaServerItem, "getMediaInfo",param, null); + } + + public JSONObject getRtpInfo(MediaServer mediaServerItem, String stream_id){ + Map param = new HashMap<>(); + param.put("stream_id",stream_id); + return sendPost(mediaServerItem, "getRtpInfo",param, null); + } + + public JSONObject addFFmpegSource(MediaServer mediaServerItem, String src_url, String dst_url, Integer timeout_ms, + boolean enable_audio, boolean enable_mp4, String ffmpeg_cmd_key){ + logger.info(src_url); + logger.info(dst_url); + Map param = new HashMap<>(); + param.put("src_url", src_url); + param.put("dst_url", dst_url); + param.put("timeout_ms", timeout_ms); + param.put("enable_mp4", enable_mp4); + param.put("ffmpeg_cmd_key", ffmpeg_cmd_key); + return sendPost(mediaServerItem, "addFFmpegSource",param, null); + } + + public JSONObject delFFmpegSource(MediaServer mediaServerItem, String key){ + Map param = new HashMap<>(); + param.put("key", key); + return sendPost(mediaServerItem, "delFFmpegSource",param, null); + } + + public JSONObject delStreamProxy(MediaServer mediaServerItem, String key){ + Map param = new HashMap<>(); + param.put("key", key); + return sendPost(mediaServerItem, "delStreamProxy",param, null); + } + + public JSONObject getMediaServerConfig(MediaServer mediaServerItem){ + return sendPost(mediaServerItem, "getServerConfig",null, null); + } + + public JSONObject setServerConfig(MediaServer mediaServerItem, Map param){ + return sendPost(mediaServerItem,"setServerConfig",param, null); + } + + public JSONObject openRtpServer(MediaServer mediaServerItem, Map param){ + return sendPost(mediaServerItem, "openRtpServer",param, null); + } + + public JSONObject closeRtpServer(MediaServer mediaServerItem, Map param) { + return sendPost(mediaServerItem, "closeRtpServer",param, null); + } + + public void closeRtpServer(MediaServer mediaServerItem, Map param, RequestCallback callback) { + sendPost(mediaServerItem, "closeRtpServer",param, callback); + } + + public JSONObject listRtpServer(MediaServer mediaServerItem) { + return sendPost(mediaServerItem, "listRtpServer",null, null); + } + + public JSONObject startSendRtp(MediaServer mediaServerItem, Map param) { + return sendPost(mediaServerItem, "startSendRtp",param, null); + } + + public JSONObject startSendRtpPassive(MediaServer mediaServerItem, Map param) { + return sendPost(mediaServerItem, "startSendRtpPassive",param, null); + } + + public JSONObject startSendRtpPassive(MediaServer mediaServerItem, Map param, RequestCallback callback) { + return sendPost(mediaServerItem, "startSendRtpPassive",param, callback); + } + + public JSONObject stopSendRtp(MediaServer mediaServerItem, Map param) { + return sendPost(mediaServerItem, "stopSendRtp",param, null); + } + + public JSONObject restartServer(MediaServer mediaServerItem) { + return sendPost(mediaServerItem, "restartServer",null, null); + } + + public JSONObject addStreamProxy(MediaServer mediaServerItem, String app, String stream, String url, boolean enable_audio, boolean enable_mp4, String rtp_type) { + Map param = new HashMap<>(); + param.put("vhost", "__defaultVhost__"); + param.put("app", app); + param.put("stream", stream); + param.put("url", url); + param.put("enable_mp4", enable_mp4?1:0); + param.put("enable_audio", enable_audio?1:0); + param.put("rtp_type", rtp_type); + return sendPost(mediaServerItem, "addStreamProxy",param, null, 20); + } + + public JSONObject closeStreams(MediaServer mediaServerItem, String app, String stream) { + Map param = new HashMap<>(); + param.put("vhost", "__defaultVhost__"); + param.put("app", app); + param.put("stream", stream); + param.put("force", 1); + return sendPost(mediaServerItem, "close_streams",param, null); + } + + public JSONObject getAllSession(MediaServer mediaServerItem) { + return sendPost(mediaServerItem, "getAllSession",null, null); + } + + public void kickSessions(MediaServer mediaServerItem, String localPortSStr) { + Map param = new HashMap<>(); + param.put("local_port", localPortSStr); + sendPost(mediaServerItem, "kick_sessions",param, null); + } + + public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { + Map param = new HashMap<>(3); + param.put("url", streamUrl); + param.put("timeout_sec", timeout_sec); + param.put("expire_sec", expire_sec); + sendGetForImg(mediaServerItem, "getSnap", param, targetPath, fileName); + } + + public JSONObject pauseRtpCheck(MediaServer mediaServerItem, String streamId) { + Map param = new HashMap<>(1); + param.put("stream_id", streamId); + return sendPost(mediaServerItem, "pauseRtpCheck",param, null); + } + + public JSONObject resumeRtpCheck(MediaServer mediaServerItem, String streamId) { + Map param = new HashMap<>(1); + param.put("stream_id", streamId); + return sendPost(mediaServerItem, "resumeRtpCheck",param, null); + } + + public JSONObject connectRtpServer(MediaServer mediaServerItem, String dst_url, int dst_port, String stream_id) { + Map param = new HashMap<>(1); + param.put("dst_url", dst_url); + param.put("dst_port", dst_port); + param.put("stream_id", stream_id); + return sendPost(mediaServerItem, "connectRtpServer",param, null); + } + + public JSONObject updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { + Map param = new HashMap<>(1); + param.put("ssrc", ssrc); + param.put("stream_id", streamId); + return sendPost(mediaServerItem, "updateRtpServerSSRC",param, null); + } + + public JSONObject deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { + Map param = new HashMap<>(1); + param.put("vhost", "__defaultVhost__"); + param.put("app", app); + param.put("stream", stream); + param.put("period", date); + param.put("name", fileName); + return sendPost(mediaServerItem, "deleteRecordDirectory",param, null); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java new file mode 100644 index 000000000..489832657 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java @@ -0,0 +1,4 @@ +package com.genersoft.iot.vmp.media.abl.bean; + +public class AblServerConfig { +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java new file mode 100644 index 000000000..bbedd6dfa --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java @@ -0,0 +1,24 @@ +package com.genersoft.iot.vmp.media.abl.event; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import org.springframework.context.ApplicationEvent; + +/** + * zlm 心跳事件 + */ +public class HookAblServerKeepaliveEvent extends ApplicationEvent { + + public HookAblServerKeepaliveEvent(Object source) { + super(source); + } + + private MediaServer mediaServerItem; + + public MediaServer getMediaServerItem() { + return mediaServerItem; + } + + public void setMediaServerItem(MediaServer mediaServerItem) { + this.mediaServerItem = mediaServerItem; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java new file mode 100644 index 000000000..4e1960e23 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java @@ -0,0 +1,24 @@ +package com.genersoft.iot.vmp.media.abl.event; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import org.springframework.context.ApplicationEvent; + +/** + * zlm server_start事件 + */ +public class HookAblServerStartEvent extends ApplicationEvent { + + public HookAblServerStartEvent(Object source) { + super(source); + } + + private MediaServer mediaServerItem; + + public MediaServer getMediaServerItem() { + return mediaServerItem; + } + + public void setMediaServerItem(MediaServer mediaServerItem) { + this.mediaServerItem = mediaServerItem; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 01fc6358b..a247a78b1 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -142,14 +142,6 @@ public class ZLMHttpHookListener { @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { - taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); - if (subscribes != null && !subscribes.isEmpty()) { - for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { - subscribe.response(null, param); - } - } - }); try { HookZlmServerKeepaliveEvent event = new HookZlmServerKeepaliveEvent(this); MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); @@ -184,6 +176,7 @@ public class ZLMHttpHookListener { } } }); + // TODO 此处逻辑适合迁移到MediaService中 if (!"rtp".equals(param.getApp())) { Map paramMap = urlParamToMap(param.getParams()); StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); @@ -208,8 +201,8 @@ public class ZLMHttpHookListener { // TODO 加快处理速度 String mediaServerId = json.getString("mediaServerId"); - MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); - if (mediaInfo == null) { + MediaServer mediaServer = mediaServerService.getOne(mediaServerId); + if (mediaServer == null) { return new HookResultForOnPublish(200, "success"); } // 推流鉴权的处理 @@ -257,7 +250,7 @@ public class ZLMHttpHookListener { taskExecutor.execute(() -> { ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); if (subscribe != null) { - subscribe.response(mediaInfo, param); + subscribe.response(mediaServer, param); } }); @@ -273,7 +266,7 @@ public class ZLMHttpHookListener { InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); // 单端口模式下修改流 ID - if (!mediaInfo.isRtpEnable() && inviteInfo == null) { + if (!mediaServer.isRtpEnable() && inviteInfo == null) { String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16)); inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc); if (inviteInfo != null) { From 999192fa8afd1a5739953db8dc875ca1d0b0d811 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Sat, 23 Mar 2024 23:40:32 +0800 Subject: [PATCH 18/58] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=AF=BB=E5=8F=96abl?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/abl/ABLHttpHookListener.java | 2 +- .../media/abl/ABLMediaServerStatusManger.java | 185 ++--- .../iot/vmp/media/abl/ABLRESTfulUtils.java | 2 +- .../vmp/media/abl/bean/AblServerConfig.java | 775 ++++++++++++++++++ .../iot/vmp/media/abl/bean/ConfigKeyId.java | 10 + 5 files changed, 878 insertions(+), 96 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/ConfigKeyId.java diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java index 026134acb..e3c19b1b3 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java @@ -60,7 +60,7 @@ import java.util.UUID; * ABL服务Hook事件 */ @RestController -@RequestMapping("/index/hook") +@RequestMapping("/index/hook/abl") public class ABLHttpHookListener { private final static Logger logger = LoggerFactory.getLogger(ABLHttpHookListener.class); diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java index 28181e89e..0d2f043c6 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.media.abl; -import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.DynamicTask; @@ -12,9 +11,6 @@ import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; -import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; -import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -28,7 +24,6 @@ import org.springframework.util.ObjectUtils; import java.io.File; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; /** @@ -136,17 +131,18 @@ public class ABLMediaServerStatusManger { continue; } logger.info("[ABL-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - JSONObject responseJson = ablResTfulUtils.getMediaServerConfig(mediaServerItem); + JSONObject responseJson = ablResTfulUtils.getServerConfig(mediaServerItem); AblServerConfig ablServerConfig = null; if (responseJson == null) { logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); continue; } - JSONArray data = responseJson.getJSONArray("data"); + JSONArray data = responseJson.getJSONArray("params"); if (data == null || data.isEmpty()) { logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); }else { - ablServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), AblServerConfig.class); +// ablServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), AblServerConfig.class); + ablServerConfig = AblServerConfig.getInstance(data); initPort(mediaServerItem, ablServerConfig); online(mediaServerItem, ablServerConfig); } @@ -158,21 +154,22 @@ public class ABLMediaServerStatusManger { continue; } logger.info("[ABL-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - JSONObject responseJson = ablResTfulUtils.getMediaServerConfig(mediaServerItem); - ZLMServerConfig zlmServerConfig = null; + JSONObject responseJson = ablResTfulUtils.getServerConfig(mediaServerItem); + AblServerConfig ablServerConfig = null; if (responseJson == null) { logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); continue; } - JSONArray data = responseJson.getJSONArray("data"); + JSONArray data = responseJson.getJSONArray("params"); if (data == null || data.isEmpty()) { logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); }else { - zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); - initPort(mediaServerItem, zlmServerConfig); - online(mediaServerItem, zlmServerConfig); +// ablServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); + ablServerConfig = AblServerConfig.getInstance(data); + initPort(mediaServerItem, ablServerConfig); + online(mediaServerItem, ablServerConfig); } } } @@ -189,16 +186,16 @@ public class ABLMediaServerStatusManger { mediaServerService.update(mediaServerItem); if(mediaServerItem.isAutoConfig()) { if (config == null) { - JSONObject responseJSON = ablResTfulUtils.getMediaServerConfig(mediaServerItem); - JSONArray data = responseJSON.getJSONArray("data"); + JSONObject responseJSON = ablResTfulUtils.getServerConfig(mediaServerItem); + JSONArray data = responseJSON.getJSONArray("params"); if (data != null && !data.isEmpty()) { - config = JSON.parseObject(JSON.toJSONString(data.get(0)), AblServerConfig.class); +// config = JSON.parseObject(JSON.toJSONString(data.get(0)), AblServerConfig.class); + config = AblServerConfig.getInstance(data); } } if (config != null) { initPort(mediaServerItem, config); - setZLMConfig(mediaServerItem, "0".equals(config.getHookEnable()) - || !Objects.equals(mediaServerItem.getHookAliveInterval(), config.getHookAliveInterval())); + setAblConfig(mediaServerItem, false); } } mediaServerService.update(mediaServerItem); @@ -216,90 +213,90 @@ public class ABLMediaServerStatusManger { } private void initPort(MediaServer mediaServerItem, AblServerConfig ablServerConfig) { // 端口只会从配置中读取一次,一旦自己配置或者读取过了将不在配置 - if (mediaServerItem.getHttpSSlPort() == 0) { - mediaServerItem.setHttpSSlPort(ablServerConfig.getHttpSSLport()); - } +// if (mediaServerItem.getHttpSSlPort() == 0) { +// mediaServerItem.setHttpSSlPort(ablServerConfig.getHttpSSLport()); +// } if (mediaServerItem.getRtmpPort() == 0) { mediaServerItem.setRtmpPort(ablServerConfig.getRtmpPort()); } - if (mediaServerItem.getRtmpSSlPort() == 0) { - mediaServerItem.setRtmpSSlPort(ablServerConfig.getRtmpSslPort()); - } +// if (mediaServerItem.getRtmpSSlPort() == 0) { +// mediaServerItem.setRtmpSSlPort(ablServerConfig.getRtmpSslPort()); +// } if (mediaServerItem.getRtspPort() == 0) { mediaServerItem.setRtspPort(ablServerConfig.getRtspPort()); } - if (mediaServerItem.getRtspSSLPort() == 0) { - mediaServerItem.setRtspSSLPort(ablServerConfig.getRtspSSlport()); - } - if (mediaServerItem.getRtpProxyPort() == 0) { - mediaServerItem.setRtpProxyPort(ablServerConfig.getRtpProxyPort()); - } +// if (mediaServerItem.getRtspSSLPort() == 0) { +// mediaServerItem.setRtspSSLPort(ablServerConfig.getRtspSSlport()); +// } +// if (mediaServerItem.getRtpProxyPort() == 0) { +// mediaServerItem.setRtpProxyPort(ablServerConfig.getRtpProxyPort()); +// } mediaServerItem.setHookAliveInterval(10F); } - public void setZLMConfig(MediaServer mediaServerItem, boolean restart) { - logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - String protocol = sslEnabled ? "https" : "http"; - String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); - - Map param = new HashMap<>(); - param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline - if (mediaServerItem.getRtspPort() != 0) { - param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); - } - param.put("hook.enable","1"); - param.put("hook.on_flow_report",""); - param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); - param.put("hook.on_http_access",""); - param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); - param.put("hook.on_record_ts",""); - param.put("hook.on_rtsp_auth",""); - param.put("hook.on_rtsp_realm",""); - param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); - param.put("hook.on_shell_login",""); - param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); - param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); - param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); - param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); - param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); - param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); - param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); - param.put("hook.timeoutSec","30"); - param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); - // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 - // 置0关闭此特性(推流断开会导致立即断开播放器) - // 此参数不应大于播放器超时时间 - // 优化此消息以更快的收到流注销事件 - param.put("protocol.continue_push_ms", "3000" ); - // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, - // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 - if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { - param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); - } - - if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { - File recordPathFile = new File(mediaServerItem.getRecordPath()); - param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); - param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); - param.put("record.appName", recordPathFile.getName()); - } - - JSONObject responseJSON = ablResTfulUtils.setServerConfig(mediaServerItem, param); - - if (responseJSON != null && responseJSON.getInteger("code") == 0) { - if (restart) { - logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - ablResTfulUtils.restartServer(mediaServerItem); - }else { - logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - } - }else { - logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - } + public void setAblConfig(MediaServer mediaServerItem, boolean restart) { +// logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", +// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); +// String protocol = sslEnabled ? "https" : "http"; +// String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); +// +// Map param = new HashMap<>(); +// param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline +// if (mediaServerItem.getRtspPort() != 0) { +// param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); +// } +// param.put("hook.enable","1"); +// param.put("hook.on_flow_report",""); +// param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); +// param.put("hook.on_http_access",""); +// param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); +// param.put("hook.on_record_ts",""); +// param.put("hook.on_rtsp_auth",""); +// param.put("hook.on_rtsp_realm",""); +// param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); +// param.put("hook.on_shell_login",""); +// param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); +// param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); +// param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); +// param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); +// param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); +// param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); +// param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); +// param.put("hook.timeoutSec","30"); +// param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); +// // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 +// // 置0关闭此特性(推流断开会导致立即断开播放器) +// // 此参数不应大于播放器超时时间 +// // 优化此消息以更快的收到流注销事件 +// param.put("protocol.continue_push_ms", "3000" ); +// // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, +// // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 +// if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { +// param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); +// } +// +// if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { +// File recordPathFile = new File(mediaServerItem.getRecordPath()); +// param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); +// param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); +// param.put("record.appName", recordPathFile.getName()); +// } +// +// JSONObject responseJSON = ablResTfulUtils.setServerConfig(mediaServerItem, param); +// +// if (responseJSON != null && responseJSON.getInteger("code") == 0) { +// if (restart) { +// logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", +// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); +// ablResTfulUtils.restartServer(mediaServerItem); +// }else { +// logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", +// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); +// } +// }else { +// logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", +// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); +// } } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java index ce9432494..02a9b667b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java @@ -281,7 +281,7 @@ public class ABLRESTfulUtils { return sendPost(mediaServerItem, "delStreamProxy",param, null); } - public JSONObject getMediaServerConfig(MediaServer mediaServerItem){ + public JSONObject getServerConfig(MediaServer mediaServerItem){ return sendPost(mediaServerItem, "getServerConfig",null, null); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java index 489832657..e7aac3a78 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java @@ -1,4 +1,779 @@ package com.genersoft.iot.vmp.media.abl.bean; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + public class AblServerConfig { + + @ConfigKeyId("secret") + private String secret; + + @ConfigKeyId("ServerIP") + private String serverIp; + + @ConfigKeyId("mediaServerID") + private String mediaServerId; + + @ConfigKeyId("hook_enable") + private Integer hookEnable; + + @ConfigKeyId("enable_audio") + private Integer enableAudio; + + @ConfigKeyId("httpServerPort") + private Integer httpServerPort; + + @ConfigKeyId("rtspPort") + private Integer rtspPort; + + @ConfigKeyId("rtmpPort") + private Integer rtmpPort; + + @ConfigKeyId("httpFlvPort") + private Integer httpFlvPort; + + @ConfigKeyId("hls_enable") + private Integer hlsEnable; + + @ConfigKeyId("hlsPort") + private Integer hlsPort; + + @ConfigKeyId("wsPort") + private Integer wsPort; + + @ConfigKeyId("mp4Port") + private Integer mp4Port; + + @ConfigKeyId("ps_tsRecvPort") + private Integer psTsRecvPort; + + @ConfigKeyId("hlsCutType") + private Integer hlsCutType; + + @ConfigKeyId("h265CutType") + private Integer h265CutType; + + @ConfigKeyId("RecvThreadCount") + private Integer RecvThreadCount; + + @ConfigKeyId("SendThreadCount") + private Integer SendThreadCount; + + @ConfigKeyId("GB28181RtpTCPHeadType") + private Integer GB28181RtpTCPHeadType; + + @ConfigKeyId("ReConnectingCount") + private Integer ReConnectingCount; + + @ConfigKeyId("maxTimeNoOneWatch") + private Integer maxTimeNoOneWatch; + + @ConfigKeyId("pushEnable_mp4") + private Integer pushEnableMp4; + + @ConfigKeyId("fileSecond") + private Integer fileSecond; + + @ConfigKeyId("fileKeepMaxTime") + private Integer fileKeepMaxTime; + + @ConfigKeyId("httpDownloadSpeed") + private Integer httpDownloadSpeed; + + @ConfigKeyId("RecordReplayThread") + private Integer RecordReplayThread; + + @ConfigKeyId("convertMaxObject") + private Integer convertMaxObject; + + @ConfigKeyId("version") + private String version; + + @ConfigKeyId("recordPath") + private String recordPath; + + @ConfigKeyId("picturePath") + private String picturePath; + + @ConfigKeyId("noneReaderDuration") + private Integer noneReaderDuration; + + @ConfigKeyId("on_server_started") + private String onServerStarted; + + @ConfigKeyId("on_server_keepalive") + private String onServerKeepalive; + + @ConfigKeyId("on_play") + private String onPlay; + + @ConfigKeyId("on_publish") + private String onPublish; + + @ConfigKeyId("on_stream_arrive") + private String onStreamArrive; + + @ConfigKeyId("on_stream_not_arrive") + private String onStreamNotArrive; + + @ConfigKeyId("on_stream_none_reader") + private String onStreamNoneReader; + + @ConfigKeyId("on_stream_disconnect") + private String onStreamDisconnect; + + @ConfigKeyId("on_delete_record_mp4") + private String onDeleteRecordMp4; + + @ConfigKeyId("on_record_progress") + private String onRecordProgress; + + @ConfigKeyId("on_record_ts") + private String onRecordTs; + + @ConfigKeyId("enable_GetFileDuration") + private Integer enableGetFileDuration; + + @ConfigKeyId("keepaliveDuration") + private Integer keepaliveDuration; + + @ConfigKeyId("captureReplayType") + private Integer captureReplayType; + + @ConfigKeyId("videoFileFormat") + private Integer videoFileFormat; + + @ConfigKeyId("MaxDiconnectTimeoutSecond") + private Integer maxDiconnectTimeoutSecond; + + @ConfigKeyId("G711ConvertAAC") + private Integer g711ConvertAAC; + + @ConfigKeyId("filterVideo_enable") + private Integer filterVideoEnable; + + @ConfigKeyId("filterVideo_text") + private String filterVideoText; + + @ConfigKeyId("FilterFontSize") + private Integer filterFontSize; + + @ConfigKeyId("FilterFontColor") + private String filterFontColor; + + @ConfigKeyId("FilterFontLeft") + private Integer filterFontLeft; + + @ConfigKeyId("FilterFontTop") + private Integer filterFontTop; + + @ConfigKeyId("FilterFontAlpha") + private Double filterFontAlpha; + + @ConfigKeyId("convertOutWidth") + private Integer convertOutWidth; + + @ConfigKeyId("convertOutHeight") + private Integer convertOutHeight; + + @ConfigKeyId("convertOutBitrate") + private Integer convertOutBitrate; + + @ConfigKeyId("flvPlayAddMute") + private Integer flvPlayAddMute; + + @ConfigKeyId("gb28181LibraryUse") + private Integer gb28181LibraryUse; + + @ConfigKeyId("rtc.listening-ip") + private String rtcListeningIp; + + @ConfigKeyId("rtc.listening-port") + private Integer rtcListeningIpPort; + + @ConfigKeyId("rtc.external-ip") + private String rtcExternalIp; + + @ConfigKeyId("rtc.realm") + private String rtcRealm; + + @ConfigKeyId("rtc.user") + private String rtcUser; + + @ConfigKeyId("rtc.min-port") + private Integer rtcMinPort; + + @ConfigKeyId("rtc.max-port") + private Integer rtcMaxPort; + + public static AblServerConfig getInstance(JSONArray jsonArray) { + if (jsonArray == null || jsonArray.isEmpty()) { + return null; + } + AblServerConfig ablServerConfig = new AblServerConfig(); + Field[] fields = AblServerConfig.class.getDeclaredFields(); + Map fieldMap = new HashMap<>(); + for (Field field : fields) { + if (field.isAnnotationPresent(ConfigKeyId.class)) { + ConfigKeyId configKeyId = field.getAnnotation(ConfigKeyId.class); + fieldMap.put(configKeyId.value(), field); + } + } + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + if (jsonObject == null) { + continue; + } + for (String key : fieldMap.keySet()) { + if (jsonObject.containsKey(key)) { + Field field = fieldMap.get(key); + field.setAccessible(true); + try { + field.set(ablServerConfig, jsonObject.getObject(key, fieldMap.get(key).getType())); + } catch (IllegalAccessException e) {} + } + } + } + return ablServerConfig; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public String getServerIp() { + return serverIp; + } + + public void setServerIp(String serverIp) { + this.serverIp = serverIp; + } + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } + + public Integer getHookEnable() { + return hookEnable; + } + + public void setHookEnable(Integer hookEnable) { + this.hookEnable = hookEnable; + } + + public Integer getEnableAudio() { + return enableAudio; + } + + public void setEnableAudio(Integer enableAudio) { + this.enableAudio = enableAudio; + } + + public Integer getHttpServerPort() { + return httpServerPort; + } + + public void setHttpServerPort(Integer httpServerPort) { + this.httpServerPort = httpServerPort; + } + + public Integer getRtspPort() { + return rtspPort; + } + + public void setRtspPort(Integer rtspPort) { + this.rtspPort = rtspPort; + } + + public Integer getRtmpPort() { + return rtmpPort; + } + + public void setRtmpPort(Integer rtmpPort) { + this.rtmpPort = rtmpPort; + } + + public Integer getHttpFlvPort() { + return httpFlvPort; + } + + public void setHttpFlvPort(Integer httpFlvPort) { + this.httpFlvPort = httpFlvPort; + } + + public Integer getHlsEnable() { + return hlsEnable; + } + + public void setHlsEnable(Integer hlsEnable) { + this.hlsEnable = hlsEnable; + } + + public Integer getHlsPort() { + return hlsPort; + } + + public void setHlsPort(Integer hlsPort) { + this.hlsPort = hlsPort; + } + + public Integer getWsPort() { + return wsPort; + } + + public void setWsPort(Integer wsPort) { + this.wsPort = wsPort; + } + + public Integer getMp4Port() { + return mp4Port; + } + + public void setMp4Port(Integer mp4Port) { + this.mp4Port = mp4Port; + } + + public Integer getPsTsRecvPort() { + return psTsRecvPort; + } + + public void setPsTsRecvPort(Integer psTsRecvPort) { + this.psTsRecvPort = psTsRecvPort; + } + + public Integer getHlsCutType() { + return hlsCutType; + } + + public void setHlsCutType(Integer hlsCutType) { + this.hlsCutType = hlsCutType; + } + + public Integer getH265CutType() { + return h265CutType; + } + + public void setH265CutType(Integer h265CutType) { + this.h265CutType = h265CutType; + } + + public Integer getRecvThreadCount() { + return RecvThreadCount; + } + + public void setRecvThreadCount(Integer recvThreadCount) { + RecvThreadCount = recvThreadCount; + } + + public Integer getSendThreadCount() { + return SendThreadCount; + } + + public void setSendThreadCount(Integer sendThreadCount) { + SendThreadCount = sendThreadCount; + } + + public Integer getGB28181RtpTCPHeadType() { + return GB28181RtpTCPHeadType; + } + + public void setGB28181RtpTCPHeadType(Integer GB28181RtpTCPHeadType) { + this.GB28181RtpTCPHeadType = GB28181RtpTCPHeadType; + } + + public Integer getReConnectingCount() { + return ReConnectingCount; + } + + public void setReConnectingCount(Integer reConnectingCount) { + ReConnectingCount = reConnectingCount; + } + + public Integer getMaxTimeNoOneWatch() { + return maxTimeNoOneWatch; + } + + public void setMaxTimeNoOneWatch(Integer maxTimeNoOneWatch) { + this.maxTimeNoOneWatch = maxTimeNoOneWatch; + } + + public Integer getPushEnableMp4() { + return pushEnableMp4; + } + + public void setPushEnableMp4(Integer pushEnableMp4) { + this.pushEnableMp4 = pushEnableMp4; + } + + public Integer getFileSecond() { + return fileSecond; + } + + public void setFileSecond(Integer fileSecond) { + this.fileSecond = fileSecond; + } + + public Integer getFileKeepMaxTime() { + return fileKeepMaxTime; + } + + public void setFileKeepMaxTime(Integer fileKeepMaxTime) { + this.fileKeepMaxTime = fileKeepMaxTime; + } + + public Integer getHttpDownloadSpeed() { + return httpDownloadSpeed; + } + + public void setHttpDownloadSpeed(Integer httpDownloadSpeed) { + this.httpDownloadSpeed = httpDownloadSpeed; + } + + public Integer getRecordReplayThread() { + return RecordReplayThread; + } + + public void setRecordReplayThread(Integer recordReplayThread) { + RecordReplayThread = recordReplayThread; + } + + public Integer getConvertMaxObject() { + return convertMaxObject; + } + + public void setConvertMaxObject(Integer convertMaxObject) { + this.convertMaxObject = convertMaxObject; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getRecordPath() { + return recordPath; + } + + public void setRecordPath(String recordPath) { + this.recordPath = recordPath; + } + + public String getPicturePath() { + return picturePath; + } + + public void setPicturePath(String picturePath) { + this.picturePath = picturePath; + } + + public Integer getNoneReaderDuration() { + return noneReaderDuration; + } + + public void setNoneReaderDuration(Integer noneReaderDuration) { + this.noneReaderDuration = noneReaderDuration; + } + + public String getOnServerStarted() { + return onServerStarted; + } + + public void setOnServerStarted(String onServerStarted) { + this.onServerStarted = onServerStarted; + } + + public String getOnServerKeepalive() { + return onServerKeepalive; + } + + public void setOnServerKeepalive(String onServerKeepalive) { + this.onServerKeepalive = onServerKeepalive; + } + + public String getOnPlay() { + return onPlay; + } + + public void setOnPlay(String onPlay) { + this.onPlay = onPlay; + } + + public String getOnPublish() { + return onPublish; + } + + public void setOnPublish(String onPublish) { + this.onPublish = onPublish; + } + + public String getOnStreamArrive() { + return onStreamArrive; + } + + public void setOnStreamArrive(String onStreamArrive) { + this.onStreamArrive = onStreamArrive; + } + + public String getOnStreamNotArrive() { + return onStreamNotArrive; + } + + public void setOnStreamNotArrive(String onStreamNotArrive) { + this.onStreamNotArrive = onStreamNotArrive; + } + + public String getOnStreamNoneReader() { + return onStreamNoneReader; + } + + public void setOnStreamNoneReader(String onStreamNoneReader) { + this.onStreamNoneReader = onStreamNoneReader; + } + + public String getOnStreamDisconnect() { + return onStreamDisconnect; + } + + public void setOnStreamDisconnect(String onStreamDisconnect) { + this.onStreamDisconnect = onStreamDisconnect; + } + + public String getOnDeleteRecordMp4() { + return onDeleteRecordMp4; + } + + public void setOnDeleteRecordMp4(String onDeleteRecordMp4) { + this.onDeleteRecordMp4 = onDeleteRecordMp4; + } + + public String getOnRecordProgress() { + return onRecordProgress; + } + + public void setOnRecordProgress(String onRecordProgress) { + this.onRecordProgress = onRecordProgress; + } + + public String getOnRecordTs() { + return onRecordTs; + } + + public void setOnRecordTs(String onRecordTs) { + this.onRecordTs = onRecordTs; + } + + public Integer getEnableGetFileDuration() { + return enableGetFileDuration; + } + + public void setEnableGetFileDuration(Integer enableGetFileDuration) { + this.enableGetFileDuration = enableGetFileDuration; + } + + public Integer getKeepaliveDuration() { + return keepaliveDuration; + } + + public void setKeepaliveDuration(Integer keepaliveDuration) { + this.keepaliveDuration = keepaliveDuration; + } + + public Integer getCaptureReplayType() { + return captureReplayType; + } + + public void setCaptureReplayType(Integer captureReplayType) { + this.captureReplayType = captureReplayType; + } + + public Integer getVideoFileFormat() { + return videoFileFormat; + } + + public void setVideoFileFormat(Integer videoFileFormat) { + this.videoFileFormat = videoFileFormat; + } + + public Integer getMaxDiconnectTimeoutSecond() { + return maxDiconnectTimeoutSecond; + } + + public void setMaxDiconnectTimeoutSecond(Integer maxDiconnectTimeoutSecond) { + this.maxDiconnectTimeoutSecond = maxDiconnectTimeoutSecond; + } + + public Integer getG711ConvertAAC() { + return g711ConvertAAC; + } + + public void setG711ConvertAAC(Integer g711ConvertAAC) { + this.g711ConvertAAC = g711ConvertAAC; + } + + public Integer getFilterVideoEnable() { + return filterVideoEnable; + } + + public void setFilterVideoEnable(Integer filterVideoEnable) { + this.filterVideoEnable = filterVideoEnable; + } + + public String getFilterVideoText() { + return filterVideoText; + } + + public void setFilterVideoText(String filterVideoText) { + this.filterVideoText = filterVideoText; + } + + public Integer getFilterFontSize() { + return filterFontSize; + } + + public void setFilterFontSize(Integer filterFontSize) { + this.filterFontSize = filterFontSize; + } + + public String getFilterFontColor() { + return filterFontColor; + } + + public void setFilterFontColor(String filterFontColor) { + this.filterFontColor = filterFontColor; + } + + public Integer getFilterFontLeft() { + return filterFontLeft; + } + + public void setFilterFontLeft(Integer filterFontLeft) { + this.filterFontLeft = filterFontLeft; + } + + public Integer getFilterFontTop() { + return filterFontTop; + } + + public void setFilterFontTop(Integer filterFontTop) { + this.filterFontTop = filterFontTop; + } + + public Double getFilterFontAlpha() { + return filterFontAlpha; + } + + public void setFilterFontAlpha(Double filterFontAlpha) { + this.filterFontAlpha = filterFontAlpha; + } + + public Integer getConvertOutWidth() { + return convertOutWidth; + } + + public void setConvertOutWidth(Integer convertOutWidth) { + this.convertOutWidth = convertOutWidth; + } + + public Integer getConvertOutHeight() { + return convertOutHeight; + } + + public void setConvertOutHeight(Integer convertOutHeight) { + this.convertOutHeight = convertOutHeight; + } + + public Integer getConvertOutBitrate() { + return convertOutBitrate; + } + + public void setConvertOutBitrate(Integer convertOutBitrate) { + this.convertOutBitrate = convertOutBitrate; + } + + public Integer getFlvPlayAddMute() { + return flvPlayAddMute; + } + + public void setFlvPlayAddMute(Integer flvPlayAddMute) { + this.flvPlayAddMute = flvPlayAddMute; + } + + public Integer getGb28181LibraryUse() { + return gb28181LibraryUse; + } + + public void setGb28181LibraryUse(Integer gb28181LibraryUse) { + this.gb28181LibraryUse = gb28181LibraryUse; + } + + public String getRtcListeningIp() { + return rtcListeningIp; + } + + public void setRtcListeningIp(String rtcListeningIp) { + this.rtcListeningIp = rtcListeningIp; + } + + public Integer getRtcListeningIpPort() { + return rtcListeningIpPort; + } + + public void setRtcListeningIpPort(Integer rtcListeningIpPort) { + this.rtcListeningIpPort = rtcListeningIpPort; + } + + public String getRtcExternalIp() { + return rtcExternalIp; + } + + public void setRtcExternalIp(String rtcExternalIp) { + this.rtcExternalIp = rtcExternalIp; + } + + public String getRtcRealm() { + return rtcRealm; + } + + public void setRtcRealm(String rtcRealm) { + this.rtcRealm = rtcRealm; + } + + public String getRtcUser() { + return rtcUser; + } + + public void setRtcUser(String rtcUser) { + this.rtcUser = rtcUser; + } + + public Integer getRtcMinPort() { + return rtcMinPort; + } + + public void setRtcMinPort(Integer rtcMinPort) { + this.rtcMinPort = rtcMinPort; + } + + public Integer getRtcMaxPort() { + return rtcMaxPort; + } + + public void setRtcMaxPort(Integer rtcMaxPort) { + this.rtcMaxPort = rtcMaxPort; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/ConfigKeyId.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/ConfigKeyId.java new file mode 100644 index 000000000..244bb9495 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/ConfigKeyId.java @@ -0,0 +1,10 @@ +package com.genersoft.iot.vmp.media.abl.bean; + +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ConfigKeyId { + String value(); +} From 3e02e496f6c3e4d2fae73b1d42a51d0ce35795dc Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Sun, 24 Mar 2024 15:51:19 +0800 Subject: [PATCH 19/58] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=AE=BE=E7=BD=AEabl?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../media/abl/ABLMediaServerStatusManger.java | 135 +++++++++--------- .../iot/vmp/media/abl/ABLRESTfulUtils.java | 4 +- .../vmp/media/abl/bean/AblServerConfig.java | 22 +++ 3 files changed, 92 insertions(+), 69 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java index 0d2f043c6..de65b64f7 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java @@ -141,7 +141,6 @@ public class ABLMediaServerStatusManger { if (data == null || data.isEmpty()) { logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); }else { -// ablServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), AblServerConfig.class); ablServerConfig = AblServerConfig.getInstance(data); initPort(mediaServerItem, ablServerConfig); online(mediaServerItem, ablServerConfig); @@ -166,7 +165,6 @@ public class ABLMediaServerStatusManger { logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); }else { -// ablServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); ablServerConfig = AblServerConfig.getInstance(data); initPort(mediaServerItem, ablServerConfig); online(mediaServerItem, ablServerConfig); @@ -189,13 +187,12 @@ public class ABLMediaServerStatusManger { JSONObject responseJSON = ablResTfulUtils.getServerConfig(mediaServerItem); JSONArray data = responseJSON.getJSONArray("params"); if (data != null && !data.isEmpty()) { -// config = JSON.parseObject(JSON.toJSONString(data.get(0)), AblServerConfig.class); config = AblServerConfig.getInstance(data); } } if (config != null) { initPort(mediaServerItem, config); - setAblConfig(mediaServerItem, false); + setAblConfig(mediaServerItem, false, config); } } mediaServerService.update(mediaServerItem); @@ -234,69 +231,73 @@ public class ABLMediaServerStatusManger { mediaServerItem.setHookAliveInterval(10F); } - public void setAblConfig(MediaServer mediaServerItem, boolean restart) { -// logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", -// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); -// String protocol = sslEnabled ? "https" : "http"; -// String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); -// -// Map param = new HashMap<>(); -// param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline -// if (mediaServerItem.getRtspPort() != 0) { -// param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); -// } -// param.put("hook.enable","1"); -// param.put("hook.on_flow_report",""); -// param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); -// param.put("hook.on_http_access",""); -// param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); -// param.put("hook.on_record_ts",""); -// param.put("hook.on_rtsp_auth",""); -// param.put("hook.on_rtsp_realm",""); -// param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); -// param.put("hook.on_shell_login",""); -// param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); -// param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); -// param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); -// param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); -// param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); -// param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); -// param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); -// param.put("hook.timeoutSec","30"); -// param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); -// // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 -// // 置0关闭此特性(推流断开会导致立即断开播放器) -// // 此参数不应大于播放器超时时间 -// // 优化此消息以更快的收到流注销事件 -// param.put("protocol.continue_push_ms", "3000" ); -// // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, -// // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 -// if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { -// param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); -// } -// -// if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { -// File recordPathFile = new File(mediaServerItem.getRecordPath()); -// param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); -// param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); -// param.put("record.appName", recordPathFile.getName()); -// } -// -// JSONObject responseJSON = ablResTfulUtils.setServerConfig(mediaServerItem, param); -// -// if (responseJSON != null && responseJSON.getInteger("code") == 0) { -// if (restart) { -// logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", -// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); -// ablResTfulUtils.restartServer(mediaServerItem); -// }else { -// logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", -// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); -// } -// }else { -// logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", -// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); -// } + public void setAblConfig(MediaServer mediaServerItem, boolean restart, AblServerConfig config) { + if (config.getHookEnable() == 0) { + logger.info("[媒体服务节点-ABL] 开启HOOK功能 :{}", mediaServerItem.getId()); + JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, "hook_enable", "1"); + } + logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + String protocol = sslEnabled ? "https" : "http"; + String hookPrefix = String.format("%s://%s:%s/index/hook/abl", protocol, mediaServerItem.getHookIp(), serverPort); + + Map param = new HashMap<>(); + param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline + if (mediaServerItem.getRtspPort() != 0) { + param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); + } + param.put("hook.enable","1"); + param.put("hook.on_flow_report",""); + param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); + param.put("hook.on_http_access",""); + param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); + param.put("hook.on_record_ts",""); + param.put("hook.on_rtsp_auth",""); + param.put("hook.on_rtsp_realm",""); + param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); + param.put("hook.on_shell_login",""); + param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); + param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); + param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); + param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); + param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); + param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); + param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); + param.put("hook.timeoutSec","30"); + param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); + // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 + // 置0关闭此特性(推流断开会导致立即断开播放器) + // 此参数不应大于播放器超时时间 + // 优化此消息以更快的收到流注销事件 + param.put("protocol.continue_push_ms", "3000" ); + // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, + // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 + if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { + param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); + } + + if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { + File recordPathFile = new File(mediaServerItem.getRecordPath()); + param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); + param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); + param.put("record.appName", recordPathFile.getName()); + } + + JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, param); + + if (responseJSON != null && responseJSON.getInteger("code") == 0) { + if (restart) { + logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + ablResTfulUtils.restartServer(mediaServerItem); + }else { + logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + } + }else { + logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + } } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java index 02a9b667b..de6866224 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java @@ -285,8 +285,8 @@ public class ABLRESTfulUtils { return sendPost(mediaServerItem, "getServerConfig",null, null); } - public JSONObject setServerConfig(MediaServer mediaServerItem, Map param){ - return sendPost(mediaServerItem,"setServerConfig",param, null); + public JSONObject setConfigParamValue(MediaServer mediaServerItem, String key, Object value){ + return sendPost(mediaServerItem,"setConfigParamValue", param, null); } public JSONObject openRtpServer(MediaServer mediaServerItem, Map param){ diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java index e7aac3a78..5b6f0fb0b 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java @@ -126,6 +126,9 @@ public class AblServerConfig { @ConfigKeyId("on_stream_disconnect") private String onStreamDisconnect; + @ConfigKeyId("on_record_mp4") + private String onRecordMp4; + @ConfigKeyId("on_delete_record_mp4") private String onDeleteRecordMp4; @@ -144,6 +147,9 @@ public class AblServerConfig { @ConfigKeyId("captureReplayType") private Integer captureReplayType; + @ConfigKeyId("pictureMaxCount") + private Integer pictureMaxCount; + @ConfigKeyId("videoFileFormat") private Integer videoFileFormat; @@ -776,4 +782,20 @@ public class AblServerConfig { public void setRtcMaxPort(Integer rtcMaxPort) { this.rtcMaxPort = rtcMaxPort; } + + public String getOnRecordMp4() { + return onRecordMp4; + } + + public void setOnRecordMp4(String onRecordMp4) { + this.onRecordMp4 = onRecordMp4; + } + + public Integer getPictureMaxCount() { + return pictureMaxCount; + } + + public void setPictureMaxCount(Integer pictureMaxCount) { + this.pictureMaxCount = pictureMaxCount; + } } From 7ce4f44caa58b9020e26ffca4d11023b8e3e499a Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 25 Mar 2024 00:12:32 +0800 Subject: [PATCH 20/58] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=AE=BE=E7=BD=AEabl?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=B8=AD=E7=9A=84hook=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../media/abl/ABLMediaServerStatusManger.java | 175 ++++++++++++------ .../iot/vmp/media/abl/ABLRESTfulUtils.java | 73 +++++++- 2 files changed, 178 insertions(+), 70 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java index de65b64f7..dcb465540 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.media.abl.bean.AblServerConfig; +import com.genersoft.iot.vmp.media.abl.bean.ConfigKeyId; import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; @@ -22,6 +23,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import java.io.File; +import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -232,72 +234,123 @@ public class ABLMediaServerStatusManger { } public void setAblConfig(MediaServer mediaServerItem, boolean restart, AblServerConfig config) { - if (config.getHookEnable() == 0) { - logger.info("[媒体服务节点-ABL] 开启HOOK功能 :{}", mediaServerItem.getId()); - JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, "hook_enable", "1"); + try { + if (config.getHookEnable() == 0) { + logger.info("[媒体服务节点-ABL] 开启HOOK功能 :{}", mediaServerItem.getId()); + JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, "hook_enable", "1"); + if (responseJSON.getInteger("code") == 0) { + logger.info("[媒体服务节点-ABL] 开启HOOK功能成功 :{}", mediaServerItem.getId()); + }else { + logger.info("[媒体服务节点-ABL] 开启HOOK功能失败 :{}->{}", mediaServerItem.getId(), responseJSON.getString("memo")); + } + } + }catch (Exception e) { + logger.info("[媒体服务节点-ABL] 开启HOOK功能失败 :{}", mediaServerItem.getId(), e); } - logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + // 设置相关的HOOK + String[] hookUrlArray = { + "on_stream_arrive", + "on_stream_none_reader", + "on_record_mp4", + "on_stream_disconnect", + "on_stream_not_found", + "on_server_started", + "on_publish", + "on_play", + "on_record_progress", + "on_server_keepalive", + "on_stream_not_arrive", + "on_delete_record_mp4", + }; + String protocol = sslEnabled ? "https" : "http"; String hookPrefix = String.format("%s://%s:%s/index/hook/abl", protocol, mediaServerItem.getHookIp(), serverPort); - - Map param = new HashMap<>(); - param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline - if (mediaServerItem.getRtspPort() != 0) { - param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); - } - param.put("hook.enable","1"); - param.put("hook.on_flow_report",""); - param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); - param.put("hook.on_http_access",""); - param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); - param.put("hook.on_record_ts",""); - param.put("hook.on_rtsp_auth",""); - param.put("hook.on_rtsp_realm",""); - param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); - param.put("hook.on_shell_login",""); - param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); - param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); - param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); - param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); - param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); - param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); - param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); - param.put("hook.timeoutSec","30"); - param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); - // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 - // 置0关闭此特性(推流断开会导致立即断开播放器) - // 此参数不应大于播放器超时时间 - // 优化此消息以更快的收到流注销事件 - param.put("protocol.continue_push_ms", "3000" ); - // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, - // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 - if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { - param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); - } - - if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { - File recordPathFile = new File(mediaServerItem.getRecordPath()); - param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); - param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); - param.put("record.appName", recordPathFile.getName()); - } - - JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, param); - - if (responseJSON != null && responseJSON.getInteger("code") == 0) { - if (restart) { - logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - ablResTfulUtils.restartServer(mediaServerItem); - }else { - logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); + Field[] fields = AblServerConfig.class.getDeclaredFields(); + for (Field field : fields) { + try { + if (field.isAnnotationPresent(ConfigKeyId.class)) { + ConfigKeyId configKeyId = field.getAnnotation(ConfigKeyId.class); + for (String hook : hookUrlArray) { + if (configKeyId.value().equals(hook)) { + String hookUrl = String.format("%s/%s", hookPrefix, hook); + field.setAccessible(true); + // 利用反射获取值后对比是否与配置中相同,不同则进行设置 + if (!hookUrl.equals(field.get(config))) { + JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, hook, hookUrl); + if (responseJSON.getInteger("code") == 0) { + logger.info("[媒体服务节点-ABL] 设置HOOK {} 成功 :{}", hook, mediaServerItem.getId()); + }else { + logger.info("[媒体服务节点-ABL] 设置HOOK {} 失败 :{}->{}", hook, mediaServerItem.getId(), responseJSON.getString("memo")); + } + } + } + } + } + }catch (Exception e) { + logger.info("[媒体服务节点-ABL] 设置HOOK 失败 :{}", mediaServerItem.getId(), e); } - }else { - logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", - mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); } + + + + +// Map param = new HashMap<>(); +// param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline +// if (mediaServerItem.getRtspPort() != 0) { +// param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); +// } +// param.put("hook.enable","1"); +// param.put("hook.on_flow_report",""); +// param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); +// param.put("hook.on_http_access",""); +// param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); +// param.put("hook.on_record_ts",""); +// param.put("hook.on_rtsp_auth",""); +// param.put("hook.on_rtsp_realm",""); +// param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); +// param.put("hook.on_shell_login",""); +// param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); +// param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); +// param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); +// param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); +// param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); +// param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); +// param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); +// param.put("hook.timeoutSec","30"); +// param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); +// // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 +// // 置0关闭此特性(推流断开会导致立即断开播放器) +// // 此参数不应大于播放器超时时间 +// // 优化此消息以更快的收到流注销事件 +// param.put("protocol.continue_push_ms", "3000" ); +// // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, +// // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 +// if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { +// param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); +// } +// +// if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { +// File recordPathFile = new File(mediaServerItem.getRecordPath()); +// param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); +// param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); +// param.put("record.appName", recordPathFile.getName()); +// } +// +// JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, param); +// +// if (responseJSON != null && responseJSON.getInteger("code") == 0) { +// if (restart) { +// logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", +// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); +// ablResTfulUtils.restartServer(mediaServerItem); +// }else { +// logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", +// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); +// } +// }else { +// logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", +// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); +// } } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java index de6866224..b76f59ef1 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java @@ -116,15 +116,15 @@ public class ABLRESTfulUtils { if(e instanceof SocketTimeoutException){ //读取超时超时异常 - logger.error(String.format("读取ZLM数据超时失败: %s, %s", url, e.getMessage())); + logger.error(String.format("读取ABL数据超时失败: %s, %s", url, e.getMessage())); } if(e instanceof ConnectException){ //判断连接异常,我这里是报Failed to connect to 10.7.5.144 - logger.error(String.format("连接ZLM连接失败: %s, %s", url, e.getMessage())); + logger.error(String.format("连接ABL连接失败: %s, %s", url, e.getMessage())); } }catch (Exception e){ - logger.error(String.format("访问ZLM失败: %s, %s", url, e.getMessage())); + logger.error(String.format("访问ABL失败: %s, %s", url, e.getMessage())); } }else { client.newCall(request).enqueue(new Callback(){ @@ -147,15 +147,15 @@ public class ABLRESTfulUtils { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { - logger.error(String.format("连接ZLM失败: %s, %s", call.request().toString(), e.getMessage())); + logger.error(String.format("连接ABL失败: %s, %s", call.request().toString(), e.getMessage())); if(e instanceof SocketTimeoutException){ //读取超时超时异常 - logger.error(String.format("读取ZLM数据失败: %s, %s", call.request().toString(), e.getMessage())); + logger.error(String.format("读取ABL数据失败: %s, %s", call.request().toString(), e.getMessage())); } if(e instanceof ConnectException){ //判断连接异常,我这里是报Failed to connect to 10.7.5.144 - logger.error(String.format("连接ZLM失败: %s, %s", call.request().toString(), e.getMessage())); + logger.error(String.format("连接ABL失败: %s, %s", call.request().toString(), e.getMessage())); } } }); @@ -163,6 +163,58 @@ public class ABLRESTfulUtils { + return responseJSON; + } + + public JSONObject sendGet(MediaServer mediaServerItem, String api, Map param) { + OkHttpClient client = getClient(); + + if (mediaServerItem == null) { + return null; + } + JSONObject responseJSON = null; + StringBuilder stringBuffer = new StringBuilder(); + stringBuffer.append(String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api)); + if (param != null && !param.keySet().isEmpty()) { + stringBuffer.append("?secret=").append(mediaServerItem.getSecret()).append("&"); + int index = 1; + for (String key : param.keySet()){ + if (param.get(key) != null) { + stringBuffer.append(key + "=" + param.get(key)); + if (index < param.size()) { + stringBuffer.append("&"); + } + } + index++; + } + } + String url = stringBuffer.toString(); + logger.info("[访问ABL]: {}", url); + Request request = new Request.Builder() + .get() + .url(url) + .build(); + try { + Response response = client.newCall(request).execute(); + if (response.isSuccessful()) { + ResponseBody responseBody = response.body(); + if (responseBody != null) { + String responseStr = responseBody.string(); + responseJSON = JSON.parseObject(responseStr); + } + }else { + response.close(); + Objects.requireNonNull(response.body()).close(); + } + } catch (ConnectException e) { + logger.error(String.format("连接ABL失败: %s, %s", e.getCause().getMessage(), e.getMessage())); + logger.info("请检查media配置并确认ABL已启动..."); + }catch (IOException e) { + logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); + } + + + return responseJSON; } @@ -211,8 +263,8 @@ public class ABLRESTfulUtils { } Objects.requireNonNull(response.body()).close(); } catch (ConnectException e) { - logger.error(String.format("连接ZLM失败: %s, %s", e.getCause().getMessage(), e.getMessage())); - logger.info("请检查media配置并确认ZLM已启动..."); + logger.error(String.format("连接ABL失败: %s, %s", e.getCause().getMessage(), e.getMessage())); + logger.info("请检查media配置并确认ABL已启动..."); } catch (IOException e) { logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); } @@ -286,7 +338,10 @@ public class ABLRESTfulUtils { } public JSONObject setConfigParamValue(MediaServer mediaServerItem, String key, Object value){ - return sendPost(mediaServerItem,"setConfigParamValue", param, null); + Map param = new HashMap<>(); + param.put("key", key); + param.put("value", value); + return sendGet(mediaServerItem,"setConfigParamValue", param); } public JSONObject openRtpServer(MediaServer mediaServerItem, Map param){ From 2b0af3be14d3f8ac28a1cb031e21dc3a69146d2b Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 25 Mar 2024 17:59:09 +0800 Subject: [PATCH 21/58] =?UTF-8?q?=E6=94=AF=E6=8C=81hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/abl/bean/AblServerConfig.java | 11 ++++++ .../vmp/media/zlm/ZLMHttpHookListener.java | 35 +++++-------------- .../iot/vmp/service/IMediaService.java | 7 ++++ .../vmp/service/impl/MediaServiceImpl.java | 18 ++++++++++ 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java index 5b6f0fb0b..dc0edecda 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java @@ -126,6 +126,9 @@ public class AblServerConfig { @ConfigKeyId("on_stream_disconnect") private String onStreamDisconnect; + @ConfigKeyId("on_stream_not_found") + private String onStreamNotFound; + @ConfigKeyId("on_record_mp4") private String onRecordMp4; @@ -798,4 +801,12 @@ public class AblServerConfig { public void setPictureMaxCount(Integer pictureMaxCount) { this.pictureMaxCount = pictureMaxCount; } + + public String getOnStreamNotFound() { + return onStreamNotFound; + } + + public void setOnStreamNotFound(String onStreamNotFound) { + this.onStreamNotFound = onStreamNotFound; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index a247a78b1..b8f6f2f1b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -139,7 +139,6 @@ public class ZLMHttpHookListener { * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 */ @ResponseBody - @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { try { @@ -164,25 +163,11 @@ public class ZLMHttpHookListener { if (logger.isDebugEnabled()) { logger.debug("[ZLM HOOK] 播放鉴权:{}->{}", param.getMediaServerId(), param); } - String mediaServerId = param.getMediaServerId(); - - taskExecutor.execute(() -> { - JSONObject json = (JSONObject) JSON.toJSON(param); - ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); - if (subscribe != null) { - MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); - if (mediaInfo != null) { - subscribe.response(mediaInfo, param); - } - } - }); - // TODO 此处逻辑适合迁移到MediaService中 - if (!"rtp".equals(param.getApp())) { - Map paramMap = urlParamToMap(param.getParams()); - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); - if (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(paramMap.get("callId"))) { - return new HookResult(401, "Unauthorized"); - } + Map paramMap = urlParamToMap(param.getParams()); + // 对于播放流进行鉴权 + boolean authenticateResult = mediaService.authenticatePlay(param.getApp(), param.getStream(), paramMap.get("callId")); + if (!authenticateResult) { + return new HookResult(401, "Unauthorized"); } return HookResult.SUCCESS(); @@ -215,12 +200,14 @@ public class ZLMHttpHookListener { return result; } if (userSetting.getPushAuthority()) { + // 对于推流进行鉴权 + Map paramMap = urlParamToMap(param.getParams()); // 推流鉴权 if (param.getParams() == null) { logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); return new HookResultForOnPublish(401, "Unauthorized"); } - Map paramMap = urlParamToMap(param.getParams()); + String sign = paramMap.get("sign"); if (sign == null) { logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); @@ -648,12 +635,6 @@ public class ZLMHttpHookListener { } return ret; } - // TODO 推流具有主动性,暂时不做处理 -// StreamPushItem streamPushItem = streamPushService.getPush(app, streamId); -// if (streamPushItem != null) { -// // TODO 发送停止 -// -// } } return ret; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java index 338814c51..9230b353c 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java @@ -41,4 +41,11 @@ public interface IMediaService { * @return */ StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay); + + /** + * 播放鉴权 + */ + boolean authenticatePlay(String app, String stream, String callId); + + boolean authenticatePublish(String app, String stream, String callId, String sign); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 07a28a3be..9c54068fd 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -4,10 +4,14 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResultForOnPublish; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; @@ -17,6 +21,8 @@ import java.util.List; @Service public class MediaServiceImpl implements IMediaService { + private final static Logger logger = LoggerFactory.getLogger(MediaServiceImpl.class); + @Autowired private IRedisCatchStorage redisCatchStorage; @@ -85,4 +91,16 @@ public class MediaServiceImpl implements IMediaService { streamInfoResult.setMediaInfo(mediaInfo); return streamInfoResult; } + + @Override + public boolean authenticatePlay(String app, String stream, String callId) { + if (app == null || stream == null) { + return false; + } + if ("rtp".equals(app)) { + return true; + } + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); + return (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(callId)); + } } From c6dfb63f8fd5f04fa00ac6c45da2eb6bcc5cada4 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 25 Mar 2024 23:59:50 +0800 Subject: [PATCH 22/58] =?UTF-8?q?=E4=BC=98=E5=8C=96hook=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/bean/ResultForOnPublish.java | 59 ++++++ .../vmp/media/event/MediaArrivalEvent.java | 75 +++++++ .../vmp/media/event/MediaDepartureEvent.java | 65 ++++++ .../service/impl/MediaServerServiceImpl.java | 31 +++ .../vmp/media/zlm/ZLMHttpHookListener.java | 138 ++----------- .../media/zlm/dto/StreamAuthorityInfo.java | 23 ++- .../vmp/media/zlm/dto/hook/HookResult.java | 4 +- .../zlm/dto/hook/HookResultForOnPublish.java | 13 ++ .../iot/vmp/service/IMediaService.java | 3 +- .../service/impl/InviteStreamServiceImpl.java | 34 ++++ .../vmp/service/impl/MediaServiceImpl.java | 190 +++++++++++++++++- .../iot/vmp/service/impl/PlayServiceImpl.java | 81 +++++++- .../service/impl/StreamProxyServiceImpl.java | 26 +++ .../service/impl/StreamPushServiceImpl.java | 42 ++++ 14 files changed, 649 insertions(+), 135 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/bean/ResultForOnPublish.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/ResultForOnPublish.java b/src/main/java/com/genersoft/iot/vmp/media/bean/ResultForOnPublish.java new file mode 100644 index 000000000..88f7387db --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/ResultForOnPublish.java @@ -0,0 +1,59 @@ +package com.genersoft.iot.vmp.media.bean; + +public class ResultForOnPublish { + + private boolean enable_audio; + private boolean enable_mp4; + private int mp4_max_second; + private String mp4_save_path; + private String stream_replace; + private Integer modify_stamp; + + public boolean isEnable_audio() { + return enable_audio; + } + + public void setEnable_audio(boolean enable_audio) { + this.enable_audio = enable_audio; + } + + public boolean isEnable_mp4() { + return enable_mp4; + } + + public void setEnable_mp4(boolean enable_mp4) { + this.enable_mp4 = enable_mp4; + } + + public int getMp4_max_second() { + return mp4_max_second; + } + + public void setMp4_max_second(int mp4_max_second) { + this.mp4_max_second = mp4_max_second; + } + + public String getMp4_save_path() { + return mp4_save_path; + } + + public void setMp4_save_path(String mp4_save_path) { + this.mp4_save_path = mp4_save_path; + } + + public String getStream_replace() { + return stream_replace; + } + + public void setStream_replace(String stream_replace) { + this.stream_replace = stream_replace; + } + + public Integer getModify_stamp() { + return modify_stamp; + } + + public void setModify_stamp(Integer modify_stamp) { + this.modify_stamp = modify_stamp; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java new file mode 100644 index 000000000..1b79b0c87 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java @@ -0,0 +1,75 @@ +package com.genersoft.iot.vmp.media.event; + +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import org.springframework.context.ApplicationEvent; + +/** + * 流到来事件 + */ +public class MediaArrivalEvent extends ApplicationEvent { + public MediaArrivalEvent(Object source) { + super(source); + } + + public static MediaArrivalEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){ + MediaArrivalEvent mediaArrivalEvent = new MediaArrivalEvent(source); + mediaArrivalEvent.setMediaInfo(MediaInfo.getInstance(hookParam)); + mediaArrivalEvent.setApp(hookParam.getApp()); + mediaArrivalEvent.setStream(hookParam.getStream()); + mediaArrivalEvent.setMediaServer(mediaServer); + mediaArrivalEvent.setSchema(hookParam.getSchema()); + return mediaArrivalEvent; + } + + private MediaInfo mediaInfo; + + private String app; + + private String stream; + + private MediaServer mediaServer; + + private String schema; + + public MediaInfo getMediaInfo() { + return mediaInfo; + } + + public void setMediaInfo(MediaInfo mediaInfo) { + this.mediaInfo = mediaInfo; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public MediaServer getMediaServer() { + return mediaServer; + } + + public void setMediaServer(MediaServer mediaServer) { + this.mediaServer = mediaServer; + } + + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java new file mode 100644 index 000000000..f11138523 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java @@ -0,0 +1,65 @@ +package com.genersoft.iot.vmp.media.event; + +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import org.springframework.context.ApplicationEvent; + +/** + * 流离开事件 + */ +public class MediaDepartureEvent extends ApplicationEvent { + public MediaDepartureEvent(Object source) { + super(source); + } + + private String app; + + private String stream; + + private MediaServer mediaServer; + + private String schema; + + public static MediaDepartureEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){ + MediaDepartureEvent mediaDepartureEven = new MediaDepartureEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setSchema(hookParam.getSchema()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public MediaServer getMediaServer() { + return mediaServer; + } + + public void setMediaServer(MediaServer mediaServer) { + this.mediaServer = mediaServer; + } + + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index c5367fb1d..e4538e105 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -8,11 +8,15 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -30,7 +34,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.event.EventListener; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; @@ -71,6 +77,31 @@ public class MediaServerServiceImpl implements IMediaServerService { private ApplicationEventPublisher applicationEventPublisher; + /** + * 流到来的处理 + */ + @Async("taskExecutor") + @org.springframework.context.event.EventListener + public void onApplicationEvent(MediaArrivalEvent event) { + if ("rtsp".equals(event.getSchema())) { + logger.info("流变化:注册 app->{}, stream->{}", event.getApp(), event.getStream()); + addCount(event.getSeverId()); + } + } + + /** + * 流离开的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaDepartureEvent event) { + if ("rtsp".equals(event.getSchema())) { + logger.info("流变化:注销, app->{}, stream->{}", event.getApp(), event.getStream()); + removeCount(event.getSeverId()); + } + } + + /** * 初始化 */ diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index b8f6f2f1b..ca5261983 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -19,6 +19,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; @@ -190,50 +193,7 @@ public class ZLMHttpHookListener { if (mediaServer == null) { return new HookResultForOnPublish(200, "success"); } - // 推流鉴权的处理 - if (!"rtp".equals(param.getApp())) { - StreamProxyItem stream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); - if (stream != null) { - HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); - result.setEnable_audio(stream.isEnableAudio()); - result.setEnable_mp4(stream.isEnableMp4()); - return result; - } - if (userSetting.getPushAuthority()) { - // 对于推流进行鉴权 - Map paramMap = urlParamToMap(param.getParams()); - // 推流鉴权 - if (param.getParams() == null) { - logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); - return new HookResultForOnPublish(401, "Unauthorized"); - } - String sign = paramMap.get("sign"); - if (sign == null) { - logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); - return new HookResultForOnPublish(401, "Unauthorized"); - } - // 推流自定义播放鉴权码 - String callId = paramMap.get("callId"); - // 鉴权配置 - boolean hasAuthority = userService.checkPushAuthority(callId, sign); - if (!hasAuthority) { - logger.info("推流鉴权失败: sign 无权限: callId={}. sign={}", callId, sign); - return new HookResultForOnPublish(401, "Unauthorized"); - } - StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); - streamAuthorityInfo.setCallId(callId); - streamAuthorityInfo.setSign(sign); - // 鉴权通过 - redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); - } - } else { - zlmMediaListManager.sendStreamEvent(param.getApp(), param.getStream(), param.getMediaServerId()); - } - - - HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); - result.setEnable_audio(true); taskExecutor.execute(() -> { ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); if (subscribe != null) { @@ -241,81 +201,16 @@ public class ZLMHttpHookListener { } }); - // 是否录像 - if ("rtp".equals(param.getApp())) { - result.setEnable_mp4(userSetting.getRecordSip()); - } else { - result.setEnable_mp4(userSetting.isRecordPushLive()); + ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams()); + if (resultForOnPublish != null) { + HookResultForOnPublish successResult = HookResultForOnPublish.getInstance(resultForOnPublish); + logger.info("[ZLM HOOK]推流鉴权 响应:{}->{}->>>>{}", param.getMediaServerId(), param, successResult); + return successResult; + }else { + HookResultForOnPublish fail = HookResultForOnPublish.Fail(); + logger.info("[ZLM HOOK]推流鉴权 响应:{}->{}->>>>{}", param.getMediaServerId(), param, fail); + return fail; } - // 国标流 - if ("rtp".equals(param.getApp())) { - - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); - - // 单端口模式下修改流 ID - if (!mediaServer.isRtpEnable() && inviteInfo == null) { - String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16)); - inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc); - if (inviteInfo != null) { - result.setStream_replace(inviteInfo.getStream()); - logger.info("[ZLM HOOK]推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream()); - } - } - - // 设置音频信息及录制信息 - List ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream()); - if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) { - - // 为录制国标模拟一个鉴权信息, 方便后续写入录像文件时使用 - StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); - streamAuthorityInfo.setApp(param.getApp()); - streamAuthorityInfo.setStream(ssrcTransactionForAll.get(0).getStream()); - streamAuthorityInfo.setCallId(ssrcTransactionForAll.get(0).getSipTransactionInfo().getCallId()); - - redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), ssrcTransactionForAll.get(0).getStream(), streamAuthorityInfo); - - String deviceId = ssrcTransactionForAll.get(0).getDeviceId(); - String channelId = ssrcTransactionForAll.get(0).getChannelId(); - DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); - if (deviceChannel != null) { - result.setEnable_audio(deviceChannel.isHasAudio()); - } - // 如果是录像下载就设置视频间隔十秒 - if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) { - // 获取录像的总时长,然后设置为这个视频的时长 - InviteInfo inviteInfoForDownload = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, param.getStream()); - if (inviteInfoForDownload != null && inviteInfoForDownload.getStreamInfo() != null) { - String startTime = inviteInfoForDownload.getStreamInfo().getStartTime(); - String endTime = inviteInfoForDownload.getStreamInfo().getEndTime(); - long difference = DateUtil.getDifference(startTime, endTime) / 1000; - result.setMp4_max_second((int) difference); - result.setEnable_mp4(true); - // 设置为2保证得到的mp4的时长是正常的 - result.setModify_stamp(2); - } - } - // 如果是talk对讲,则默认获取声音 - if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.TALK) { - result.setEnable_audio(true); - } - } - } else if (param.getApp().equals("broadcast")) { - result.setEnable_audio(true); - } else if (param.getApp().equals("talk")) { - result.setEnable_audio(true); - } - if (param.getApp().equalsIgnoreCase("rtp")) { - String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_" + param.getStream(); - OtherRtpSendInfo otherRtpSendInfo = (OtherRtpSendInfo) redisTemplate.opsForValue().get(receiveKey); - - String receiveKeyForPS = VideoManagerConstants.WVP_OTHER_RECEIVE_PS_INFO + userSetting.getServerId() + "_" + param.getStream(); - OtherPsSendInfo otherPsSendInfo = (OtherPsSendInfo) redisTemplate.opsForValue().get(receiveKeyForPS); - if (otherRtpSendInfo != null || otherPsSendInfo != null) { - result.setEnable_mp4(true); - } - } - logger.info("[ZLM HOOK]推流鉴权 响应:{}->{}->>>>{}", param.getMediaServerId(), param, result); - return result; } @@ -326,11 +221,20 @@ public class ZLMHttpHookListener { @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8") public HookResult onStreamChanged(@RequestBody OnStreamChangedHookParam param) { + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (param.isRegist()) { logger.info("[ZLM HOOK] 流注册, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + MediaArrivalEvent mediaArrivalEvent = MediaArrivalEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaArrivalEvent); } else { logger.info("[ZLM HOOK] 流注销, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + MediaDepartureEvent mediaArrivalEvent = MediaDepartureEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaArrivalEvent); } + return HookResult.SUCCESS(); + + JSONObject json = (JSONObject) JSON.toJSON(param); taskExecutor.execute(() -> { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java index ef77225d6..7d66a1ffe 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.dto; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnPublishHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; @@ -97,21 +98,23 @@ public class StreamAuthorityInfo { this.sign = sign; } - public static StreamAuthorityInfo getInstanceByHook(OnPublishHookParam hookParam) { + public static StreamAuthorityInfo getInstanceByHook(String app, String stream, String id) { StreamAuthorityInfo streamAuthorityInfo = new StreamAuthorityInfo(); - streamAuthorityInfo.setApp(hookParam.getApp()); - streamAuthorityInfo.setStream(hookParam.getStream()); - streamAuthorityInfo.setId(hookParam.getId()); + streamAuthorityInfo.setApp(app); + streamAuthorityInfo.setStream(stream); + streamAuthorityInfo.setId(id); return streamAuthorityInfo; } - public static StreamAuthorityInfo getInstanceByHook(OnStreamChangedHookParam onStreamChangedHookParam) { + public static StreamAuthorityInfo getInstanceByHook(MediaArrivalEvent event) { StreamAuthorityInfo streamAuthorityInfo = new StreamAuthorityInfo(); - streamAuthorityInfo.setApp(onStreamChangedHookParam.getApp()); - streamAuthorityInfo.setStream(onStreamChangedHookParam.getStream()); - streamAuthorityInfo.setId(onStreamChangedHookParam.getMediaServerId()); - streamAuthorityInfo.setOriginType(onStreamChangedHookParam.getOriginType()); - streamAuthorityInfo.setOriginTypeStr(onStreamChangedHookParam.getOriginTypeStr()); + streamAuthorityInfo.setApp(event.getApp()); + streamAuthorityInfo.setStream(event.getStream()); + streamAuthorityInfo.setId(event.getSeverId()); + if (event.getMediaInfo() != null) { + streamAuthorityInfo.setOriginType(event.getMediaInfo().getOriginType()); + } + return streamAuthorityInfo; } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResult.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResult.java index b327f13a4..dee9d6608 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResult.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResult.java @@ -18,8 +18,8 @@ public class HookResult { return new HookResult(0, "success"); } - public static HookResult Fail(){ - return new HookResult(-1, "fail"); + public static HookResultForOnPublish Fail(){ + return new HookResultForOnPublish(-1, "fail"); } public int getCode() { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResultForOnPublish.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResultForOnPublish.java index 55369e5ba..33f9856f4 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResultForOnPublish.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResultForOnPublish.java @@ -1,5 +1,7 @@ package com.genersoft.iot.vmp.media.zlm.dto.hook; +import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; + public class HookResultForOnPublish extends HookResult{ private boolean enable_audio; @@ -16,6 +18,17 @@ public class HookResultForOnPublish extends HookResult{ return new HookResultForOnPublish(0, "success"); } + public static HookResultForOnPublish getInstance(ResultForOnPublish resultForOnPublish){ + HookResultForOnPublish successResult = new HookResultForOnPublish(0, "success"); + successResult.setEnable_audio(resultForOnPublish.isEnable_audio()); + successResult.setEnable_mp4(resultForOnPublish.isEnable_mp4()); + successResult.setModify_stamp(resultForOnPublish.getModify_stamp()); + successResult.setStream_replace(resultForOnPublish.getStream_replace()); + successResult.setMp4_max_second(resultForOnPublish.getMp4_max_second()); + successResult.setMp4_save_path(resultForOnPublish.getMp4_save_path()); + return successResult; + } + public HookResultForOnPublish(int code, String msg) { setCode(code); setMsg(msg); diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java index 9230b353c..490545590 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; /** @@ -47,5 +48,5 @@ public interface IMediaService { */ boolean authenticatePlay(String app, String stream, String callId); - boolean authenticatePublish(String app, String stream, String callId, String sign); + ResultForOnPublish authenticatePublish(MediaServer mediaServer, String app, String stream, String params); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java index 9dc86f826..014c76169 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java @@ -6,13 +6,18 @@ import com.genersoft.iot.vmp.common.InviteInfo; import com.genersoft.iot.vmp.common.InviteSessionStatus; import com.genersoft.iot.vmp.common.InviteSessionType; import com.genersoft.iot.vmp.common.VideoManagerConstants; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.ErrorCallback; +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.List; @@ -31,6 +36,35 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @Autowired private RedisTemplate redisTemplate; + @Autowired + private IVideoManagerStorage storage; + + /** + * 流到来的处理 + */ + @Async("taskExecutor") + @org.springframework.context.event.EventListener + public void onApplicationEvent(MediaArrivalEvent event) { + if ("rtsp".equals(event.getSchema()) && "rtp".equals(event.getApp())) { + + } + } + + /** + * 流离开的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaDepartureEvent event) { + if ("rtsp".equals(event.getSchema()) && "rtp".equals(event.getApp())) { + InviteInfo inviteInfo = getInviteInfoByStream(null, event.getStream()); + if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) { + removeInviteInfo(inviteInfo); + stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); + } + } + } + @Override public void updateInviteInfo(InviteInfo inviteInfo) { if (inviteInfo == null || (inviteInfo.getDeviceId() == null || inviteInfo.getChannelId() == null)) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 9c54068fd..21c3472cf 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -1,22 +1,43 @@ 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.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.MediaConfig; +import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.conf.exception.ControllerException; +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener; +import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResultForOnPublish; -import com.genersoft.iot.vmp.service.IMediaService; +import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.utils.DateUtil; +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; +import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Service public class MediaServiceImpl implements IMediaService { @@ -32,6 +53,31 @@ public class MediaServiceImpl implements IMediaService { @Autowired private MediaConfig mediaConfig; + @Autowired + private IStreamProxyService streamProxyService; + + @Autowired + private UserSetting userSetting; + + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private IUserService userService; + + @Autowired + private IInviteStreamService inviteStreamService; + + @Autowired + private VideoStreamSessionManager sessionManager; + + @Autowired + private IVideoManagerStorage storager; + + @Autowired + private ZLMMediaListManager zlmMediaListManager; + + @Override public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId) { @@ -103,4 +149,146 @@ public class MediaServiceImpl implements IMediaService { StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); return (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(callId)); } + + @Override + public ResultForOnPublish authenticatePublish(MediaServer mediaServer, String app, String stream, String params) { + // 推流鉴权的处理 + if (!"rtp".equals(app)) { + StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(app, stream); + if (streamProxyItem != null) { + ResultForOnPublish result = new ResultForOnPublish(); + result.setEnable_audio(streamProxyItem.isEnableAudio()); + result.setEnable_mp4(streamProxyItem.isEnableMp4()); + return result; + } + if (userSetting.getPushAuthority()) { + // 对于推流进行鉴权 + Map paramMap = urlParamToMap(params); + // 推流鉴权 + if (params == null) { + logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); + throw new ControllerException(ErrorCode.ERROR401.getCode(), "Unauthorized"); + } + + String sign = paramMap.get("sign"); + if (sign == null) { + logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); + throw new ControllerException(ErrorCode.ERROR401.getCode(), "Unauthorized"); + } + // 推流自定义播放鉴权码 + String callId = paramMap.get("callId"); + // 鉴权配置 + boolean hasAuthority = userService.checkPushAuthority(callId, sign); + if (!hasAuthority) { + logger.info("推流鉴权失败: sign 无权限: callId={}. sign={}", callId, sign); + throw new ControllerException(ErrorCode.ERROR401.getCode(), "Unauthorized"); + } + StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(app, stream, mediaServer.getId()); + streamAuthorityInfo.setCallId(callId); + streamAuthorityInfo.setSign(sign); + // 鉴权通过 + redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo); + } + } else { + zlmMediaListManager.sendStreamEvent(app, stream, mediaServer.getId()); + } + + + ResultForOnPublish result = new ResultForOnPublish(); + result.setEnable_audio(true); + + + // 是否录像 + if ("rtp".equals(app)) { + result.setEnable_mp4(userSetting.getRecordSip()); + } else { + result.setEnable_mp4(userSetting.isRecordPushLive()); + } + // 国标流 + if ("rtp".equals(app)) { + + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, stream); + + // 单端口模式下修改流 ID + if (!mediaServer.isRtpEnable() && inviteInfo == null) { + String ssrc = String.format("%010d", Long.parseLong(stream, 16)); + inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc); + if (inviteInfo != null) { + result.setStream_replace(inviteInfo.getStream()); + logger.info("[ZLM HOOK]推流鉴权 stream: {} 替换为 {}", stream, inviteInfo.getStream()); + } + } + + // 设置音频信息及录制信息 + List ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, stream); + if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) { + + // 为录制国标模拟一个鉴权信息, 方便后续写入录像文件时使用 + StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(app, stream, mediaServer.getId()); + streamAuthorityInfo.setApp(app); + streamAuthorityInfo.setStream(ssrcTransactionForAll.get(0).getStream()); + streamAuthorityInfo.setCallId(ssrcTransactionForAll.get(0).getSipTransactionInfo().getCallId()); + + redisCatchStorage.updateStreamAuthorityInfo(app, ssrcTransactionForAll.get(0).getStream(), streamAuthorityInfo); + + String deviceId = ssrcTransactionForAll.get(0).getDeviceId(); + String channelId = ssrcTransactionForAll.get(0).getChannelId(); + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); + if (deviceChannel != null) { + result.setEnable_audio(deviceChannel.isHasAudio()); + } + // 如果是录像下载就设置视频间隔十秒 + if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) { + // 获取录像的总时长,然后设置为这个视频的时长 + InviteInfo inviteInfoForDownload = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, stream); + if (inviteInfoForDownload != null && inviteInfoForDownload.getStreamInfo() != null) { + String startTime = inviteInfoForDownload.getStreamInfo().getStartTime(); + String endTime = inviteInfoForDownload.getStreamInfo().getEndTime(); + long difference = DateUtil.getDifference(startTime, endTime) / 1000; + result.setMp4_max_second((int) difference); + result.setEnable_mp4(true); + // 设置为2保证得到的mp4的时长是正常的 + result.setModify_stamp(2); + } + } + // 如果是talk对讲,则默认获取声音 + if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.TALK) { + result.setEnable_audio(true); + } + } + } else if (app.equals("broadcast")) { + result.setEnable_audio(true); + } else if (app.equals("talk")) { + result.setEnable_audio(true); + } + if (app.equalsIgnoreCase("rtp")) { + String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_" + stream; + OtherRtpSendInfo otherRtpSendInfo = (OtherRtpSendInfo) redisTemplate.opsForValue().get(receiveKey); + + String receiveKeyForPS = VideoManagerConstants.WVP_OTHER_RECEIVE_PS_INFO + userSetting.getServerId() + "_" + stream; + OtherPsSendInfo otherPsSendInfo = (OtherPsSendInfo) redisTemplate.opsForValue().get(receiveKeyForPS); + if (otherRtpSendInfo != null || otherPsSendInfo != null) { + result.setEnable_mp4(true); + } + } + return result; + } + + private Map urlParamToMap(String params) { + HashMap map = new HashMap<>(); + if (ObjectUtils.isEmpty(params)) { + return map; + } + String[] paramsArray = params.split("&"); + if (paramsArray.length == 0) { + return map; + } + for (String param : paramsArray) { + String[] paramArray = param.split("="); + if (paramArray.length == 2) { + map.put(paramArray[0], paramArray[1]); + } + } + return map; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index ee84dc819..65cf69365 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -17,17 +17,17 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; @@ -43,6 +43,8 @@ import gov.nist.javax.sip.message.SIPResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; @@ -121,6 +123,77 @@ public class PlayServiceImpl implements IPlayService { @Autowired private SSRCFactory ssrcFactory; + /** + * 流到来的处理 + */ + @Async("taskExecutor") + @org.springframework.context.event.EventListener + public void onApplicationEvent(MediaArrivalEvent event) { + if ("broadcast".equals(event.getApp())) { + if (event.getStream().indexOf("_") > 0) { + String[] streamArray = event.getStream().split("_"); + if (streamArray.length == 2) { + String deviceId = streamArray[0]; + String channelId = streamArray[1]; + Device device = deviceService.getDevice(deviceId); + if (device == null) { + logger.info("[语音对讲/喊话] 未找到设备:{}", deviceId); + return; + } + if ("broadcast".equals(event.getApp())) { + if (audioBroadcastManager.exit(deviceId, channelId)) { + stopAudioBroadcast(deviceId, channelId); + } + // 开启语音对讲通道 + try { + audioBroadcastCmd(device, channelId, event.getMediaServer(), + event.getApp(), event.getStream(), 60, false, (msg) -> { + logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); + }); + } catch (InvalidArgumentException | ParseException | SipException e) { + logger.error("[命令发送失败] 语音对讲: {}", e.getMessage()); + } + }else if ("talk".equals(event.getApp())) { + // 开启语音对讲通道 + talkCmd(device, channelId, event.getMediaServer(), event.getStream(), (msg) -> { + logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); + }); + } + } + } + } + + + } + + /** + * 流离开的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaDepartureEvent event) { + if ("broadcast".equals(event.getApp()) || "talk".equals(event.getApp())) { + if (event.getStream().indexOf("_") > 0) { + String[] streamArray = event.getStream().split("_"); + if (streamArray.length == 2) { + String deviceId = streamArray[0]; + String channelId = streamArray[1]; + Device device = deviceService.getDevice(deviceId); + if (device == null) { + logger.info("[语音对讲/喊话] 未找到设备:{}", deviceId); + return; + } + if ("broadcast".equals(event.getApp())) { + stopAudioBroadcast(deviceId, channelId); + }else if ("talk".equals(event.getApp())) { + stopTalk(device, channelId, false); + } + + } + } + } + } + @Override public SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback callback) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index ea824ffef..dd0eae2b0 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -9,6 +9,8 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; @@ -33,7 +35,9 @@ import com.github.pagehelper.PageInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionDefinition; @@ -102,6 +106,28 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @Autowired TransactionDefinition transactionDefinition; + /** + * 流到来的处理 + */ + @Async("taskExecutor") + @org.springframework.context.event.EventListener + public void onApplicationEvent(MediaArrivalEvent event) { + if ("rtsp".equals(event.getSchema())) { + updateStatus(true, event.getApp(), event.getStream()); + } + } + + /** + * 流离开的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaDepartureEvent event) { + if ("rtsp".equals(event.getSchema())) { + updateStatus(true, event.getApp(), event.getStream()); + } + } + @Override public void save(StreamProxyItem param, GeneralCallback callback) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index c5b7f58e2..2c1a47674 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -10,6 +10,10 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; @@ -28,7 +32,9 @@ import com.github.pagehelper.PageInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; @@ -85,6 +91,42 @@ public class StreamPushServiceImpl implements IStreamPushService { @Autowired private MediaConfig mediaConfig; + /** + * 流到来的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaArrivalEvent event) { + MediaInfo mediaInfo = event.getMediaInfo(); + if (mediaInfo == null) { + return; + } + if (mediaInfo.getOriginType() != OriginType.RTMP_PUSH.ordinal() + && mediaInfo.getOriginType() != OriginType.RTSP_PUSH.ordinal() + && mediaInfo.getOriginType() != OriginType.RTC_PUSH.ordinal()) { + return; + } + + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(event.getApp(), event.getStream()); + if (streamAuthorityInfo == null) { + streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(event); + } else { + streamAuthorityInfo.setOriginType(mediaInfo.getOriginType()); + } + redisCatchStorage.updateStreamAuthorityInfo(event.getApp(), event.getStream(), streamAuthorityInfo); + + + } + + /** + * 流离开的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaDepartureEvent event) { + + } + private List handleJSON(List streamInfoList) { if (streamInfoList == null || streamInfoList.isEmpty()) { From cad5f97c2f23435783886b6b5a4f1182391c529f Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 26 Mar 2024 10:28:08 +0800 Subject: [PATCH 23/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B5=81=E5=8F=98?= =?UTF-8?q?=E5=8C=96=E5=A4=84=E7=90=86=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/zlm/dto/StreamPushItem.java | 23 ++++++++++++++- .../service/impl/StreamPushServiceImpl.java | 29 ++++++++++++++++--- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java index 85d481a2c..eda660ebd 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.media.zlm.dto; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.bean.GbStream; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.utils.DateUtil; import io.swagger.v3.oas.annotations.media.Schema; @@ -151,7 +152,7 @@ public class StreamPushItem extends GbStream implements Comparable Date: Tue, 26 Mar 2024 11:42:38 +0800 Subject: [PATCH 24/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B5=81=E5=8F=98?= =?UTF-8?q?=E5=8C=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/AudioBroadcastManager.java | 60 +++++ .../service/impl/MediaServerServiceImpl.java | 6 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 215 +----------------- .../service/impl/InviteStreamServiceImpl.java | 8 +- .../vmp/service/impl/PlatformServiceImpl.java | 44 +++- .../iot/vmp/service/impl/PlayServiceImpl.java | 7 +- .../service/impl/StreamProxyServiceImpl.java | 2 +- .../service/impl/StreamPushServiceImpl.java | 41 +++- 8 files changed, 151 insertions(+), 232 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java index 343d2a6ec..bc5f02232 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java @@ -1,11 +1,26 @@ package com.genersoft.iot.vmp.gb28181.session; import com.genersoft.iot.vmp.conf.SipConfig; +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.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.service.IDeviceService; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import java.text.ParseException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -18,11 +33,56 @@ import java.util.stream.Stream; @Component public class AudioBroadcastManager { + private final static Logger logger = LoggerFactory.getLogger(AudioBroadcastManager.class); + @Autowired private SipConfig config; + @Autowired + private SIPCommander cmder; + + @Autowired + private IRedisCatchStorage redisCatchStorage; + + @Autowired + private IDeviceService deviceService; + public static Map data = new ConcurrentHashMap<>(); + /** + * 流离开的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaDepartureEvent event) { + List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream()); + if (!sendRtpItems.isEmpty()) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp())) { + String platformId = sendRtpItem.getPlatformId(); + Device device = deviceService.getDevice(platformId); + try { + if (device != null) { + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), event.getStream(), sendRtpItem.getCallId()); + if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) + || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { + AudioBroadcastCatch audioBroadcastCatch = get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + if (audioBroadcastCatch != null) { + // 来自上级平台的停止对讲 + logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + } + } + } + } catch (SipException | InvalidArgumentException | ParseException | + SsrcTransactionNotFoundException e) { + logger.error("[命令发送失败] 发送BYE: {}", e.getMessage()); + } + } + } + } + } + public void update(AudioBroadcastCatch audioBroadcastCatch) { if (SipUtils.isFrontEnd(audioBroadcastCatch.getDeviceId())) { audioBroadcastCatch.setChannelId(audioBroadcastCatch.getDeviceId()); diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index e4538e105..58f92f8cd 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -15,8 +15,6 @@ import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -85,7 +83,7 @@ public class MediaServerServiceImpl implements IMediaServerService { public void onApplicationEvent(MediaArrivalEvent event) { if ("rtsp".equals(event.getSchema())) { logger.info("流变化:注册 app->{}, stream->{}", event.getApp(), event.getStream()); - addCount(event.getSeverId()); + addCount(event.getMediaServer().getId()); } } @@ -97,7 +95,7 @@ public class MediaServerServiceImpl implements IMediaServerService { public void onApplicationEvent(MediaDepartureEvent event) { if ("rtsp".equals(event.getSchema())) { logger.info("流变化:注销, app->{}, stream->{}", event.getApp(), event.getStream()); - removeCount(event.getSeverId()); + removeCount(event.getMediaServer().getId()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index ca5261983..77ff9b01e 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -4,13 +4,10 @@ import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; 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.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; @@ -18,12 +15,14 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.*; +import com.genersoft.iot.vmp.media.zlm.dto.HookType; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; +import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; @@ -34,9 +33,6 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; -import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; -import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -233,209 +229,6 @@ public class ZLMHttpHookListener { applicationEventPublisher.publishEvent(mediaArrivalEvent); } return HookResult.SUCCESS(); - - - - JSONObject json = (JSONObject) JSON.toJSON(param); - taskExecutor.execute(() -> { - ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); - MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); - if (mediaInfo == null) { - logger.info("[ZLM HOOK] 流变化未找到ZLM, {}", param.getMediaServerId()); - return; - } - if (subscribe != null) { - subscribe.response(mediaInfo, param); - } - - // TODO 重构此处逻辑 - if (param.isRegist()) { - // 处理流注册的鉴权信息, 流注销这里不再删除鉴权信息,下次来了新的鉴权信息会对就的进行覆盖 - if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal() - || param.getOriginType() == OriginType.RTSP_PUSH.ordinal() - || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); - if (streamAuthorityInfo == null) { - streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); - } else { - streamAuthorityInfo.setOriginType(param.getOriginType()); - streamAuthorityInfo.setOriginTypeStr(param.getOriginTypeStr()); - } - redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); - } - } - if ("rtsp".equals(param.getSchema())) { - logger.info("流变化:注册->{}, app->{}, stream->{}", param.isRegist(), param.getApp(), param.getStream()); - if (param.isRegist()) { - mediaServerService.addCount(param.getMediaServerId()); - } else { - mediaServerService.removeCount(param.getMediaServerId()); - } - - int updateStatusResult = streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream()); - if (updateStatusResult > 0) { - - } - - if ("rtp".equals(param.getApp()) && !param.isRegist()) { - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); - if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) { - inviteStreamService.removeInviteInfo(inviteInfo); - storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); - } - } else if ("broadcast".equals(param.getApp())) { - // 语音对讲推流 stream需要满足格式deviceId_channelId - if (param.getStream().indexOf("_") > 0) { - String[] streamArray = param.getStream().split("_"); - if (streamArray.length == 2) { - String deviceId = streamArray[0]; - String channelId = streamArray[1]; - Device device = deviceService.getDevice(deviceId); - if (device != null) { - if (param.isRegist()) { - if (audioBroadcastManager.exit(deviceId, channelId)) { - playService.stopAudioBroadcast(deviceId, channelId); - } - // 开启语音对讲通道 - try { - playService.audioBroadcastCmd(device, channelId, mediaInfo, param.getApp(), param.getStream(), 60, false, (msg) -> { - logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); - }); - } catch (InvalidArgumentException | ParseException | SipException e) { - logger.error("[命令发送失败] 语音对讲: {}", e.getMessage()); - } - } else { - // 流注销 - playService.stopAudioBroadcast(deviceId, channelId); - } - } else { - logger.info("[语音对讲] 未找到设备:{}", deviceId); - } - } - } - } else if ("talk".equals(param.getApp())) { - // 语音对讲推流 stream需要满足格式deviceId_channelId - if (param.getStream().indexOf("_") > 0) { - String[] streamArray = param.getStream().split("_"); - if (streamArray.length == 2) { - String deviceId = streamArray[0]; - String channelId = streamArray[1]; - Device device = deviceService.getDevice(deviceId); - if (device != null) { - if (param.isRegist()) { - if (audioBroadcastManager.exit(deviceId, channelId)) { - playService.stopAudioBroadcast(deviceId, channelId); - } - // 开启语音对讲通道 - playService.talkCmd(device, channelId, mediaInfo, param.getStream(), (msg) -> { - logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); - }); - } else { - // 流注销 - playService.stopTalk(device, channelId, param.isRegist()); - } - } else { - logger.info("[语音对讲] 未找到设备:{}", deviceId); - } - } - } - - } else { - if (!"rtp".equals(param.getApp())) { - String type = OriginType.values()[param.getOriginType()].getType(); - if (param.isRegist()) { - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo( - param.getApp(), param.getStream()); - String callId = null; - if (streamAuthorityInfo != null) { - callId = streamAuthorityInfo.getCallId(); - } - StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo, - param.getApp(), param.getStream(), MediaInfo.getInstance(param), callId); - param.setStreamInfo(new StreamContent(streamInfoByAppAndStream)); - redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param); - if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() - || param.getOriginType() == OriginType.RTMP_PUSH.ordinal() - || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { - param.setSeverId(userSetting.getServerId()); - zlmMediaListManager.addPush(param); - - // 冗余数据,自己系统中自用 - redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param); - } - } else { - // 兼容流注销时类型从redis记录获取 - OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo( - param.getApp(), param.getStream(), param.getMediaServerId()); - if (onStreamChangedHookParam != null) { - type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType(); - redisCatchStorage.removeStream(mediaInfo.getId(), type, param.getApp(), param.getStream()); - if ("PUSH".equalsIgnoreCase(type)) { - // 冗余数据,自己系统中自用 - redisCatchStorage.removePushListItem(param.getApp(), param.getStream(), param.getMediaServerId()); - } - } - GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream()); - if (gbStream != null) { -// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); - } - zlmMediaListManager.removeMedia(param.getApp(), param.getStream()); - } - GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream()); - if (gbStream != null) { - if (userSetting.isUsePushingAsStatus()) { - eventPublisher.catalogEventPublishForStream(null, gbStream, param.isRegist() ? CatalogEvent.ON : CatalogEvent.OFF); - } - } - if (type != null) { - // 发送流变化redis消息 - JSONObject jsonObject = new JSONObject(); - jsonObject.put("serverId", userSetting.getServerId()); - jsonObject.put("app", param.getApp()); - jsonObject.put("stream", param.getStream()); - jsonObject.put("register", param.isRegist()); - jsonObject.put("mediaServerId", param.getMediaServerId()); - redisCatchStorage.sendStreamChangeMsg(type, jsonObject); - } - } - } - if (!param.isRegist()) { - List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream()); - if (!sendRtpItems.isEmpty()) { - for (SendRtpItem sendRtpItem : sendRtpItems) { - if (sendRtpItem != null && sendRtpItem.getApp().equals(param.getApp())) { - String platformId = sendRtpItem.getPlatformId(); - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); - Device device = deviceService.getDevice(platformId); - - try { - if (platform != null) { - commanderFroPlatform.streamByeCmd(platform, sendRtpItem); - redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), - sendRtpItem.getCallId(), sendRtpItem.getStream()); - } else { - cmder.streamByeCmd(device, sendRtpItem.getChannelId(), param.getStream(), sendRtpItem.getCallId()); - if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) - || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { - AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - if (audioBroadcastCatch != null) { - // 来自上级平台的停止对讲 - logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - } - } - } - } catch (SipException | InvalidArgumentException | ParseException | - SsrcTransactionNotFoundException e) { - logger.error("[命令发送失败] 发送BYE: {}", e.getMessage()); - } - } - } - } - } - } - }); - return HookResult.SUCCESS(); } /** diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java index 014c76169..360e29c0f 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java @@ -45,9 +45,9 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @Async("taskExecutor") @org.springframework.context.event.EventListener public void onApplicationEvent(MediaArrivalEvent event) { - if ("rtsp".equals(event.getSchema()) && "rtp".equals(event.getApp())) { - - } +// if ("rtsp".equals(event.getSchema()) && "rtp".equals(event.getApp())) { +// +// } } /** @@ -60,7 +60,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService { InviteInfo inviteInfo = getInviteInfoByStream(null, event.getStream()); if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) { removeInviteInfo(inviteInfo); - stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); + storage.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 4de8420e8..54e06c200 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -1,9 +1,9 @@ package com.genersoft.iot.vmp.service.impl; +import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.InviteInfo; import com.genersoft.iot.vmp.common.InviteSessionStatus; import com.genersoft.iot.vmp.common.InviteSessionType; -import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; @@ -12,18 +12,20 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IInviteStreamService; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.dao.*; +import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; +import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; import com.genersoft.iot.vmp.utils.DateUtil; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; @@ -31,6 +33,8 @@ import gov.nist.javax.sip.message.SIPResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import javax.sdp.*; @@ -38,10 +42,6 @@ import javax.sip.InvalidArgumentException; import javax.sip.ResponseEvent; import javax.sip.SipException; import java.text.ParseException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; import java.util.*; /** @@ -101,6 +101,34 @@ public class PlatformServiceImpl implements IPlatformService { private IInviteStreamService inviteStreamService; + /** + * 流离开的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaDepartureEvent event) { + List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream()); + if (!sendRtpItems.isEmpty()) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp())) { + String platformId = sendRtpItem.getPlatformId(); + ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformId); + + try { + if (platform != null) { + commanderForPlatform.streamByeCmd(platform, sendRtpItem); + redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), + sendRtpItem.getCallId(), sendRtpItem.getStream()); + } + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 发送BYE: {}", e.getMessage()); + } + } + } + } + } + + @Override public ParentPlatform queryPlatformByServerGBId(String platformGbId) { return platformMapper.getParentPlatByServerGBId(platformGbId); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 65cf69365..722139e91 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -23,11 +23,13 @@ import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.*; +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4; +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; @@ -188,7 +190,6 @@ public class PlayServiceImpl implements IPlayService { }else if ("talk".equals(event.getApp())) { stopTalk(device, channelId, false); } - } } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index dd0eae2b0..02c5b30d1 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -124,7 +124,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @EventListener public void onApplicationEvent(MediaDepartureEvent event) { if ("rtsp".equals(event.getSchema())) { - updateStatus(true, event.getApp(), event.getStream()); + updateStatus(false, event.getApp(), event.getStream()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index c3128e820..dd0e8854d 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -126,6 +126,7 @@ public class StreamPushServiceImpl implements IStreamPushService { streamPushMapper.update(transform); gbStreamMapper.updateMediaServer(event.getApp(), event.getStream(), event.getMediaServer().getId()); } + // TODO 相关的事件自行管理,不需要写入ZLMMediaListManager // ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(transform.getApp(), transform.getStream()); // if ( channelOnlineEventLister != null) { // try { @@ -137,6 +138,15 @@ public class StreamPushServiceImpl implements IStreamPushService { // } // 冗余数据,自己系统中自用 redisCatchStorage.addPushListItem(event.getApp(), event.getStream(), event); + + // 发送流变化redis消息 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("serverId", userSetting.getServerId()); + jsonObject.put("app", event.getApp()); + jsonObject.put("stream", event.getStream()); + jsonObject.put("register", true); + jsonObject.put("mediaServerId", event.getMediaServer().getId()); + redisCatchStorage.sendStreamChangeMsg(OriginType.values()[event.getMediaInfo().getOriginType()].getType(), jsonObject); } /** @@ -145,7 +155,36 @@ public class StreamPushServiceImpl implements IStreamPushService { @Async("taskExecutor") @EventListener public void onApplicationEvent(MediaDepartureEvent event) { - + // 兼容流注销时类型从redis记录获取 + OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo( + event.getApp(), event.getStream(), event.getMediaServer().getId()); + if (onStreamChangedHookParam != null) { + String type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType(); + redisCatchStorage.removeStream(event.getMediaServer().getId(), type, event.getApp(), event.getStream()); + if ("PUSH".equalsIgnoreCase(type)) { + // 冗余数据,自己系统中自用 + redisCatchStorage.removePushListItem(event.getApp(), event.getStream(), event.getMediaServer().getId()); + } + if (type != null) { + // 发送流变化redis消息 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("serverId", userSetting.getServerId()); + jsonObject.put("app", event.getApp()); + jsonObject.put("stream", event.getStream()); + jsonObject.put("register", false); + jsonObject.put("mediaServerId", event.getMediaServer().getId()); + redisCatchStorage.sendStreamChangeMsg(type, jsonObject); + } + } + GbStream gbStream = storager.getGbStream(event.getApp(), event.getStream()); + if (gbStream != null) { + if (userSetting.isUsePushingAsStatus()) { + storager.mediaOffline(event.getApp(), event.getStream()); + eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); + } + }else { + storager.removeMedia(event.getApp(), event.getStream()); + } } From 1ce30e6656a9513cd753e20db3ea38f3c646d4eb Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 26 Mar 2024 17:49:56 +0800 Subject: [PATCH 25/58] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/zlm/ZLMHttpHookListener.java | 103 ++-------------- .../iot/vmp/service/IMediaService.java | 2 + .../vmp/service/impl/MediaServiceImpl.java | 113 +++++++++++++++++- 3 files changed, 120 insertions(+), 98 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 77ff9b01e..a5b78ed86 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -241,98 +241,9 @@ public class ZLMHttpHookListener { logger.info("[ZLM HOOK]流无人观看:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); JSONObject ret = new JSONObject(); - ret.put("code", 0); - // 国标类型的流 - if ("rtp".equals(param.getApp())) { - ret.put("close", userSetting.getStreamOnDemand()); - // 国标流, 点播/录像回放/录像下载 - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); - // 点播 - if (inviteInfo != null) { - // 录像下载 - if (inviteInfo.getType() == InviteSessionType.DOWNLOAD) { - ret.put("close", false); - return ret; - } - // 收到无人观看说明流也没有在往上级推送 - if (redisCatchStorage.isChannelSendingRTP(inviteInfo.getChannelId())) { - List sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId( - inviteInfo.getChannelId()); - if (!sendRtpItems.isEmpty()) { - for (SendRtpItem sendRtpItem : sendRtpItems) { - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); - try { - commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); - } - redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(), - sendRtpItem.getCallId(), sendRtpItem.getStream()); - if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) { - MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, - sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), - sendRtpItem.getPlatformId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); - messageForPushChannel.setPlatFormIndex(parentPlatform.getId()); - redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); - } - } - } - } - Device device = deviceService.getDevice(inviteInfo.getDeviceId()); - if (device != null) { - try { - // 多查询一次防止已经被处理了 - InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(), - inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream()); - if (info != null) { - cmder.streamByeCmd(device, inviteInfo.getChannelId(), - inviteInfo.getStream(), null); - } else { - logger.info("[无人观看] 未找到设备的点播信息: {}, 流:{}", inviteInfo.getDeviceId(), param.getStream()); - } - } catch (InvalidArgumentException | ParseException | SipException | - SsrcTransactionNotFoundException e) { - logger.error("[无人观看]点播, 发送BYE失败 {}", e.getMessage()); - } - } else { - logger.info("[无人观看] 未找到设备: {},流:{}", inviteInfo.getDeviceId(), param.getStream()); - } - inviteStreamService.removeInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), - inviteInfo.getChannelId(), inviteInfo.getStream()); - storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); - return ret; - } - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null); - if (sendRtpItem != null && "talk".equals(sendRtpItem.getApp())) { - ret.put("close", false); - return ret; - } - } else if ("talk".equals(param.getApp()) || "broadcast".equals(param.getApp())) { - ret.put("close", false); - } else { - // 非国标流 推流/拉流代理 - // 拉流代理 - StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); - if (streamProxyItem != null) { - if (streamProxyItem.isEnableRemoveNoneReader()) { - // 无人观看自动移除 - ret.put("close", true); - streamProxyService.del(param.getApp(), param.getStream()); - String url = streamProxyItem.getUrl() != null ? streamProxyItem.getUrl() : streamProxyItem.getSrcUrl(); - logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", param.getApp(), param.getStream(), url); - } else if (streamProxyItem.isEnableDisableNoneReader()) { - // 无人观看停用 - ret.put("close", true); - // 修改数据 - streamProxyService.stop(param.getApp(), param.getStream()); - } else { - // 无人观看不做处理 - ret.put("close", false); - } - return ret; - } - } + boolean close = mediaService.closeStreamOnNoneReader(param.getMediaServerId(), param.getApp(), param.getStream(), param.getSchema()); + ret.put("code", close); return ret; } @@ -346,8 +257,8 @@ public class ZLMHttpHookListener { DeferredResult defaultResult = new DeferredResult<>(); - MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); - if (!userSetting.isAutoApplyPlay() || mediaInfo == null) { + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (!userSetting.isAutoApplyPlay() || mediaServer == null) { defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); return defaultResult; } @@ -392,7 +303,7 @@ public class ZLMHttpHookListener { resultHolder.put(key, uuid, result); if (!exist) { - playService.play(mediaInfo, deviceId, channelId, null, (code, message, data) -> { + playService.play(mediaServer, deviceId, channelId, null, (code, message, data) -> { msg.setData(new HookResult(code, message)); resultHolder.invokeResult(msg); }); @@ -431,9 +342,9 @@ public class ZLMHttpHookListener { resultHolder.put(key, uuid, result); if (!exist) { - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaInfo, param.getStream(), null, + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServer, param.getStream(), null, device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); - playService.playBack(mediaInfo, ssrcInfo, deviceId, channelId, startTime, endTime, (code, message, data) -> { + playService.playBack(mediaServer, ssrcInfo, deviceId, channelId, startTime, endTime, (code, message, data) -> { msg.setData(new HookResult(code, message)); resultHolder.invokeResult(msg); }); diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java index 490545590..d3a57f7af 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java @@ -49,4 +49,6 @@ public interface IMediaService { boolean authenticatePlay(String app, String stream, String callId); ResultForOnPublish authenticatePublish(MediaServer mediaServer, String app, String stream, String params); + + boolean closeStreamOnNoneReader(String mediaServerId, String app, String stream, String schema); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 21c3472cf..e57c7eaf5 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -7,9 +7,11 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; +import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; +import com.genersoft.iot.vmp.gb28181.bean.*; 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.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -22,6 +24,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResultForOnPublish; import com.genersoft.iot.vmp.service.*; +import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; @@ -35,6 +38,9 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import java.text.ParseException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -77,6 +83,15 @@ public class MediaServiceImpl implements IMediaService { @Autowired private ZLMMediaListManager zlmMediaListManager; + @Autowired + private IDeviceService deviceService; + + @Autowired + private ISIPCommanderForPlatform commanderForPlatform; + + @Autowired + private ISIPCommander commander; + @Override @@ -291,4 +306,98 @@ public class MediaServiceImpl implements IMediaService { } return map; } + + @Override + public boolean closeStreamOnNoneReader(String mediaServerId, String app, String stream, String schema) { + boolean result = false; + // 国标类型的流 + if ("rtp".equals(app)) { + result = userSetting.getStreamOnDemand(); + // 国标流, 点播/录像回放/录像下载 + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, stream); + // 点播 + if (inviteInfo != null) { + // 录像下载 + if (inviteInfo.getType() == InviteSessionType.DOWNLOAD) { + return false; + } + // 收到无人观看说明流也没有在往上级推送 + if (redisCatchStorage.isChannelSendingRTP(inviteInfo.getChannelId())) { + List sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId( + inviteInfo.getChannelId()); + if (!sendRtpItems.isEmpty()) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); + try { + commanderForPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); + } + redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(), + sendRtpItem.getCallId(), sendRtpItem.getStream()); + if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) { + MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, + sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), + sendRtpItem.getPlatformId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); + messageForPushChannel.setPlatFormIndex(parentPlatform.getId()); + redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); + } + } + } + } + Device device = deviceService.getDevice(inviteInfo.getDeviceId()); + if (device != null) { + try { + // 多查询一次防止已经被处理了 + InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(), + inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream()); + if (info != null) { + commander.streamByeCmd(device, inviteInfo.getChannelId(), + inviteInfo.getStream(), null); + } else { + logger.info("[无人观看] 未找到设备的点播信息: {}, 流:{}", inviteInfo.getDeviceId(), stream); + } + } catch (InvalidArgumentException | ParseException | SipException | + SsrcTransactionNotFoundException e) { + logger.error("[无人观看]点播, 发送BYE失败 {}", e.getMessage()); + } + } else { + logger.info("[无人观看] 未找到设备: {},流:{}", inviteInfo.getDeviceId(), stream); + } + + inviteStreamService.removeInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), + inviteInfo.getChannelId(), inviteInfo.getStream()); + storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); + return result; + } + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, stream, null); + if (sendRtpItem != null && "talk".equals(sendRtpItem.getApp())) { + return false; + } + } else if ("talk".equals(app) || "broadcast".equals(app)) { + return false; + } else { + // 非国标流 推流/拉流代理 + // 拉流代理 + StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(app, stream); + if (streamProxyItem != null) { + if (streamProxyItem.isEnableRemoveNoneReader()) { + // 无人观看自动移除 + result = true; + streamProxyService.del(app, stream); + String url = streamProxyItem.getUrl() != null ? streamProxyItem.getUrl() : streamProxyItem.getSrcUrl(); + logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", app, stream, url); + } else if (streamProxyItem.isEnableDisableNoneReader()) { + // 无人观看停用 + result = true; + // 修改数据 + streamProxyService.stop(app, stream); + } else { + // 无人观看不做处理 + result = false; + } + } + } + return result; + } } From f218d7bbd68a2dee9863b294102d27a76a6e3fbf Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 26 Mar 2024 23:16:08 +0800 Subject: [PATCH 26/58] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8F=91=E9=80=81?= =?UTF-8?q?=E6=B5=81=E6=B2=A1=E6=89=BE=E5=88=B0=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/event/MediaNotFoundEvent.java | 64 +++++++++++++++++++ .../vmp/media/zlm/ZLMHttpHookListener.java | 5 ++ 2 files changed, 69 insertions(+) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java new file mode 100644 index 000000000..2f8a8405b --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java @@ -0,0 +1,64 @@ +package com.genersoft.iot.vmp.media.event; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; +import org.springframework.context.ApplicationEvent; + +/** + * 流未找到 + */ +public class MediaNotFoundEvent extends ApplicationEvent { + public MediaNotFoundEvent(Object source) { + super(source); + } + + private String app; + + private String stream; + + private MediaServer mediaServer; + + private String schema; + + public static MediaNotFoundEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){ + MediaNotFoundEvent mediaDepartureEven = new MediaNotFoundEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setSchema(hookParam.getSchema()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public MediaServer getMediaServer() { + return mediaServer; + } + + public void setMediaServer(MediaServer mediaServer) { + this.mediaServer = mediaServer; + } + + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index a5b78ed86..702cc0deb 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; @@ -262,6 +263,10 @@ public class ZLMHttpHookListener { defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); return defaultResult; } + MediaNotFoundEvent mediaNotFoundEvent = MediaNotFoundEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaNotFoundEvent); + + if ("rtp".equals(param.getApp())) { String[] s = param.getStream().split("_"); From 0c2180c07fd26c04f8d49aa7c7968a09b9c06d46 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 26 Mar 2024 23:36:55 +0800 Subject: [PATCH 27/58] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=B5=81=E6=B2=A1=E6=89=BE=E5=88=B0=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/zlm/ZLMHttpHookListener.java | 112 +----------------- .../iot/vmp/service/impl/PlayServiceImpl.java | 52 ++++++++ .../service/impl/StreamProxyServiceImpl.java | 19 +++ 3 files changed, 74 insertions(+), 109 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 702cc0deb..71ceb2e30 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -253,123 +253,17 @@ public class ZLMHttpHookListener { */ @ResponseBody @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") - public DeferredResult onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param) { + public HookResult onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param) { logger.info("[ZLM HOOK] 流未找到:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); - DeferredResult defaultResult = new DeferredResult<>(); MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); if (!userSetting.isAutoApplyPlay() || mediaServer == null) { - defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); - return defaultResult; + return HookResult.SUCCESS(); } MediaNotFoundEvent mediaNotFoundEvent = MediaNotFoundEvent.getInstance(this, param, mediaServer); applicationEventPublisher.publishEvent(mediaNotFoundEvent); - - - - if ("rtp".equals(param.getApp())) { - String[] s = param.getStream().split("_"); - if ((s.length != 2 && s.length != 4)) { - defaultResult.setResult(HookResult.SUCCESS()); - return defaultResult; - } - String deviceId = s[0]; - String channelId = s[1]; - Device device = redisCatchStorage.getDevice(deviceId); - if (device == null || !device.isOnLine()) { - defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); - return defaultResult; - } - DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); - if (deviceChannel == null) { - defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); - return defaultResult; - } - if (s.length == 2) { - logger.info("[ZLM HOOK] 预览流未找到, 发起自动点播:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); - - RequestMessage msg = new RequestMessage(); - String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; - boolean exist = resultHolder.exist(key, null); - msg.setKey(key); - String uuid = UUID.randomUUID().toString(); - msg.setId(uuid); - DeferredResult result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); - - result.onTimeout(() -> { - logger.info("[ZLM HOOK] 预览流自动点播, 等待超时"); - msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时")); - resultHolder.invokeAllResult(msg); - inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); - storager.stopPlay(deviceId, channelId); - }); - - resultHolder.put(key, uuid, result); - - if (!exist) { - playService.play(mediaServer, deviceId, channelId, null, (code, message, data) -> { - msg.setData(new HookResult(code, message)); - resultHolder.invokeResult(msg); - }); - } - return result; - } else if (s.length == 4) { - // 此时为录像回放, 录像回放格式为> 设备ID_通道ID_开始时间_结束时间 - String startTimeStr = s[2]; - String endTimeStr = s[3]; - if (startTimeStr == null || endTimeStr == null || startTimeStr.length() != 14 || endTimeStr.length() != 14) { - defaultResult.setResult(HookResult.SUCCESS()); - return defaultResult; - } - String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr); - String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr); - logger.info("[ZLM HOOK] 回放流未找到, 发起自动点播:{}->{}->{}/{}-{}-{}", - param.getMediaServerId(), param.getSchema(), - param.getApp(), param.getStream(), - startTime, endTime - ); - RequestMessage msg = new RequestMessage(); - String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId; - boolean exist = resultHolder.exist(key, null); - msg.setKey(key); - String uuid = UUID.randomUUID().toString(); - msg.setId(uuid); - DeferredResult result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); - - result.onTimeout(() -> { - logger.info("[ZLM HOOK] 回放流自动点播, 等待超时"); - // 释放rtpserver - msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时")); - resultHolder.invokeResult(msg); - }); - - resultHolder.put(key, uuid, result); - - if (!exist) { - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServer, param.getStream(), null, - device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); - playService.playBack(mediaServer, ssrcInfo, deviceId, channelId, startTime, endTime, (code, message, data) -> { - msg.setData(new HookResult(code, message)); - resultHolder.invokeResult(msg); - }); - } - return result; - } else { - defaultResult.setResult(HookResult.SUCCESS()); - return defaultResult; - } - - } else { - // 拉流代理 - StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); - if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnableDisableNoneReader()) { - streamProxyService.start(param.getApp(), param.getStream()); - } - DeferredResult result = new DeferredResult<>(); - result.setResult(HookResult.SUCCESS()); - return result; - } + return HookResult.SUCCESS(); } /** diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 722139e91..31a43c9dd 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -13,12 +13,15 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; @@ -28,6 +31,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResult; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.*; @@ -49,6 +53,7 @@ import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; +import org.springframework.web.context.request.async.DeferredResult; import javax.sdp.*; import javax.sip.InvalidArgumentException; @@ -195,6 +200,53 @@ public class PlayServiceImpl implements IPlayService { } } + /** + * 流未找到的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaNotFoundEvent event) { + if (!"rtp".equals(event.getApp())) { + return; + } + String[] s = event.getStream().split("_"); + if ((s.length != 2 && s.length != 4)) { + return; + } + String deviceId = s[0]; + String channelId = s[1]; + Device device = redisCatchStorage.getDevice(deviceId); + if (device == null || !device.isOnLine()) { + return; + } + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); + if (deviceChannel == null) { + return; + } + if (s.length == 2) { + logger.info("[ZLM HOOK] 预览流未找到, 发起自动点播:{}->{}->{}/{}", event.getMediaServer().getId(), event.getSchema(), event.getApp(), event.getStream()); + play(event.getMediaServer(), deviceId, channelId, null, null); + } else if (s.length == 4) { + // 此时为录像回放, 录像回放格式为> 设备ID_通道ID_开始时间_结束时间 + String startTimeStr = s[2]; + String endTimeStr = s[3]; + if (startTimeStr == null || endTimeStr == null || startTimeStr.length() != 14 || endTimeStr.length() != 14) { + return; + } + String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr); + String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr); + logger.info("[ZLM HOOK] 回放流未找到, 发起自动点播:{}->{}->{}/{}-{}-{}", + event.getMediaServer().getId(), event.getSchema(), + event.getApp(), event.getStream(), + startTime, endTime + ); + + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(event.getMediaServer(), event.getStream(), null, + device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); + playBack(event.getMediaServer(), ssrcInfo, deviceId, channelId, startTime, endTime, null); + } + } + @Override public SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback callback) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 02c5b30d1..0713ab35a 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; @@ -18,6 +19,7 @@ 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.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResult; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.service.IMediaService; @@ -44,6 +46,7 @@ import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; +import org.springframework.web.context.request.async.DeferredResult; import java.util.HashMap; import java.util.List; @@ -128,6 +131,22 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } } + /** + * 流离开的处理 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaNotFoundEvent event) { + if ("rtp".equals(event.getApp())) { + return; + } + // 拉流代理 + StreamProxyItem streamProxyByAppAndStream = getStreamProxyByAppAndStream(event.getApp(), event.getStream()); + if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnableDisableNoneReader()) { + start(event.getApp(), event.getStream()); + } + } + @Override public void save(StreamProxyItem param, GeneralCallback callback) { From 6de0c329ea9aceaee398356fb4aab99b37508d07 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 26 Mar 2024 23:38:49 +0800 Subject: [PATCH 28/58] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84=E8=8A=82=E7=82=B9=E5=90=AF=E5=8A=A8=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=88=86=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/zlm/ZLMHttpHookListener.java | 8 ---- .../media/zlm/dto/HookSubscribeFactory.java | 8 ---- .../dto/HookSubscribeForServerStarted.java | 44 ------------------- 3 files changed, 60 deletions(-) delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForServerStarted.java diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 71ceb2e30..42f5e28a0 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -277,14 +277,6 @@ public class ZLMHttpHookListener { ZLMServerConfig zlmServerConfig = JSON.to(ZLMServerConfig.class, jsonObject); zlmServerConfig.setIp(request.getRemoteAddr()); logger.info("[ZLM HOOK] zlm 启动 " + zlmServerConfig.getGeneralMediaServerId()); - taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_server_started); - if (subscribes != null && !subscribes.isEmpty()) { - for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { - subscribe.response(null, zlmServerConfig); - } - } - }); try { HookZlmServerStartEvent event = new HookZlmServerStartEvent(this); MediaServer mediaServerItem = mediaServerService.getOne(zlmServerConfig.getMediaServerId()); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeFactory.java index f828bdd8b..417251f0c 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeFactory.java @@ -49,14 +49,6 @@ public class HookSubscribeFactory { return hookSubscribe; } - - public static HookSubscribeForServerStarted on_server_started() { - HookSubscribeForServerStarted hookSubscribe = new HookSubscribeForServerStarted(); - hookSubscribe.setContent(new JSONObject()); - - return hookSubscribe; - } - public static HookSubscribeForRecordMp4 on_record_mp4(String mediaServerId, String app, String stream) { HookSubscribeForRecordMp4 hookSubscribe = new HookSubscribeForRecordMp4(); JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForServerStarted.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForServerStarted.java deleted file mode 100755 index 8bcde0a05..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForServerStarted.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm.dto; - -import com.alibaba.fastjson2.JSONObject; -import com.alibaba.fastjson2.annotation.JSONField; - -import java.time.Instant; - -/** - * hook订阅-流变化 - * @author lin - */ -public class HookSubscribeForServerStarted implements IHookSubscribe{ - - private HookType hookType = HookType.on_server_started; - - private JSONObject content; - - @JSONField(format="yyyy-MM-dd HH:mm:ss") - private Instant expires; - - @Override - public HookType getHookType() { - return hookType; - } - - @Override - public JSONObject getContent() { - return content; - } - - public void setContent(JSONObject content) { - this.content = content; - } - - @Override - public Instant getExpires() { - return expires; - } - - @Override - public void setExpires(Instant expires) { - this.expires = expires; - } -} From f3ac974036be387e8636029415888620cae54a7b Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Thu, 28 Mar 2024 17:12:31 +0800 Subject: [PATCH 29/58] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/gb28181/transmit/cmd/impl/SIPCommander.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index fcbe6d4c4..e86418f54 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -7,10 +7,6 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.SipLayer; import com.genersoft.iot.vmp.gb28181.bean.*; -import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; @@ -18,14 +14,13 @@ 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.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 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.HookSubscribeForStreamPush; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.message.SIPRequest; @@ -618,8 +613,8 @@ public class SIPCommander implements ISIPCommander { CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); callIdHeader.setCallId(callId); - HookSubscribeForStreamPush hookSubscribeForStreamPush = HookSubscribeFactory.on_publish("rtp", stream, null, mediaServerItem.getId()); - subscribe.addSubscribe(hookSubscribeForStreamPush, (mediaServerItemInUse, hookParam) -> { + HookSubscribeForStreamChange subscribeForStreamChange = HookSubscribeFactory.on_stream_changed("rtp", stream, true,"rtsp", mediaServerItem.getId()); + subscribe.addSubscribe(subscribeForStreamChange, (mediaServerItemInUse, hookParam) -> { if (eventForPush != null) { eventForPush.response(mediaServerItemInUse, hookParam); } From cc793d16f5114122304573e452bcef9dd23d32c2 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Thu, 28 Mar 2024 18:35:28 +0800 Subject: [PATCH 30/58] =?UTF-8?q?=E8=B0=83=E6=95=B4hook=E8=AE=A2=E9=98=85?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E7=9A=84=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gb28181/transmit/cmd/ISIPCommander.java | 10 ++++---- .../cmd/ISIPCommanderForPlatform.java | 4 ++-- .../transmit/cmd/impl/SIPCommander.java | 17 ++++++------- .../cmd/impl/SIPCommanderFroPlatform.java | 6 ++--- .../request/impl/AckRequestProcessor.java | 4 ++-- .../request/impl/InviteRequestProcessor.java | 4 ++-- .../cmd/MediaStatusNotifyMessageHandler.java | 4 ++-- .../vmp/media/abl/ABLHttpHookListener.java | 22 ++++++++--------- .../HookSubscribe.java} | 24 +++++++++---------- .../vmp/media/zlm/ZLMHttpHookListener.java | 24 ++++++------------- .../vmp/media/zlm/ZLMMediaListManager.java | 3 ++- .../iot/vmp/media/zlm/ZLMServerFactory.java | 3 ++- .../iot/vmp/service/IPlatformService.java | 4 ++-- .../vmp/service/impl/MediaServiceImpl.java | 4 ---- .../vmp/service/impl/PlatformServiceImpl.java | 6 ++--- .../iot/vmp/service/impl/PlayServiceImpl.java | 16 +++++-------- .../service/impl/StreamProxyServiceImpl.java | 6 ++--- .../redisMsg/RedisGbPlayMsgListener.java | 4 ++-- .../iot/vmp/vmanager/ps/PsController.java | 4 ++-- .../iot/vmp/vmanager/rtp/RtpController.java | 4 ++-- .../vmp/vmanager/server/ServerController.java | 4 ++-- 21 files changed, 80 insertions(+), 97 deletions(-) rename src/main/java/com/genersoft/iot/vmp/media/{zlm/ZlmHttpHookSubscribe.java => event/HookSubscribe.java} (85%) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index f30ead17d..6a54a340e 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import gov.nist.javax.sip.message.SIPRequest; @@ -100,7 +100,7 @@ public interface ISIPCommander { * @param device 视频设备 * @param channel 预览通道 */ - void playStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; + void playStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, HookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; /** * 请求回放视频流 @@ -110,7 +110,7 @@ public interface ISIPCommander { * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss */ - void playbackStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; + void playbackStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime, HookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; /** * 请求历史媒体下载 @@ -122,7 +122,7 @@ public interface ISIPCommander { * @param downloadSpeed 下载倍速参数 */ void downloadStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, - String startTime, String endTime, int downloadSpeed, ZlmHttpHookSubscribe.Event hookEvent, + String startTime, String endTime, int downloadSpeed, HookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; @@ -131,7 +131,7 @@ public interface ISIPCommander { */ void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException; - void talkStreamCmd(MediaServer mediaServerItem, SendRtpItem sendRtpItem, Device device, String channelId, String callId, ZlmHttpHookSubscribe.Event event, ZlmHttpHookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; + void talkStreamCmd(MediaServer mediaServerItem, SendRtpItem sendRtpItem, Device device, String channelId, String callId, HookSubscribe.Event event, HookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; void streamByeCmd(Device device, String channelId, String stream, String callId) throws InvalidArgumentException, ParseException, SipException, SsrcTransactionNotFoundException; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java index 5c088d50e..d222e71ad 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -155,7 +155,7 @@ public interface ISIPCommanderForPlatform { void streamByeCmd(ParentPlatform platform, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException; void broadcastInviteCmd(ParentPlatform platform, String channelId, MediaServer mediaServerItem, - SSRCInfo ssrcInfo, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, + SSRCInfo ssrcInfo, HookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws ParseException, SipException, InvalidArgumentException; void broadcastResultCmd(ParentPlatform platform, DeviceChannel deviceChannel, String sn, boolean result, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index e86418f54..338f4679b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -16,9 +16,10 @@ import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; 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.HookSubscribeForStreamPush; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -71,7 +72,7 @@ public class SIPCommander implements ISIPCommander { private UserSetting userSetting; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private IMediaServerService mediaServerService; @@ -270,7 +271,7 @@ public class SIPCommander implements ISIPCommander { */ @Override public void playStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel, - ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { + HookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { String stream = ssrcInfo.getStream(); if (device == null) { @@ -379,7 +380,7 @@ public class SIPCommander implements ISIPCommander { */ @Override public void playbackStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, - String startTime, String endTime, ZlmHttpHookSubscribe.Event hookEvent, + String startTime, String endTime, HookSubscribe.Event hookEvent, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { @@ -482,7 +483,7 @@ public class SIPCommander implements ISIPCommander { @Override public void downloadStreamCmd(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, int downloadSpeed, - ZlmHttpHookSubscribe.Event hookEvent, + HookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); @@ -589,7 +590,7 @@ public class SIPCommander implements ISIPCommander { } @Override - public void talkStreamCmd(MediaServer mediaServerItem, SendRtpItem sendRtpItem, Device device, String channelId, String callId, ZlmHttpHookSubscribe.Event event, ZlmHttpHookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { + public void talkStreamCmd(MediaServer mediaServerItem, SendRtpItem sendRtpItem, Device device, String channelId, String callId, HookSubscribe.Event event, HookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { String stream = sendRtpItem.getStream(); @@ -613,8 +614,8 @@ public class SIPCommander implements ISIPCommander { CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); callIdHeader.setCallId(callId); - HookSubscribeForStreamChange subscribeForStreamChange = HookSubscribeFactory.on_stream_changed("rtp", stream, true,"rtsp", mediaServerItem.getId()); - subscribe.addSubscribe(subscribeForStreamChange, (mediaServerItemInUse, hookParam) -> { + HookSubscribeForStreamPush hookSubscribeForStreamPush = HookSubscribeFactory.on_publish("rtp", stream, null, mediaServerItem.getId()); + subscribe.addSubscribe(hookSubscribeForStreamPush, (mediaServerItemInUse, hookParam) -> { if (eventForPush != null) { eventForPush.response(mediaServerItemInUse, hookParam); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 8eec48dd2..0e969d968 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; 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.ZLMServerFactory; @@ -76,7 +76,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { private SIPSender sipSender; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private UserSetting userSetting; @@ -896,7 +896,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @Override public void broadcastInviteCmd(ParentPlatform platform, String channelId, MediaServer mediaServerItem, - SSRCInfo ssrcInfo, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, + SSRCInfo ssrcInfo, HookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws ParseException, SipException, InvalidArgumentException { String stream = ssrcInfo.getStream(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index a27ad44a7..0fdc38d7f 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -69,7 +69,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In private ZLMServerFactory zlmServerFactory; @Autowired - private ZlmHttpHookSubscribe hookSubscribe; + private HookSubscribe hookSubscribe; @Autowired private IMediaServerService mediaServerService; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 0f83bd8fb..616c1a0b1 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -21,7 +21,7 @@ import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.*; @@ -113,7 +113,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements private IMediaServerService mediaServerService; @Autowired - private ZlmHttpHookSubscribe zlmHttpHookSubscribe; + private HookSubscribe zlmHttpHookSubscribe; @Autowired private SIPProcessorObserver sipProcessorObserver; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java index 55094f981..6ad345233 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.service.IInviteStreamService; @@ -64,7 +64,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i private VideoStreamSessionManager sessionManager; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private IInviteStreamService inviteStreamService; diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java index e3c19b1b3..aa49ac1b0 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java @@ -22,7 +22,7 @@ import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; @@ -108,7 +108,7 @@ public class ABLHttpHookListener { private ZLMMediaListManager zlmMediaListManager; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private UserSetting userSetting; @@ -168,7 +168,7 @@ public class ABLHttpHookListener { taskExecutor.execute(() -> { JSONObject json = (JSONObject) JSON.toJSON(param); - ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); + HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); if (subscribe != null) { MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { @@ -247,7 +247,7 @@ public class ABLHttpHookListener { HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); result.setEnable_audio(true); taskExecutor.execute(() -> { - ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); + HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); if (subscribe != null) { subscribe.response(mediaInfo, param); } @@ -346,7 +346,7 @@ public class ABLHttpHookListener { JSONObject json = (JSONObject) JSON.toJSON(param); taskExecutor.execute(() -> { - ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); + HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); if (mediaInfo == null) { logger.info("[ABL HOOK] 流变化未找到ABL, {}", param.getMediaServerId()); @@ -789,9 +789,9 @@ public class ABLHttpHookListener { zlmServerConfig.setIp(request.getRemoteAddr()); logger.info("[ABL HOOK] ABL 启动 " + zlmServerConfig.getGeneralMediaServerId()); taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_server_started); + List subscribes = this.subscribe.getSubscribes(HookType.on_server_started); if (subscribes != null && !subscribes.isEmpty()) { - for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { + for (HookSubscribe.Event subscribe : subscribes) { subscribe.response(null, zlmServerConfig); } } @@ -853,9 +853,9 @@ public class ABLHttpHookListener { logger.info("[ABL HOOK] rtpServer收流超时:{}->{}({})", param.getMediaServerId(), param.getStream_id(), param.getSsrc()); taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); + List subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); if (subscribes != null && !subscribes.isEmpty()) { - for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { + for (HookSubscribe.Event subscribe : subscribes) { subscribe.response(null, param); } } @@ -873,9 +873,9 @@ public class ABLHttpHookListener { logger.info("[AB HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path()); taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4); + List subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4); if (subscribes != null && !subscribes.isEmpty()) { - for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { + for (HookSubscribe.Event subscribe : subscribes) { subscribe.response(null, param); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/HookSubscribe.java similarity index 85% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java rename to src/main/java/com/genersoft/iot/vmp/media/event/HookSubscribe.java index 4d1762af0..14e27c36e 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/HookSubscribe.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm; +package com.genersoft.iot.vmp.media.event; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.media.zlm.dto.HookType; @@ -21,18 +21,18 @@ import java.util.concurrent.TimeUnit; * @author lin */ @Component -public class ZlmHttpHookSubscribe { +public class HookSubscribe { - private final static Logger logger = LoggerFactory.getLogger(ZlmHttpHookSubscribe.class); + private final static Logger logger = LoggerFactory.getLogger(HookSubscribe.class); @FunctionalInterface public interface Event{ void response(MediaServer mediaServerItem, HookParam hookParam); } - private Map> allSubscribes = new ConcurrentHashMap<>(); + private Map> allSubscribes = new ConcurrentHashMap<>(); - public void addSubscribe(IHookSubscribe hookSubscribe, ZlmHttpHookSubscribe.Event event) { + public void addSubscribe(IHookSubscribe hookSubscribe, HookSubscribe.Event event) { if (hookSubscribe.getExpires() == null) { // 默认5分钟过期 Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(5)); @@ -42,8 +42,8 @@ public class ZlmHttpHookSubscribe { System.out.println(allSubscribes); } - public ZlmHttpHookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { - ZlmHttpHookSubscribe.Event event= null; + public HookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { + HookSubscribe.Event event= null; Map eventMap = allSubscribes.get(type); if (eventMap == null) { return null; @@ -76,8 +76,8 @@ public class ZlmHttpHookSubscribe { Set> entries = eventMap.entrySet(); if (entries.size() > 0) { - List> entriesToRemove = new ArrayList<>(); - for (Map.Entry entry : entries) { + List> entriesToRemove = new ArrayList<>(); + for (Map.Entry entry : entries) { JSONObject content = entry.getKey().getContent(); if (content == null || content.size() == 0) { entriesToRemove.add(entry); @@ -100,7 +100,7 @@ public class ZlmHttpHookSubscribe { } if (!CollectionUtils.isEmpty(entriesToRemove)) { - for (Map.Entry entry : entriesToRemove) { + for (Map.Entry entry : entriesToRemove) { eventMap.remove(entry.getKey()); } if (eventMap.size() == 0) { @@ -116,12 +116,12 @@ public class ZlmHttpHookSubscribe { * @param type * @return */ - public List getSubscribes(HookType type) { + public List getSubscribes(HookType type) { Map eventMap = allSubscribes.get(type); if (eventMap == null) { return null; } - List result = new ArrayList<>(); + List result = new ArrayList<>(); for (IHookSubscribe key : eventMap.keySet()) { result.add(eventMap.get(key)); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 42f5e28a0..50cb9e33e 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -2,38 +2,30 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.common.InviteInfo; -import com.genersoft.iot.vmp.common.InviteSessionType; import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; import com.genersoft.iot.vmp.service.*; -import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; -import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import com.genersoft.iot.vmp.utils.DateUtil; -import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -43,7 +35,6 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; -import org.springframework.web.context.request.async.DeferredResult; import javax.servlet.http.HttpServletRequest; import javax.sip.InvalidArgumentException; @@ -52,7 +43,6 @@ import java.text.ParseException; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; /** * @description:针对 ZLMediaServer的hook事件监听 @@ -108,7 +98,7 @@ public class ZLMHttpHookListener { private ZLMMediaListManager zlmMediaListManager; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private UserSetting userSetting; @@ -192,7 +182,7 @@ public class ZLMHttpHookListener { } taskExecutor.execute(() -> { - ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); + HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); if (subscribe != null) { subscribe.response(mediaServer, param); } @@ -334,9 +324,9 @@ public class ZLMHttpHookListener { logger.info("[ZLM HOOK] rtpServer收流超时:{}->{}({})", param.getMediaServerId(), param.getStream_id(), param.getSsrc()); taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); + List subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); if (subscribes != null && !subscribes.isEmpty()) { - for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { + for (HookSubscribe.Event subscribe : subscribes) { subscribe.response(null, param); } } @@ -354,9 +344,9 @@ public class ZLMHttpHookListener { logger.info("[ZLM HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path()); taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4); + List subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4); if (subscribes != null && !subscribes.isEmpty()) { - for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { + for (HookSubscribe.Event subscribe : subscribes) { subscribe.response(null, param); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 5223be8cf..51b539364 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.GbStream; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -48,7 +49,7 @@ public class ZLMMediaListManager { private StreamPushMapper streamPushMapper; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private UserSetting userSetting; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java index ccb5b355e..472687149 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +27,7 @@ public class ZLMServerFactory { private UserSetting userSetting; @Autowired - private ZlmHttpHookSubscribe hookSubscribe; + private HookSubscribe hookSubscribe; @Autowired private SendRtpPortManager sendRtpPortManager; diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java index fb5ffdda0..9dff5b034 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; @@ -73,7 +73,7 @@ public interface IPlatformService { * @param errorEvent 信令错误事件 * @param timeoutCallback 超时事件 */ - void broadcastInvite(ParentPlatform platform, String channelId, MediaServer mediaServerItem, ZlmHttpHookSubscribe.Event hookEvent, + void broadcastInvite(ParentPlatform platform, String channelId, MediaServer mediaServerItem, HookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, InviteTimeOutCallback timeoutCallback) throws InvalidArgumentException, ParseException, SipException; /** diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index e57c7eaf5..9316aa674 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -15,14 +15,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResultForOnPublish; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 54e06c200..090e24cfc 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -16,7 +16,7 @@ import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IInviteStreamService; @@ -89,7 +89,7 @@ public class PlatformServiceImpl implements IPlatformService { private UserSetting userSetting; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private VideoStreamSessionManager streamSession; @@ -477,7 +477,7 @@ public class PlatformServiceImpl implements IPlatformService { } @Override - public void broadcastInvite(ParentPlatform platform, String channelId, MediaServer mediaServerItem, ZlmHttpHookSubscribe.Event hookEvent, + public void broadcastInvite(ParentPlatform platform, String channelId, MediaServer mediaServerItem, HookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, InviteTimeOutCallback timeoutCallback) throws InvalidArgumentException, ParseException, SipException { if (mediaServerItem == null) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 31a43c9dd..330497faf 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -13,8 +13,6 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; @@ -25,13 +23,12 @@ import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResult; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.*; @@ -53,7 +50,6 @@ import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; -import org.springframework.web.context.request.async.DeferredResult; import javax.sdp.*; import javax.sip.InvalidArgumentException; @@ -98,7 +94,7 @@ public class PlayServiceImpl implements IPlayService { private IInviteStreamService inviteStreamService; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private SendRtpPortManager sendRtpPortManager; @@ -318,7 +314,7 @@ public class PlayServiceImpl implements IPlayService { } private void talk(MediaServer mediaServerItem, Device device, String channelId, String stream, - ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, + HookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, Runnable timeoutCallback, AudioBroadcastEvent audioEvent) { String playSsrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId()); @@ -816,7 +812,7 @@ public class PlayServiceImpl implements IPlayService { inviteStreamService.removeInviteInfo(inviteInfo); }; - ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { + HookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { logger.info("收到回放订阅消息: " + hookParam); dynamicTask.stop(playBackTimeOutTaskKey); StreamInfo streamInfo = onPublishHandlerForPlayback(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); @@ -1005,7 +1001,7 @@ public class PlayServiceImpl implements IPlayService { streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); inviteStreamService.removeInviteInfo(inviteInfo); }; - ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { + HookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { logger.info("[录像下载]收到订阅消息: " + hookParam); dynamicTask.stop(downLoadTimeOutTaskKey); StreamInfo streamInfo = onPublishHandlerForDownload(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); @@ -1026,7 +1022,7 @@ public class PlayServiceImpl implements IPlayService { downLoadTimeOutTaskKey, callback, inviteInfo, InviteSessionType.DOWNLOAD); // 注册录像回调事件,录像下载结束后写入下载地址 - ZlmHttpHookSubscribe.Event hookEventForRecord = (mediaServerItemInuse, hookParam) -> { + HookSubscribe.Event hookEventForRecord = (mediaServerItemInuse, hookParam) -> { logger.info("[录像下载] 收到录像写入磁盘消息: , {}/{}-{}", inviteInfo.getDeviceId(), inviteInfo.getChannelId(), ssrcInfo.getStream()); logger.info("[录像下载] 收到录像写入磁盘消息内容: " + hookParam); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 0713ab35a..86146889c 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -14,12 +14,11 @@ import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; 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.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResult; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.service.IMediaService; @@ -46,7 +45,6 @@ import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import org.springframework.web.context.request.async.DeferredResult; import java.util.HashMap; import java.util.List; @@ -98,7 +96,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { private IMediaServerService mediaServerService; @Autowired - private ZlmHttpHookSubscribe hookSubscribe; + private HookSubscribe hookSubscribe; @Autowired private DynamicTask dynamicTask; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index b5b1b3cad..dd48a2b53 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; 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.MediaServer; @@ -87,7 +87,7 @@ public class RedisGbPlayMsgListener implements MessageListener { @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index 4566ddae0..b7d546b0e 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; @@ -50,7 +50,7 @@ public class PsController { private ZLMServerFactory zlmServerFactory; @Autowired - private ZlmHttpHookSubscribe hookSubscribe; + private HookSubscribe hookSubscribe; @Autowired private IMediaServerService mediaServerService; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index ac51bc575..0c2478a56 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; @@ -54,7 +54,7 @@ public class RtpController { private final static Logger logger = LoggerFactory.getLogger(RtpController.class); @Autowired - private ZlmHttpHookSubscribe hookSubscribe; + private HookSubscribe hookSubscribe; @Autowired private IMediaServerService mediaServerService; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index c6c024e1e..7451ccc67 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.*; @@ -41,7 +41,7 @@ import java.util.List; public class ServerController { @Autowired - private ZlmHttpHookSubscribe zlmHttpHookSubscribe; + private HookSubscribe zlmHttpHookSubscribe; @Autowired private IMediaServerService mediaServerService; From 7a3b9c6f6908ce27e7114c1732bbf8071b064aad Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Thu, 28 Mar 2024 19:10:53 +0800 Subject: [PATCH 31/58] =?UTF-8?q?=E8=B0=83=E6=95=B4hook=E8=AE=A2=E9=98=85?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E7=9A=84=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/gb28181/event/EventPublisher.java | 9 +- .../gb28181/transmit/cmd/ISIPCommander.java | 2 +- .../cmd/ISIPCommanderForPlatform.java | 2 +- .../transmit/cmd/impl/SIPCommander.java | 8 +- .../cmd/impl/SIPCommanderFroPlatform.java | 6 +- .../request/impl/AckRequestProcessor.java | 2 +- .../request/impl/InviteRequestProcessor.java | 4 +- .../cmd/MediaStatusNotifyMessageHandler.java | 6 +- .../vmp/media/abl/ABLHttpHookListener.java | 906 ------------------ .../event/MediaRtpServerTimeoutEvent.java | 52 + .../media/event/MediaSendRtpStoppedEvent.java | 52 + .../media/event/{ => hook}/HookSubscribe.java | 20 +- .../hook}/HookSubscribeFactory.java | 3 +- .../hook}/HookSubscribeForRecordMp4.java | 2 +- .../HookSubscribeForRtpServerTimeout.java | 2 +- .../hook}/HookSubscribeForStreamChange.java | 2 +- .../hook}/HookSubscribeForStreamPush.java | 2 +- .../iot/vmp/media/event/hook/HookType.java | 15 + .../dto => event/hook}/IHookSubscribe.java | 2 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 46 +- .../vmp/media/zlm/ZLMMediaListManager.java | 2 +- .../iot/vmp/media/zlm/ZLMServerFactory.java | 2 +- .../iot/vmp/media/zlm/dto/HookType.java | 26 - .../media/zlm/dto/StreamAuthorityInfo.java | 4 +- .../iot/vmp/service/IPlatformService.java | 2 +- .../vmp/service/impl/PlatformServiceImpl.java | 26 +- .../iot/vmp/service/impl/PlayServiceImpl.java | 8 +- .../service/impl/StreamProxyServiceImpl.java | 6 +- .../redisMsg/RedisGbPlayMsgListener.java | 6 +- .../iot/vmp/vmanager/ps/PsController.java | 8 +- .../iot/vmp/vmanager/rtp/RtpController.java | 8 +- .../vmp/vmanager/server/ServerController.java | 4 +- 32 files changed, 230 insertions(+), 1015 deletions(-) delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java rename src/main/java/com/genersoft/iot/vmp/media/event/{ => hook}/HookSubscribe.java (92%) rename src/main/java/com/genersoft/iot/vmp/media/{zlm/dto => event/hook}/HookSubscribeFactory.java (98%) rename src/main/java/com/genersoft/iot/vmp/media/{zlm/dto => event/hook}/HookSubscribeForRecordMp4.java (94%) rename src/main/java/com/genersoft/iot/vmp/media/{zlm/dto => event/hook}/HookSubscribeForRtpServerTimeout.java (94%) rename src/main/java/com/genersoft/iot/vmp/media/{zlm/dto => event/hook}/HookSubscribeForStreamChange.java (94%) rename src/main/java/com/genersoft/iot/vmp/media/{zlm/dto => event/hook}/HookSubscribeForStreamPush.java (93%) create mode 100755 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java rename src/main/java/com/genersoft/iot/vmp/media/{zlm/dto => event/hook}/IHookSubscribe.java (92%) delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookType.java diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java index 5ca45bfcc..f386c33e1 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java @@ -1,18 +1,13 @@ package com.genersoft.iot.vmp.gb28181.event; -import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.GbStream; -import com.genersoft.iot.vmp.gb28181.bean.RecordInfo; +import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent; import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent; import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; +import com.genersoft.iot.vmp.gb28181.event.subscribe.mobilePosition.MobilePositionEvent; import com.genersoft.iot.vmp.media.event.MediaServerOfflineEvent; import com.genersoft.iot.vmp.media.event.MediaServerOnlineEvent; -import com.genersoft.iot.vmp.gb28181.event.subscribe.mobilePosition.MobilePositionEvent; -import com.genersoft.iot.vmp.media.zlm.event.ZLMOfflineEvent; -import com.genersoft.iot.vmp.media.zlm.event.ZLMOnlineEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index 6a54a340e..61badd36d 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.event.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import gov.nist.javax.sip.message.SIPRequest; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java index d222e71ad..ac62caf81 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.event.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 338f4679b..5233a7313 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -16,10 +16,10 @@ import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -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.HookSubscribeForStreamPush; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamPush; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.service.bean.SSRCInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 0e969d968..441e0f0a9 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -13,9 +13,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index 0fdc38d7f..ab40798f8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.media.service.IMediaServerService; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 616c1a0b1..a8c03d7b1 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -18,10 +18,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.*; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java index 6ad345233..b11b9a8f9 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java @@ -13,9 +13,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java deleted file mode 100755 index aa49ac1b0..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java +++ /dev/null @@ -1,906 +0,0 @@ -package com.genersoft.iot.vmp.media.abl; - -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; -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.common.VideoManagerConstants; -import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; -import com.genersoft.iot.vmp.gb28181.bean.*; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; -import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; -import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; -import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; -import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.*; -import com.genersoft.iot.vmp.media.zlm.dto.hook.*; -import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; -import com.genersoft.iot.vmp.service.*; -import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; -import com.genersoft.iot.vmp.service.bean.SSRCInfo; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import com.genersoft.iot.vmp.utils.DateUtil; -import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo; -import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo; -import com.genersoft.iot.vmp.vmanager.bean.StreamContent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.util.ObjectUtils; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.context.request.async.DeferredResult; - -import javax.servlet.http.HttpServletRequest; -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import java.text.ParseException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * ABL服务Hook事件 - */ -@RestController -@RequestMapping("/index/hook/abl") -public class ABLHttpHookListener { - - private final static Logger logger = LoggerFactory.getLogger(ABLHttpHookListener.class); - - @Autowired - private SIPCommander cmder; - - @Autowired - private ISIPCommanderForPlatform commanderFroPlatform; - - @Autowired - private AudioBroadcastManager audioBroadcastManager; - - @Autowired - private IPlayService playService; - - @Autowired - private IVideoManagerStorage storager; - - @Autowired - private IRedisCatchStorage redisCatchStorage; - - @Autowired - private IInviteStreamService inviteStreamService; - - @Autowired - private IDeviceService deviceService; - - @Autowired - private IMediaServerService mediaServerService; - - @Autowired - private IStreamProxyService streamProxyService; - - @Autowired - private DeferredResultHolder resultHolder; - - @Autowired - private IMediaService mediaService; - - @Autowired - private EventPublisher eventPublisher; - - @Autowired - private ZLMMediaListManager zlmMediaListManager; - - @Autowired - private HookSubscribe subscribe; - - @Autowired - private UserSetting userSetting; - - @Autowired - private IUserService userService; - - @Autowired - private ICloudRecordService cloudRecordService; - - @Autowired - private VideoStreamSessionManager sessionManager; - - @Autowired - private SSRCFactory ssrcFactory; - - @Qualifier("taskExecutor") - @Autowired - private ThreadPoolTaskExecutor taskExecutor; - - @Autowired - private RedisTemplate redisTemplate; - - @Autowired - private ApplicationEventPublisher applicationEventPublisher; - - /** - * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 - */ - @ResponseBody - - @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") - public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { - try { - HookAblServerKeepaliveEvent event = new HookAblServerKeepaliveEvent(this); - MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); - if (mediaServerItem != null) { - event.setMediaServerItem(mediaServerItem); - applicationEventPublisher.publishEvent(event); - } - }catch (Exception e) { - logger.info("[ZLM-HOOK-心跳] 发送通知失败 ", e); - } - return HookResult.SUCCESS(); - } - - /** - * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。 - */ - @ResponseBody - @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") - public HookResult onPlay(@RequestBody OnPlayHookParam param) { - if (logger.isDebugEnabled()) { - logger.debug("[ZLM HOOK] 播放鉴权:{}->{}", param.getMediaServerId(), param); - } - String mediaServerId = param.getMediaServerId(); - - taskExecutor.execute(() -> { - JSONObject json = (JSONObject) JSON.toJSON(param); - HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); - if (subscribe != null) { - MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); - if (mediaInfo != null) { - subscribe.response(mediaInfo, param); - } - } - }); - if (!"rtp".equals(param.getApp())) { - Map paramMap = urlParamToMap(param.getParams()); - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); - if (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(paramMap.get("callId"))) { - return new HookResult(401, "Unauthorized"); - } - } - - return HookResult.SUCCESS(); - } - - /** - * rtsp/rtmp/rtp推流鉴权事件。 - */ - @ResponseBody - @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8") - public HookResultForOnPublish onPublish(@RequestBody OnPublishHookParam param) { - - JSONObject json = (JSONObject) JSON.toJSON(param); - - logger.info("[ABL HOOK]推流鉴权:{}->{}", param.getMediaServerId(), param); - // TODO 加快处理速度 - - String mediaServerId = json.getString("mediaServerId"); - MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); - if (mediaInfo == null) { - return new HookResultForOnPublish(200, "success"); - } - // 推流鉴权的处理 - if (!"rtp".equals(param.getApp())) { - StreamProxyItem stream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); - if (stream != null) { - HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); - result.setEnable_audio(stream.isEnableAudio()); - result.setEnable_mp4(stream.isEnableMp4()); - return result; - } - if (userSetting.getPushAuthority()) { - // 推流鉴权 - if (param.getParams() == null) { - logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); - return new HookResultForOnPublish(401, "Unauthorized"); - } - Map paramMap = urlParamToMap(param.getParams()); - String sign = paramMap.get("sign"); - if (sign == null) { - logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); - return new HookResultForOnPublish(401, "Unauthorized"); - } - // 推流自定义播放鉴权码 - String callId = paramMap.get("callId"); - // 鉴权配置 - boolean hasAuthority = userService.checkPushAuthority(callId, sign); - if (!hasAuthority) { - logger.info("推流鉴权失败: sign 无权限: callId={}. sign={}", callId, sign); - return new HookResultForOnPublish(401, "Unauthorized"); - } - StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); - streamAuthorityInfo.setCallId(callId); - streamAuthorityInfo.setSign(sign); - // 鉴权通过 - redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); - } - } else { - zlmMediaListManager.sendStreamEvent(param.getApp(), param.getStream(), param.getMediaServerId()); - } - - - HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); - result.setEnable_audio(true); - taskExecutor.execute(() -> { - HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); - if (subscribe != null) { - subscribe.response(mediaInfo, param); - } - }); - - // 是否录像 - if ("rtp".equals(param.getApp())) { - result.setEnable_mp4(userSetting.getRecordSip()); - } else { - result.setEnable_mp4(userSetting.isRecordPushLive()); - } - // 国标流 - if ("rtp".equals(param.getApp())) { - - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); - - // 单端口模式下修改流 ID - if (!mediaInfo.isRtpEnable() && inviteInfo == null) { - String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16)); - inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc); - if (inviteInfo != null) { - result.setStream_replace(inviteInfo.getStream()); - logger.info("[ABL HOOK]推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream()); - } - } - - // 设置音频信息及录制信息 - List ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream()); - if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) { - - // 为录制国标模拟一个鉴权信息, 方便后续写入录像文件时使用 - StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); - streamAuthorityInfo.setApp(param.getApp()); - streamAuthorityInfo.setStream(ssrcTransactionForAll.get(0).getStream()); - streamAuthorityInfo.setCallId(ssrcTransactionForAll.get(0).getSipTransactionInfo().getCallId()); - - redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), ssrcTransactionForAll.get(0).getStream(), streamAuthorityInfo); - - String deviceId = ssrcTransactionForAll.get(0).getDeviceId(); - String channelId = ssrcTransactionForAll.get(0).getChannelId(); - DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); - if (deviceChannel != null) { - result.setEnable_audio(deviceChannel.isHasAudio()); - } - // 如果是录像下载就设置视频间隔十秒 - if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) { - // 获取录像的总时长,然后设置为这个视频的时长 - InviteInfo inviteInfoForDownload = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, param.getStream()); - if (inviteInfoForDownload != null && inviteInfoForDownload.getStreamInfo() != null) { - String startTime = inviteInfoForDownload.getStreamInfo().getStartTime(); - String endTime = inviteInfoForDownload.getStreamInfo().getEndTime(); - long difference = DateUtil.getDifference(startTime, endTime) / 1000; - result.setMp4_max_second((int) difference); - result.setEnable_mp4(true); - // 设置为2保证得到的mp4的时长是正常的 - result.setModify_stamp(2); - } - } - // 如果是talk对讲,则默认获取声音 - if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.TALK) { - result.setEnable_audio(true); - } - } - } else if (param.getApp().equals("broadcast")) { - result.setEnable_audio(true); - } else if (param.getApp().equals("talk")) { - result.setEnable_audio(true); - } - if (param.getApp().equalsIgnoreCase("rtp")) { - String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_" + param.getStream(); - OtherRtpSendInfo otherRtpSendInfo = (OtherRtpSendInfo) redisTemplate.opsForValue().get(receiveKey); - - String receiveKeyForPS = VideoManagerConstants.WVP_OTHER_RECEIVE_PS_INFO + userSetting.getServerId() + "_" + param.getStream(); - OtherPsSendInfo otherPsSendInfo = (OtherPsSendInfo) redisTemplate.opsForValue().get(receiveKeyForPS); - if (otherRtpSendInfo != null || otherPsSendInfo != null) { - result.setEnable_mp4(true); - } - } - logger.info("[ABL HOOK]推流鉴权 响应:{}->{}->>>>{}", param.getMediaServerId(), param, result); - return result; - } - - - /** - * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 - */ - @ResponseBody - @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8") - public HookResult onStreamChanged(@RequestBody OnStreamChangedHookParam param) { - - if (param.isRegist()) { - logger.info("[ABL HOOK] 流注册, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); - } else { - logger.info("[ABL HOOK] 流注销, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); - } - - JSONObject json = (JSONObject) JSON.toJSON(param); - taskExecutor.execute(() -> { - HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); - MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); - if (mediaInfo == null) { - logger.info("[ABL HOOK] 流变化未找到ABL, {}", param.getMediaServerId()); - return; - } - if (subscribe != null) { - subscribe.response(mediaInfo, param); - } - - // TODO 重构此处逻辑 - if (param.isRegist()) { - // 处理流注册的鉴权信息, 流注销这里不再删除鉴权信息,下次来了新的鉴权信息会对就的进行覆盖 - if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal() - || param.getOriginType() == OriginType.RTSP_PUSH.ordinal() - || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); - if (streamAuthorityInfo == null) { - streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); - } else { - streamAuthorityInfo.setOriginType(param.getOriginType()); - streamAuthorityInfo.setOriginTypeStr(param.getOriginTypeStr()); - } - redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); - } - } - if ("rtsp".equals(param.getSchema())) { - logger.info("流变化:注册->{}, app->{}, stream->{}", param.isRegist(), param.getApp(), param.getStream()); - if (param.isRegist()) { - mediaServerService.addCount(param.getMediaServerId()); - } else { - mediaServerService.removeCount(param.getMediaServerId()); - } - - int updateStatusResult = streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream()); - if (updateStatusResult > 0) { - - } - - if ("rtp".equals(param.getApp()) && !param.isRegist()) { - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); - if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) { - inviteStreamService.removeInviteInfo(inviteInfo); - storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); - } - } else if ("broadcast".equals(param.getApp())) { - // 语音对讲推流 stream需要满足格式deviceId_channelId - if (param.getStream().indexOf("_") > 0) { - String[] streamArray = param.getStream().split("_"); - if (streamArray.length == 2) { - String deviceId = streamArray[0]; - String channelId = streamArray[1]; - Device device = deviceService.getDevice(deviceId); - if (device != null) { - if (param.isRegist()) { - if (audioBroadcastManager.exit(deviceId, channelId)) { - playService.stopAudioBroadcast(deviceId, channelId); - } - // 开启语音对讲通道 - try { - playService.audioBroadcastCmd(device, channelId, mediaInfo, param.getApp(), param.getStream(), 60, false, (msg) -> { - logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); - }); - } catch (InvalidArgumentException | ParseException | SipException e) { - logger.error("[命令发送失败] 语音对讲: {}", e.getMessage()); - } - } else { - // 流注销 - playService.stopAudioBroadcast(deviceId, channelId); - } - } else { - logger.info("[语音对讲] 未找到设备:{}", deviceId); - } - } - } - } else if ("talk".equals(param.getApp())) { - // 语音对讲推流 stream需要满足格式deviceId_channelId - if (param.getStream().indexOf("_") > 0) { - String[] streamArray = param.getStream().split("_"); - if (streamArray.length == 2) { - String deviceId = streamArray[0]; - String channelId = streamArray[1]; - Device device = deviceService.getDevice(deviceId); - if (device != null) { - if (param.isRegist()) { - if (audioBroadcastManager.exit(deviceId, channelId)) { - playService.stopAudioBroadcast(deviceId, channelId); - } - // 开启语音对讲通道 - playService.talkCmd(device, channelId, mediaInfo, param.getStream(), (msg) -> { - logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); - }); - } else { - // 流注销 - playService.stopTalk(device, channelId, param.isRegist()); - } - } else { - logger.info("[语音对讲] 未找到设备:{}", deviceId); - } - } - } - - } else { - if (!"rtp".equals(param.getApp())) { - String type = OriginType.values()[param.getOriginType()].getType(); - if (param.isRegist()) { - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo( - param.getApp(), param.getStream()); - String callId = null; - if (streamAuthorityInfo != null) { - callId = streamAuthorityInfo.getCallId(); - } - StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo, - param.getApp(), param.getStream(), MediaInfo.getInstance(param), callId); - param.setStreamInfo(new StreamContent(streamInfoByAppAndStream)); - redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param); - if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() - || param.getOriginType() == OriginType.RTMP_PUSH.ordinal() - || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { - param.setSeverId(userSetting.getServerId()); - zlmMediaListManager.addPush(param); - - // 冗余数据,自己系统中自用 - redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param); - } - } else { - // 兼容流注销时类型从redis记录获取 - OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo( - param.getApp(), param.getStream(), param.getMediaServerId()); - if (onStreamChangedHookParam != null) { - type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType(); - redisCatchStorage.removeStream(mediaInfo.getId(), type, param.getApp(), param.getStream()); - if ("PUSH".equalsIgnoreCase(type)) { - // 冗余数据,自己系统中自用 - redisCatchStorage.removePushListItem(param.getApp(), param.getStream(), param.getMediaServerId()); - } - } - GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream()); - if (gbStream != null) { -// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); - } - zlmMediaListManager.removeMedia(param.getApp(), param.getStream()); - } - GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream()); - if (gbStream != null) { - if (userSetting.isUsePushingAsStatus()) { - eventPublisher.catalogEventPublishForStream(null, gbStream, param.isRegist() ? CatalogEvent.ON : CatalogEvent.OFF); - } - } - if (type != null) { - // 发送流变化redis消息 - JSONObject jsonObject = new JSONObject(); - jsonObject.put("serverId", userSetting.getServerId()); - jsonObject.put("app", param.getApp()); - jsonObject.put("stream", param.getStream()); - jsonObject.put("register", param.isRegist()); - jsonObject.put("mediaServerId", param.getMediaServerId()); - redisCatchStorage.sendStreamChangeMsg(type, jsonObject); - } - } - } - if (!param.isRegist()) { - List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream()); - if (!sendRtpItems.isEmpty()) { - for (SendRtpItem sendRtpItem : sendRtpItems) { - if (sendRtpItem != null && sendRtpItem.getApp().equals(param.getApp())) { - String platformId = sendRtpItem.getPlatformId(); - ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId); - Device device = deviceService.getDevice(platformId); - - try { - if (platform != null) { - commanderFroPlatform.streamByeCmd(platform, sendRtpItem); - redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), - sendRtpItem.getCallId(), sendRtpItem.getStream()); - } else { - cmder.streamByeCmd(device, sendRtpItem.getChannelId(), param.getStream(), sendRtpItem.getCallId()); - if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) - || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { - AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - if (audioBroadcastCatch != null) { - // 来自上级平台的停止对讲 - logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - } - } - } - } catch (SipException | InvalidArgumentException | ParseException | - SsrcTransactionNotFoundException e) { - logger.error("[命令发送失败] 发送BYE: {}", e.getMessage()); - } - } - } - } - } - } - }); - return HookResult.SUCCESS(); - } - - /** - * 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 - */ - @ResponseBody - @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") - public JSONObject onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) { - - logger.info("[ABL HOOK]流无人观看:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), - param.getApp(), param.getStream()); - JSONObject ret = new JSONObject(); - ret.put("code", 0); - // 国标类型的流 - if ("rtp".equals(param.getApp())) { - ret.put("close", userSetting.getStreamOnDemand()); - // 国标流, 点播/录像回放/录像下载 - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); - // 点播 - if (inviteInfo != null) { - // 录像下载 - if (inviteInfo.getType() == InviteSessionType.DOWNLOAD) { - ret.put("close", false); - return ret; - } - // 收到无人观看说明流也没有在往上级推送 - if (redisCatchStorage.isChannelSendingRTP(inviteInfo.getChannelId())) { - List sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId( - inviteInfo.getChannelId()); - if (!sendRtpItems.isEmpty()) { - for (SendRtpItem sendRtpItem : sendRtpItems) { - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); - try { - commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); - } - redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(), - sendRtpItem.getCallId(), sendRtpItem.getStream()); - if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) { - MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, - sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), - sendRtpItem.getPlatformId(), parentPlatform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId()); - messageForPushChannel.setPlatFormIndex(parentPlatform.getId()); - redisCatchStorage.sendPlatformStopPlayMsg(messageForPushChannel); - } - } - } - } - Device device = deviceService.getDevice(inviteInfo.getDeviceId()); - if (device != null) { - try { - // 多查询一次防止已经被处理了 - InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(), - inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream()); - if (info != null) { - cmder.streamByeCmd(device, inviteInfo.getChannelId(), - inviteInfo.getStream(), null); - } else { - logger.info("[无人观看] 未找到设备的点播信息: {}, 流:{}", inviteInfo.getDeviceId(), param.getStream()); - } - } catch (InvalidArgumentException | ParseException | SipException | - SsrcTransactionNotFoundException e) { - logger.error("[无人观看]点播, 发送BYE失败 {}", e.getMessage()); - } - } else { - logger.info("[无人观看] 未找到设备: {},流:{}", inviteInfo.getDeviceId(), param.getStream()); - } - - inviteStreamService.removeInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), - inviteInfo.getChannelId(), inviteInfo.getStream()); - storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId()); - return ret; - } - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null); - if (sendRtpItem != null && "talk".equals(sendRtpItem.getApp())) { - ret.put("close", false); - return ret; - } - } else if ("talk".equals(param.getApp()) || "broadcast".equals(param.getApp())) { - ret.put("close", false); - } else { - // 非国标流 推流/拉流代理 - // 拉流代理 - StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); - if (streamProxyItem != null) { - if (streamProxyItem.isEnableRemoveNoneReader()) { - // 无人观看自动移除 - ret.put("close", true); - streamProxyService.del(param.getApp(), param.getStream()); - String url = streamProxyItem.getUrl() != null ? streamProxyItem.getUrl() : streamProxyItem.getSrcUrl(); - logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", param.getApp(), param.getStream(), url); - } else if (streamProxyItem.isEnableDisableNoneReader()) { - // 无人观看停用 - ret.put("close", true); - // 修改数据 - streamProxyService.stop(param.getApp(), param.getStream()); - } else { - // 无人观看不做处理 - ret.put("close", false); - } - return ret; - } - // TODO 推流具有主动性,暂时不做处理 -// StreamPushItem streamPushItem = streamPushService.getPush(app, streamId); -// if (streamPushItem != null) { -// // TODO 发送停止 -// -// } - } - return ret; - } - - /** - * 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感。 - */ - @ResponseBody - @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") - public DeferredResult onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param) { - logger.info("[ABL HOOK] 流未找到:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); - - DeferredResult defaultResult = new DeferredResult<>(); - - MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); - if (!userSetting.isAutoApplyPlay() || mediaInfo == null) { - defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); - return defaultResult; - } - - if ("rtp".equals(param.getApp())) { - String[] s = param.getStream().split("_"); - if ((s.length != 2 && s.length != 4)) { - defaultResult.setResult(HookResult.SUCCESS()); - return defaultResult; - } - String deviceId = s[0]; - String channelId = s[1]; - Device device = redisCatchStorage.getDevice(deviceId); - if (device == null || !device.isOnLine()) { - defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); - return defaultResult; - } - DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); - if (deviceChannel == null) { - defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); - return defaultResult; - } - if (s.length == 2) { - logger.info("[ABL HOOK] 预览流未找到, 发起自动点播:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); - - RequestMessage msg = new RequestMessage(); - String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; - boolean exist = resultHolder.exist(key, null); - msg.setKey(key); - String uuid = UUID.randomUUID().toString(); - msg.setId(uuid); - DeferredResult result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); - - result.onTimeout(() -> { - logger.info("[ABL HOOK] 预览流自动点播, 等待超时"); - msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时")); - resultHolder.invokeAllResult(msg); - inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); - storager.stopPlay(deviceId, channelId); - }); - - resultHolder.put(key, uuid, result); - - if (!exist) { - playService.play(mediaInfo, deviceId, channelId, null, (code, message, data) -> { - msg.setData(new HookResult(code, message)); - resultHolder.invokeResult(msg); - }); - } - return result; - } else if (s.length == 4) { - // 此时为录像回放, 录像回放格式为> 设备ID_通道ID_开始时间_结束时间 - String startTimeStr = s[2]; - String endTimeStr = s[3]; - if (startTimeStr == null || endTimeStr == null || startTimeStr.length() != 14 || endTimeStr.length() != 14) { - defaultResult.setResult(HookResult.SUCCESS()); - return defaultResult; - } - String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr); - String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr); - logger.info("[ABL HOOK] 回放流未找到, 发起自动点播:{}->{}->{}/{}-{}-{}", - param.getMediaServerId(), param.getSchema(), - param.getApp(), param.getStream(), - startTime, endTime - ); - RequestMessage msg = new RequestMessage(); - String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId; - boolean exist = resultHolder.exist(key, null); - msg.setKey(key); - String uuid = UUID.randomUUID().toString(); - msg.setId(uuid); - DeferredResult result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); - - result.onTimeout(() -> { - logger.info("[ABL HOOK] 回放流自动点播, 等待超时"); - // 释放rtpserver - msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时")); - resultHolder.invokeResult(msg); - }); - - resultHolder.put(key, uuid, result); - - if (!exist) { - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaInfo, param.getStream(), null, - device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); - playService.playBack(mediaInfo, ssrcInfo, deviceId, channelId, startTime, endTime, (code, message, data) -> { - msg.setData(new HookResult(code, message)); - resultHolder.invokeResult(msg); - }); - } - return result; - } else { - defaultResult.setResult(HookResult.SUCCESS()); - return defaultResult; - } - - } else { - // 拉流代理 - StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); - if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnableDisableNoneReader()) { - streamProxyService.start(param.getApp(), param.getStream()); - } - DeferredResult result = new DeferredResult<>(); - result.setResult(HookResult.SUCCESS()); - return result; - } - } - - /** - * 服务器启动事件,可以用于监听服务器崩溃重启;此事件对回复不敏感。 - */ - @ResponseBody - @PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8") - public HookResult onServerStarted(HttpServletRequest request, @RequestBody JSONObject jsonObject) { - - jsonObject.put("ip", request.getRemoteAddr()); - ZLMServerConfig zlmServerConfig = JSON.to(ZLMServerConfig.class, jsonObject); - zlmServerConfig.setIp(request.getRemoteAddr()); - logger.info("[ABL HOOK] ABL 启动 " + zlmServerConfig.getGeneralMediaServerId()); - taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_server_started); - if (subscribes != null && !subscribes.isEmpty()) { - for (HookSubscribe.Event subscribe : subscribes) { - subscribe.response(null, zlmServerConfig); - } - } - }); - try { - HookZlmServerStartEvent event = new HookZlmServerStartEvent(this); - MediaServer mediaServerItem = mediaServerService.getOne(zlmServerConfig.getMediaServerId()); - if (mediaServerItem != null) { - event.setMediaServerItem(mediaServerItem); - applicationEventPublisher.publishEvent(event); - } - }catch (Exception e) { - logger.info("[ABL-HOOK-ABL启动] 发送通知失败 ", e); - } - - return HookResult.SUCCESS(); - } - - /** - * 发送rtp(startSendRtp)被动关闭时回调 - */ - @ResponseBody - @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8") - public HookResult onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param) { - - logger.info("[ABL HOOK] rtp发送关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); - - // 查找对应的上级推流,发送停止 - if (!"rtp".equals(param.getApp())) { - return HookResult.SUCCESS(); - } - taskExecutor.execute(() -> { - List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream()); - if (sendRtpItems.size() > 0) { - for (SendRtpItem sendRtpItem : sendRtpItems) { - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); - ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); - try { - commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); - } - redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(), - sendRtpItem.getCallId(), sendRtpItem.getStream()); - } - } - }); - - return HookResult.SUCCESS(); - } - - /** - * rtpServer收流超时 - */ - @ResponseBody - @PostMapping(value = "/on_rtp_server_timeout", produces = "application/json;charset=UTF-8") - public HookResult onRtpServerTimeout(@RequestBody OnRtpServerTimeoutHookParam - param) { - logger.info("[ABL HOOK] rtpServer收流超时:{}->{}({})", param.getMediaServerId(), param.getStream_id(), param.getSsrc()); - - taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); - if (subscribes != null && !subscribes.isEmpty()) { - for (HookSubscribe.Event subscribe : subscribes) { - subscribe.response(null, param); - } - } - }); - - return HookResult.SUCCESS(); - } - - /** - * 录像完成事件 - */ - @ResponseBody - @PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8") - public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4HookParam param) { - logger.info("[AB HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path()); - - taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4); - if (subscribes != null && !subscribes.isEmpty()) { - for (HookSubscribe.Event subscribe : subscribes) { - subscribe.response(null, param); - } - } - cloudRecordService.addRecord(param); - - }); - - return HookResult.SUCCESS(); - } - - private Map urlParamToMap(String params) { - HashMap map = new HashMap<>(); - if (ObjectUtils.isEmpty(params)) { - return map; - } - String[] paramsArray = params.split("&"); - if (paramsArray.length == 0) { - return map; - } - for (String param : paramsArray) { - String[] paramArray = param.split("="); - if (paramArray.length == 2) { - map.put(paramArray[0], paramArray[1]); - } - } - return map; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java new file mode 100644 index 000000000..ca01142a2 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java @@ -0,0 +1,52 @@ +package com.genersoft.iot.vmp.media.event; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; +import org.springframework.context.ApplicationEvent; + +/** + * rtp 服务收流超时通知 + */ +public class MediaRtpServerTimeoutEvent extends ApplicationEvent { + public MediaRtpServerTimeoutEvent(Object source) { + super(source); + } + + private String app; + + private String stream; + + private MediaServer mediaServer; + + public static MediaRtpServerTimeoutEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){ + MediaRtpServerTimeoutEvent mediaDepartureEven = new MediaRtpServerTimeoutEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public MediaServer getMediaServer() { + return mediaServer; + } + + public void setMediaServer(MediaServer mediaServer) { + this.mediaServer = mediaServer; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java new file mode 100644 index 000000000..931928093 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java @@ -0,0 +1,52 @@ +package com.genersoft.iot.vmp.media.event; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; +import org.springframework.context.ApplicationEvent; + +/** + * 发送流停止事件 + */ +public class MediaSendRtpStoppedEvent extends ApplicationEvent { + public MediaSendRtpStoppedEvent(Object source) { + super(source); + } + + private String app; + + private String stream; + + private MediaServer mediaServer; + + public static MediaSendRtpStoppedEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){ + MediaSendRtpStoppedEvent mediaDepartureEven = new MediaSendRtpStoppedEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public MediaServer getMediaServer() { + return mediaServer; + } + + public void setMediaServer(MediaServer mediaServer) { + this.mediaServer = mediaServer; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/HookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java similarity index 92% rename from src/main/java/com/genersoft/iot/vmp/media/event/HookSubscribe.java rename to src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java index 14e27c36e..f5dac01c9 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/HookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java @@ -1,12 +1,12 @@ -package com.genersoft.iot.vmp.media.event; +package com.genersoft.iot.vmp.media.event.hook; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.HookType; -import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -30,6 +30,19 @@ public class HookSubscribe { void response(MediaServer mediaServerItem, HookParam hookParam); } + /** + * 流到来的处理 + */ + @Async("taskExecutor") + @org.springframework.context.event.EventListener + public void onApplicationEvent(MediaArrivalEvent event) { + for (HookType hookType : allSubscribes.keySet()) { + if (hookType.equals(HookType.on_stream_changed)) { + + } + } + } + private Map> allSubscribes = new ConcurrentHashMap<>(); public void addSubscribe(IHookSubscribe hookSubscribe, HookSubscribe.Event event) { @@ -39,7 +52,6 @@ public class HookSubscribe { hookSubscribe.setExpires(expiresInstant); } allSubscribes.computeIfAbsent(hookSubscribe.getHookType(), k -> new ConcurrentHashMap<>()).put(hookSubscribe, event); - System.out.println(allSubscribes); } public HookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeFactory.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java similarity index 98% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeFactory.java rename to src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java index 417251f0c..9182205ea 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm.dto; +package com.genersoft.iot.vmp.media.event.hook; import com.alibaba.fastjson2.JSONObject; @@ -31,7 +31,6 @@ public class HookSubscribeFactory { subscribeKey.put("ssrc", ssrc); subscribeKey.put("mediaServerId", mediaServerId); hookSubscribe.setContent(subscribeKey); - return hookSubscribe; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForRecordMp4.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java similarity index 94% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForRecordMp4.java rename to src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java index 34c467c54..46f62a898 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForRecordMp4.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm.dto; +package com.genersoft.iot.vmp.media.event.hook; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.annotation.JSONField; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForRtpServerTimeout.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java similarity index 94% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForRtpServerTimeout.java rename to src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java index d633560d7..d526c7851 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForRtpServerTimeout.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm.dto; +package com.genersoft.iot.vmp.media.event.hook; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.annotation.JSONField; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForStreamChange.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java similarity index 94% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForStreamChange.java rename to src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java index b73d74c1b..b8d267559 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForStreamChange.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm.dto; +package com.genersoft.iot.vmp.media.event.hook; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.annotation.JSONField; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForStreamPush.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java similarity index 93% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForStreamPush.java rename to src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java index 6418134fc..e61918143 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForStreamPush.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm.dto; +package com.genersoft.iot.vmp.media.event.hook; import com.alibaba.fastjson2.JSONObject; diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java new file mode 100755 index 000000000..77e37a829 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java @@ -0,0 +1,15 @@ +package com.genersoft.iot.vmp.media.event.hook; + +/** + * hook类型 + * @author lin + */ + +public enum HookType { + + on_publish, + on_record_mp4, + on_media_arrival, + on_stream_changed, + on_rtp_server_timeout, +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java similarity index 92% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IHookSubscribe.java rename to src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java index 7b76a9599..7fb48ce76 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IHookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.zlm.dto; +package com.genersoft.iot.vmp.media.event.hook; import com.alibaba.fastjson2.JSONObject; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 50cb9e33e..fc128590c 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; @@ -12,12 +11,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; -import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; +import com.genersoft.iot.vmp.media.event.*; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.HookType; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; @@ -37,9 +34,6 @@ import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import java.text.ParseException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -294,22 +288,16 @@ public class ZLMHttpHookListener { if (!"rtp".equals(param.getApp())) { return HookResult.SUCCESS(); } - taskExecutor.execute(() -> { - List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream()); - if (sendRtpItems.size() > 0) { - for (SendRtpItem sendRtpItem : sendRtpItems) { - ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); - ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); - try { - commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); - } - redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(), - sendRtpItem.getCallId(), sendRtpItem.getStream()); - } + try { + MediaSendRtpStoppedEvent event = new MediaSendRtpStoppedEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServer(mediaServerItem); + applicationEventPublisher.publishEvent(event); } - }); + }catch (Exception e) { + logger.info("[ZLM-HOOK-rtp发送关闭] 发送通知失败 ", e); + } return HookResult.SUCCESS(); } @@ -323,6 +311,16 @@ public class ZLMHttpHookListener { param) { logger.info("[ZLM HOOK] rtpServer收流超时:{}->{}({})", param.getMediaServerId(), param.getStream_id(), param.getSsrc()); + try { + MediaRtpServerTimeoutEvent event = new MediaRtpServerTimeoutEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServer(mediaServerItem); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ZLM-HOOK-rtpServer收流超时] 发送通知失败 ", e); + } taskExecutor.execute(() -> { List subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); if (subscribes != null && !subscribes.isEmpty()) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 51b539364..1d9fc40fa 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.GbStream; -import com.genersoft.iot.vmp.media.event.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java index 472687149..5e3facdc6 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java @@ -5,7 +5,7 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.event.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookType.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookType.java deleted file mode 100755 index 235cea7b7..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookType.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm.dto; - -/** - * hook类型 - * @author lin - */ - -public enum HookType { - - on_flow_report, - on_http_access, - on_play, - on_publish, - on_record_mp4, - on_rtsp_auth, - on_rtsp_realm, - on_shell_login, - on_stream_changed, - on_stream_none_reader, - on_stream_not_found, - on_server_started, - - on_rtp_server_timeout, - on_server_keepalive, - on_send_rtp_stopped -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java index 7d66a1ffe..66d07de2a 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java @@ -1,8 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.dto; import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnPublishHookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; /** * 流的鉴权信息 @@ -110,7 +108,7 @@ public class StreamAuthorityInfo { StreamAuthorityInfo streamAuthorityInfo = new StreamAuthorityInfo(); streamAuthorityInfo.setApp(event.getApp()); streamAuthorityInfo.setStream(event.getStream()); - streamAuthorityInfo.setId(event.getSeverId()); + streamAuthorityInfo.setId(event.getMediaServer().getId()); if (event.getMediaInfo() != null) { streamAuthorityInfo.setOriginType(event.getMediaInfo().getOriginType()); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java index 9dff5b034..17f890853 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.event.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 090e24cfc..cfb9abbc7 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -14,9 +14,10 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.MediaSendRtpStoppedEvent; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IInviteStreamService; @@ -129,6 +130,29 @@ public class PlatformServiceImpl implements IPlatformService { } + /** + * 发流停止 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaSendRtpStoppedEvent event) { + List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream()); + if (!sendRtpItems.isEmpty()) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + ParentPlatform parentPlatform = platformMapper.getParentPlatByServerGBId(sendRtpItem.getPlatformId()); + ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); + try { + commanderForPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); + } + redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(), + sendRtpItem.getCallId(), sendRtpItem.getStream()); + } + } + } + + @Override public ParentPlatform queryPlatformByServerGBId(String platformGbId) { return platformMapper.getParentPlatByServerGBId(platformGbId); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 330497faf..e6b082d5f 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -23,10 +23,10 @@ import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRecordMp4; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 86146889c..c768ae1a8 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -14,9 +14,9 @@ import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index dd48a2b53..d2d32e841 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -7,9 +7,9 @@ import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.*; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index b7d546b0e..3e1e97330 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -8,10 +8,10 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRtpServerTimeout; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index 0c2478a56..c810745f7 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -8,10 +8,10 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; -import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRtpServerTimeout; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index 7451ccc67..dc31b5a7f 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -11,8 +11,8 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; -import com.genersoft.iot.vmp.media.event.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.IHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; From 728e60ce8431fe5a70e44a1da2d4835425ce83a5 Mon Sep 17 00:00:00 2001 From: pei Date: Fri, 29 Mar 2024 11:55:44 +0800 Subject: [PATCH 32/58] =?UTF-8?q?=E5=A4=84=E7=90=86=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E4=BC=9A=E5=87=BA=E7=8E=B0=E7=9A=84=E7=A9=BA=E6=8C=87=E9=92=88?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/message/MessageRequestProcessor.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java index 0c23acea1..34d7077e8 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java @@ -37,7 +37,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement private final String method = "MESSAGE"; - private static Map messageHandlerMap = new ConcurrentHashMap<>(); + private static final Map messageHandlerMap = new ConcurrentHashMap<>(); @Autowired private SIPProcessorObserver sipProcessorObserver; @@ -100,9 +100,9 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement deviceNotFoundEvent.setCallId(callIdHeader.getCallId()); SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(deviceNotFoundEvent); sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()).response(eventResult); - }; + } }else { - Element rootElement = null; + Element rootElement; try { rootElement = getRootElement(evt); if (rootElement == null) { @@ -110,24 +110,24 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement responseAck(request, Response.BAD_REQUEST, "content is null"); return; } + String name = rootElement.getName(); + IMessageHandler messageHandler = messageHandlerMap.get(name); + if (messageHandler != null) { + if (device != null) { + messageHandler.handForDevice(evt, device, rootElement); + }else { // 由于上面已经判断都为null则直接返回,所以这里device和parentPlatform必有一个不为null + messageHandler.handForPlatform(evt, parentPlatform, rootElement); + } + }else { + // 不支持的message + // 不存在则回复415 + responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE, "Unsupported message type, must Control/Notify/Query/Response"); + } } catch (DocumentException e) { logger.warn("解析XML消息内容异常", e); // 不存在则回复404 responseAck(request, Response.BAD_REQUEST, e.getMessage()); } - String name = rootElement.getName(); - IMessageHandler messageHandler = messageHandlerMap.get(name); - if (messageHandler != null) { - if (device != null) { - messageHandler.handForDevice(evt, device, rootElement); - }else { // 由于上面已经判断都为null则直接返回,所以这里device和parentPlatform必有一个不为null - messageHandler.handForPlatform(evt, parentPlatform, rootElement); - } - }else { - // 不支持的message - // 不存在则回复415 - responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE, "Unsupported message type, must Control/Notify/Query/Response"); - } } } catch (SipException e) { logger.warn("SIP 回复错误", e); From 0447b83c3a5e48741adcd85ce9552ff202831784 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 29 Mar 2024 23:41:00 +0800 Subject: [PATCH 33/58] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/AudioBroadcastManager.java | 42 ------------------- .../vmp/media/event/MediaArrivalEvent.java | 11 +++++ .../vmp/service/impl/MediaServiceImpl.java | 1 - .../iot/vmp/service/impl/PlayServiceImpl.java | 27 ++++++++++++ .../service/impl/StreamPushServiceImpl.java | 6 +-- .../iot/vmp/storager/IRedisCatchStorage.java | 3 +- .../storager/impl/RedisCatchStorageImpl.java | 5 ++- 7 files changed, 46 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java index bc5f02232..f5385d4aa 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java @@ -38,50 +38,8 @@ public class AudioBroadcastManager { @Autowired private SipConfig config; - @Autowired - private SIPCommander cmder; - - @Autowired - private IRedisCatchStorage redisCatchStorage; - - @Autowired - private IDeviceService deviceService; - public static Map data = new ConcurrentHashMap<>(); - /** - * 流离开的处理 - */ - @Async("taskExecutor") - @EventListener - public void onApplicationEvent(MediaDepartureEvent event) { - List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream()); - if (!sendRtpItems.isEmpty()) { - for (SendRtpItem sendRtpItem : sendRtpItems) { - if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp())) { - String platformId = sendRtpItem.getPlatformId(); - Device device = deviceService.getDevice(platformId); - try { - if (device != null) { - cmder.streamByeCmd(device, sendRtpItem.getChannelId(), event.getStream(), sendRtpItem.getCallId()); - if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) - || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { - AudioBroadcastCatch audioBroadcastCatch = get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - if (audioBroadcastCatch != null) { - // 来自上级平台的停止对讲 - logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - } - } - } - } catch (SipException | InvalidArgumentException | ParseException | - SsrcTransactionNotFoundException e) { - logger.error("[命令发送失败] 发送BYE: {}", e.getMessage()); - } - } - } - } - } public void update(AudioBroadcastCatch audioBroadcastCatch) { if (SipUtils.isFrontEnd(audioBroadcastCatch.getDeviceId())) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java index 1b79b0c87..b70fcf790 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java @@ -20,6 +20,7 @@ public class MediaArrivalEvent extends ApplicationEvent { mediaArrivalEvent.setStream(hookParam.getStream()); mediaArrivalEvent.setMediaServer(mediaServer); mediaArrivalEvent.setSchema(hookParam.getSchema()); + mediaArrivalEvent.setCallId(hookParam.getCallId()); return mediaArrivalEvent; } @@ -33,6 +34,8 @@ public class MediaArrivalEvent extends ApplicationEvent { private String schema; + private String callId; + public MediaInfo getMediaInfo() { return mediaInfo; } @@ -72,4 +75,12 @@ public class MediaArrivalEvent extends ApplicationEvent { public void setSchema(String schema) { this.schema = schema; } + + public String getCallId() { + return callId; + } + + public void setCallId(String callId) { + this.callId = callId; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 9316aa674..3fcb9d088 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -208,7 +208,6 @@ public class MediaServiceImpl implements IMediaService { ResultForOnPublish result = new ResultForOnPublish(); result.setEnable_audio(true); - // 是否录像 if ("rtp".equals(app)) { result.setEnable_mp4(userSetting.getRecordSip()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index e6b082d5f..1fad2be28 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -175,6 +175,33 @@ public class PlayServiceImpl implements IPlayService { @Async("taskExecutor") @EventListener public void onApplicationEvent(MediaDepartureEvent event) { + List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream()); + if (!sendRtpItems.isEmpty()) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp())) { + String platformId = sendRtpItem.getPlatformId(); + Device device = deviceService.getDevice(platformId); + try { + if (device != null) { + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), event.getStream(), sendRtpItem.getCallId()); + if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) + || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + if (audioBroadcastCatch != null) { + // 来自上级平台的停止对讲 + logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + } + } + } + } catch (SipException | InvalidArgumentException | ParseException | + SsrcTransactionNotFoundException e) { + logger.error("[命令发送失败] 发送BYE: {}", e.getMessage()); + } + } + } + } + if ("broadcast".equals(event.getApp()) || "talk".equals(event.getApp())) { if (event.getStream().indexOf("_") > 0) { String[] streamArray = event.getStream().split("_"); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index dd0e8854d..4bdcc2fe5 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -176,14 +176,14 @@ public class StreamPushServiceImpl implements IStreamPushService { redisCatchStorage.sendStreamChangeMsg(type, jsonObject); } } - GbStream gbStream = storager.getGbStream(event.getApp(), event.getStream()); + GbStream gbStream = gbStreamMapper.selectOne(event.getApp(), event.getStream()); if (gbStream != null) { if (userSetting.isUsePushingAsStatus()) { - storager.mediaOffline(event.getApp(), event.getStream()); + streamPushMapper.updatePushStatus(event.getApp(), event.getStream(), false); eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); } }else { - storager.removeMedia(event.getApp(), event.getStream()); + streamPushMapper.del(event.getApp(), event.getStream()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index 2a48a4969..7edf7e851 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.AlarmChannelMessage; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; @@ -209,7 +210,7 @@ public interface IRedisCatchStorage { void sendPlatformStopPlayMsg(MessageForPushChannel messageForPushChannel); - void addPushListItem(String app, String stream, OnStreamChangedHookParam param); + void addPushListItem(String app, String stream, MediaArrivalEvent param); void removePushListItem(String app, String stream, String mediaServerId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 4fc16fc40..252331232 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.AlarmChannelMessage; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; @@ -651,9 +652,9 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { } @Override - public void addPushListItem(String app, String stream, OnStreamChangedHookParam param) { + public void addPushListItem(String app, String stream, MediaArrivalEvent event) { String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream; - redisTemplate.opsForValue().set(key, param); + redisTemplate.opsForValue().set(key, event); } @Override From 4548695a0b79cc6a3cc940d698cdf1d0b535d570 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Sun, 31 Mar 2024 00:28:45 +0800 Subject: [PATCH 34/58] =?UTF-8?q?hook=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/gb28181/event/EventPublisher.java | 4 +- .../session/AudioBroadcastManager.java | 13 -- .../transmit/cmd/impl/SIPCommander.java | 51 +++-- .../cmd/impl/SIPCommanderFroPlatform.java | 14 +- .../request/impl/InviteRequestProcessor.java | 17 +- .../cmd/BroadcastNotifyMessageHandler.java | 23 +-- .../cmd/MediaStatusNotifyMessageHandler.java | 9 +- .../iot/vmp/media/MediaServerConfig.java | 2 +- .../media/abl/ABLMediaServerStatusManger.java | 7 +- .../iot/vmp/media/bean/MediaInfo.java | 57 +++++- .../iot/vmp/media/bean/RecordInfo.java | 92 +++++++++ .../vmp/media/event/MediaNotFoundEvent.java | 64 ------ .../event/MediaRtpServerTimeoutEvent.java | 52 ----- .../iot/vmp/media/event/hook/Hook.java | 86 ++++++++ .../iot/vmp/media/event/hook/HookData.java | 132 ++++++++++++ .../vmp/media/event/hook/HookSubscribe.java | 189 ++++++------------ .../event/hook/HookSubscribeFactory.java | 62 ------ .../event/hook/HookSubscribeForRecordMp4.java | 44 ---- .../HookSubscribeForRtpServerTimeout.java | 44 ---- .../hook/HookSubscribeForStreamChange.java | 44 ---- .../hook/HookSubscribeForStreamPush.java | 43 ---- .../iot/vmp/media/event/hook/HookType.java | 2 +- .../vmp/media/event/hook/IHookSubscribe.java | 36 ---- .../event/{ => media}/MediaArrivalEvent.java | 46 +---- .../event/media/MediaDepartureEvent.java | 22 ++ .../MediaEvent.java} | 19 +- .../media/event/media/MediaNotFoundEvent.java | 22 ++ .../media/event/media/MediaPublishEvent.java | 33 +++ .../event/media/MediaRecordMp4Event.java | 36 ++++ .../media/MediaRtpServerTimeoutEvent.java | 22 ++ .../MediaSendRtpStoppedEvent.java | 2 +- .../MediaServerChangeEvent.java | 2 +- .../MediaServerDeleteEvent.java | 2 +- .../MediaServerEventAbstract.java | 2 +- .../MediaServerOfflineEvent.java | 4 +- .../MediaServerOnlineEvent.java | 4 +- .../MediaServerStatusEventListener.java | 2 +- .../media/service/IMediaServerService.java | 32 +++ .../service/impl/MediaServerServiceImpl.java | 73 ++++++- .../vmp/media/zlm/ZLMHttpHookListener.java | 37 ++-- .../media/zlm/ZLMMediaNodeServerService.java | 4 +- .../media/zlm/ZLMMediaServerStatusManger.java | 4 +- .../media/zlm/dto/StreamAuthorityInfo.java | 2 +- .../iot/vmp/media/zlm/dto/StreamPushItem.java | 2 +- .../iot/vmp/service/ICloudRecordService.java | 5 - .../iot/vmp/service/IMediaService.java | 33 --- .../iot/vmp/service/IPlayService.java | 3 +- .../iot/vmp/service/bean/CloudRecordItem.java | 19 +- .../service/impl/CloudRecordServiceImpl.java | 15 +- .../service/impl/InviteStreamServiceImpl.java | 4 +- .../vmp/service/impl/MediaServiceImpl.java | 67 ------- .../vmp/service/impl/PlatformServiceImpl.java | 30 +-- .../iot/vmp/service/impl/PlayServiceImpl.java | 87 ++++---- .../service/impl/StreamProxyServiceImpl.java | 28 ++- .../service/impl/StreamPushServiceImpl.java | 4 +- .../redisMsg/RedisGbPlayMsgListener.java | 17 +- .../iot/vmp/storager/IRedisCatchStorage.java | 2 +- .../storager/impl/RedisCatchStorageImpl.java | 2 +- .../gb28181/media/MediaController.java | 14 +- .../iot/vmp/vmanager/ps/PsController.java | 28 ++- .../iot/vmp/vmanager/rtp/RtpController.java | 40 ++-- .../vmp/vmanager/server/ServerController.java | 14 +- .../streamPush/StreamPushController.java | 2 +- 63 files changed, 900 insertions(+), 973 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java create mode 100755 src/main/java/com/genersoft/iot/vmp/media/event/hook/Hook.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java rename src/main/java/com/genersoft/iot/vmp/media/event/{ => media}/MediaArrivalEvent.java (58%) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java rename src/main/java/com/genersoft/iot/vmp/media/event/{MediaDepartureEvent.java => media/MediaEvent.java} (58%) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java rename src/main/java/com/genersoft/iot/vmp/media/event/{ => mediaServer}/MediaSendRtpStoppedEvent.java (96%) rename src/main/java/com/genersoft/iot/vmp/media/event/{ => mediaServer}/MediaServerChangeEvent.java (94%) rename src/main/java/com/genersoft/iot/vmp/media/event/{ => mediaServer}/MediaServerDeleteEvent.java (75%) rename src/main/java/com/genersoft/iot/vmp/media/event/{ => mediaServer}/MediaServerEventAbstract.java (89%) rename src/main/java/com/genersoft/iot/vmp/media/event/{ => mediaServer}/MediaServerOfflineEvent.java (61%) rename src/main/java/com/genersoft/iot/vmp/media/event/{ => mediaServer}/MediaServerOnlineEvent.java (60%) rename src/main/java/com/genersoft/iot/vmp/media/event/{ => mediaServer}/MediaServerStatusEventListener.java (97%) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java index f386c33e1..299d59ac5 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java @@ -6,8 +6,8 @@ import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent; import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.gb28181.event.subscribe.mobilePosition.MobilePositionEvent; -import com.genersoft.iot.vmp.media.event.MediaServerOfflineEvent; -import com.genersoft.iot.vmp.media.event.MediaServerOnlineEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOfflineEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOnlineEvent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java index f5385d4aa..24eadbace 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java @@ -1,26 +1,13 @@ package com.genersoft.iot.vmp.gb28181.session; import com.genersoft.iot.vmp.conf.SipConfig; -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.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; -import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.event.EventListener; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import java.text.ParseException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 14d496d5b..1711938ac 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -14,12 +14,11 @@ 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.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamPush; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -279,11 +278,11 @@ public class SIPCommander implements ISIPCommander { } logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); - subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> { + Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, "rtp", stream, mediaServerItem.getId()); + subscribe.addSubscribe(rtpHook, (hookData) -> { if (event != null) { - event.response(mediaServerItemInUse, hookParam); - subscribe.removeSubscribe(hookSubscribe); + event.response(hookData); + subscribe.removeSubscribe(rtpHook); } }); String sdpIp; @@ -453,13 +452,13 @@ public class SIPCommander implements ISIPCommander { //ssrc content.append("y=" + ssrcInfo.getSsrc() + "\r\n"); - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); + Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcInfo.getStream(), mediaServerItem.getId()); // 添加订阅 - subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> { + subscribe.addSubscribe(rtpHook, (hookData) -> { if (hookEvent != null) { - hookEvent.response(mediaServerItemInUse, hookParam); + hookEvent.response(hookData); } - subscribe.removeSubscribe(hookSubscribe); + subscribe.removeSubscribe(rtpHook); }); Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc()); @@ -554,19 +553,18 @@ public class SIPCommander implements ISIPCommander { content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc logger.debug("此时请求下载信令的ssrc===>{}",ssrcInfo.getSsrc()); - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); + Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcInfo.getStream(), mediaServerItem.getId()); // 添加订阅 CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); String callId= newCallIdHeader.getCallId(); - subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> { + subscribe.addSubscribe(rtpHook, (hookData) -> { logger.debug("sipc 添加订阅===callId {}",callId); - hookEvent.response(mediaServerItemInUse, hookParam); - subscribe.removeSubscribe(hookSubscribe); - hookSubscribe.getContent().put("regist", false); - hookSubscribe.getContent().put("schema", "rtsp"); + hookEvent.response(hookData); + subscribe.removeSubscribe(rtpHook); // 添加流注销的订阅,注销了后向设备发送bye - subscribe.addSubscribe(hookSubscribe, - (mediaServerItemForEnd, hookParam1) -> { + Hook departureHook = Hook.getInstance(HookType.on_media_departure, "rtp", ssrcInfo.getStream(), mediaServerItem.getId()); + subscribe.addSubscribe(departureHook, + (departureHookData) -> { logger.info("[录像]下载结束, 发送BYE"); try { streamByeCmd(device, channelId, ssrcInfo.getStream(), callId); @@ -604,20 +602,20 @@ public class SIPCommander implements ISIPCommander { } logger.info("[语音喊话] {} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getIp(), sendRtpItem.getPort()); - HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); - subscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItemInUse, hookParam) -> { + Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", stream, mediaServerItem.getId()); + subscribe.addSubscribe(hook, (hookData) -> { if (event != null) { - event.response(mediaServerItemInUse, hookParam); - subscribe.removeSubscribe(hookSubscribeForStreamChange); + event.response(hookData); + subscribe.removeSubscribe(hook); } }); CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); callIdHeader.setCallId(callId); - HookSubscribeForStreamPush hookSubscribeForStreamPush = HookSubscribeFactory.on_publish("rtp", stream, null, mediaServerItem.getId()); - subscribe.addSubscribe(hookSubscribeForStreamPush, (mediaServerItemInUse, hookParam) -> { + Hook publishHook = Hook.getInstance(HookType.on_publish, "rtp", stream, mediaServerItem.getId()); + subscribe.addSubscribe(publishHook, (hookData) -> { if (eventForPush != null) { - eventForPush.response(mediaServerItemInUse, hookParam); + eventForPush.response(hookData); } }); // @@ -1260,7 +1258,6 @@ public class SIPCommander implements ISIPCommander { * @param startPriority 报警起始级别(可选) * @param endPriority 报警终止级别(可选) * @param alarmMethod 报警方式条件(可选) - * @param alarmType 报警类型 * @param startTime 报警发生起始时间(可选) * @param endTime 报警发生终止时间(可选) * @return true = 命令发送成功 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 441e0f0a9..21aba6c4f 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -13,9 +13,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.event.hook.Hook; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; @@ -905,11 +905,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { } logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); - subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> { + Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", stream, mediaServerItem.getId()); + subscribe.addSubscribe(hook, (hookData) -> { if (event != null) { - event.response(mediaServerItemInUse, hookParam); - subscribe.removeSubscribe(hookSubscribe); + event.response(hookData); + subscribe.removeSubscribe(hook); } }); String sdpIp = mediaServerItem.getSdpIp(); @@ -949,7 +949,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { sipSender.transmitRequest(sipLayer.getLocalIp(platform.getDeviceIp()), request, (e -> { streamSession.remove(platform.getServerGBId(), channelId, ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); - subscribe.removeSubscribe(hookSubscribe); + subscribe.removeSubscribe(hook); errorEvent.response(e); }), e -> { ResponseEvent responseEvent = (ResponseEvent) e.event; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index a8c03d7b1..9f4e47046 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -18,8 +18,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; @@ -115,7 +115,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements private IMediaServerService mediaServerService; @Autowired - private HookSubscribe zlmHttpHookSubscribe; + private HookSubscribe hookSubscribe; @Autowired private SIPProcessorObserver sipProcessorObserver; @@ -723,17 +723,16 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements // TODO 控制启用以使设备上线 logger.info("[ app={}, stream={} ]通道未推流,启用流后开始推流", gbStream.getApp(), gbStream.getStream()); // 监听流上线 - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(gbStream.getApp(), gbStream.getStream(), true, "rtsp", mediaServerItem.getId()); - zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, hookParam) -> { - OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam; - logger.info("[上级点播]拉流代理已经就绪, {}/{}", streamChangedHookParam.getApp(), streamChangedHookParam.getStream()); + Hook hook = Hook.getInstance(HookType.on_media_arrival, gbStream.getApp(), gbStream.getStream(), mediaServerItem.getId()); + this.hookSubscribe.addSubscribe(hook, (hookData) -> { + logger.info("[上级点播]拉流代理已经就绪, {}/{}", hookData.getApp(), hookData.getStream()); dynamicTask.stop(callIdHeader.getCallId()); pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); }); dynamicTask.startDelay(callIdHeader.getCallId(), () -> { logger.info("[ app={}, stream={} ] 等待拉流代理流超时", gbStream.getApp(), gbStream.getStream()); - zlmHttpHookSubscribe.removeSubscribe(hookSubscribe); + this.hookSubscribe.removeSubscribe(hook); }, userSetting.getPlatformPlayTimeout()); boolean start = streamProxyService.start(gbStream.getApp(), gbStream.getStream()); if (!start) { @@ -742,7 +741,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements } catch (SipException | InvalidArgumentException | ParseException e) { logger.error("[命令发送失败] invite 通道未推流: {}", e.getMessage()); } - zlmHttpHookSubscribe.removeSubscribe(hookSubscribe); + this.hookSubscribe.removeSubscribe(hook); dynamicTask.stop(callIdHeader.getCallId()); } } else if ("push".equals(gbStream.getStreamType())) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java index 57b76829e..72ba51af7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java @@ -127,8 +127,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp // 消息发送成功, 向上级发送invite,获取推流 try { - platformService.broadcastInvite(platform, deviceChannel.getChannelId(), mediaServerForMinimumLoad, (mediaServerItem, hookParam)->{ - OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam; + platformService.broadcastInvite(platform, deviceChannel.getChannelId(), mediaServerForMinimumLoad, (hookData)->{ // 上级平台推流成功 AudioBroadcastCatch broadcastCatch = audioBroadcastManager.get(device.getDeviceId(), targetId); if (broadcastCatch != null ) { @@ -136,20 +135,20 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp logger.info("[国标级联] 语音喊话 设备正在使用中 platform: {}, channel: {}", platform.getServerGBId(), deviceChannel.getChannelId()); // 查看语音通道已经建立且已经占用 回复BYE - platformService.stopBroadcast(platform, deviceChannel, streamChangedHookParam.getStream(), true, mediaServerItem); + platformService.stopBroadcast(platform, deviceChannel, hookData.getStream(), true, hookData.getMediaServer()); }else { // 查看语音通道已经建立但是未占用 - broadcastCatch.setApp(streamChangedHookParam.getApp()); - broadcastCatch.setStream(streamChangedHookParam.getStream()); - broadcastCatch.setMediaServerItem(mediaServerItem); + broadcastCatch.setApp(hookData.getApp()); + broadcastCatch.setStream(hookData.getStream()); + broadcastCatch.setMediaServerItem(hookData.getMediaServer()); audioBroadcastManager.update(broadcastCatch); // 推流到设备 - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, targetId, streamChangedHookParam.getStream(), null); + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, targetId, hookData.getStream(), null); if (sendRtpItem == null) { - logger.warn("[国标级联] 语音喊话 异常,未找到发流信息, channelId: {}, stream: {}", targetId, streamChangedHookParam.getStream()); - logger.info("[国标级联] 语音喊话 重新开始,channelId: {}, stream: {}", targetId, streamChangedHookParam.getStream()); + logger.warn("[国标级联] 语音喊话 异常,未找到发流信息, channelId: {}, stream: {}", targetId, hookData.getStream()); + logger.info("[国标级联] 语音喊话 重新开始,channelId: {}, stream: {}", targetId, hookData.getStream()); try { - playService.audioBroadcastCmd(device, targetId, mediaServerItem, streamChangedHookParam.getApp(), streamChangedHookParam.getStream(), 60, true, msg -> { + playService.audioBroadcastCmd(device, targetId, hookData.getMediaServer(), hookData.getApp(), hookData.getStream(), 60, true, msg -> { logger.info("[语音喊话] 通道建立成功, device: {}, channel: {}", device.getDeviceId(), targetId); }); } catch (SipException | InvalidArgumentException | ParseException e) { @@ -157,7 +156,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp } }else { // 发流 - JSONObject jsonObject = zlmServerFactory.startSendRtp(mediaServerItem, sendRtpItem); + JSONObject jsonObject = zlmServerFactory.startSendRtp(hookData.getMediaServer(), sendRtpItem); if (jsonObject != null && jsonObject.getInteger("code") == 0 ) { logger.info("[语音喊话] 自动推流成功, device: {}, channel: {}", device.getDeviceId(), targetId); }else { @@ -167,7 +166,7 @@ public class BroadcastNotifyMessageHandler extends SIPRequestProcessorParent imp } }else { try { - playService.audioBroadcastCmd(device, targetId, mediaServerItem, streamChangedHookParam.getApp(), streamChangedHookParam.getStream(), 60, true, msg -> { + playService.audioBroadcastCmd(device, targetId, hookData.getMediaServer(), hookData.getApp(), hookData.getStream(), 60, true, msg -> { logger.info("[语音喊话] 通道建立成功, device: {}, channel: {}", device.getDeviceId(), targetId); }); } catch (SipException | InvalidArgumentException | ParseException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java index b11b9a8f9..f8ff69cf1 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java @@ -13,9 +13,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; +import com.genersoft.iot.vmp.media.event.hook.Hook; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; @@ -106,9 +106,8 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i logger.error("[录像流]推送完毕,收到关流通知, 发送BYE失败 {}", e.getMessage()); } // 去除监听流注销自动停止下载的监听 - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcTransaction.getStream(), false, "rtsp", ssrcTransaction.getMediaServerId()); - subscribe.removeSubscribe(hookSubscribe); - + Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcTransaction.getStream(), ssrcTransaction.getMediaServerId()); + subscribe.removeSubscribe(hook); // 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题,需要将点播CallId进行上下级绑定 SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, ssrcTransaction.getChannelId(), null, null); if (sendRtpItem != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java index 942f63a95..4eb10412b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.media; import com.genersoft.iot.vmp.conf.MediaConfig; -import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.slf4j.Logger; diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java index dcb465540..62015dc48 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java @@ -8,8 +8,8 @@ import com.genersoft.iot.vmp.media.abl.bean.AblServerConfig; import com.genersoft.iot.vmp.media.abl.bean.ConfigKeyId; import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent; -import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; -import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.slf4j.Logger; @@ -20,11 +20,8 @@ import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import org.springframework.util.ObjectUtils; -import java.io.File; import java.lang.reflect.Field; -import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java index 2cc9943e7..e753fb6c6 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.media.bean; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import io.swagger.v3.oas.annotations.media.Schema; @@ -12,6 +13,15 @@ import java.util.List; */ @Schema(description = "视频信息") public class MediaInfo { + @Schema(description = "应用名") + private String app; + @Schema(description = "流ID") + private String stream; + @Schema(description = "流媒体节点") + private MediaServer mediaServer; + @Schema(description = "协议") + private String schema; + @Schema(description = "观看人数") private Integer readerCount; @Schema(description = "视频编码类型") @@ -37,8 +47,15 @@ public class MediaInfo { @Schema(description = "数据产生速度,单位byte/s") private Long bytesSpeed; - public static MediaInfo getInstance(JSONObject jsonObject) { + public static MediaInfo getInstance(JSONObject jsonObject, MediaServer mediaServer) { MediaInfo mediaInfo = new MediaInfo(); + mediaInfo.setMediaServer(mediaServer); + String app = jsonObject.getString("app"); + mediaInfo.setApp(app); + String stream = jsonObject.getString("stream"); + mediaInfo.setStream(stream); + String schema = jsonObject.getString("schema"); + mediaInfo.setSchema(schema); Integer totalReaderCount = jsonObject.getInteger("totalReaderCount"); Boolean online = jsonObject.getBoolean("online"); Integer originType = jsonObject.getInteger("originType"); @@ -110,9 +127,13 @@ public class MediaInfo { return mediaInfo; } - public static MediaInfo getInstance(OnStreamChangedHookParam param) { + public static MediaInfo getInstance(OnStreamChangedHookParam param, MediaServer mediaServer) { List tracks = param.getTracks(); MediaInfo mediaInfo = new MediaInfo(); + mediaInfo.setApp(param.getApp()); + mediaInfo.setStream(param.getStream()); + mediaInfo.setSchema(param.getSchema()); + mediaInfo.setMediaServer(mediaServer); mediaInfo.setReaderCount(param.getTotalReaderCount()); mediaInfo.setOnline(param.isRegist()); mediaInfo.setOriginType(param.getOriginType()); @@ -247,4 +268,36 @@ public class MediaInfo { public void setBytesSpeed(Long bytesSpeed) { this.bytesSpeed = bytesSpeed; } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public MediaServer getMediaServer() { + return mediaServer; + } + + public void setMediaServer(MediaServer mediaServer) { + this.mediaServer = mediaServer; + } + + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java new file mode 100644 index 000000000..aafc5db10 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java @@ -0,0 +1,92 @@ +package com.genersoft.iot.vmp.media.bean; + +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; + +public class RecordInfo { + private String fileName; + private String filePath; + private long fileSize; + private String folder; + private String url; + private long startTime; + private double timeLen; + + public static RecordInfo getInstance(OnRecordMp4HookParam hookParam) { + RecordInfo recordInfo = new RecordInfo(); + recordInfo.setFileName(hookParam.getFile_name()); + recordInfo.setUrl(hookParam.getUrl()); + recordInfo.setFolder(hookParam.getFolder()); + recordInfo.setFilePath(hookParam.getFile_path()); + recordInfo.setFileSize(hookParam.getFile_size()); + recordInfo.setStartTime(hookParam.getStart_time()); + recordInfo.setTimeLen(hookParam.getTime_len()); + return recordInfo; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public long getFileSize() { + return fileSize; + } + + public void setFileSize(long fileSize) { + this.fileSize = fileSize; + } + + public String getFolder() { + return folder; + } + + public void setFolder(String folder) { + this.folder = folder; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public double getTimeLen() { + return timeLen; + } + + public void setTimeLen(double timeLen) { + this.timeLen = timeLen; + } + + @Override + public String toString() { + return "RecordInfo{" + + "文件名称='" + fileName + '\'' + + ", 文件路径='" + filePath + '\'' + + ", 文件大小=" + fileSize + + ", 开始时间=" + startTime + + ", 时长=" + timeLen + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java deleted file mode 100644 index 2f8a8405b..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.genersoft.iot.vmp.media.event; - -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; -import org.springframework.context.ApplicationEvent; - -/** - * 流未找到 - */ -public class MediaNotFoundEvent extends ApplicationEvent { - public MediaNotFoundEvent(Object source) { - super(source); - } - - private String app; - - private String stream; - - private MediaServer mediaServer; - - private String schema; - - public static MediaNotFoundEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){ - MediaNotFoundEvent mediaDepartureEven = new MediaNotFoundEvent(source); - mediaDepartureEven.setApp(hookParam.getApp()); - mediaDepartureEven.setStream(hookParam.getStream()); - mediaDepartureEven.setSchema(hookParam.getSchema()); - mediaDepartureEven.setMediaServer(mediaServer); - return mediaDepartureEven; - } - - public String getApp() { - return app; - } - - public void setApp(String app) { - this.app = app; - } - - public String getStream() { - return stream; - } - - public void setStream(String stream) { - this.stream = stream; - } - - public MediaServer getMediaServer() { - return mediaServer; - } - - public void setMediaServer(MediaServer mediaServer) { - this.mediaServer = mediaServer; - } - - public String getSchema() { - return schema; - } - - public void setSchema(String schema) { - this.schema = schema; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java deleted file mode 100644 index ca01142a2..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.genersoft.iot.vmp.media.event; - -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; -import org.springframework.context.ApplicationEvent; - -/** - * rtp 服务收流超时通知 - */ -public class MediaRtpServerTimeoutEvent extends ApplicationEvent { - public MediaRtpServerTimeoutEvent(Object source) { - super(source); - } - - private String app; - - private String stream; - - private MediaServer mediaServer; - - public static MediaRtpServerTimeoutEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){ - MediaRtpServerTimeoutEvent mediaDepartureEven = new MediaRtpServerTimeoutEvent(source); - mediaDepartureEven.setApp(hookParam.getApp()); - mediaDepartureEven.setStream(hookParam.getStream()); - mediaDepartureEven.setMediaServer(mediaServer); - return mediaDepartureEven; - } - - public String getApp() { - return app; - } - - public void setApp(String app) { - this.app = app; - } - - public String getStream() { - return stream; - } - - public void setStream(String stream) { - this.stream = stream; - } - - public MediaServer getMediaServer() { - return mediaServer; - } - - public void setMediaServer(MediaServer mediaServer) { - this.mediaServer = mediaServer; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/Hook.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/Hook.java new file mode 100755 index 000000000..a0dc7c32c --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/Hook.java @@ -0,0 +1,86 @@ +package com.genersoft.iot.vmp.media.event.hook; + +/** + * zlm hook事件的参数 + * @author lin + */ +public class Hook { + + private HookType hookType; + + private String app; + + private String stream; + + private String mediaServerId; + + private Long createTime; + + public static Hook getInstance(HookType hookType, String app, String stream, String mediaServerId) { + Hook hookSubscribe = new Hook(); + hookSubscribe.setApp(app); + hookSubscribe.setStream(stream); + hookSubscribe.setHookType(hookType); + hookSubscribe.setMediaServerId(mediaServerId); + hookSubscribe.setCreateTime(System.currentTimeMillis()); + return hookSubscribe; + } + + public HookType getHookType() { + return hookType; + } + + public void setHookType(HookType hookType) { + this.hookType = hookType; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public Long getCreateTime() { + return createTime; + } + + public void setCreateTime(Long createTime) { + this.createTime = createTime; + } + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Hook) { + Hook param = (Hook) obj; + return param.getHookType().equals(this.hookType) + && param.getApp().equals(this.app) + && param.getStream().equals(this.stream) + && param.getMediaServerId().equals(this.mediaServerId); + }else { + return false; + } + } + + @Override + public String toString() { + return this.getHookType() + this.getApp() + this.getStream() + this.getMediaServerId(); + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java new file mode 100644 index 000000000..25c02de51 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java @@ -0,0 +1,132 @@ +package com.genersoft.iot.vmp.media.event.hook; + +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.bean.RecordInfo; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaEvent; +import com.genersoft.iot.vmp.media.event.media.MediaPublishEvent; +import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * Hook返回的内容 + */ +public class HookData { + /** + * 应用名 + */ + private String app; + /** + * 流ID + */ + private String stream; + /** + * 流媒体节点 + */ + private MediaServer mediaServer; + /** + * 协议 + */ + private String schema; + + /** + * 流信息 + */ + private MediaInfo mediaInfo; + + /** + * 录像信息 + */ + private RecordInfo recordInfo; + + @Schema(description = "推流的额外参数") + private String params; + public static HookData getInstance(MediaEvent mediaEvent) { + HookData hookData = new HookData(); + if (mediaEvent instanceof MediaPublishEvent) { + MediaPublishEvent event = (MediaPublishEvent) mediaEvent; + hookData.setApp(event.getApp()); + hookData.setStream(event.getStream()); + hookData.setSchema(event.getSchema()); + hookData.setMediaServer(event.getMediaServer()); + hookData.setParams(event.getParams()); + }else if (mediaEvent instanceof MediaArrivalEvent) { + MediaArrivalEvent event = (MediaArrivalEvent) mediaEvent; + hookData.setApp(event.getApp()); + hookData.setStream(event.getStream()); + hookData.setSchema(event.getSchema()); + hookData.setMediaServer(event.getMediaServer()); + hookData.setMediaInfo(event.getMediaInfo()); + }else if (mediaEvent instanceof MediaRecordMp4Event) { + MediaRecordMp4Event event = (MediaRecordMp4Event) mediaEvent; + hookData.setApp(event.getApp()); + hookData.setStream(event.getStream()); + hookData.setSchema(event.getSchema()); + hookData.setMediaServer(event.getMediaServer()); + hookData.setRecordInfo(event.getRecordInfo()); + }else { + hookData.setApp(mediaEvent.getApp()); + hookData.setStream(mediaEvent.getStream()); + hookData.setSchema(mediaEvent.getSchema()); + hookData.setMediaServer(mediaEvent.getMediaServer()); + } + return hookData; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public MediaServer getMediaServer() { + return mediaServer; + } + + public void setMediaServer(MediaServer mediaServer) { + this.mediaServer = mediaServer; + } + + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } + + public MediaInfo getMediaInfo() { + return mediaInfo; + } + + public void setMediaInfo(MediaInfo mediaInfo) { + this.mediaInfo = mediaInfo; + } + + public String getParams() { + return params; + } + + public void setParams(String params) { + this.params = params; + } + + public RecordInfo getRecordInfo() { + return recordInfo; + } + + public void setRecordInfo(RecordInfo recordInfo) { + this.recordInfo = recordInfo; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java index f5dac01c9..64b8ffeb2 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java @@ -1,172 +1,105 @@ package com.genersoft.iot.vmp.media.event.hook; -import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.media.MediaEvent; +import com.genersoft.iot.vmp.media.event.media.MediaPublishEvent; +import org.mybatis.logging.Logger; +import org.mybatis.logging.LoggerFactory; +import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; import java.time.Instant; -import java.util.*; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; /** - * ZLMediaServer的hook事件订阅 + * zlm hook事件的参数 * @author lin */ @Component public class HookSubscribe { - private final static Logger logger = LoggerFactory.getLogger(HookSubscribe.class); + /** + * 订阅数据过期时间 + */ + private final long subscribeExpire = 5 * 1000; @FunctionalInterface public interface Event{ - void response(MediaServer mediaServerItem, HookParam hookParam); + void response(HookData data); } /** * 流到来的处理 */ @Async("taskExecutor") - @org.springframework.context.event.EventListener + @EventListener public void onApplicationEvent(MediaArrivalEvent event) { - for (HookType hookType : allSubscribes.keySet()) { - if (hookType.equals(HookType.on_stream_changed)) { - - } - } - } - - private Map> allSubscribes = new ConcurrentHashMap<>(); - - public void addSubscribe(IHookSubscribe hookSubscribe, HookSubscribe.Event event) { - if (hookSubscribe.getExpires() == null) { - // 默认5分钟过期 - Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(5)); - hookSubscribe.setExpires(expiresInstant); - } - allSubscribes.computeIfAbsent(hookSubscribe.getHookType(), k -> new ConcurrentHashMap<>()).put(hookSubscribe, event); - } - - public HookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { - HookSubscribe.Event event= null; - Map eventMap = allSubscribes.get(type); - if (eventMap == null) { - return null; - } - for (IHookSubscribe key : eventMap.keySet()) { - Boolean result = null; - - for (String s : key.getContent().keySet()) { - if (result == null) { - result = key.getContent().getString(s).equals(hookResponse.getString(s)); - }else { - if (key.getContent().getString(s) == null) { - continue; - } - result = result && key.getContent().getString(s).equals(hookResponse.getString(s)); - } - } - if (null != result && result) { - event = eventMap.get(key); - } - } - return event; - } - - public void removeSubscribe(IHookSubscribe hookSubscribe) { - Map eventMap = allSubscribes.get(hookSubscribe.getHookType()); - if (eventMap == null) { - return; + if ("rtsp".equals(event.getSchema())) { + System.out.println("流到来的处理: " + allSubscribes.size()); + sendNotify(HookType.on_media_arrival, event); } - Set> entries = eventMap.entrySet(); - if (entries.size() > 0) { - List> entriesToRemove = new ArrayList<>(); - for (Map.Entry entry : entries) { - JSONObject content = entry.getKey().getContent(); - if (content == null || content.size() == 0) { - entriesToRemove.add(entry); - continue; - } - Boolean result = null; - for (String s : content.keySet()) { - if (result == null) { - result = content.getString(s).equals(hookSubscribe.getContent().getString(s)); - }else { - if (content.getString(s) == null) { - continue; - } - result = result && content.getString(s).equals(hookSubscribe.getContent().getString(s)); - } - } - if (result){ - entriesToRemove.add(entry); - } - } - - if (!CollectionUtils.isEmpty(entriesToRemove)) { - for (Map.Entry entry : entriesToRemove) { - eventMap.remove(entry.getKey()); - } - if (eventMap.size() == 0) { - allSubscribes.remove(hookSubscribe.getHookType()); - } - } - - } } /** - * 获取某个类型的所有的订阅 - * @param type - * @return + * 流结束事件 */ - public List getSubscribes(HookType type) { - Map eventMap = allSubscribes.get(type); - if (eventMap == null) { - return null; + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaDepartureEvent event) { + if ("rtsp".equals(event.getSchema())) { + sendNotify(HookType.on_media_departure, event); } - List result = new ArrayList<>(); - for (IHookSubscribe key : eventMap.keySet()) { - result.add(eventMap.get(key)); - } - return result; + + } + /** + * 推流鉴权事件 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaPublishEvent event) { + sendNotify(HookType.on_publish, event); } - public List getAll(){ - ArrayList result = new ArrayList<>(); - Collection> values = allSubscribes.values(); - for (Map value : values) { - result.addAll(value.keySet()); + private final Map allSubscribes = new ConcurrentHashMap<>(); + private final Map allHook = new ConcurrentHashMap<>(); + + private void sendNotify(HookType hookType, MediaEvent event) { + Hook paramHook = Hook.getInstance(hookType, event.getApp(), event.getStream(), event.getMediaServer().getId()); + Event hookSubscribeEvent = allSubscribes.get(paramHook.toString()); + if (hookSubscribeEvent != null) { + HookData data = HookData.getInstance(event); + hookSubscribeEvent.response(data); } - return result; + } + + public void addSubscribe(Hook hook, HookSubscribe.Event event) { + if (hook.getCreateTime() == null) { + hook.setCreateTime(System.currentTimeMillis()); + } + allSubscribes.put(hook.toString(), event); + allHook.put(hook.toString(), hook); + } + + public void removeSubscribe(Hook hook) { + allSubscribes.remove(hook.toString()); + allHook.remove(hook.toString()); } /** * 对订阅数据进行过期清理 */ -// @Scheduled(cron="0 0/5 * * * ?") //每5分钟执行一次 - @Scheduled(fixedRate = 2 * 1000) + @Scheduled(fixedRate=subscribeExpire) //每5分钟执行一次 public void execute(){ - Instant instant = Instant.now().minusMillis(TimeUnit.MINUTES.toMillis(5)); - int total = 0; - for (HookType hookType : allSubscribes.keySet()) { - Map hookSubscribeEventMap = allSubscribes.get(hookType); - if (hookSubscribeEventMap.size() > 0) { - for (IHookSubscribe hookSubscribe : hookSubscribeEventMap.keySet()) { - if (hookSubscribe.getExpires().isBefore(instant)) { - // 过期的 - hookSubscribeEventMap.remove(hookSubscribe); - total ++; - } - } + long expireTime = System.currentTimeMillis() - subscribeExpire; + for (Hook hook : allHook.values()) { + if (hook.getCreateTime() < expireTime) { + allSubscribes.remove(hook.toString()); + allHook.remove(hook.toString()); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java deleted file mode 100755 index 9182205ea..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.genersoft.iot.vmp.media.event.hook; - - -import com.alibaba.fastjson2.JSONObject; - -/** - * hook 订阅工厂 - * @author lin - */ -public class HookSubscribeFactory { - - public static HookSubscribeForStreamChange on_stream_changed(String app, String stream, boolean regist, String scheam, String mediaServerId) { - HookSubscribeForStreamChange hookSubscribe = new HookSubscribeForStreamChange(); - JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject(); - subscribeKey.put("app", app); - subscribeKey.put("stream", stream); - subscribeKey.put("regist", regist); - if (scheam != null) { - subscribeKey.put("schema", scheam); - } - subscribeKey.put("mediaServerId", mediaServerId); - hookSubscribe.setContent(subscribeKey); - - return hookSubscribe; - } - - public static HookSubscribeForRtpServerTimeout on_rtp_server_timeout(String stream, String ssrc, String mediaServerId) { - HookSubscribeForRtpServerTimeout hookSubscribe = new HookSubscribeForRtpServerTimeout(); - JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject(); - subscribeKey.put("stream_id", stream); - subscribeKey.put("ssrc", ssrc); - subscribeKey.put("mediaServerId", mediaServerId); - hookSubscribe.setContent(subscribeKey); - return hookSubscribe; - } - - public static HookSubscribeForStreamPush on_publish(String app, String stream, String scheam, String mediaServerId) { - HookSubscribeForStreamPush hookSubscribe = new HookSubscribeForStreamPush(); - JSONObject subscribeKey = new JSONObject(); - subscribeKey.put("app", app); - subscribeKey.put("stream", stream); - if (scheam != null) { - subscribeKey.put("schema", scheam); - } - subscribeKey.put("mediaServerId", mediaServerId); - hookSubscribe.setContent(subscribeKey); - - return hookSubscribe; - } - - public static HookSubscribeForRecordMp4 on_record_mp4(String mediaServerId, String app, String stream) { - HookSubscribeForRecordMp4 hookSubscribe = new HookSubscribeForRecordMp4(); - JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject(); - subscribeKey.put("app", app); - subscribeKey.put("stream", stream); - subscribeKey.put("mediaServerId", mediaServerId); - hookSubscribe.setContent(subscribeKey); - - return hookSubscribe; - } - -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java deleted file mode 100755 index 46f62a898..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.genersoft.iot.vmp.media.event.hook; - -import com.alibaba.fastjson2.JSONObject; -import com.alibaba.fastjson2.annotation.JSONField; - -import java.time.Instant; - -/** - * hook订阅-录像完成 - * @author lin - */ -public class HookSubscribeForRecordMp4 implements IHookSubscribe{ - - private HookType hookType = HookType.on_record_mp4; - - private JSONObject content; - - @JSONField(format="yyyy-MM-dd HH:mm:ss") - private Instant expires; - - @Override - public HookType getHookType() { - return hookType; - } - - @Override - public JSONObject getContent() { - return content; - } - - public void setContent(JSONObject content) { - this.content = content; - } - - @Override - public Instant getExpires() { - return expires; - } - - @Override - public void setExpires(Instant expires) { - this.expires = expires; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java deleted file mode 100755 index d526c7851..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.genersoft.iot.vmp.media.event.hook; - -import com.alibaba.fastjson2.JSONObject; -import com.alibaba.fastjson2.annotation.JSONField; - -import java.time.Instant; - -/** - * hook订阅-收流超时 - * @author lin - */ -public class HookSubscribeForRtpServerTimeout implements IHookSubscribe{ - - private HookType hookType = HookType.on_rtp_server_timeout; - - private JSONObject content; - - @JSONField(format="yyyy-MM-dd HH:mm:ss") - private Instant expires; - - @Override - public HookType getHookType() { - return hookType; - } - - @Override - public JSONObject getContent() { - return content; - } - - public void setContent(JSONObject content) { - this.content = content; - } - - @Override - public Instant getExpires() { - return expires; - } - - @Override - public void setExpires(Instant expires) { - this.expires = expires; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java deleted file mode 100755 index b8d267559..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.genersoft.iot.vmp.media.event.hook; - -import com.alibaba.fastjson2.JSONObject; -import com.alibaba.fastjson2.annotation.JSONField; - -import java.time.Instant; - -/** - * hook订阅-流变化 - * @author lin - */ -public class HookSubscribeForStreamChange implements IHookSubscribe{ - - private HookType hookType = HookType.on_stream_changed; - - private JSONObject content; - - @JSONField(format="yyyy-MM-dd HH:mm:ss") - private Instant expires; - - @Override - public HookType getHookType() { - return hookType; - } - - @Override - public JSONObject getContent() { - return content; - } - - public void setContent(JSONObject content) { - this.content = content; - } - - @Override - public Instant getExpires() { - return expires; - } - - @Override - public void setExpires(Instant expires) { - this.expires = expires; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java deleted file mode 100644 index e61918143..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.genersoft.iot.vmp.media.event.hook; - - -import com.alibaba.fastjson2.JSONObject; - -import java.time.Instant; - -/** - * hook订阅-开始推流 - * @author lin - */ -public class HookSubscribeForStreamPush implements IHookSubscribe{ - - private HookType hookType = HookType.on_publish; - - private JSONObject content; - - private Instant expires; - - @Override - public HookType getHookType() { - return hookType; - } - - @Override - public JSONObject getContent() { - return content; - } - - public void setContent(JSONObject content) { - this.content = content; - } - - @Override - public Instant getExpires() { - return expires; - } - - @Override - public void setExpires(Instant expires) { - this.expires = expires; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java index 77e37a829..58bd65687 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java @@ -10,6 +10,6 @@ public enum HookType { on_publish, on_record_mp4, on_media_arrival, - on_stream_changed, + on_media_departure, on_rtp_server_timeout, } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java deleted file mode 100755 index 7fb48ce76..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.genersoft.iot.vmp.media.event.hook; - -import com.alibaba.fastjson2.JSONObject; - -import java.time.Instant; - -/** - * zlm hook事件的参数 - * @author lin - */ -public interface IHookSubscribe { - - /** - * 获取hook类型 - * @return hook类型 - */ - HookType getHookType(); - - /** - * 获取hook的具体内容 - * @return hook的具体内容 - */ - JSONObject getContent(); - - /** - * 设置过期时间 - * @param instant 过期时间 - */ - void setExpires(Instant instant); - - /** - * 获取过期时间 - * @return 过期时间 - */ - Instant getExpires(); -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java similarity index 58% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java index b70fcf790..af1e23e5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java @@ -1,21 +1,20 @@ -package com.genersoft.iot.vmp.media.event; +package com.genersoft.iot.vmp.media.event.media; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import org.springframework.context.ApplicationEvent; /** * 流到来事件 */ -public class MediaArrivalEvent extends ApplicationEvent { +public class MediaArrivalEvent extends MediaEvent { public MediaArrivalEvent(Object source) { super(source); } public static MediaArrivalEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){ MediaArrivalEvent mediaArrivalEvent = new MediaArrivalEvent(source); - mediaArrivalEvent.setMediaInfo(MediaInfo.getInstance(hookParam)); + mediaArrivalEvent.setMediaInfo(MediaInfo.getInstance(hookParam, mediaServer)); mediaArrivalEvent.setApp(hookParam.getApp()); mediaArrivalEvent.setStream(hookParam.getStream()); mediaArrivalEvent.setMediaServer(mediaServer); @@ -26,14 +25,6 @@ public class MediaArrivalEvent extends ApplicationEvent { private MediaInfo mediaInfo; - private String app; - - private String stream; - - private MediaServer mediaServer; - - private String schema; - private String callId; public MediaInfo getMediaInfo() { @@ -44,37 +35,6 @@ public class MediaArrivalEvent extends ApplicationEvent { this.mediaInfo = mediaInfo; } - public String getApp() { - return app; - } - - public void setApp(String app) { - this.app = app; - } - - public String getStream() { - return stream; - } - - public void setStream(String stream) { - this.stream = stream; - } - - public MediaServer getMediaServer() { - return mediaServer; - } - - public void setMediaServer(MediaServer mediaServer) { - this.mediaServer = mediaServer; - } - - public String getSchema() { - return schema; - } - - public void setSchema(String schema) { - this.schema = schema; - } public String getCallId() { return callId; diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java new file mode 100644 index 000000000..5cf87de28 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java @@ -0,0 +1,22 @@ +package com.genersoft.iot.vmp.media.event.media; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; + +/** + * 流离开事件 + */ +public class MediaDepartureEvent extends MediaEvent { + public MediaDepartureEvent(Object source) { + super(source); + } + + public static MediaDepartureEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){ + MediaDepartureEvent mediaDepartureEven = new MediaDepartureEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setSchema(hookParam.getSchema()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java similarity index 58% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java index f11138523..54d0a4203 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java @@ -1,16 +1,16 @@ -package com.genersoft.iot.vmp.media.event; +package com.genersoft.iot.vmp.media.event.media; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import org.springframework.context.ApplicationEvent; /** - * 流离开事件 + * 流到来事件 */ -public class MediaDepartureEvent extends ApplicationEvent { - public MediaDepartureEvent(Object source) { +public class MediaEvent extends ApplicationEvent { + + public MediaEvent(Object source) { super(source); } @@ -22,14 +22,6 @@ public class MediaDepartureEvent extends ApplicationEvent { private String schema; - public static MediaDepartureEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){ - MediaDepartureEvent mediaDepartureEven = new MediaDepartureEvent(source); - mediaDepartureEven.setApp(hookParam.getApp()); - mediaDepartureEven.setStream(hookParam.getStream()); - mediaDepartureEven.setSchema(hookParam.getSchema()); - mediaDepartureEven.setMediaServer(mediaServer); - return mediaDepartureEven; - } public String getApp() { return app; @@ -62,4 +54,5 @@ public class MediaDepartureEvent extends ApplicationEvent { public void setSchema(String schema) { this.schema = schema; } + } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java new file mode 100644 index 000000000..b45f55e84 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java @@ -0,0 +1,22 @@ +package com.genersoft.iot.vmp.media.event.media; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; + +/** + * 流未找到 + */ +public class MediaNotFoundEvent extends MediaEvent { + public MediaNotFoundEvent(Object source) { + super(source); + } + + public static MediaNotFoundEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){ + MediaNotFoundEvent mediaDepartureEven = new MediaNotFoundEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setSchema(hookParam.getSchema()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java new file mode 100644 index 000000000..b50f89651 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java @@ -0,0 +1,33 @@ +package com.genersoft.iot.vmp.media.event.media; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnPublishHookParam; + +/** + * 推流鉴权事件 + */ +public class MediaPublishEvent extends MediaEvent { + public MediaPublishEvent(Object source) { + super(source); + } + + public static MediaPublishEvent getInstance(Object source, OnPublishHookParam hookParam, MediaServer mediaServer){ + MediaPublishEvent mediaPublishEvent = new MediaPublishEvent(source); + mediaPublishEvent.setApp(hookParam.getApp()); + mediaPublishEvent.setStream(hookParam.getStream()); + mediaPublishEvent.setMediaServer(mediaServer); + mediaPublishEvent.setSchema(hookParam.getSchema()); + mediaPublishEvent.setParams(hookParam.getParams()); + return mediaPublishEvent; + } + + private String params; + + public String getParams() { + return params; + } + + public void setParams(String params) { + this.params = params; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java new file mode 100644 index 000000000..e4750c1cd --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java @@ -0,0 +1,36 @@ +package com.genersoft.iot.vmp.media.event.media; + +import com.genersoft.iot.vmp.media.bean.RecordInfo; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; + +/** + * 录像文件生成事件 + */ +public class MediaRecordMp4Event extends MediaEvent { + public MediaRecordMp4Event(Object source) { + super(source); + } + + private RecordInfo recordInfo; + + public static MediaRecordMp4Event getInstance(Object source, OnRecordMp4HookParam hookParam, MediaServer mediaServer){ + MediaRecordMp4Event mediaRecordMp4Event = new MediaRecordMp4Event(source); + mediaRecordMp4Event.setApp(hookParam.getApp()); + mediaRecordMp4Event.setStream(hookParam.getStream()); + RecordInfo recordInfo = RecordInfo.getInstance(hookParam); + mediaRecordMp4Event.setRecordInfo(recordInfo); + mediaRecordMp4Event.setMediaServer(mediaServer); + return mediaRecordMp4Event; + } + + public RecordInfo getRecordInfo() { + return recordInfo; + } + + public void setRecordInfo(RecordInfo recordInfo) { + this.recordInfo = recordInfo; + } + +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java new file mode 100644 index 000000000..939c85263 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java @@ -0,0 +1,22 @@ +package com.genersoft.iot.vmp.media.event.media; + +import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; + +/** + * RtpServer收流超时事件 + */ +public class MediaRtpServerTimeoutEvent extends MediaEvent { + public MediaRtpServerTimeoutEvent(Object source) { + super(source); + } + + public static MediaRtpServerTimeoutEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){ + MediaRtpServerTimeoutEvent mediaDepartureEven = new MediaRtpServerTimeoutEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setSchema(hookParam.getSchema()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java similarity index 96% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java index 931928093..c9679f752 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.event; +package com.genersoft.iot.vmp.media.event.mediaServer; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java similarity index 94% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java index 0da054fe9..e3650454e 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.event; +package com.genersoft.iot.vmp.media.event.mediaServer; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import org.springframework.context.ApplicationEvent; diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerDeleteEvent.java similarity index 75% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerDeleteEvent.java index 10a368b4c..a716ff0e6 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerDeleteEvent.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.event; +package com.genersoft.iot.vmp.media.event.mediaServer; /** * zlm在线事件 diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerEventAbstract.java similarity index 89% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerEventAbstract.java index 91806f8d1..a9bf76981 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerEventAbstract.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.event; +package com.genersoft.iot.vmp.media.event.mediaServer; import org.springframework.context.ApplicationEvent; diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOfflineEvent.java similarity index 61% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOfflineEvent.java index ce3c5a9d4..2f9ac235c 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOfflineEvent.java @@ -1,6 +1,4 @@ -package com.genersoft.iot.vmp.media.event; - -import com.genersoft.iot.vmp.media.event.MediaServerEventAbstract; +package com.genersoft.iot.vmp.media.event.mediaServer; /** * zlm离线事件类 diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOnlineEvent.java similarity index 60% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOnlineEvent.java index 5d9bdc43c..673dce435 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOnlineEvent.java @@ -1,6 +1,4 @@ -package com.genersoft.iot.vmp.media.event; - -import com.genersoft.iot.vmp.media.event.MediaServerEventAbstract; +package com.genersoft.iot.vmp.media.event.mediaServer; /** * zlm在线事件 diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java similarity index 97% rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java index 0d8e38c08..2413f5676 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java @@ -1,4 +1,4 @@ -package com.genersoft.iot.vmp.media.event; +package com.genersoft.iot.vmp.media.event.mediaServer; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.IStreamProxyService; diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index de095eacc..4ec0bfed6 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -104,4 +104,36 @@ public interface IMediaServerService { Map getFFmpegCMDs(MediaServer mediaServer); + /** + * 根据应用名和流ID获取播放地址, 通过zlm接口检查是否存在 + * @param app + * @param stream + * @return + */ + StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr, boolean authority); + + + /** + * 根据应用名和流ID获取播放地址, 通过zlm接口检查是否存在, 返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 + * @param app + * @param stream + * @return + */ + StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority); + + /** + * 根据应用名和流ID获取播放地址, 只是地址拼接 + * @param app + * @param stream + * @return + */ + StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId); + + /** + * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 + * @param app + * @param stream + * @return + */ + StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 58f92f8cd..30a9b8310 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -4,17 +4,19 @@ import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.VideoManagerConstants; +import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; -import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; -import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -74,6 +76,10 @@ public class MediaServerServiceImpl implements IMediaServerService { @Autowired private ApplicationEventPublisher applicationEventPublisher; + @Autowired + private MediaConfig mediaConfig; + + /** * 流到来的处理 @@ -714,4 +720,63 @@ public class MediaServerServiceImpl implements IMediaServerService { } return mediaNodeServerService.getFFmpegCMDs(mediaServer); } + + @Override + public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId) { + return getStreamInfoByAppAndStream(mediaServerItem, app, stream, mediaInfo, null, callId, true); + } + + @Override + public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr, boolean authority) { + StreamInfo streamInfo = null; + if (mediaServerId == null) { + mediaServerId = mediaConfig.getId(); + } + MediaServer mediaInfo = getOne(mediaServerId); + if (mediaInfo == null) { + return null; + } + String calld = null; + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); + if (streamAuthorityInfo != null) { + calld = streamAuthorityInfo.getCallId(); + } + List streamInfoList = getMediaList(mediaInfo, app, stream, calld); + if (streamInfoList.isEmpty()) { + return null; + }else { + return streamInfoList.get(0); + } + } + + + + @Override + public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority) { + return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null, authority); + } + + @Override + public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay) { + StreamInfo streamInfoResult = new StreamInfo(); + streamInfoResult.setStream(stream); + streamInfoResult.setApp(app); + if (addr == null) { + addr = mediaServer.getStreamIp(); + } + + streamInfoResult.setIp(addr); + streamInfoResult.setMediaServerId(mediaServer.getId()); + String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; + streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); + + streamInfoResult.setMediaInfo(mediaInfo); + return streamInfoResult; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index fc128590c..2717fc3de 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -11,9 +11,10 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; -import com.genersoft.iot.vmp.media.event.*; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookType; +import com.genersoft.iot.vmp.media.event.media.*; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; @@ -175,13 +176,6 @@ public class ZLMHttpHookListener { return new HookResultForOnPublish(200, "success"); } - taskExecutor.execute(() -> { - HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); - if (subscribe != null) { - subscribe.response(mediaServer, param); - } - }); - ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams()); if (resultForOnPublish != null) { HookResultForOnPublish successResult = HookResultForOnPublish.getInstance(resultForOnPublish); @@ -316,19 +310,12 @@ public class ZLMHttpHookListener { MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); if (mediaServerItem != null) { event.setMediaServer(mediaServerItem); + event.setApp("rtp"); applicationEventPublisher.publishEvent(event); } }catch (Exception e) { logger.info("[ZLM-HOOK-rtpServer收流超时] 发送通知失败 ", e); } - taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); - if (subscribes != null && !subscribes.isEmpty()) { - for (HookSubscribe.Event subscribe : subscribes) { - subscribe.response(null, param); - } - } - }); return HookResult.SUCCESS(); } @@ -341,16 +328,16 @@ public class ZLMHttpHookListener { public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4HookParam param) { logger.info("[ZLM HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path()); - taskExecutor.execute(() -> { - List subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4); - if (subscribes != null && !subscribes.isEmpty()) { - for (HookSubscribe.Event subscribe : subscribes) { - subscribe.response(null, param); - } + try { + MediaRecordMp4Event event = new MediaRecordMp4Event(this); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServer(mediaServerItem); + applicationEventPublisher.publishEvent(event); } - cloudRecordService.addRecord(param); - - }); + }catch (Exception e) { + logger.info("[ZLM-HOOK-rtpServer收流超时] 发送通知失败 ", e); + } return HookResult.SUCCESS(); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 60327ebfb..11e6063be 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -158,7 +158,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { return null; } JSONObject mediaJSON = data.getJSONObject(0); - MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON); + MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON, mediaServer); StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, app, stream, mediaInfo, callId, true); if (streamInfo != null) { streamInfoList.add(streamInfo); @@ -207,7 +207,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { if (jsonObject.getInteger("code") != 0) { return null; } - return MediaInfo.getInstance(jsonObject); + return MediaInfo.getInstance(jsonObject, mediaServer); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index 6d6332983..27e62b2bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -5,8 +5,8 @@ import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent; -import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java index 66d07de2a..8b722a98f 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.dto; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; /** * 流的鉴权信息 diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java index eda660ebd..797286fe2 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.media.zlm.dto; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.bean.GbStream; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.utils.DateUtil; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java index bffd25b5c..86ee7b8db 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java @@ -20,11 +20,6 @@ public interface ICloudRecordService { */ PageInfo getList(int page, int count, String query, String app, String stream, String startTime, String endTime, List mediaServerItems); - /** - * 根据hook消息增加一条记录 - */ - void addRecord(OnRecordMp4HookParam param); - /** * 获取所有的日期 */ diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java index d3a57f7af..649c72768 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java @@ -10,39 +10,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; */ public interface IMediaService { - /** - * 根据应用名和流ID获取播放地址, 通过zlm接口检查是否存在 - * @param app - * @param stream - * @return - */ - StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr, boolean authority); - - - /** - * 根据应用名和流ID获取播放地址, 通过zlm接口检查是否存在, 返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 - * @param app - * @param stream - * @return - */ - StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority); - - /** - * 根据应用名和流ID获取播放地址, 只是地址拼接 - * @param app - * @param stream - * @return - */ - StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId); - - /** - * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 - * @param app - * @param stream - * @return - */ - StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay); - /** * 播放鉴权 */ diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java index 88cac66c1..9ba4964a7 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.service.bean.ErrorCallback; @@ -30,7 +31,7 @@ public interface IPlayService { ErrorCallback callback); SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback callback); - StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, HookParam hookParam, String deviceId, String channelId); + StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId); MediaServer getNewMediaServerItem(Device device); diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java b/src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java index 771e4c811..c9a54bc97 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.service.bean; +import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; /** @@ -76,18 +77,18 @@ public class CloudRecordItem { */ private long timeLen; - public static CloudRecordItem getInstance(OnRecordMp4HookParam param) { + public static CloudRecordItem getInstance(MediaRecordMp4Event param) { CloudRecordItem cloudRecordItem = new CloudRecordItem(); cloudRecordItem.setApp(param.getApp()); cloudRecordItem.setStream(param.getStream()); - cloudRecordItem.setStartTime(param.getStart_time()*1000); - cloudRecordItem.setFileName(param.getFile_name()); - cloudRecordItem.setFolder(param.getFolder()); - cloudRecordItem.setFileSize(param.getFile_size()); - cloudRecordItem.setFilePath(param.getFile_path()); - cloudRecordItem.setMediaServerId(param.getMediaServerId()); - cloudRecordItem.setTimeLen((long) param.getTime_len() * 1000); - cloudRecordItem.setEndTime((param.getStart_time() + (long)param.getTime_len()) * 1000); + cloudRecordItem.setStartTime(param.getRecordInfo().getStartTime()*1000); + cloudRecordItem.setFileName(param.getRecordInfo().getFileName()); + cloudRecordItem.setFolder(param.getRecordInfo().getFolder()); + cloudRecordItem.setFileSize(param.getRecordInfo().getFileSize()); + cloudRecordItem.setFilePath(param.getRecordInfo().getFilePath()); + cloudRecordItem.setMediaServerId(param.getMediaServer().getId()); + cloudRecordItem.setTimeLen((long) param.getRecordInfo().getTimeLen() * 1000); + cloudRecordItem.setEndTime((param.getRecordInfo().getStartTime() + (long)param.getRecordInfo().getTimeLen()) * 1000); return cloudRecordItem; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java index de4af6c53..6907e908d 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java @@ -5,6 +5,8 @@ import com.alibaba.fastjson2.JSONObject; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; +import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event; import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; @@ -24,6 +26,8 @@ import org.apache.commons.lang3.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.time.*; @@ -99,14 +103,15 @@ public class CloudRecordServiceImpl implements ICloudRecordService { return new ArrayList<>(resultSet); } - @Override - public void addRecord(OnRecordMp4HookParam param) { - CloudRecordItem cloudRecordItem = CloudRecordItem.getInstance(param); - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaRecordMp4Event event) { + CloudRecordItem cloudRecordItem = CloudRecordItem.getInstance(event); + StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(event.getApp(), event.getStream()); if (streamAuthorityInfo != null) { cloudRecordItem.setCallId(streamAuthorityInfo.getCallId()); } - logger.info("[添加录像记录] {}/{} 文件大小:{}, 时长: {}秒", param.getApp(), param.getStream(), param.getFile_size(),param.getTime_len()); + logger.info("[添加录像记录] {}/{} 内容:{}", event.getApp(), event.getStream(), event.getRecordInfo()); cloudRecordServiceMapper.add(cloudRecordItem); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java index 360e29c0f..6e0096099 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java @@ -6,8 +6,8 @@ import com.genersoft.iot.vmp.common.InviteInfo; import com.genersoft.iot.vmp.common.InviteSessionStatus; import com.genersoft.iot.vmp.common.InviteSessionType; import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 3fcb9d088..126ea2410 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -49,12 +49,6 @@ public class MediaServiceImpl implements IMediaService { @Autowired private IRedisCatchStorage redisCatchStorage; - @Autowired - private IMediaServerService mediaServerService; - - @Autowired - private MediaConfig mediaConfig; - @Autowired private IStreamProxyService streamProxyService; @@ -88,67 +82,6 @@ public class MediaServiceImpl implements IMediaService { @Autowired private ISIPCommander commander; - - - @Override - public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId) { - return getStreamInfoByAppAndStream(mediaServerItem, app, stream, mediaInfo, null, callId, true); - } - - @Override - public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr, boolean authority) { - StreamInfo streamInfo = null; - if (mediaServerId == null) { - mediaServerId = mediaConfig.getId(); - } - MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); - if (mediaInfo == null) { - return null; - } - String calld = null; - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); - if (streamAuthorityInfo != null) { - calld = streamAuthorityInfo.getCallId(); - } - List streamInfoList = mediaServerService.getMediaList(mediaInfo, app, stream, calld); - if (streamInfoList.isEmpty()) { - return null; - }else { - return streamInfoList.get(0); - } - } - - - - @Override - public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority) { - return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null, authority); - } - - @Override - public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay) { - StreamInfo streamInfoResult = new StreamInfo(); - streamInfoResult.setStream(stream); - streamInfoResult.setApp(app); - if (addr == null) { - addr = mediaServer.getStreamIp(); - } - - streamInfoResult.setIp(addr); - streamInfoResult.setMediaServerId(mediaServer.getId()); - String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; - streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); - - streamInfoResult.setMediaInfo(mediaInfo); - return streamInfoResult; - } - @Override public boolean authenticatePlay(String app, String stream, String callId) { if (app == null || stream == null) { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index cfb9abbc7..48a8fbba6 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -1,9 +1,7 @@ package com.genersoft.iot.vmp.service.impl; import com.baomidou.dynamic.datasource.annotation.DS; -import com.genersoft.iot.vmp.common.InviteInfo; -import com.genersoft.iot.vmp.common.InviteSessionStatus; -import com.genersoft.iot.vmp.common.InviteSessionType; +import com.genersoft.iot.vmp.common.*; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; @@ -11,10 +9,12 @@ import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; -import com.genersoft.iot.vmp.media.event.MediaSendRtpStoppedEvent; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookData; +import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; @@ -72,7 +72,7 @@ public class PlatformServiceImpl implements IPlatformService { private IMediaServerService mediaServerService; @Autowired - private SIPCommanderFroPlatform commanderForPlatform; + private ISIPCommanderForPlatform commanderForPlatform; @Autowired private DynamicTask dynamicTask; @@ -520,11 +520,11 @@ public class PlatformServiceImpl implements IPlatformService { inviteStreamService.removeInviteInfo(inviteInfoForOld); }else { // 流确实尚在推流,直接回调结果 - OnStreamChangedHookParam hookParam = new OnStreamChangedHookParam(); - hookParam.setApp(inviteInfoForOld.getStreamInfo().getApp()); - hookParam.setStream(inviteInfoForOld.getStreamInfo().getStream()); - - hookEvent.response(mediaServerItemForStreamInfo, hookParam); + HookData hookData = new HookData(); + hookData.setApp(inviteInfoForOld.getStreamInfo().getApp()); + hookData.setStream(inviteInfoForOld.getStreamInfo().getStream()); + hookData.setMediaServer(mediaServerItemForStreamInfo); + hookEvent.response(hookData); return; } } @@ -582,14 +582,14 @@ public class PlatformServiceImpl implements IPlatformService { } } }, userSetting.getPlayTimeout()); - commanderForPlatform.broadcastInviteCmd(platform, channelId, mediaServerItem, ssrcInfo, (mediaServerItemForInvite, hookParam)->{ + commanderForPlatform.broadcastInviteCmd(platform, channelId, mediaServerItem, ssrcInfo, (hookData)->{ logger.info("[国标级联] 发起语音喊话 收到上级推流 deviceId: {}, channelId: {}", platform.getServerGBId(), channelId); dynamicTask.stop(timeOutTaskKey); // hook响应 - playService.onPublishHandlerForPlay(mediaServerItemForInvite, hookParam, platform.getServerGBId(), channelId); + playService.onPublishHandlerForPlay(hookData.getMediaServer(), hookData.getMediaInfo(), platform.getServerGBId(), channelId); // 收到流 if (hookEvent != null) { - hookEvent.response(mediaServerItem, hookParam); + hookEvent.response(hookData); } }, event -> { diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 1fad2be28..32af05752 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -17,16 +17,17 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; -import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; +import com.genersoft.iot.vmp.media.bean.RecordInfo; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookData; +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.event.media.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRecordMp4; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; @@ -99,9 +100,6 @@ public class PlayServiceImpl implements IPlayService { @Autowired private SendRtpPortManager sendRtpPortManager; - @Autowired - private IMediaService mediaService; - @Autowired private IMediaServerService mediaServerService; @@ -423,12 +421,12 @@ public class PlayServiceImpl implements IPlayService { // 查看设备是否已经在推流 try { - cmder.talkStreamCmd(mediaServerItem, sendRtpItem, device, channelId, callId, (mediaServerItemInuse, hookParam) -> { - logger.info("[语音对讲] 流已生成, 开始推流: " + hookParam); + cmder.talkStreamCmd(mediaServerItem, sendRtpItem, device, channelId, callId, (hookData) -> { + logger.info("[语音对讲] 流已生成, 开始推流: " + hookData); dynamicTask.stop(timeOutTaskKey); // TODO 暂不做处理 - }, (mediaServerItemInuse, hookParam) -> { - logger.info("[语音对讲] 设备开始推流: " + hookParam); + }, (hookData) -> { + logger.info("[语音对讲] 设备开始推流: " + hookData); dynamicTask.stop(timeOutTaskKey); }, (event) -> { @@ -538,8 +536,7 @@ public class PlayServiceImpl implements IPlayService { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); // 取消订阅消息监听 - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); - subscribe.removeSubscribe(hookSubscribe); + subscribe.removeSubscribe(Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcInfo.getStream(), mediaServerItem.getId())); } }else { logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},码流:{},端口:{}, SSRC: {}", @@ -554,11 +551,11 @@ public class PlayServiceImpl implements IPlayService { }, userSetting.getPlayTimeout()); try { - cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channel, (mediaServerItemInuse, hookParam ) -> { - logger.info("收到订阅消息: " + hookParam); + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channel, (hookData ) -> { + logger.info("收到订阅消息: " + hookData); dynamicTask.stop(timeOutTaskKey); // hook响应 - StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, hookParam, device.getDeviceId(), channel.getChannelId()); + StreamInfo streamInfo = onPublishHandlerForPlay(hookData.getMediaServer(), hookData.getMediaInfo(), device.getDeviceId(), channel.getChannelId()); if (streamInfo == null){ callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null); @@ -574,7 +571,7 @@ public class PlayServiceImpl implements IPlayService { streamInfo); logger.info("[点播成功] deviceId: {}, channelId:{}, 码流类型:{}", device.getDeviceId(), channel.getChannelId(), channel.getStreamIdentification()); - snapOnPlay(mediaServerItemInuse, device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); + snapOnPlay(hookData.getMediaServer(), device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); }, (eventResult) -> { // 处理收到200ok后的TCP主动连接以及SSRC不一致的问题 InviteOKHandler(eventResult, ssrcInfo, mediaServerItem, device, channel.getChannelId(), @@ -700,11 +697,10 @@ public class PlayServiceImpl implements IPlayService { mediaServerService.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); } - public StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, HookParam hookParam, String deviceId, String channelId) { + public StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId) { StreamInfo streamInfo = null; Device device = redisCatchStorage.getDevice(deviceId); - OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam; - streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId); + streamInfo = onPublishHandler(mediaServerItem, mediaInfo, deviceId, channelId); if (streamInfo != null) { DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); if (deviceChannel != null) { @@ -722,9 +718,8 @@ public class PlayServiceImpl implements IPlayService { } - private StreamInfo onPublishHandlerForPlayback(MediaServer mediaServerItem, HookParam param, String deviceId, String channelId, String startTime, String endTime) { - OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) param; - StreamInfo streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId); + private StreamInfo onPublishHandlerForPlayback(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId, String startTime, String endTime) { + StreamInfo streamInfo = onPublishHandler(mediaServerItem, mediaInfo, deviceId, channelId); if (streamInfo != null) { streamInfo.setStartTime(startTime); streamInfo.setEndTime(endTime); @@ -733,7 +728,7 @@ public class PlayServiceImpl implements IPlayService { deviceChannel.setStreamId(streamInfo.getStream()); storager.startPlay(deviceId, channelId, streamInfo.getStream()); } - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, ((OnStreamChangedHookParam) param).getStream()); + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, mediaInfo.getStream()); if (inviteInfo != null) { inviteInfo.setStatus(InviteSessionStatus.ok); @@ -839,10 +834,10 @@ public class PlayServiceImpl implements IPlayService { inviteStreamService.removeInviteInfo(inviteInfo); }; - HookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { - logger.info("收到回放订阅消息: " + hookParam); + HookSubscribe.Event hookEvent = (hookData) -> { + logger.info("收到回放订阅消息: " + hookData); dynamicTask.stop(playBackTimeOutTaskKey); - StreamInfo streamInfo = onPublishHandlerForPlayback(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); + StreamInfo streamInfo = onPublishHandlerForPlayback(hookData.getMediaServer(), hookData.getMediaInfo(), deviceId, channelId, startTime, endTime); if (streamInfo == null) { logger.warn("设备回放API调用失败!"); callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), @@ -1028,10 +1023,10 @@ public class PlayServiceImpl implements IPlayService { streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); inviteStreamService.removeInviteInfo(inviteInfo); }; - HookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { - logger.info("[录像下载]收到订阅消息: " + hookParam); + HookSubscribe.Event hookEvent = (hookData) -> { + logger.info("[录像下载]收到订阅消息: " + hookData); dynamicTask.stop(downLoadTimeOutTaskKey); - StreamInfo streamInfo = onPublishHandlerForDownload(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); + StreamInfo streamInfo = onPublishHandlerForDownload(hookData.getMediaServer(), hookData.getMediaInfo(), deviceId, channelId, startTime, endTime); if (streamInfo == null) { logger.warn("[录像下载] 获取流地址信息失败"); callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), @@ -1049,26 +1044,24 @@ public class PlayServiceImpl implements IPlayService { downLoadTimeOutTaskKey, callback, inviteInfo, InviteSessionType.DOWNLOAD); // 注册录像回调事件,录像下载结束后写入下载地址 - HookSubscribe.Event hookEventForRecord = (mediaServerItemInuse, hookParam) -> { + HookSubscribe.Event hookEventForRecord = (hookData) -> { logger.info("[录像下载] 收到录像写入磁盘消息: , {}/{}-{}", inviteInfo.getDeviceId(), inviteInfo.getChannelId(), ssrcInfo.getStream()); - logger.info("[录像下载] 收到录像写入磁盘消息内容: " + hookParam); - OnRecordMp4HookParam recordMp4HookParam = (OnRecordMp4HookParam)hookParam; - String filePath = recordMp4HookParam.getFile_path(); + logger.info("[录像下载] 收到录像写入磁盘消息内容: " + hookData); + RecordInfo recordInfo = hookData.getRecordInfo(); + String filePath = recordInfo.getFilePath(); DownloadFileInfo downloadFileInfo = CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath); InviteInfo inviteInfoForNew = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId() , inviteInfo.getChannelId(), inviteInfo.getStream()); inviteInfoForNew.getStreamInfo().setDownLoadFilePath(downloadFileInfo); inviteStreamService.updateInviteInfo(inviteInfoForNew); }; - HookSubscribeForRecordMp4 hookSubscribe = HookSubscribeFactory.on_record_mp4( - mediaServerItem.getId(), "rtp", ssrcInfo.getStream()); - + Hook hook = Hook.getInstance(HookType.on_record_mp4, "rtp", ssrcInfo.getStream(), mediaServerItem.getId()); // 设置过期时间,下载失败时自动处理订阅数据 // long difference = DateUtil.getDifference(startTime, endTime)/1000; // Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(difference * 2)); // hookSubscribe.setExpires(expiresInstant); - subscribe.addSubscribe(hookSubscribe, hookEventForRecord); + subscribe.addSubscribe(hook, hookEventForRecord); }); } catch (InvalidArgumentException | SipException | ParseException e) { logger.error("[命令发送失败] 录像下载: {}", e.getMessage()); @@ -1134,9 +1127,8 @@ public class PlayServiceImpl implements IPlayService { return inviteInfo.getStreamInfo(); } - private StreamInfo onPublishHandlerForDownload(MediaServer mediaServerItemInuse, HookParam hookParam, String deviceId, String channelId, String startTime, String endTime) { - OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) hookParam; - StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, streamChangedHookParam, deviceId, channelId); + private StreamInfo onPublishHandlerForDownload(MediaServer mediaServerItemInuse, MediaInfo mediaInfo, String deviceId, String channelId, String startTime, String endTime) { + StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, mediaInfo, deviceId, channelId); if (streamInfo != null) { streamInfo.setProgress(0); streamInfo.setStartTime(startTime); @@ -1153,9 +1145,8 @@ public class PlayServiceImpl implements IPlayService { } - public StreamInfo onPublishHandler(MediaServer mediaServerItem, OnStreamChangedHookParam hookParam, String deviceId, String channelId) { - MediaInfo mediaInfo = MediaInfo.getInstance(hookParam); - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", hookParam.getStream(), mediaInfo, null); + public StreamInfo onPublishHandler(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId) { + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", mediaInfo.getStream(), mediaInfo, null); streamInfo.setDeviceID(deviceId); streamInfo.setChannelId(channelId); return streamInfo; @@ -1220,7 +1211,7 @@ public class PlayServiceImpl implements IPlayService { AudioBroadcastResult audioBroadcastResult = new AudioBroadcastResult(); audioBroadcastResult.setApp(app); audioBroadcastResult.setStream(stream); - audioBroadcastResult.setStreamInfo(new StreamContent(mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, stream, null, null, null, false))); + audioBroadcastResult.setStreamInfo(new StreamContent(mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, app, stream, null, null, null, false))); audioBroadcastResult.setCodec("G.711"); return audioBroadcastResult; } @@ -1591,7 +1582,7 @@ public class PlayServiceImpl implements IPlayService { } } - talk(mediaServerItem, device, channelId, stream, (mediaServerItem1, hookParam) -> { + talk(mediaServerItem, device, channelId, stream, (hookData) -> { logger.info("[语音对讲] 收到设备发来的流"); }, eventResult -> { logger.warn("[语音对讲] 失败,{}/{}, 错误码 {} {}", device.getDeviceId(), channelId, eventResult.statusCode, eventResult.msg); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index c768ae1a8..2ac9de677 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -9,19 +9,18 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; -import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; +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.event.media.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; -import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; @@ -65,9 +64,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @Autowired private IVideoManagerStorage videoManagerStorager; - @Autowired - private IMediaService mediaService; - @Autowired private ZLMServerFactory zlmServerFactory; @@ -203,9 +199,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { callback.run(ErrorCode.ERROR100.getCode(), "保存失败", null); return; } - HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(param.getApp(), param.getStream(), true, "rtsp", mediaServer.getId()); - hookSubscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItem, response) -> { - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( + Hook hook = Hook.getInstance(HookType.on_media_arrival, param.getApp(), param.getStream(), mediaServer.getId()); + hookSubscribe.addSubscribe(hook, (hookData) -> { + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream( mediaServer, param.getApp(), param.getStream(), null, null); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); }); @@ -213,7 +209,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { String talkKey = UUID.randomUUID().toString(); String delayTalkKey = UUID.randomUUID().toString(); dynamicTask.startDelay(delayTalkKey, ()->{ - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaServer.getId(), false); + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaServer.getId(), false); if (streamInfo != null) { callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); }else { @@ -223,9 +219,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { }, 7000); WVPResult result = addStreamProxyToZlm(param); if (result != null && result.getCode() == 0) { - hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); + hookSubscribe.removeSubscribe(hook); dynamicTask.stop(talkKey); - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream( mediaServer, param.getApp(), param.getStream(), null, null); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); }else { @@ -244,7 +240,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } } else{ - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream( mediaServer, param.getApp(), param.getStream(), null, null); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index 4bdcc2fe5..b3c510d0b 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -11,8 +11,8 @@ import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +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.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index d2d32e841..d14cea5cc 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -6,10 +6,10 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.*; @@ -61,9 +61,9 @@ public class RedisGbPlayMsgListener implements MessageListener { */ public static final int ERROR_CODE_TIMEOUT = -3; - private Map callbacks = new ConcurrentHashMap<>(); - private Map callbacksForStartSendRtpStream = new ConcurrentHashMap<>(); - private Map callbacksForError = new ConcurrentHashMap<>(); + private final Map callbacks = new ConcurrentHashMap<>(); + private final Map callbacksForStartSendRtpStream = new ConcurrentHashMap<>(); + private final Map callbacksForError = new ConcurrentHashMap<>(); @Autowired private UserSetting userSetting; @@ -89,7 +89,7 @@ public class RedisGbPlayMsgListener implements MessageListener { @Autowired private HookSubscribe subscribe; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); + private final ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @Autowired @@ -297,9 +297,8 @@ public class RedisGbPlayMsgListener implements MessageListener { }, userSetting.getPlatformPlayTimeout()); // 添加订阅 - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(content.getApp(), content.getStream(), true, "rtsp", mediaServerItem.getId()); - - subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam)->{ + Hook hook = Hook.getInstance(HookType.on_media_arrival, content.getApp(), content.getStream(), content.getMediaServerId()); + subscribe.addSubscribe(hook, (hookData)->{ dynamicTask.stop(taskKey); responseSendItem(mediaServerItem, content, toId, serial); }); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index 7edf7e851..9cb4d38b5 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.AlarmChannelMessage; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 252331232..3c0b749e3 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.AlarmChannelMessage; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java index 56d192e98..26e96857c 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.conf.security.SecurityUtils; import com.genersoft.iot.vmp.conf.security.dto.LoginUser; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamProxyService; @@ -35,11 +36,12 @@ public class MediaController { @Autowired private IRedisCatchStorage redisCatchStorage; - @Autowired - private IMediaService mediaService; @Autowired private IStreamProxyService streamProxyService; + @Autowired + private IMediaServerService mediaServerService; + /** * 根据应用名和流id获取播放地址 @@ -85,9 +87,9 @@ public class MediaController { String host = request.getHeader("Host"); String localAddr = host.split(":")[0]; logger.info("使用{}作为返回流的ip", localAddr); - streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority); + streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority); }else { - streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); + streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); } if (streamInfo != null){ @@ -105,9 +107,9 @@ public class MediaController { String host = request.getHeader("Host"); String localAddr = host.split(":")[0]; logger.info("使用{}作为返回流的ip", localAddr); - streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority); + streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority); }else { - streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); + streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); } if (streamInfo != null){ return new StreamContent(streamInfo); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index 3e1e97330..dc01c4380 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -6,12 +6,11 @@ import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRtpServerTimeout; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -108,12 +107,11 @@ public class PsController { } // 注册回调如果rtp收流超时则通过回调发送通知 if (callBack != null) { - HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(stream, String.valueOf(ssrcInt), mediaServerItem.getId()); + Hook hook = Hook.getInstance(HookType.on_rtp_server_timeout, "rtp", stream, mediaServerItem.getId()); // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 - hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout, - (mediaServerItemInUse, hookParam)->{ - OnRtpServerTimeoutHookParam serverTimeoutHookParam = (OnRtpServerTimeoutHookParam) hookParam; - if (stream.equals(serverTimeoutHookParam.getStream_id())) { + hookSubscribe.addSubscribe(hook, + (hookData)->{ + if (stream.equals(hookData.getStream())) { logger.info("[第三方PS服务对接->开启收流和获取发流信息] 等待收流超时 callId->{}, 发送回调", callId); // 将信息写入redis中,以备后用 redisTemplate.delete(receiveKey); @@ -126,7 +124,7 @@ public class PsController { } catch (IOException e) { logger.error("[第三方PS服务对接->开启收流和获取发流信息] 等待收流超时 callId->{}, 发送回调失败", callId, e); } - hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout); + hookSubscribe.removeSubscribe(hook); } }); } @@ -241,18 +239,18 @@ public class PsController { }else { logger.info("[第三方PS服务对接->发送流] 流不存在,等待流上线,callId->{}", callId); String uuid = UUID.randomUUID().toString(); - HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(app, stream, true, "rtsp", mediaServerItem.getId()); + Hook hook = Hook.getInstance(HookType.on_media_arrival, app, stream, mediaServerItem.getId()); dynamicTask.startDelay(uuid, ()->{ logger.info("[第三方PS服务对接->发送流] 等待流上线超时 callId->{}", callId); redisTemplate.delete(key); - hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); + hookSubscribe.removeSubscribe(hook); }, 10000); // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 OtherPsSendInfo finalSendInfo = sendInfo; - hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); - hookSubscribe.addSubscribe(hookSubscribeForStreamChange, - (mediaServerItemInUse, response)->{ + hookSubscribe.removeSubscribe(hook); + hookSubscribe.addSubscribe(hook, + (hookData)->{ dynamicTask.stop(uuid); logger.info("[第三方PS服务对接->发送流] 流上线,开始发流 callId->{}", callId); try { @@ -269,7 +267,7 @@ public class PsController { logger.info("[第三方PS服务对接->发送流] 视频流发流失败,callId->{}, {}", callId, jsonObject.getString("msg")); throw new ControllerException(ErrorCode.ERROR100.getCode(), "[视频流发流失败] " + jsonObject.getString("msg")); } - hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); + hookSubscribe.removeSubscribe(hook); }); } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index c810745f7..96b0d4904 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -6,12 +6,11 @@ import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRtpServerTimeout; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -109,12 +108,11 @@ public class RtpController { } // 注册回调如果rtp收流超时则通过回调发送通知 if (callBack != null) { - HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(stream, String.valueOf(ssrcInt), mediaServerItem.getId()); + Hook hook = Hook.getInstance(HookType.on_rtp_server_timeout, "rtp", stream, mediaServerItem.getId()); // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 - hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout, - (mediaServerItemInUse, hookParam)->{ - OnRtpServerTimeoutHookParam serverTimeoutHookParam = (OnRtpServerTimeoutHookParam) hookParam; - if (stream.equals(serverTimeoutHookParam.getStream_id())) { + hookSubscribe.addSubscribe(hook, + (hookData)->{ + if (stream.equals(hookData.getStream())) { logger.info("[开启收流和获取发流信息] 等待收流超时 callId->{}, 发送回调", callId); OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); OkHttpClient client = httpClientBuilder.build(); @@ -125,7 +123,7 @@ public class RtpController { } catch (IOException e) { logger.error("[第三方服务对接->开启收流和获取发流信息] 等待收流超时 callId->{}, 发送回调失败", callId, e); } - hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout); + hookSubscribe.removeSubscribe(hook); } }); } @@ -225,7 +223,7 @@ public class RtpController { if (!((dstPortForAudio > 0 && !ObjectUtils.isEmpty(dstPortForAudio) || (dstPortForVideo > 0 && !ObjectUtils.isEmpty(dstIpForVideo))))) { throw new ControllerException(ErrorCode.ERROR400.getCode(), "至少应该存在一组音频或视频发送参数"); } - MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer(); + MediaServer mediaServer = mediaServerService.getDefaultMediaServer(); String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + "_" + callId; OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key); if (sendInfo == null) { @@ -278,10 +276,10 @@ public class RtpController { paramForVideo = null; } - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, app, stream); + Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, app, stream); if (streamReady) { if (paramForVideo != null) { - JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, paramForVideo); + JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForVideo); if (jsonObject.getInteger("code") == 0) { logger.info("[第三方服务对接->发送流] 视频流发流成功,callId->{},param->{}", callId, paramForVideo); redisTemplate.opsForValue().set(key, sendInfo); @@ -292,7 +290,7 @@ public class RtpController { } } if(paramForAudio != null) { - JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, paramForAudio); + JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForAudio); if (jsonObject.getInteger("code") == 0) { logger.info("[第三方服务对接->发送流] 音频流发流成功,callId->{},param->{}", callId, paramForAudio); redisTemplate.opsForValue().set(key, sendInfo); @@ -305,18 +303,18 @@ public class RtpController { }else { logger.info("[第三方服务对接->发送流] 流不存在,等待流上线,callId->{}", callId); String uuid = UUID.randomUUID().toString(); - HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(app, stream, true, "rtsp", mediaServerItem.getId()); + Hook hook = Hook.getInstance(HookType.on_media_arrival, app, stream, mediaServer.getId()); dynamicTask.startDelay(uuid, ()->{ logger.info("[第三方服务对接->发送流] 等待流上线超时 callId->{}", callId); redisTemplate.delete(key); - hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); + hookSubscribe.removeSubscribe(hook); }, 10000); // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 OtherRtpSendInfo finalSendInfo = sendInfo; - hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); - hookSubscribe.addSubscribe(hookSubscribeForStreamChange, - (mediaServerItemInUse, response)->{ + hookSubscribe.removeSubscribe(hook); + hookSubscribe.addSubscribe(hook, + (hookData)->{ dynamicTask.stop(uuid); logger.info("[第三方服务对接->发送流] 流上线,开始发流 callId->{}", callId); try { @@ -325,7 +323,7 @@ public class RtpController { throw new RuntimeException(e); } if (paramForVideo != null) { - JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, paramForVideo); + JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForVideo); if (jsonObject.getInteger("code") == 0) { logger.info("[第三方服务对接->发送流] 视频流发流成功,callId->{},param->{}", callId, paramForVideo); redisTemplate.opsForValue().set(key, finalSendInfo); @@ -336,7 +334,7 @@ public class RtpController { } } if(paramForAudio != null) { - JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, paramForAudio); + JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForAudio); if (jsonObject.getInteger("code") == 0) { logger.info("[第三方服务对接->发送流] 音频流发流成功,callId->{},param->{}", callId, paramForAudio); redisTemplate.opsForValue().set(key, finalSendInfo); @@ -346,7 +344,7 @@ public class RtpController { throw new ControllerException(ErrorCode.ERROR100.getCode(), "[音频流发流失败] " + jsonObject.getString("msg")); } } - hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); + hookSubscribe.removeSubscribe(hook); }); } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index dc31b5a7f..780f8a732 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -9,10 +9,9 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.VersionInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.IHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; @@ -40,8 +39,6 @@ import java.util.List; @RequestMapping("/api/server") public class ServerController { - @Autowired - private HookSubscribe zlmHttpHookSubscribe; @Autowired private IMediaServerService mediaServerService; @@ -76,8 +73,6 @@ public class ServerController { @Autowired private IRedisCatchStorage redisCatchStorage; - @Autowired - private SendRtpPortManager sendRtpPortManager; @GetMapping(value = "/media_server/list") @@ -217,13 +212,6 @@ public class ServerController { return jsonObject; } - @GetMapping(value = "/hooks") - @ResponseBody - @Operation(summary = "获取当前所有hook") - public List getHooks() { - return zlmHttpHookSubscribe.getAll(); - } - @GetMapping(value = "/system/info") @ResponseBody @Operation(summary = "获取系统信息") diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java index 459f3cc87..309cd694d 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java @@ -249,7 +249,7 @@ public class StreamPushController { if (push != null && !push.isSelf()) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "来自其他平台的推流信息"); } - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); if (streamInfo == null){ throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取播放地址失败"); } From 5973dcd9752079aaf32b4b5f00bd90d689844ec8 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Sun, 31 Mar 2024 00:34:44 +0800 Subject: [PATCH 35/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=82=B9=E6=92=AD?= =?UTF-8?q?=E4=B8=8E=E5=BD=95=E5=83=8F=E5=9B=9E=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 2717fc3de..7873cf5b5 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -173,7 +173,7 @@ public class ZLMHttpHookListener { String mediaServerId = json.getString("mediaServerId"); MediaServer mediaServer = mediaServerService.getOne(mediaServerId); if (mediaServer == null) { - return new HookResultForOnPublish(200, "success"); + return new HookResultForOnPublish(0, "success"); } ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams()); @@ -197,6 +197,9 @@ public class ZLMHttpHookListener { public HookResult onStreamChanged(@RequestBody OnStreamChangedHookParam param) { MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServer == null) { + return HookResult.SUCCESS(); + } if (param.isRegist()) { logger.info("[ZLM HOOK] 流注册, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); @@ -329,9 +332,9 @@ public class ZLMHttpHookListener { logger.info("[ZLM HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path()); try { - MediaRecordMp4Event event = new MediaRecordMp4Event(this); MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); if (mediaServerItem != null) { + MediaRecordMp4Event event = MediaRecordMp4Event.getInstance(this, param, mediaServerItem); event.setMediaServer(mediaServerItem); applicationEventPublisher.publishEvent(event); } From ecd1d2a414f650987579ac95ebdf848cd98d7af0 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 1 Apr 2024 15:22:45 +0800 Subject: [PATCH 36/58] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java | 4 ++-- .../java/com/genersoft/iot/vmp/media/bean/MediaInfo.java | 6 +++++- .../iot/vmp/media/event/hook/HookSubscribe.java | 9 ++++++--- .../genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 6 ++---- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 1711938ac..b7f57d750 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -15,12 +15,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.message.SIPRequest; @@ -279,6 +278,7 @@ public class SIPCommander implements ISIPCommander { logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, "rtp", stream, mediaServerItem.getId()); + System.out.println("rtpHook: " + rtpHook.toString()); subscribe.addSubscribe(rtpHook, (hookData) -> { if (event != null) { event.response(hookData); diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java index e753fb6c6..c33eeccc2 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java @@ -128,7 +128,7 @@ public class MediaInfo { } public static MediaInfo getInstance(OnStreamChangedHookParam param, MediaServer mediaServer) { - List tracks = param.getTracks(); + MediaInfo mediaInfo = new MediaInfo(); mediaInfo.setApp(param.getApp()); mediaInfo.setStream(param.getStream()); @@ -139,6 +139,10 @@ public class MediaInfo { mediaInfo.setOriginType(param.getOriginType()); mediaInfo.setAliveSecond(param.getAliveSecond()); mediaInfo.setBytesSpeed(param.getBytesSpeed()); + List tracks = param.getTracks(); + if (tracks == null || tracks.isEmpty()) { + return mediaInfo; + } for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { switch (mediaTrack.getCodec_id()) { case 0: diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java index 64b8ffeb2..598178fe9 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java @@ -4,14 +4,11 @@ import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; import com.genersoft.iot.vmp.media.event.media.MediaEvent; import com.genersoft.iot.vmp.media.event.media.MediaPublishEvent; -import org.mybatis.logging.Logger; -import org.mybatis.logging.LoggerFactory; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import java.time.Instant; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -40,6 +37,9 @@ public class HookSubscribe { public void onApplicationEvent(MediaArrivalEvent event) { if ("rtsp".equals(event.getSchema())) { System.out.println("流到来的处理: " + allSubscribes.size()); + for (String s : allSubscribes.keySet()) { + System.out.println("key: " + s); + } sendNotify(HookType.on_media_arrival, event); } @@ -70,6 +70,7 @@ public class HookSubscribe { private void sendNotify(HookType hookType, MediaEvent event) { Hook paramHook = Hook.getInstance(hookType, event.getApp(), event.getStream(), event.getMediaServer().getId()); + System.out.println("sendNotify: " + paramHook.toString()); Event hookSubscribeEvent = allSubscribes.get(paramHook.toString()); if (hookSubscribeEvent != null) { HookData data = HookData.getInstance(event); @@ -86,6 +87,7 @@ public class HookSubscribe { } public void removeSubscribe(Hook hook) { + System.out.println("removeSubscribe: " + hook.toString()); allSubscribes.remove(hook.toString()); allHook.remove(hook.toString()); } @@ -98,6 +100,7 @@ public class HookSubscribe { long expireTime = System.currentTimeMillis() - subscribeExpire; for (Hook hook : allHook.values()) { if (hook.getCreateTime() < expireTime) { + System.out.println("execute removeSubscribe: " + hook.toString()); allSubscribes.remove(hook.toString()); allHook.remove(hook.toString()); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 7873cf5b5..e0793a5c3 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -12,7 +12,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.event.media.*; import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -36,7 +35,6 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -207,8 +205,8 @@ public class ZLMHttpHookListener { applicationEventPublisher.publishEvent(mediaArrivalEvent); } else { logger.info("[ZLM HOOK] 流注销, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); - MediaDepartureEvent mediaArrivalEvent = MediaDepartureEvent.getInstance(this, param, mediaServer); - applicationEventPublisher.publishEvent(mediaArrivalEvent); + MediaDepartureEvent mediaDepartureEvent = MediaDepartureEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaDepartureEvent); } return HookResult.SUCCESS(); } From fd2ef6effe7b484c70079a7ac054ac4834b394d9 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 1 Apr 2024 15:29:49 +0800 Subject: [PATCH 37/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9B=BD=E6=A0=87?= =?UTF-8?q?=E7=82=B9=E6=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/event/hook/HookSubscribe.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java index 598178fe9..345cc48a6 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java @@ -22,7 +22,7 @@ public class HookSubscribe { /** * 订阅数据过期时间 */ - private final long subscribeExpire = 5 * 1000; + private final long subscribeExpire = 5 * 60 * 1000; @FunctionalInterface public interface Event{ @@ -36,10 +36,6 @@ public class HookSubscribe { @EventListener public void onApplicationEvent(MediaArrivalEvent event) { if ("rtsp".equals(event.getSchema())) { - System.out.println("流到来的处理: " + allSubscribes.size()); - for (String s : allSubscribes.keySet()) { - System.out.println("key: " + s); - } sendNotify(HookType.on_media_arrival, event); } @@ -70,7 +66,6 @@ public class HookSubscribe { private void sendNotify(HookType hookType, MediaEvent event) { Hook paramHook = Hook.getInstance(hookType, event.getApp(), event.getStream(), event.getMediaServer().getId()); - System.out.println("sendNotify: " + paramHook.toString()); Event hookSubscribeEvent = allSubscribes.get(paramHook.toString()); if (hookSubscribeEvent != null) { HookData data = HookData.getInstance(event); @@ -87,7 +82,6 @@ public class HookSubscribe { } public void removeSubscribe(Hook hook) { - System.out.println("removeSubscribe: " + hook.toString()); allSubscribes.remove(hook.toString()); allHook.remove(hook.toString()); } @@ -100,7 +94,6 @@ public class HookSubscribe { long expireTime = System.currentTimeMillis() - subscribeExpire; for (Hook hook : allHook.values()) { if (hook.getCreateTime() < expireTime) { - System.out.println("execute removeSubscribe: " + hook.toString()); allSubscribes.remove(hook.toString()); allHook.remove(hook.toString()); } From 73733ab13f83a8e599a742322ed423ba37f29c71 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 1 Apr 2024 15:40:21 +0800 Subject: [PATCH 38/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8E=A8=E6=B5=81?= =?UTF-8?q?=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 7 +++---- .../genersoft/iot/vmp/service/impl/MediaServiceImpl.java | 6 +----- .../iot/vmp/storager/impl/RedisCatchStorageImpl.java | 1 + 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index e0793a5c3..abea49fb0 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -143,16 +143,15 @@ public class ZLMHttpHookListener { @ResponseBody @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") public HookResult onPlay(@RequestBody OnPlayHookParam param) { - if (logger.isDebugEnabled()) { - logger.debug("[ZLM HOOK] 播放鉴权:{}->{}", param.getMediaServerId(), param); - } + Map paramMap = urlParamToMap(param.getParams()); // 对于播放流进行鉴权 boolean authenticateResult = mediaService.authenticatePlay(param.getApp(), param.getStream(), paramMap.get("callId")); if (!authenticateResult) { + logger.info("[ZLM HOOK] 播放鉴权 失败:{}->{}", param.getMediaServerId(), param); return new HookResult(401, "Unauthorized"); } - + logger.info("[ZLM HOOK] 播放鉴权 成功:{}->{}", param.getMediaServerId(), param); return HookResult.SUCCESS(); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 126ea2410..d98b52e4f 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -2,9 +2,7 @@ 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.common.VideoManagerConstants; -import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; @@ -12,9 +10,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*; 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.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; @@ -91,7 +87,7 @@ public class MediaServiceImpl implements IMediaService { return true; } StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); - return (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(callId)); + return (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && streamAuthorityInfo.getCallId().equals(callId)); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 3c0b749e3..62ccf8d89 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -447,6 +447,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @Override public StreamAuthorityInfo getStreamAuthorityInfo(String app, String stream) { String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ; + System.out.println(key); return JsonUtil.redisJsonToObject(redisTemplate, key, StreamAuthorityInfo.class); } From 426ea72d7f31e0f4c5ad90c48d98299b9ac83e45 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 1 Apr 2024 15:46:36 +0800 Subject: [PATCH 39/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8B=89=E6=B5=81?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 2 +- .../com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index abea49fb0..c9aad4d44 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -151,7 +151,7 @@ public class ZLMHttpHookListener { logger.info("[ZLM HOOK] 播放鉴权 失败:{}->{}", param.getMediaServerId(), param); return new HookResult(401, "Unauthorized"); } - logger.info("[ZLM HOOK] 播放鉴权 成功:{}->{}", param.getMediaServerId(), param); + logger.info("[ZLM HOOK] 播放鉴权 失败:{}->{}", param.getMediaServerId(), param); return HookResult.SUCCESS(); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index d98b52e4f..e98076289 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -87,7 +87,10 @@ public class MediaServiceImpl implements IMediaService { return true; } StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream); - return (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && streamAuthorityInfo.getCallId().equals(callId)); + if (streamAuthorityInfo == null || streamAuthorityInfo.getCallId() == null) { + return true; + } + return streamAuthorityInfo.getCallId().equals(callId); } @Override From 722f1d0ee761cee4f8a1a99da46cc799380303e8 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 1 Apr 2024 16:17:01 +0800 Subject: [PATCH 40/58] =?UTF-8?q?=E5=9B=BD=E6=A0=87=E7=BA=A7=E8=81=94-?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8B=89=E6=B5=81=E4=BB=A3=E7=90=86=E6=92=AD?= =?UTF-8?q?=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 2 +- .../iot/vmp/media/zlm/ZLMMediaNodeServerService.java | 3 +-- .../iot/vmp/service/impl/StreamProxyServiceImpl.java | 9 +++++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index c9aad4d44..dc24874e6 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -151,7 +151,7 @@ public class ZLMHttpHookListener { logger.info("[ZLM HOOK] 播放鉴权 失败:{}->{}", param.getMediaServerId(), param); return new HookResult(401, "Unauthorized"); } - logger.info("[ZLM HOOK] 播放鉴权 失败:{}->{}", param.getMediaServerId(), param); + logger.info("[ZLM HOOK] 播放鉴权成功:{}->{}", param.getMediaServerId(), param); return HookResult.SUCCESS(); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 11e6063be..06c8c3e5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -257,14 +257,13 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { public WVPResult addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType) { JSONObject jsonObject = zlmresTfulUtils.addStreamProxy(mediaServer, app, stream, url, enableAudio, enableMp4, rtpType); if (jsonObject.getInteger("code") != 0) { - logger.warn("[addStreamProxy] 添加代理失败"); return WVPResult.fail(ErrorCode.ERROR100.getCode(), "添加代理失败"); }else { JSONObject data = jsonObject.getJSONObject("data"); if (data == null) { return WVPResult.fail(ErrorCode.ERROR100.getCode(), "代理结果异常: " + jsonObject); }else { - return WVPResult.success(""); + return WVPResult.success(data.getString("key")); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 2ac9de677..60dd8af8a 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -361,8 +361,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { result = mediaServerService.addStreamProxy(mediaServer, param.getApp(), param.getStream(), param.getUrl().trim(), param.isEnableAudio(), param.isEnableMp4(), param.getRtpType()); } - System.out.println("addStreamProxyToZlm===="); - System.out.println(result); if (result != null && result.getCode() == 0) { String key = result.getData(); if (key == null) { @@ -381,6 +379,13 @@ public class StreamProxyServiceImpl implements IStreamProxyService { return null; } MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServer == null) { + return null; + } + List mediaList = mediaServerService.getMediaList(mediaServer, param.getApp(), param.getStream(), null); + if (mediaList.isEmpty()) { + return true; + } Boolean result = false; if ("ffmpeg".equalsIgnoreCase(param.getType())){ result = mediaServerService.delFFmpegSource(mediaServer, param.getStreamKey()); From 4d6f881460dd8a5f343f5a3183afc5e41d20f00e Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 1 Apr 2024 16:20:30 +0800 Subject: [PATCH 41/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A9=BA=E6=8C=87?= =?UTF-8?q?=E9=92=88=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 60dd8af8a..ee7235513 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -383,7 +383,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { return null; } List mediaList = mediaServerService.getMediaList(mediaServer, param.getApp(), param.getStream(), null); - if (mediaList.isEmpty()) { + if (mediaList == null || mediaList.isEmpty()) { return true; } Boolean result = false; From b7b950ec8b74947275ba5f6c84570be005b6f675 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 1 Apr 2024 16:47:45 +0800 Subject: [PATCH 42/58] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=B1=95=E7=A4=BAabl-l?= =?UTF-8?q?ogo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web_src/src/components/MediaServerManger.vue | 10 +++++++++- web_src/static/images/abl-logo.jpg | Bin 0 -> 19328 bytes 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 web_src/static/images/abl-logo.jpg diff --git a/web_src/src/components/MediaServerManger.vue b/web_src/src/components/MediaServerManger.vue index 1d3c057ca..4d6b6bf6e 100755 --- a/web_src/src/components/MediaServerManger.vue +++ b/web_src/src/components/MediaServerManger.vue @@ -10,7 +10,8 @@ -
+
+
{{item.id}} 编辑 @@ -154,6 +155,13 @@ background-size: contain; margin: 0 auto; } + .card-img-abl{ + width: 200px; height: 200px; + background: url('~@static/images/abl-logo.jpg') no-repeat center; + background-position: center; + background-size: contain; + margin: 0 auto; + } .server-card-status-online{ position: absolute; right: 20px; diff --git a/web_src/static/images/abl-logo.jpg b/web_src/static/images/abl-logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..82a564d451dc110d183e9c5bbe2ce8cc30dd0733 GIT binary patch literal 19328 zcmeIZbyyrr_bxhEa3{eDPH=a33l6~{0}SpSG`JI-KyXNKha^C73l0GS1SbS{cTNvG z*?Zsf`_8$~{ri6X^w6tUt@YNbx2tMu)in3h_e&rw1sQo65DaiI!7zb9_sgIPX-_M2 z5J+C00fYnsfe=ABFmNCkK!SdVU=SXzCV))*Teb$|XTNP=0ht{J7K9F5oq-PrAmaho z*TBar4F17436P-&695Rs{BxC+S5hVCU}0xt;p724**Lfa*npFroSjF23plv|YnYsW zVu51ZFQbiEy1F_Fu(H~_uz<}ROdu?#4tA`bU`JMV7B*Ipkf^64*whB%N^SzNu(B7X z+;3{7B)2jXrqt$EVpDRIgjib1c{xKgyp%Ofy=+YR%_v1h$b~!wJnbCqAg*9?Pdi(C z7XeRU$_H=(K!&PWDajv9Ty2CYb%3xX9h@QLTr6BHY|H?C?i`c=hO?QufVz~-Zv@~@ znDTe19v&Vn9-J%=&K9if{QUf^Y#gi{9L#_Pv&$=cSFk6uy$jVJ1SyD%sk4=%tCfR2 zITR6W;^5{gObOKgS73IIN=knN|3?n&?4Z#;Si87Ny93VuH^y8vUpYcp)gdkpZqB9< zX?KXdE7c!&Gt<9)9o?L59~xk0$_lZC*a2oP0ORa`R|S2Ve_KNvY++^R_}~FB`?nP! z|84XigNIfPv`|3G!PE^}iM*6BB@{`(%)!*kOyEI;@N@F9^PBN8o0)O4F>|rALzuyQ z5N>7@9y2p8Zaxz*CqMWPj=a5#E7;x?0>uH4S*!pM9y7q%3~a^>W;Zcq=Hg{HVdiHu zG~T)|N0*m>F6`FYqmfJpf`xVSieTfBfcy8!(K3iU9W z9)cH;bcTRk9h@~C9BhRt{~m0Al_>#z+6?RpmIAv%0Jp!#p5~vi$H>Mfzy`zxv{gXK z!OY71)&H9*bQC>2IyoyBpxRfzM}!8%>9=HSMgGtq1;D1z-Yrb&0(OU(QT|q%T7vB@ zAiy{U`pREsR{!DAahY&I`1m=@m`&LE%mK>T_?S)1fLkthUNasJel~tHZoWVME)M3d z9$;sPxCPLU00w|w^f29!KYL)8{*Rr9B?L+xzyUKGaI*j5fcrNGtU&y%(4qKOQ&|7^ zRz8&dYuNrV2j&8(`1jNzLjK?5zYP4Bf&Vh_Uk3imz<(L|{~rVYBqtDiV5Q>$q#pMx zuvPMslE$j)Dl+oVrGd;01cJ@6HMMhr7XyLp>|LGJWhKaUboIy)H$c#Q3JJsvLIs<; zIEt&PK8L16|M@uk{*Y^d#+jj5|JmmMs6{sek`N$SBL^(ROdXwF0r@2$^LV&ALglxB zj0Y^(%mBFzkeQr;00DU#syF#d-hs*%4>B}K1mQVrs!IZGgJy^17XOk>{w14QI@x-s zC&z;d22BD4LRh%JKc)dv=tL0cHtzoZI`{tmHV*`Xn*)K`?Emq1$N_=)P62(~KRW7c z5C}6E1p3(ZkIp0&1o{*P0ujtOf}Oz+^}qptVaa7RHP6#c(=1InP~ zp!_KiNE6`d`49+{mJR~ZS^(Gv|A%%%bN;`1`@h=!=I?$MBng6pg@vBL0S}xANC*h< z@CYb~h>wuaP|(m&QBYCQF>tWZF|aXEQL&z2VdLUGe*72>6QAG-9sv&CV>~Db3>@GC zkARGTfQ*NZijMdH`MB=@VI#pv!#KggV1r<>Vc@V~?z@1-z<^-kfDH~P6@MKt2(WPQ zj}Vc7Qer?4E&O*W96T(-BgFe3AT&6@6$=gv=*qY1f1Llv6)6Ch1H_Lg_U{6CL?K?Y zm5(jyyVZp+)JBouU;nEVDR?D@biJ~PP9zc|V|duMdZeQi_~q>EyZq@s)mOAZ$mV- zK6|h0gRPpRa~yKITzaQLLaDB5MsZ+cBgJXf$JmiB1VB+ z6c?A4_U72ww%YNIrb>S6=Z0*a>&i#Rm6SEv+H3obt=X8HseT?$wAlFH?xAJ6ug`$r zz37#C4TXYBQ!*;kv+Li(ontBdIr*V4IK`?;HKa9`9>E zIgX*^DlOnn+)Xal=y=UJ)#nMo>I_~&DVDhAq%Zwx2$^USHk zH%JQKiFj*oh#0jN)@I{xd5Ln&Omax&$a5>XpRLW#cHg*<_4+BfJR$t3JNEIRJCih9 zygw1z6zA96E>&^UK04QaRQ9$sZDUIid5wYo+)vkdqv2Ro>(eo+pid6D8~fnNWL_`N z7r~0go%G5=vPOwcvL*qZerOBf63b2&!ZM#>XrNuxHkJ!No^AJIQG7Pg&|_w~wx6VN z<&RI6-MYWzYq!YEBG#jC-PkMgWyPklFYoHZtKN!m=l#Bq{h4V}uK_GXI^E4?OaWDf zYhCAoEED33nqJXdk|FmDqKXQQauJc%>dK0HQ10x(u@DUVl)bNEhGD0hkcYXO?l)C< z!6UnxLUT2800*Y;yO)FHa1zaNww+}0i74`h^AwV-Z?esPzP50(qg7vJNzIx(1zYUZ z#u)gW3Ukub*1#JB5D4Dm*CIrDFi#A?0NORN5SGn}W=O2sflMR8sD9u)C}|MS2H zgY%geEkE2GXH;mT`9_}Yd+_S4P2!YKzR`B=OpARDf)za4ugN!;2Vg)LM#t*=#~&zI z)4h+y8&3Q)vk~^C{XR7w@SkOALi!=KQA`{=Go%N)Dk{9LvRaKCF1nJ%Sr`of3P$FP z`^?&G(pM;s^GtfGM9`Ii1{)7bLK z-pp3NY;iamgjX!JHA=RRCfX@Wc-CUEN&f}2;H)+0&VvW|Hh}`UW!a_uPoP)x`xQ6o zJqgG@KQ~B-vb8Qf;Ykg^r;J>ejXO(;>8$Bj)(&tRx0M^BnM28KAQ+aNrm|z(eluv> z_`OFITL=5G*^gCnw)?J?PK66Y&&e1)SaG+7@W({v59708u_s$t6+XQ{*LM8Hj%Un% zGO>U->TNvgFQTt52BIOI@t7W~<@#6iu(6L-yeow_n=8W)$$mmq^nVoz(-+P>b-pN? zK{LUg>|s@?g`x!?58)5qO7jNnUmK6Mig^5IGzsiuBj z@?2qjxjX;iC$%cnn|C?#`6_#;;<)X9AgKUIi+>@($5C(sjhs=dq!R;>UITUtDzHJ6q||UU(=x-#q1g(#mPE z=Q+CSI$1IxGBo*P10D(s6D?E9P~M8qe5u-5d_3!QV6;^_nz7~UvYPjkO9Fdx_^EQG z5&8>Fk|F$oTW-2RUzQ>My}PjW-R6B%$f?vPEl8|yvyUYX00pelVBty5)b#zB@h#l= zlFv?488Kk6*6bax+`JB~YjV~sTO2m(%x7Mm_zSnbAmBOn@D;c&9uum`di~%IENl%9 zXRt;TtR2K(Xdw+aFc?Hka((=ShKwbzrGskzfn ztpJzvI~w33B}MXaOh5lgX$kbvF*F--ys+U?sscNvxkHb@%c7 ziL4+8J;}$DDRy4GC*04kZaPzwNh;(Qt>u4)eCTE9dA~xBthoaJhyz2CF)-GhrlOTR zCWJJ2Z@-#47gsU%MT}yXOkua}aD(B5j&Bso;8PpQHfub!6Znc})TS2|TZ%-KbS(LC zrs^xFc^Xc*#nm>PbbcnWxXI#yy2+BAW09f3SWNmj*L=6e$ek@`M&CCr#t?$3yANWG zq+EnDF`hHCu>z(G z+TpxG^u>+BNoaZ_eZwGFZXG?*Pa@K_#X_2t#7AQ}DuG>G+WV4uNe1mIK&{8Tq|_jC zwC`CLeuZ$~yQ8XT;bQR`Z0wxZ(l)K4(GVxK!Jb%bE+@WSgU;nfUbeIna*pV-6;8c~ zmv21;ci04rmd5z2sHz7`?u@{=1(b2oOv&BtiwjO7_FO|%s8 z^2VBC%TpvI1Ia*`dCtx=r9hZIGWVbzb7wb2;;fQVKjNT7kw`(*Q=WvzlR*;~aa36T zx7c6TKS681NL&~{_i&W6E9G;Y$e@1q2BUYn5q?hfc~>M4*MT6PHdvZGFrhPL*YNV1 zb4A5lWxmGA#O8|#Z2@d}m4R{c@rk%#B+eS4#hB=B#&|RwO=r?a>;37&^{%Y5)F#_Q zGy%b}w|E?2{Fb9nQe^br$K6=xwv&t1KSv^jcdbN{ChfZ|T}Q%8eFX`aQv=t3n|Rnx z{AIF*j6wOnOYhk)9s^BV0NsH2gj| zm*MPvk?JA4^UB+xMRq#_S(!iPXVzEyIzU){S7BdXFi6|7EOE5$Ux*VbTqt9R(@BX? z9a%(Ng?aBxp4x4b30=Hd7(Gv0@noB|Gb`pH_OWjt!;Dm+^~^5vXc;m#gjys57MUcH zDkq)0&58nBGo34meOWYHq_;#LZcemL7qWY^ad@vOcq0{r#7Q=@4R*T5#Ta3#Pm9+7 zMsm?bO8OqFr9Hc@J>{jghC^nsUQQa<^qRzKW@gjGMcs?<3om|2Tsq$rTJ}1hkNPXl zu3O1wMK-CzmLmwdMzYLPWudfsRoT7+B!Z;m@sDYG2i#P=0j;XD>8@D3&6k2HQie zEv@cSz&f@`fX#6lTC0eR$AFTi+o=STD0h2=yuS42B+z;~xwh5(h@cBPVj^I$KL@xs z$8IQE0^iYhbVc&oE+0Pi0(+=UJr`>2b)N(}_{vW1VRix^e_Rme5fE=@|Dsa;_}vsR zkVAyPjR>F0BuzDsgkJ2Wd8thwe(mEaC_Mrys*edSit2 zetwS1J2=&~PD1Xgw|MDPmRbHB8ftVl=FX;tE{J^ueYe=(W-P|EAAN)f5z2m@bj-fO z*MP8Il8k)g;gXq)SU(~;P+sn9X?Yv>NBL{J~+GvU9XEQ++cVIh9u4 zV3(WtELprh?I2U%a0NMcv%b)n?t9R9cB-jLMNNv8XBm@DJj2#RSAJMeu{qsUhKlh$ zh=}Q3;?A>=5|ukHYBW|FBYs28oPj(`>gqH`@-L=J2pSpd3lAI{hSe@bS}-We^sEoh zbX`9Bj8w4O#?a!)|8U^}<9Y1N=9*L6@h3%S-J-u7(Z(3N9$EcRG)_XfSuVt%RynDt z!F2j;HH04zPhLMJLT4uW>Scbb`MiRZEs;8%d}t%rsdr*0pIxX9_WvWM#lFQRZl!UK&w)+U{WULa3IUIkT2G1F(<*nTP=o<2W92H95OGlSF79C%3 z5y6PabY<}&>-L@7&oM=KR?+CbZ!KYjvZe5h{F?GJ0W(=c!qb$(~)nw_qk`b#9m%2&d?Q~%1rSgBuk~L zU+{k_fr$2Tx5qrNe^)$lQ8PlfT^+q+N{Z(J)YXjd^aofwis{H)s>bSsW&Z0%z8<&Z zsy`{-`Hn$X-WUbpF0`s!-HsUT0Fyh2p01wNg$K(@1zx^Jg;s0ews4Q>m@JKB?-C!a zuJ#GvQeUEQ640*JQa-gJ-B^?pgQEe)Jgn(jEuv4{dYk$yLd~}#x+t@ATJJA(fZn6Y z9rUv%@42$TDL+cMs|2CU}mIX6X(FCy7CM~gc0ZU)Bzp>?1DCq zDzn3!8Wjvn(}@d7ch|XN!!v^05Nr)RAAA-U3|Y>3>>snApZJ%=axSP=;4t(ZGPRavFhDnIKA8%SH z6GJ|dFu{yZRIu~h(4xkult<;6Wqfl$wbCa#RgEnCnbXA?r4K)dG+EQzVHEf^r9ne*ToS7Utg=1gz(Ga~iMDb)$OX7&Kn~6WwL8tH--$gAiNwCW|%J!$TYSo7oU-97; zWr;xjg$^Tlt>doKR`fG#e`11y?elA-0D*z$|3KT6us z@EL6lcoFzYsJ6%!&s8X{w!y>?1_?Ew zIBfDB6g{P`9&%-oz_+pT{%Jb>4L%gEZ`+S(*QI7pIhf%lMiz5*A4ko`4so!YxGiD7 zi7tU)V`U*yluP}B^*0Nt=GL0-(6xZ+K@a{a?;x zrsYlWDJB7_C)Hrsth)*|`&joak$=46&*rhg=7_mrplfU_A1SQmr5D3iB&h90>6@#$ z$CDkJmt<4F(dT$Y5gW_8F@6(iOnNHtdE78!YhCTkJi%b22XNe>`(mwtSuJU}C1s~s zo*#XnH9nlSIP=(JI{#_C!Bo%SU;fNcf8RW-W0uHs$wl!O1XElp+-{fUQh|jfm89Ukj<|}d4?DYGK2=%hn>!g#K@{MmB zREjhSJ=3J(O?T6Ow_%AO-cQdC6 z#q|v3wyqk4NSxCopi^o+x(B5c@EhMO0yCBXkUc|x6hT6O|2<K6Tz#?Z;!=Yps zcXGz1;t*3+2Uo*$N|=njbct_IzzYaW%>A89KN5w#wV_&0Lru~u4BFK^_+g@@(e|wL zjWP1O748g$T$hm?+5FJ&n2jaISc{h-1sx=Fy?!4sntlwM(#R5Isa-mmrItTxCqnORswwed5@sgp6MWJ2Tzh&B80FH{{Q zrR!8(tk#ex1?)mY+A<^Q`!^cgjPi>#?>vi9PxsPL6KTbLM)zg3+#IdmMec53)S-;Qr z0B+xNKuS4*c3cmB@{ zD*dK6A8blp_mFDxH(qCzZrBIgOG?J#RuA}oGYtblB~DZc(HA@C zj}?tNPf_9I)6C1;GM$M??9H_-Igr1w2$D&xMav+*(KLk9%~INu38SG+`}9?_Fz+5j zU-fzCiHrlBBb`BL7%}Zi!TgJ|@8XYsIX8FYYFspw&EsDNW;Du}GnHPwxE;tRXD_sm zy{00=hjjzUR1dq8ex8iQ2B}`KhFCK0;C-Yb&GOOA<#vI2hzipC z0DkSx!mC+e5@Eyw0qGzdB0P}i{obvE!KPrx5?3P^0|(?*x3f9LAE=HkAHMvv11Cyx z4+=@X=p(|mZ76=Svqkf4{SXsjYy>8gfSpgE=)-p$?q}KU%Dg8A{f3Mh{PsHAbyg*u z7jy^m^0s}<)(t;mA`!>baR!v{0_2Nhw}?-u;J=%!sg_9KyqnF5UPmxWBhhA4dI*O#i!<%3I%#oqVozj;Xl^~Vyizr7`$G4;>lbCil z!92=bvRQ*_Z%D*!P`s!iiXq`^E?S*aJC9t^;DTzx>HJGQnso*>SFxhw7#Jv{Wxa28hb`*Xwi^U*kxCpU|3`2)$B|` z9iE_PCtTE9q8Xf!v8S+N%FqHs@R>a7W3LjADkE-|oFV>BYQ8+pvD5P5+S@yVD;hd9 z(kE!xm2CdL@dR8Iusxq#xzlKam?O-+VB{y%M)`Y3kxCh&VysDesUG{IH{uAn(YwzLHIc;y z*$-2d^296f4&#wN3?WZtZFnjqX$c!^SEtN9!J{o%NJFUztz%%8ab~pZey&rfij|zM zGhC!NYON_%jy787x*kYn&m}>oTJW(pfVe~5Q{JfhCDCNN2klzg%MFHLo>!)l`W|X3 zeP1)1QYQL_5;-+$)owp_QehwkXDCpXGMX#%I@=eYvD=3hNbALIY|B<-Y=7^oLH8?JT^8MyLL_05;FXzE%AMo9|WXD|r~Tr6j{4=*Hm<^)g~vDETX~gNm%- z6|!tMmn?Xbsntmg%*fR7DaE3%9jN2_=_O0bVoEQCqMV*z&*^gb)R%SGh?En&U$!xL zKM_18+opmAk>;^C>@js_Mo6H*E2tiU41ObS3=_7IR?S=^B+R zTOP_`8bZGtdF~it))A4Nf!+7V%3js34ApgE+MC8elqnm&2THFH1sC@@nhE`iu--DT zX~R*mepc2je6FXK)K5@Rw<7yk8ax^9`pi1K)UPmVq|)Cs_q?6QM94LbdYE-f&>P>H zgK&|e8S}i_ptGA>Vj?)YeO3`Q7I#yj$Ao6vYelj0j#7YQ)2<6;f&!+qN{B?3w1Fj_nFXIb%f4v6NV( zl*mch?HrA|8JOXyTIjLU=tWuf^Lfd6sj>7?GSn!7QA>Ih8)8E?-Ls_azPf%wQHXReFRCdIu_E!M)- zwNn1a<>OCcKche5ZSzp2PbkjYqpK!AS1L&#F?S1$(9#n5%4Kp5^#ElU+)8xpAr*T9-=}wQn5Bi zc1TdW8HqXLH6UuL@MDfA9}D+<@&>DdPVx3hsF0^rA0BCbj&Q_;X%=oi=I2nNB`T{G z^S)GJN%>eRs*(pv`#ALLSY|pYfzSuaG5`kp@tHAxYZxMcE4EY`Vdbe9p@m zsk$A#n2w@VozUQtlSxpd*K><);w+lp8!Yf@00pN~tC?+3%DRUXtGl7P#Yle-<(MS> zO8P-G<;Q!>oPMs3%6GfU`J}H%8CffW=&?h3@g&S0p1ftAf8XsM$`)*Pghi`~U`);eF5Y^z&UQgMl zKyX)@)wO+4RZL78h)vxgijq{qNZ_K@Uso<8G|g1FGOF`|La(HsN%po7_!4<|L+9Zw zC#(c{YUn8r|6BO$7WfNSmtgl$^jkxYr6~vdcPUgbf0`Jk{x3}&lCr(A&=T@LUMQaD zw{p9qeSb7!j}&6Q#2tCP_}h!&vA2JnN5c;>nBO)qg$_JgE)N>9qcPXpu56gv-Md)52My-CSJ@2|MDG{xL8I-7P*or=+NscUZTImz`(2T0 zs0KFVDk0#bAEEp`Xy5Z!1fU|<{>4ZVfiO{J+sjPL1dRy3^|)8ae>?{p1(N8M2WaGI zZpI0wir#h%Q3J0pOyU44apu-2g#wwl_@;Z%J?QEg0G)u!{42sVP&5(#7OFe!0(5bL z{-v{)DCv4bP}SW6G=#v}+q(HP9r{EMsP60#sw1leN*n$0qFnZ&%KQjGNq*{W_o4N6 z+!$FD_(dcGs6ZZZwd98)>wqop}$c#~XfW3Jr?dRkj2s;miJQAxfr(7&Ino63b&s*>(T$i{Vx1Ef6@u z0HXcn^*!h*YrErLD(b+ez5bVr$CTU!4=8|LT-cX;(D3=HSJ;EogPjuh9k+$HfY_}F4Ezv$6>+h%dXW5TM-xR@E9%!JjM ztIm;KhfZ$B;-Di=z8;dpzL#b^F5yZy(`~gxHN>A&r-RPmsjr%_AJKFtpdIyqJ(ZV% zoN>)7Sj3>A+Qbv}sqRZ~2c9X?41HcfYw?(SRT)@G}Ta}jLMl2R28FZ$k9Xuyvt#&g6B=9n^!W;#Y=S3m7d^yr!A|Ic<$E8Esd!;9{r&BG|^)kFqA^pWn59huuFT&ic zV5~F6UJqUSpHm}*Eo)7NnMjVr=JZlh`mryJGp=uR%+^*s zU=l0_L=Zhg3Up_(&uZ7fw@msL7|6;hbJ$_a*{s99cl7M)o}HoCbNSpu({i=!DZ~tW z2&^~;Yd!ur_7-bv*EiMFeYXaEO|R{-CS2yzjBqNc(0`~q8|~0drQOIkWWS5rUsA-U zql?u0c(ui{>_(L^SF;*3sLOr$^j-Age#cP8biiC)$`kn%?ku;CF^x1;wkq!1?ncZ% zNpvw-(P5h1mT-3Vrx3B7C%7itTt$Pss1@03xuu)Q(2Wlt{8lQ&q-Z)w5S@`U{nF&#*vr@*NM87f}DHbFME)8x!HC6)9;PbKM=R3HOlw2$L|Q6ZzUZlk zATaF>r3ffAV9p`mgG9khesH3TEAy}1&OedPRYmUl(Z2c78*G0qzaz9CGnH!Wsr#`_ zhvg$#nQ7uX%zXrNn|@5hRQ)GR7KyLO4&E#U;gHH~dB}#|G){j;cvJPXlZ=Tep|QRO za-4lAG(BRWgNiVS?SGaH%pTOx+2gMt?S4-m!0f?}ML{mkCZ?wP66}=Q{`a;tFn=I) zSFRx>2Sgpl^WMY_(zX-evej6@zge-z-E#O!Rc!F{+elq!G3E==KsF}76(J|n495Zb z7J=)W#K9x-nvnpAuSdl6s1Pb z)X1fM)2B&ZttE)3iQc1CoXqf*vYoBcsnTg|OzddLCD-ZaXiO1Y(y{eS;x%Bo3zrd( zh+@lNL`NBvkcxVrp&~!$(H>XhxzdGL^L2aU7v(vUJU`P%IlJCQWKbgfGRC9hDWo+X z5d;j5sdawG`98Owh&EKkA@2y^p?0F;$5`Py^#1YPVM$MX#p1nR z*PCzDTEzU^km1{PI?_uqqo&PMILl><&PY2K`Kn~poO#GxxFM@Sg5~`M-_U}1;$^U2 zqM3zRBU4i}spIG1OgDx-jz=k&os*a6;nJTFE_UoW!TSBe!DKN3bKqDydn^}O!A}X` zEo~exbGTOC(8FT~tSEb!*xh}cyNbb=P(GuGGli#b z4;D9MVZx=*ezH;TxCutljz67>onRYMdcV>Ada9KT( zJ+QmuEI!w*>t^y02C-oV|8P6*qP+(#cX858DBgqgG1!mrQ#_f4JjU&~^n@0Ohg&>@ z4|cNNj}&z_V*gp?|PRo=Xh5$!~}F!suB zElQRJqfAhuF;-u>#cp{!L*5o`Z&UFTnqe8om0eiPAhieTZyY>cmVw}5!jC_B#w*hx zbMgcUgCzk>jV{)29pni(A4y4g;7c$Ixs5vrM!byKO_Bx&yp3ZAYb)|oe?rNAr%u!= zr+-I%4+_tp#2}XQwD3S@*#RMW8GfxhoKl((Mj444+EoNaib)Z};k1;pof601E`J!8288`uxVuoG zi-WVdI4(oldVhlM^T0uTlWzbHi3IY2Q2MF;LMy0;h2k7u#{;g2DT7SO+ZIv#TDD-P z)I{KVpgcjUH^`}jWO?>NK67!C?lXbQl0}ix&Xomo)YESERz>Vb$aB$^M^2_hZ)<2$ zMlK5^LnjdmaV%i@!4?poTYW&@E(YxOygdASw+HKv=Ad=ky84l| zS<2B}kv&A!UN2qJD1358uy=G}6G_DvFQ*{HWn#B>tPSrjfe$pwHi6?CB*mix{?uAC6$S+1SSDVpbacrRY zUG=p`665T!v93qZdotLoc4qv3CTCw4_$^|^O+^BpZ=A&0htAe03GGL3mXf8Gh{j_+XQq&|<6O0!wf4 z#P9rQ%+jvhr*a)3kFw0;5WI(oFXP^`tmY_qbyVwi0Iv*N@aG|ew~>vk*)_fy=OLoL zE=S#cRt!mF#WEREHlyy%!9G@}jY^48u||qph-{JY=?_G2yVlr$TFR{J!58})Bd0lm z{4+$U*fMPhm&>tkr()J!jNg#m;#L%iRpK4%>Lpj!J;B&FM_8yB@Cmfpk-BZCy3T{ccQ+ zyU3XL9Ik#@=_EM&d}NGDvJ9n^QC50SQK#vM`8lEtO@2gN=l+?cQEz6hTq+W%s=Glna+XauJg5Ye#q zri&kU;TbJibPaX4U_BMm<4q}+=L}`7fKNP@!5mJ6PdAG!gjDZUUswpKH7%<~#kh(xTDf*Xr@%ocV{yBV%!kKQ z8DExdCrOWvBp4L+=zM=NM#9_%m(+qw0!Uu$+XK!M6|C>;hVb&tQ!r2%o$igJp9BD=I#2yM=y9S+O$9}EiO8Wk-A;7 z*IbSM`E?vpF#6hCH%n^mj4^XeX^G_YwpLt&CS#d?m|Fi!O$iJKk|z)$-wmfu7nGKM24HY0|VRW?l?DD#;&la0$JV}-JNxc2;v1$2p zzH1#YnrAFs=cOp3YhsZj@Ox<-G3jUIG1|I{WJJ84=*C|>iAPG0U6JC5*3~=xU>LV# zWe^-_Tzw4R+EoQv+D_W{1OJBx8=;KTD|gEaW<^lzgWs|>ilZB%bzvNOEjUnqL6hNI z#uh3hi@SW2;rOQSHBZr#OZ4|Rfn_k8%`-ug`kUB-;;IG2(W;-a8V3sm-ydx!FfdLJ zu23EqYu$tTRLLaZ#9G1|?At<$;Lx15Q*n+{Juk?<6G)O#0n1Wlma3>!qnek^K|h#5 z_5=7+uKdPZMp~%KV~Mk*IV}}I6Tf)%oE=CBi@u7Fc2(pKg$JWXShrOWJ>PsHkZyxg zl`#oJZUp|2r9$tZy2`#~t})PlR@FgpNTL#Qcu(;PKZ^-q29Fol-)r`mAZg|$VKA?s67e&l~=*lxCUh9H@R;RS*D@Sj`GY;nK(ZdzTOud7X#DM#L(Qv z7lIDIN0mLt#?3gR-Ed5Dc#>`5X`YAO)mSkuYkInz!Roo*HaUAKg9IG_Py5Hrix^Y>)(YQP3HW>BDOiY(|nI9u+R1oi9&QZi@D0TWq%rHvi0q zo4(11XJ6sV##~(j$MV^0`X?Hqfb5L~xL8H)jS`8Ms9q)H@S;nedCSNIYvem7P0PcS zIb8|fp{)0N`$x1l2;abQ&UWtp`b`XhX*flDTf99sm8rRO(;Y@;o`1ULtJJsVx1;)v z0wNwTPMb2MZ(|+O%MJHfLvzXvU$4W-A@5(XpDtMc)E7}hb}+6)YBcr-4W1obzxv%l z9+B~i)TZ!J$#hC%g8Ntlws2KabgRvruXywJpKB! z31N2GnQ_4sxy?!MYjbbUm%qC&nvkon1=I9$#gIoA6NprzQF8x+--v$HRX)Ea$f?yL zgNt(UY3rABJ`=*Q4sYY}Ko0M_R-!E@PT^MAKQyi6%^bdqxrJCbBJ#KzTP@W9T*DF z-!iVI2I8i%8dcFpr*FX&zTG)R+DLg36t}anO>du@yBd3N7&;c8g&|tJ>IfgB z;ANGpcltdjBb_mG2+2LQd~}anRJP#7Z-V$jU8Y-$3Mf-f^rTqa`F-9`Fvl4V)Ox?= zoBt~IJP?y_6Lx@GKo>HH;~KE2*y_vn+UQ z&};U5_mIWg#Sq*6WgQ^`RW&>6hoHw}t5_i2wKxGa22G~fZXKrXo)p$Pv2Aigsx5{0 zbQx3O{Bpn?DLjq-DSwkB(0ZY`c>VD+4@9e}seQ3%9qZYa(gnlA>+2DhP(DJ4#^wQ) z1yzQGUcD5&hfh`+a&V~1D_Nq`816xuHBM>k@6#wb`MGe}2iBTJ!MVO)bN8rL2_jr) zCh-=kB4PO{yU}VV3b5E~&XLZ_TYvY7 Date: Mon, 1 Apr 2024 18:21:38 +0800 Subject: [PATCH 43/58] =?UTF-8?q?=E6=94=AF=E6=8C=81abl=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/conf/CloudRecordTimer.java | 2 +- .../genersoft/iot/vmp/conf/MediaConfig.java | 2 +- .../iot/vmp/conf/ProxyServletConfig.java | 2 +- .../vmp/gb28181/bean/AudioBroadcastCatch.java | 2 +- .../vmp/gb28181/bean/InviteStreamInfo.java | 2 +- .../iot/vmp/gb28181/task/SipRunner.java | 2 +- .../gb28181/transmit/cmd/ISIPCommander.java | 2 +- .../cmd/ISIPCommanderForPlatform.java | 2 +- .../transmit/cmd/impl/SIPCommander.java | 2 +- .../cmd/impl/SIPCommanderFroPlatform.java | 3 +- .../request/impl/AckRequestProcessor.java | 2 +- .../request/impl/ByeRequestProcessor.java | 2 +- .../request/impl/InviteRequestProcessor.java | 2 +- .../cmd/BroadcastNotifyMessageHandler.java | 3 +- .../iot/vmp/media/MediaServerConfig.java | 2 +- .../vmp/media/abl/ABLHttpHookListener.java | 410 ++++++++++++++++++ .../media/abl/ABLMediaNodeServerService.java | 2 +- .../media/abl/ABLMediaServerStatusManger.java | 2 +- .../iot/vmp/media/abl/ABLRESTfulUtils.java | 2 +- .../iot/vmp/media/abl/bean/AblUrls.java | 58 +++ .../vmp/media/abl/bean/hook/ABLHookParam.java | 65 +++ .../abl/bean/hook/OnPlayABLHookParam.java | 31 ++ .../abl/bean/hook/OnPublishABLHookParam.java | 31 ++ .../bean/hook/OnRecordMp4ABLHookParam.java | 13 + .../hook/OnRecordProgressABLHookParam.java | 22 + .../hook/OnServerKeepaliveABLHookParam.java | 32 ++ .../bean/hook/OnServerStaredABLHookParam.java | 32 ++ .../bean/hook/OnStreamArriveABLHookParam.java | 245 +++++++++++ .../event/HookAblServerKeepaliveEvent.java | 2 +- .../abl/event/HookAblServerStartEvent.java | 2 +- .../iot/vmp/media/bean/MediaInfo.java | 20 +- .../media/{zlm/dto => bean}/MediaServer.java | 3 +- .../iot/vmp/media/bean/RecordInfo.java | 7 + .../iot/vmp/media/event/hook/HookData.java | 2 +- .../media/event/media/MediaArrivalEvent.java | 12 +- .../event/media/MediaDepartureEvent.java | 11 +- .../iot/vmp/media/event/media/MediaEvent.java | 4 +- .../media/event/media/MediaNotFoundEvent.java | 11 +- .../media/event/media/MediaPublishEvent.java | 2 +- .../event/media/MediaRecordMp4Event.java | 15 +- .../media/MediaRtpServerTimeoutEvent.java | 2 +- .../mediaServer/MediaSendRtpStoppedEvent.java | 2 +- .../mediaServer/MediaServerChangeEvent.java | 2 +- .../service/IMediaNodeServerService.java | 2 +- .../media/service/IMediaServerService.java | 2 +- .../service/impl/MediaServerServiceImpl.java | 2 +- .../iot/vmp/media/zlm/AssistRESTfulUtils.java | 2 +- .../iot/vmp/media/zlm/SendRtpPortManager.java | 2 +- .../vmp/media/zlm/ZLMHttpHookListener.java | 2 +- .../vmp/media/zlm/ZLMMediaListManager.java | 1 + .../media/zlm/ZLMMediaNodeServerService.java | 2 +- .../media/zlm/ZLMMediaServerStatusManger.java | 2 +- .../iot/vmp/media/zlm/ZLMRESTfulUtils.java | 2 +- .../iot/vmp/media/zlm/ZLMServerFactory.java | 2 +- .../media/zlm/dto/MediaServerItemLite.java | 168 ------- .../iot/vmp/media/zlm/dto/hook/HookParam.java | 2 + .../event/HookZlmServerKeepaliveEvent.java | 2 +- .../zlm/event/HookZlmServerStartEvent.java | 2 +- .../iot/vmp/service/ICloudRecordService.java | 3 +- .../iot/vmp/service/IMediaService.java | 4 +- .../iot/vmp/service/IPlatformService.java | 2 +- .../iot/vmp/service/IPlayService.java | 3 +- .../iot/vmp/service/IStreamProxyService.java | 2 +- .../iot/vmp/service/bean/PlayBackResult.java | 2 +- .../vmp/service/bean/ResponseSendItemMsg.java | 2 +- .../service/impl/CloudRecordServiceImpl.java | 4 +- .../vmp/service/impl/DeviceServiceImpl.java | 2 +- .../vmp/service/impl/MediaServiceImpl.java | 2 +- .../vmp/service/impl/PlatformServiceImpl.java | 4 +- .../iot/vmp/service/impl/PlayServiceImpl.java | 6 +- .../service/impl/StreamProxyServiceImpl.java | 2 +- .../service/impl/StreamPushServiceImpl.java | 2 +- .../redisMsg/RedisGbPlayMsgListener.java | 2 +- .../RedisPushStreamCloseResponseListener.java | 2 +- .../iot/vmp/storager/IRedisCatchStorage.java | 2 +- .../dao/CloudRecordServiceMapper.java | 2 +- .../vmp/storager/dao/MediaServerMapper.java | 2 +- .../storager/impl/RedisCatchStorageImpl.java | 2 +- .../iot/vmp/utils/CloudRecordUtils.java | 2 +- .../cloudRecord/CloudRecordController.java | 2 +- .../vmanager/gb28181/play/PlayController.java | 2 +- .../iot/vmp/vmanager/ps/PsController.java | 3 +- .../iot/vmp/vmanager/rtp/RtpController.java | 3 +- .../vmp/vmanager/server/ServerController.java | 4 +- .../streamProxy/StreamProxyController.java | 2 +- .../vmp/web/gb28181/ApiStreamController.java | 2 +- 86 files changed, 1080 insertions(+), 261 deletions(-) create mode 100755 src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblUrls.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPlayABLHookParam.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPublishABLHookParam.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordMp4ABLHookParam.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordProgressABLHookParam.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerKeepaliveABLHookParam.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerStaredABLHookParam.java create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnStreamArriveABLHookParam.java rename src/main/java/com/genersoft/iot/vmp/media/{zlm/dto => bean}/MediaServer.java (98%) delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItemLite.java diff --git a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java index b2cd1211f..de87a9c62 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.conf; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java index baf819fb7..a61154fc8 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.conf; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.utils.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java index aaa99fca8..3948fdb64 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.conf; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/AudioBroadcastCatch.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/AudioBroadcastCatch.java index 237be7e49..2b5e16bd1 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/AudioBroadcastCatch.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/AudioBroadcastCatch.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.gb28181.bean; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent; import gov.nist.javax.sip.message.SIPResponse; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java index 005994139..e1925fac1 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.gb28181.bean; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; public class InviteStreamInfo { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java index 234e268bc..b61a623fe 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index a054ae5df..fcafbf75a 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import gov.nist.javax.sip.message.SIPRequest; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java index ac62caf81..bc999f037 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index b7f57d750..0099aafb1 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.message.SIPRequest; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 21aba6c4f..51f5c670b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -17,8 +17,7 @@ import com.genersoft.iot.vmp.media.event.hook.Hook; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index ab40798f8..27f1e71cf 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlayService; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java index 3b1788545..b2d14a0f1 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java @@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 9f4e47046..c3e5b5960 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.event.hook.Hook; import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -25,7 +26,6 @@ import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.*; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java index 72ba51af7..08be1f366 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java @@ -8,8 +8,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; diff --git a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java index 4eb10412b..fb9de3f89 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.media; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java new file mode 100755 index 000000000..e892e6df5 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java @@ -0,0 +1,410 @@ +package com.genersoft.iot.vmp.media.abl; + +import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.gb28181.event.EventPublisher; +import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; +import com.genersoft.iot.vmp.media.abl.bean.hook.*; +import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; +import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent; +import com.genersoft.iot.vmp.media.bean.MediaServer; +import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.media.*; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent; +import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; +import com.genersoft.iot.vmp.media.zlm.dto.hook.*; +import com.genersoft.iot.vmp.service.*; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.util.ObjectUtils; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; + +/** + * ABL 的hook事件监听 + */ +@RestController +@RequestMapping("/index/hook/abl") +public class ABLHttpHookListener { + + private final static Logger logger = LoggerFactory.getLogger(ABLHttpHookListener.class); + + @Autowired + private ABLRESTfulUtils ablresTfulUtils; + + @Autowired + private ISIPCommanderForPlatform commanderFroPlatform; + + @Autowired + private AudioBroadcastManager audioBroadcastManager; + + @Autowired + private IPlayService playService; + + @Autowired + private IVideoManagerStorage storager; + + @Autowired + private IRedisCatchStorage redisCatchStorage; + + @Autowired + private IInviteStreamService inviteStreamService; + + @Autowired + private IDeviceService deviceService; + + @Autowired + private IMediaServerService mediaServerService; + + @Autowired + private IStreamProxyService streamProxyService; + + @Autowired + private DeferredResultHolder resultHolder; + + @Autowired + private IMediaService mediaService; + + @Autowired + private EventPublisher eventPublisher; + + @Autowired + private ZLMMediaListManager zlmMediaListManager; + + @Autowired + private HookSubscribe subscribe; + + @Autowired + private UserSetting userSetting; + + @Autowired + private IUserService userService; + + @Autowired + private ICloudRecordService cloudRecordService; + + @Autowired + private VideoStreamSessionManager sessionManager; + + @Autowired + private SSRCFactory ssrcFactory; + + @Qualifier("taskExecutor") + @Autowired + private ThreadPoolTaskExecutor taskExecutor; + + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + /** + * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 + */ + @ResponseBody + @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") + public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveABLHookParam param) { + try { + HookAblServerKeepaliveEvent event = new HookAblServerKeepaliveEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServerItem(mediaServerItem); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ZLM-HOOK-心跳] 发送通知失败 ", e); + } + return HookResult.SUCCESS(); + } + + /** + * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。 + */ + @ResponseBody + @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") + public HookResult onPlay(@RequestBody OnPlayABLHookParam param) { + + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServer == null) { + return new HookResultForOnPublish(0, "success"); + } + + Map paramMap = urlParamToMap(param.getParams()); + // 对于播放流进行鉴权 + boolean authenticateResult = mediaService.authenticatePlay(param.getApp(), param.getStream(), paramMap.get("callId")); + if (!authenticateResult) { + logger.info("[ABL HOOK] 播放鉴权 失败:{}->{}", param.getMediaServerId(), param); + ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream()); + + } + logger.info("[ABL HOOK] 播放鉴权成功:{}->{}", param.getMediaServerId(), param); + return HookResult.SUCCESS(); + } + + /** + * rtsp/rtmp/rtp推流鉴权事件。 + */ + @ResponseBody + @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8") + public HookResult onPublish(@RequestBody OnPublishABLHookParam param) { + + + logger.info("[ABL HOOK]推流鉴权:{}->{}", param.getMediaServerId(), param); + // TODO 加快处理速度 + + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServer == null) { + return new HookResultForOnPublish(0, "success"); + } + + ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams()); + if (resultForOnPublish == null) { + logger.info("[ABL HOOK]推流鉴权 拒绝 响应:{}->{}", param.getMediaServerId(), param); + ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream()); + } + return HookResult.SUCCESS(); + } + + /** + * 如果某一个码流进行MP4录像(enable_mp4=1),会触发录像进度通知事件 + */ + @ResponseBody + @PostMapping(value = "/on_record_progress", produces = "application/json;charset=UTF-8") + public HookResult onRecordProgress(@RequestBody OnRecordProgressABLHookParam param) { + + + logger.info("[ABL HOOK] 录像进度通知:{}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration()); + + // TODO 这里用来做录像进度 +// MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); +// if (mediaServer == null) { +// return new HookResultForOnPublish(0, "success"); +// } +// +// ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams()); +// if (resultForOnPublish == null) { +// logger.info("[ABL HOOK]推流鉴权 拒绝 响应:{}->{}", param.getMediaServerId(), param); +// ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream()); +// } + return HookResult.SUCCESS(); + } + + /** + * 当代理拉流、国标接入等等 码流不到达时会发出 码流不到达的事件通知 + */ + @ResponseBody + @PostMapping(value = "/on_stream_not_arrive", produces = "application/json;charset=UTF-8") + public HookResult onStreamNotArrive(@RequestBody ABLHookParam param) { + + + logger.info("[ABL HOOK] 码流不到达通知:{}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration()); + try { + if ("rtp".equals(param.getApp())) { + return HookResult.SUCCESS(); + } + MediaRtpServerTimeoutEvent event = new MediaRtpServerTimeoutEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServer(mediaServerItem); + event.setApp("rtp"); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ABL-HOOK-码流不到达通知] 发送通知失败 ", e); + } + + return HookResult.SUCCESS(); + } + + /** + * 如果某一个码流进行MP4录像(enable_mp4=1),当某个MP4文件被删除会触发该事件通知 + */ + @ResponseBody + @PostMapping(value = "/on_delete_record_mp4", produces = "application/json;charset=UTF-8") + public HookResult onDeleteRecordMp4(@RequestBody OnRecordMp4ABLHookParam param) { + + + logger.info("[ABL HOOK] MP4文件被删除通知:{}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration()); + + + return HookResult.SUCCESS(); + } + + + /** + * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 + */ + @ResponseBody + @PostMapping(value = "/on_stream_arrive", produces = "application/json;charset=UTF-8") + public HookResult onStreamArrive(@RequestBody OnStreamArriveABLHookParam param) { + + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServer == null) { + return HookResult.SUCCESS(); + } + + logger.info("[ABL HOOK] 码流到达, {}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); + MediaArrivalEvent mediaArrivalEvent = MediaArrivalEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaArrivalEvent); + return HookResult.SUCCESS(); + } + + /** + * 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 + */ + @ResponseBody + @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") + public JSONObject onStreamNoneReader(@RequestBody ABLHookParam param) { + + logger.info("[ZLM HOOK]流无人观看:{}->{}/{}", param.getMediaServerId(), + param.getApp(), param.getStream()); + JSONObject ret = new JSONObject(); + + boolean close = mediaService.closeStreamOnNoneReader(param.getMediaServerId(), param.getApp(), param.getStream(), null); + ret.put("code", close); + return ret; + } + + /** + * 当播放一个url,如果不存在时,会发出一个消息通知 + */ + @ResponseBody + @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") + public HookResult onStreamNotFound(@RequestBody ABLHookParam param) { + logger.info("[ABL HOOK] 流未找到:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); + + + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (!userSetting.isAutoApplyPlay() || mediaServer == null) { + return HookResult.SUCCESS(); + } + MediaNotFoundEvent mediaNotFoundEvent = MediaNotFoundEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaNotFoundEvent); + return HookResult.SUCCESS(); + } + + /** + * ABLMediaServer启动时会发送上线通知 + */ + @ResponseBody + @PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8") + public HookResult onServerStarted(HttpServletRequest request, @RequestBody OnServerStaredABLHookParam param) { + + logger.info("[ABL HOOK] 启动 " + param.getMediaServerId()); + try { + HookAblServerStartEvent event = new HookAblServerStartEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServerItem(mediaServerItem); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ABL-HOOK-启动] 发送通知失败 ", e); + } + + return HookResult.SUCCESS(); + } + + /** + * TODO 发送rtp(startSendRtp)被动关闭时回调 + */ +// @ResponseBody +// @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8") +// public HookResult onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param) { +// +// logger.info("[ZLM HOOK] rtp发送关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); +// +// // 查找对应的上级推流,发送停止 +// if (!"rtp".equals(param.getApp())) { +// return HookResult.SUCCESS(); +// } +// try { +// MediaSendRtpStoppedEvent event = new MediaSendRtpStoppedEvent(this); +// MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); +// if (mediaServerItem != null) { +// event.setMediaServer(mediaServerItem); +// applicationEventPublisher.publishEvent(event); +// } +// }catch (Exception e) { +// logger.info("[ZLM-HOOK-rtp发送关闭] 发送通知失败 ", e); +// } +// +// return HookResult.SUCCESS(); +// } + + /** + * TODO 录像完成事件 + */ + @ResponseBody + @PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8") + public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4ABLHookParam param) { + logger.info("[ABL HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFileName()); + +// try { +// MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); +// if (mediaServerItem != null) { +// MediaRecordMp4Event event = MediaRecordMp4Event.getInstance(this, param, mediaServerItem); +// event.setMediaServer(mediaServerItem); +// applicationEventPublisher.publishEvent(event); +// } +// }catch (Exception e) { +// logger.info("[ZLM-HOOK-rtpServer收流超时] 发送通知失败 ", e); +// } + + return HookResult.SUCCESS(); + } + + /** + * 当某一路码流断开时会发送通知 + */ + @ResponseBody + @PostMapping(value = "/on_stream_disconnect", produces = "application/json;charset=UTF-8") + public HookResult onRecordMp4(HttpServletRequest request, @RequestBody ABLHookParam param) { + logger.info("[ABL HOOK] 码流断开事件, {}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); + + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServer == null) { + return HookResult.SUCCESS(); + } + + MediaDepartureEvent mediaDepartureEvent = MediaDepartureEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaDepartureEvent); + + return HookResult.SUCCESS(); + } + + private Map urlParamToMap(String params) { + HashMap map = new HashMap<>(); + if (ObjectUtils.isEmpty(params)) { + return map; + } + String[] paramsArray = params.split("&"); + if (paramsArray.length == 0) { + return map; + } + for (String param : paramsArray) { + String[] paramArray = param.split("="); + if (paramArray.length == 2) { + map.put(paramArray[0], paramArray[1]); + } + } + return map; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index 9c2bb904f..aaa72ddf3 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java index 62015dc48..5895ce2a3 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java index b76f59ef1..b2f360290 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.media.abl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblUrls.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblUrls.java new file mode 100644 index 000000000..42e05a04d --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblUrls.java @@ -0,0 +1,58 @@ +package com.genersoft.iot.vmp.media.abl.bean; + +public class AblUrls { + private String rtsp; + private String rtmp; + private String httpFlv; + private String wsFlv; + private String httpMp4; + private String httpHls; + + public String getRtsp() { + return rtsp; + } + + public void setRtsp(String rtsp) { + this.rtsp = rtsp; + } + + public String getRtmp() { + return rtmp; + } + + public void setRtmp(String rtmp) { + this.rtmp = rtmp; + } + + public String getHttpFlv() { + return httpFlv; + } + + public void setHttpFlv(String httpFlv) { + this.httpFlv = httpFlv; + } + + public String getWsFlv() { + return wsFlv; + } + + public void setWsFlv(String wsFlv) { + this.wsFlv = wsFlv; + } + + public String getHttpMp4() { + return httpMp4; + } + + public void setHttpMp4(String httpMp4) { + this.httpMp4 = httpMp4; + } + + public String getHttpHls() { + return httpHls; + } + + public void setHttpHls(String httpHls) { + this.httpHls = httpHls; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java new file mode 100644 index 000000000..8662085a6 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java @@ -0,0 +1,65 @@ +package com.genersoft.iot.vmp.media.abl.bean.hook; + +public class ABLHookParam { + private String mediaServerId; + + /** + * 应用名 + */ + private String app; + + /** + * 流id + */ + private String stream; + + /** + * 媒体流来源编号,可以根据这个key进行关闭流媒体 可以调用delMediaStream或close_streams 函数进行关闭 + */ + private String key; + + /** + * 媒体流来源网络编号,可参考附表 + */ + private String networkType; + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getNetworkType() { + return networkType; + } + + public void setNetworkType(String networkType) { + this.networkType = networkType; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPlayABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPlayABLHookParam.java new file mode 100644 index 000000000..af18210e6 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPlayABLHookParam.java @@ -0,0 +1,31 @@ +package com.genersoft.iot.vmp.media.abl.bean.hook; + +public class OnPlayABLHookParam extends ABLHookParam{ + private String ip; + private Integer port; + private String params; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getParams() { + return params; + } + + public void setParams(String params) { + this.params = params; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPublishABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPublishABLHookParam.java new file mode 100644 index 000000000..11da2740b --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPublishABLHookParam.java @@ -0,0 +1,31 @@ +package com.genersoft.iot.vmp.media.abl.bean.hook; + +public class OnPublishABLHookParam extends ABLHookParam{ + private String ip; + private Integer port; + private String params; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getParams() { + return params; + } + + public void setParams(String params) { + this.params = params; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordMp4ABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordMp4ABLHookParam.java new file mode 100644 index 000000000..0fb819fae --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordMp4ABLHookParam.java @@ -0,0 +1,13 @@ +package com.genersoft.iot.vmp.media.abl.bean.hook; + +public class OnRecordMp4ABLHookParam extends ABLHookParam{ + private String fileName; + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordProgressABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordProgressABLHookParam.java new file mode 100644 index 000000000..8f70781b7 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordProgressABLHookParam.java @@ -0,0 +1,22 @@ +package com.genersoft.iot.vmp.media.abl.bean.hook; + +public class OnRecordProgressABLHookParam extends OnRecordMp4ABLHookParam{ + private Integer currentFileDuration; + private Integer TotalVideoDuration; + + public Integer getCurrentFileDuration() { + return currentFileDuration; + } + + public void setCurrentFileDuration(Integer currentFileDuration) { + this.currentFileDuration = currentFileDuration; + } + + public Integer getTotalVideoDuration() { + return TotalVideoDuration; + } + + public void setTotalVideoDuration(Integer totalVideoDuration) { + TotalVideoDuration = totalVideoDuration; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerKeepaliveABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerKeepaliveABLHookParam.java new file mode 100644 index 000000000..ea1ac9702 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerKeepaliveABLHookParam.java @@ -0,0 +1,32 @@ +package com.genersoft.iot.vmp.media.abl.bean.hook; + +public class OnServerKeepaliveABLHookParam { + private String localipAddress; + private String mediaServerId; + private String datetime; + + + public String getLocalipAddress() { + return localipAddress; + } + + public void setLocalipAddress(String localipAddress) { + this.localipAddress = localipAddress; + } + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } + + public String getDatetime() { + return datetime; + } + + public void setDatetime(String datetime) { + this.datetime = datetime; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerStaredABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerStaredABLHookParam.java new file mode 100644 index 000000000..a9ec44c0c --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerStaredABLHookParam.java @@ -0,0 +1,32 @@ +package com.genersoft.iot.vmp.media.abl.bean.hook; + +public class OnServerStaredABLHookParam { + private String localipAddress; + private String mediaServerId; + private String datetime; + + + public String getLocalipAddress() { + return localipAddress; + } + + public void setLocalipAddress(String localipAddress) { + this.localipAddress = localipAddress; + } + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } + + public String getDatetime() { + return datetime; + } + + public void setDatetime(String datetime) { + this.datetime = datetime; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnStreamArriveABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnStreamArriveABLHookParam.java new file mode 100644 index 000000000..efe9b1269 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnStreamArriveABLHookParam.java @@ -0,0 +1,245 @@ +package com.genersoft.iot.vmp.media.abl.bean.hook; + +import com.genersoft.iot.vmp.media.abl.bean.AblUrls; + +/** + * 流到来的事件 + */ +public class OnStreamArriveABLHookParam extends ABLHookParam{ + + + + /** + * 推流鉴权Id + */ + private String callId; + + /** + * 状态 + */ + private Boolean status; + + + /** + * + */ + private Boolean enableHls; + + + /** + * + */ + private Boolean transcodingStatus; + + + /** + * + */ + private String sourceURL; + + + /** + * + */ + private Integer readerCount; + + + /** + * + */ + private Integer noneReaderDuration; + + + /** + * + */ + private String videoCodec; + + + /** + * + */ + private Integer videoFrameSpeed; + + + /** + * + */ + private Integer width; + + + /** + * + */ + private Integer height; + + + /** + * + */ + private Integer videoBitrate; + + + /** + * + */ + private String audioCodec; + + + /** + * + */ + private Integer audioChannels; + + + /** + * + */ + private Integer audioSampleRate; + + + /** + * + */ + private Integer audioBitrate; + + + private AblUrls url; + + + public String getCallId() { + return callId; + } + + public void setCallId(String callId) { + this.callId = callId; + } + + public Boolean getStatus() { + return status; + } + + public void setStatus(Boolean status) { + this.status = status; + } + + public Boolean getEnableHls() { + return enableHls; + } + + public void setEnableHls(Boolean enableHls) { + this.enableHls = enableHls; + } + + public Boolean getTranscodingStatus() { + return transcodingStatus; + } + + public void setTranscodingStatus(Boolean transcodingStatus) { + this.transcodingStatus = transcodingStatus; + } + + public String getSourceURL() { + return sourceURL; + } + + public void setSourceURL(String sourceURL) { + this.sourceURL = sourceURL; + } + + public Integer getReaderCount() { + return readerCount; + } + + public void setReaderCount(Integer readerCount) { + this.readerCount = readerCount; + } + + public Integer getNoneReaderDuration() { + return noneReaderDuration; + } + + public void setNoneReaderDuration(Integer noneReaderDuration) { + this.noneReaderDuration = noneReaderDuration; + } + + public String getVideoCodec() { + return videoCodec; + } + + public void setVideoCodec(String videoCodec) { + this.videoCodec = videoCodec; + } + + public Integer getVideoFrameSpeed() { + return videoFrameSpeed; + } + + public void setVideoFrameSpeed(Integer videoFrameSpeed) { + this.videoFrameSpeed = videoFrameSpeed; + } + + public Integer getWidth() { + return width; + } + + public void setWidth(Integer width) { + this.width = width; + } + + public Integer getHeight() { + return height; + } + + public void setHeight(Integer height) { + this.height = height; + } + + public Integer getVideoBitrate() { + return videoBitrate; + } + + public void setVideoBitrate(Integer videoBitrate) { + this.videoBitrate = videoBitrate; + } + + public String getAudioCodec() { + return audioCodec; + } + + public void setAudioCodec(String audioCodec) { + this.audioCodec = audioCodec; + } + + public Integer getAudioChannels() { + return audioChannels; + } + + public void setAudioChannels(Integer audioChannels) { + this.audioChannels = audioChannels; + } + + public Integer getAudioSampleRate() { + return audioSampleRate; + } + + public void setAudioSampleRate(Integer audioSampleRate) { + this.audioSampleRate = audioSampleRate; + } + + public Integer getAudioBitrate() { + return audioBitrate; + } + + public void setAudioBitrate(Integer audioBitrate) { + this.audioBitrate = audioBitrate; + } + + public AblUrls getUrl() { + return url; + } + + public void setUrl(AblUrls url) { + this.url = url; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java index bbedd6dfa..74465e4c1 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.abl.event; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.springframework.context.ApplicationEvent; /** diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java index 4e1960e23..12bdac06f 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.abl.event; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.springframework.context.ApplicationEvent; /** diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java index c33eeccc2..2853cd2a6 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.media.bean; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.abl.bean.hook.OnStreamArriveABLHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import io.swagger.v3.oas.annotations.media.Schema; @@ -177,6 +177,24 @@ public class MediaInfo { return mediaInfo; } + public static MediaInfo getInstance(OnStreamArriveABLHookParam param, MediaServer mediaServer) { + + MediaInfo mediaInfo = new MediaInfo(); + mediaInfo.setApp(param.getApp()); + mediaInfo.setStream(param.getStream()); + mediaInfo.setMediaServer(mediaServer); + mediaInfo.setReaderCount(param.getReaderCount()); + mediaInfo.setOnline(true); + mediaInfo.setVideoCodec(param.getVideoCodec()); + mediaInfo.setWidth(param.getWidth()); + mediaInfo.setHeight(param.getHeight()); + mediaInfo.setAudioCodec(param.getAudioCodec()); + mediaInfo.setAudioChannels(param.getAudioChannels()); + mediaInfo.setAudioSampleRate(param.getAudioSampleRate()); + + return mediaInfo; + } + public Integer getReaderCount() { return readerCount; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServer.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java similarity index 98% rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServer.java rename to src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java index a53924f31..5c32ea7af 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServer.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java @@ -1,6 +1,7 @@ -package com.genersoft.iot.vmp.media.zlm.dto; +package com.genersoft.iot.vmp.media.bean; +import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java index aafc5db10..eb60ed91f 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.media.bean; +import com.genersoft.iot.vmp.media.abl.bean.hook.OnRecordMp4ABLHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; public class RecordInfo { @@ -23,6 +24,12 @@ public class RecordInfo { return recordInfo; } + public static RecordInfo getInstance(OnRecordMp4ABLHookParam hookParam) { + RecordInfo recordInfo = new RecordInfo(); + recordInfo.setFileName(hookParam.getFileName()); + return recordInfo; + } + public String getFileName() { return fileName; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java index 25c02de51..d4a82a7e2 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; import com.genersoft.iot.vmp.media.event.media.MediaEvent; import com.genersoft.iot.vmp.media.event.media.MediaPublishEvent; import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import io.swagger.v3.oas.annotations.media.Schema; /** diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java index af1e23e5a..cebcccdf1 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java @@ -1,7 +1,8 @@ package com.genersoft.iot.vmp.media.event.media; +import com.genersoft.iot.vmp.media.abl.bean.hook.OnStreamArriveABLHookParam; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; /** @@ -22,6 +23,15 @@ public class MediaArrivalEvent extends MediaEvent { mediaArrivalEvent.setCallId(hookParam.getCallId()); return mediaArrivalEvent; } + public static MediaArrivalEvent getInstance(Object source, OnStreamArriveABLHookParam hookParam, MediaServer mediaServer){ + MediaArrivalEvent mediaArrivalEvent = new MediaArrivalEvent(source); + mediaArrivalEvent.setMediaInfo(MediaInfo.getInstance(hookParam, mediaServer)); + mediaArrivalEvent.setApp(hookParam.getApp()); + mediaArrivalEvent.setStream(hookParam.getStream()); + mediaArrivalEvent.setMediaServer(mediaServer); + mediaArrivalEvent.setCallId(hookParam.getCallId()); + return mediaArrivalEvent; + } private MediaInfo mediaInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java index 5cf87de28..02b99f31c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.abl.bean.hook.ABLHookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; /** @@ -19,4 +20,12 @@ public class MediaDepartureEvent extends MediaEvent { mediaDepartureEven.setMediaServer(mediaServer); return mediaDepartureEven; } + + public static MediaDepartureEvent getInstance(Object source, ABLHookParam hookParam, MediaServer mediaServer){ + MediaDepartureEvent mediaDepartureEven = new MediaDepartureEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java index 54d0a4203..b6fb89022 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java @@ -1,8 +1,6 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.springframework.context.ApplicationEvent; /** diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java index b45f55e84..675d6e9d5 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.abl.bean.hook.ABLHookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; /** @@ -19,4 +20,12 @@ public class MediaNotFoundEvent extends MediaEvent { mediaDepartureEven.setMediaServer(mediaServer); return mediaDepartureEven; } + + public static MediaNotFoundEvent getInstance(Object source, ABLHookParam hookParam, MediaServer mediaServer){ + MediaNotFoundEvent mediaDepartureEven = new MediaNotFoundEvent(source); + mediaDepartureEven.setApp(hookParam.getApp()); + mediaDepartureEven.setStream(hookParam.getStream()); + mediaDepartureEven.setMediaServer(mediaServer); + return mediaDepartureEven; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java index b50f89651..0d9f032c7 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnPublishHookParam; /** diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java index e4750c1cd..9fd6defc8 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java @@ -1,9 +1,10 @@ package com.genersoft.iot.vmp.media.event.media; +import com.genersoft.iot.vmp.media.abl.ABLHttpHookListener; +import com.genersoft.iot.vmp.media.abl.bean.hook.OnRecordMp4ABLHookParam; import com.genersoft.iot.vmp.media.bean.RecordInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; /** * 录像文件生成事件 @@ -25,6 +26,16 @@ public class MediaRecordMp4Event extends MediaEvent { return mediaRecordMp4Event; } + public static MediaRecordMp4Event getInstance(ABLHttpHookListener source, OnRecordMp4ABLHookParam hookParam, MediaServer mediaServer) { + MediaRecordMp4Event mediaRecordMp4Event = new MediaRecordMp4Event(source); + mediaRecordMp4Event.setApp(hookParam.getApp()); + mediaRecordMp4Event.setStream(hookParam.getStream()); + RecordInfo recordInfo = RecordInfo.getInstance(hookParam); + mediaRecordMp4Event.setRecordInfo(recordInfo); + mediaRecordMp4Event.setMediaServer(mediaServer); + return mediaRecordMp4Event; + } + public RecordInfo getRecordInfo() { return recordInfo; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java index 939c85263..b700dd59b 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; /** diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java index c9679f752..d37a4c24b 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.event.mediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; import org.springframework.context.ApplicationEvent; diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java index e3650454e..ecbe332b3 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.event.mediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.springframework.context.ApplicationEvent; import java.util.ArrayList; diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 9ecedd97f..397704575 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import java.util.List; diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 4ec0bfed6..2b11c033c 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 30a9b8310..add9d9499 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java index 9c473a33c..6f6d5ea8d 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.utils.SSLSocketClientUtil; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java index cb63365bb..7fffc1062 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.apache.commons.lang3.math.NumberUtils; import org.slf4j.Logger; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index dc24874e6..f5b1b6c4f 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.event.media.*; import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 1d9fc40fa..8c5f80e2b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.GbStream; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 06c8c3e5a..5b566d80c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index 27e62b2bc..d4d65636a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 49200545d..e06eb42a5 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import okhttp3.*; import okhttp3.logging.HttpLoggingInterceptor; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java index 5e3facdc6..14025cecc 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItemLite.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItemLite.java deleted file mode 100644 index c803185b0..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItemLite.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm.dto; - - -/** - * 精简的MediaServerItem信息,方便给前端返回数据 - */ -public class MediaServerItemLite { - - private String id; - - private String ip; - - private String hookIp; - - private String sdpIp; - - private String streamIp; - - private int httpPort; - - private int httpSSlPort; - - private int rtmpPort; - - private int rtmpSSlPort; - - private int rtpProxyPort; - - private int rtspPort; - - private int rtspSSLPort; - - private String secret; - - private int recordAssistPort; - - - - public MediaServerItemLite(MediaServer mediaServerItem) { - this.id = mediaServerItem.getId(); - this.ip = mediaServerItem.getIp(); - this.hookIp = mediaServerItem.getHookIp(); - this.sdpIp = mediaServerItem.getSdpIp(); - this.streamIp = mediaServerItem.getStreamIp(); - this.httpPort = mediaServerItem.getHttpPort(); - this.httpSSlPort = mediaServerItem.getHttpSSlPort(); - this.rtmpPort = mediaServerItem.getRtmpPort(); - this.rtmpSSlPort = mediaServerItem.getRtmpSSlPort(); - this.rtpProxyPort = mediaServerItem.getRtpProxyPort(); - this.rtspPort = mediaServerItem.getRtspPort(); - this.rtspSSLPort = mediaServerItem.getRtspSSLPort(); - this.secret = mediaServerItem.getSecret(); - this.recordAssistPort = mediaServerItem.getRecordAssistPort(); - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public String getHookIp() { - return hookIp; - } - - public void setHookIp(String hookIp) { - this.hookIp = hookIp; - } - - public String getSdpIp() { - return sdpIp; - } - - public void setSdpIp(String sdpIp) { - this.sdpIp = sdpIp; - } - - public String getStreamIp() { - return streamIp; - } - - public void setStreamIp(String streamIp) { - this.streamIp = streamIp; - } - - public int getHttpPort() { - return httpPort; - } - - public void setHttpPort(int httpPort) { - this.httpPort = httpPort; - } - - public int getHttpSSlPort() { - return httpSSlPort; - } - - public void setHttpSSlPort(int httpSSlPort) { - this.httpSSlPort = httpSSlPort; - } - - public int getRtmpPort() { - return rtmpPort; - } - - public void setRtmpPort(int rtmpPort) { - this.rtmpPort = rtmpPort; - } - - public int getRtmpSSlPort() { - return rtmpSSlPort; - } - - public void setRtmpSSlPort(int rtmpSSlPort) { - this.rtmpSSlPort = rtmpSSlPort; - } - - public int getRtpProxyPort() { - return rtpProxyPort; - } - - public void setRtpProxyPort(int rtpProxyPort) { - this.rtpProxyPort = rtpProxyPort; - } - - public int getRtspPort() { - return rtspPort; - } - - public void setRtspPort(int rtspPort) { - this.rtspPort = rtspPort; - } - - public int getRtspSSLPort() { - return rtspSSLPort; - } - - public void setRtspSSLPort(int rtspSSLPort) { - this.rtspSSLPort = rtspSSLPort; - } - - - public String getSecret() { - return secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - public int getRecordAssistPort() { - return recordAssistPort; - } - - public void setRecordAssistPort(int recordAssistPort) { - this.recordAssistPort = recordAssistPort; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java index 46ccf2271..ae3bd685b 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java @@ -7,6 +7,8 @@ package com.genersoft.iot.vmp.media.zlm.dto.hook; public class HookParam { private String mediaServerId; + + public String getMediaServerId() { return mediaServerId; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java index 8ac53fff2..b92706237 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerKeepaliveEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.event; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.springframework.context.ApplicationEvent; /** diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java index 4d89c7089..e1c28b1d1 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/event/HookZlmServerStartEvent.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.event; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.springframework.context.ApplicationEvent; /** diff --git a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java index 86ee7b8db..875140f95 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java @@ -1,8 +1,7 @@ package com.genersoft.iot.vmp.service; import com.alibaba.fastjson2.JSONArray; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import com.github.pagehelper.PageInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java index 649c72768..26f1585c8 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java @@ -1,9 +1,7 @@ package com.genersoft.iot.vmp.service; -import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; /** * 媒体信息业务 diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java index 17f890853..79bdf78c9 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlatformService.java @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; import com.github.pagehelper.PageInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java index 9ba4964a7..e856be2b0 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java @@ -8,8 +8,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java index 5f9e4338a..f3b516286 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.common.GeneralCallback; import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java index 8aa5dce27..d7da931da 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service.bean; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import java.util.EventObject; diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/ResponseSendItemMsg.java b/src/main/java/com/genersoft/iot/vmp/service/bean/ResponseSendItemMsg.java index 80b0d7d60..9d733845f 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/ResponseSendItemMsg.java +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/ResponseSendItemMsg.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.service.bean; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; /** * redis消息:下级回复推送信息 diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java index 6907e908d..6ff0746bb 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java @@ -5,12 +5,10 @@ import com.alibaba.fastjson2.JSONObject; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; -import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event; import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; import com.genersoft.iot.vmp.service.ICloudRecordService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index 0d864ad84..8fb772d11 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IInviteStreamService; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index e98076289..8dba01be2 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -12,7 +12,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.service.*; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 48a8fbba6..2cc4f49ad 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -11,15 +11,13 @@ import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.media.event.hook.Hook; import com.genersoft.iot.vmp.media.event.hook.HookData; import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.IPlatformService; import com.genersoft.iot.vmp.service.IPlayService; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 32af05752..c8d6f8625 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -19,7 +19,6 @@ import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.RecordInfo; import com.genersoft.iot.vmp.media.event.hook.Hook; -import com.genersoft.iot.vmp.media.event.hook.HookData; 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; @@ -28,10 +27,7 @@ import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index ee7235513..0669ff37f 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -17,7 +17,7 @@ import com.genersoft.iot.vmp.media.event.media.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index b3c510d0b..652bcdd69 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo; 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.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index d14cea5cc..fd59704f6 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.media.event.hook.Hook; import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java index ecab51f5f..a40896bc9 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index 9cb4d38b5..684fca49f 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java index 7db1dfbf9..22f2ce0ce 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.storager.dao; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import org.apache.ibatis.annotations.*; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java index 4a991f35a..1ea22548d 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.storager.dao; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import org.apache.ibatis.annotations.*; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 62ccf8d89..7e6d1ebf2 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/utils/CloudRecordUtils.java b/src/main/java/com/genersoft/iot/vmp/utils/CloudRecordUtils.java index 2df9bea31..10cb620b9 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/CloudRecordUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/CloudRecordUtils.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.utils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; public class CloudRecordUtils { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java index 6c111597a..da8bbc8ca 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -3,7 +3,7 @@ package com.genersoft.iot.vmp.vmanager.cloudRecord; import com.alibaba.fastjson2.JSONArray; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.ICloudRecordService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index c32c3e5cd..89a772451 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -17,7 +17,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index dc01c4380..f7807b9c9 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -11,8 +11,7 @@ import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index 96b0d4904..7bd231062 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -11,8 +11,7 @@ import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index 780f8a732..a7d604162 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -9,10 +9,8 @@ import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.VersionInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index 89a5f906f..dd5e703a1 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java index 8a5c96ef5..be740c193 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.IPlayService; From b78769f9972b1d8efe59b74868ce6adf7eccc2b6 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Mon, 1 Apr 2024 18:35:26 +0800 Subject: [PATCH 44/58] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/abl/ABLHttpHookListener.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java index e892e6df5..69e6d8cda 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java @@ -14,11 +14,14 @@ import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.media.*; -import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.media.MediaNotFoundEvent; +import com.genersoft.iot.vmp.media.event.media.MediaRtpServerTimeoutEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; -import com.genersoft.iot.vmp.media.zlm.dto.hook.*; +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResult; +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResultForOnPublish; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; @@ -214,7 +217,7 @@ public class ABLHttpHookListener { public HookResult onStreamNotArrive(@RequestBody ABLHookParam param) { - logger.info("[ABL HOOK] 码流不到达通知:{}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration()); + logger.info("[ABL HOOK] 码流不到达通知:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); try { if ("rtp".equals(param.getApp())) { return HookResult.SUCCESS(); @@ -241,7 +244,7 @@ public class ABLHttpHookListener { public HookResult onDeleteRecordMp4(@RequestBody OnRecordMp4ABLHookParam param) { - logger.info("[ABL HOOK] MP4文件被删除通知:{}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration()); + logger.info("[ABL HOOK] MP4文件被删除通知:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); return HookResult.SUCCESS(); From 8b90fade9eb3a62b428f23f2306cb1911c98d355 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 2 Apr 2024 00:05:09 +0800 Subject: [PATCH 45/58] =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8abl?= =?UTF-8?q?=E6=8E=A5=E6=94=B6=E5=9B=BD=E6=A0=87=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/StreamInfo.java | 12 +- .../genersoft/iot/vmp/conf/MediaConfig.java | 18 +- .../request/impl/InviteRequestProcessor.java | 4 +- .../media/abl/ABLMediaNodeServerService.java | 8 +- .../media/abl/ABLMediaServerStatusManger.java | 13 +- ...LMediaServer高性能流媒体服务器使用说明.txt | 1743 +++++++++++++++++ .../iot/vmp/media/abl/ABLRESTfulUtils.java | 191 +- .../vmp/media/abl/bean/hook/ABLHookParam.java | 6 +- .../iot/vmp/media/bean/MediaInfo.java | 19 + .../iot/vmp/media/bean/MediaServer.java | 48 + .../vmp/media/event/hook/HookSubscribe.java | 4 +- .../service/IMediaNodeServerService.java | 2 +- .../media/service/IMediaServerService.java | 4 +- .../service/impl/MediaServerServiceImpl.java | 23 +- .../media/zlm/ZLMMediaNodeServerService.java | 6 +- .../vmp/service/impl/PlatformServiceImpl.java | 2 +- .../iot/vmp/service/impl/PlayServiceImpl.java | 18 +- .../vmp/storager/dao/MediaServerMapper.java | 16 + 数据库/abl/初始化-mysql-2.7.0.sql | 4 + .../abl/初始化-postgresql-kingbase-2.7.0.sql | 4 + 数据库/abl/更新-mysql-2.7.0.sql | 9 + 数据库/abl/更新-postgresql-kingbase-2.7.0.sql | 11 +- 22 files changed, 1964 insertions(+), 201 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServer高性能流媒体服务器使用说明.txt diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index b8d5f186c..f4774393f 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -195,8 +195,7 @@ public class StreamInfo implements Serializable, Cloneable{ } } - public void setFlv(String host, int port, int sslPort, String app, String stream, String callIdParam) { - String file = String.format("%s/%s.live.flv%s", app, stream, callIdParam); + public void setFlv(String host, int port, int sslPort, String file) { if (port > 0) { this.flv = new StreamURL("http", host, port, file); } @@ -207,6 +206,15 @@ public class StreamInfo implements Serializable, Cloneable{ } } + public void setWsFlv(String host, int port, int sslPort, String file) { + if (port > 0) { + this.ws_flv = new StreamURL("ws", host, port, file); + } + if (sslPort > 0) { + this.wss_flv = new StreamURL("wss", host, sslPort, file); + } + } + public void setFmp4(String host, int port, int sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s.live.mp4%s", app, stream, callIdParam); if (port > 0) { diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java index a61154fc8..0dc1ba98a 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java @@ -42,12 +42,24 @@ public class MediaConfig{ @Value("${media.stream-ip:${media.ip}}") private String streamIp; - @Value("${media.http-port}") + @Value("${media.http-port:0}") private Integer httpPort; + @Value("${media.flv-port:0}") + private Integer flvPort = 0; + + @Value("${media.ws-flv-port:0}") + private Integer wsFlvPort = 0; + @Value("${media.http-ssl-port:0}") private Integer httpSSlPort = 0; + @Value("${media.flv-ssl-port:0}") + private Integer flvSSlPort = 0; + + @Value("${media.ws-flv-ssl-port:0}") + private Integer wsFlvSSlPort = 0; + @Value("${media.rtmp-port:0}") private Integer rtmpPort = 0; @@ -208,7 +220,11 @@ public class MediaConfig{ mediaServerItem.setSdpIp(getSdpIp()); mediaServerItem.setStreamIp(getStreamIp()); mediaServerItem.setHttpPort(httpPort); + mediaServerItem.setFlvPort(flvPort); + mediaServerItem.setWsFlvPort(wsFlvPort); mediaServerItem.setHttpSSlPort(httpSSlPort); + mediaServerItem.setFlvSSLPort(flvSSlPort); + mediaServerItem.setWsFlvSSLPort(wsFlvSSlPort); mediaServerItem.setRtmpPort(rtmpPort); mediaServerItem.setRtmpSSlPort(rtmpSSlPort); mediaServerItem.setRtpProxyPort(getRtpProxyPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index c3e5b5960..88fffba0b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -500,7 +500,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements String startTimeStr = DateUtil.urlFormatter.format(start); String endTimeStr = DateUtil.urlFormatter.format(end); String stream = device.getDeviceId() + "_" + channelId + "_" + startTimeStr + "_" + endTimeStr; - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, device.isSsrcCheck(), true, 0,false, false, device.getStreamModeForParam()); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, device.isSsrcCheck(), true, 0,false,!channel.isHasAudio(), false, device.getStreamModeForParam()); sendRtpItem.setStream(stream); // 写入redis, 超时时回复 redisCatchStorage.updateSendRTPSever(sendRtpItem); @@ -530,7 +530,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements } sendRtpItem.setPlayType(InviteStreamType.DOWNLOAD); - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,!channel.isHasAudio(), false, device.getStreamModeForParam()); sendRtpItem.setStream(ssrcInfo.getStream()); // 写入redis, 超时时回复 redisCatchStorage.updateSendRTPSever(sendRtpItem); diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index aaa72ddf3..644be2430 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -14,9 +15,12 @@ import java.util.Map; @Service("abl") public class ABLMediaNodeServerService implements IMediaNodeServerService { + @Autowired + private ABLRESTfulUtils ablresTfulUtils; + @Override - public int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { - return 0; + public int createRTPServer(MediaServer mediaServer, String stream, long ssrc, Integer port, Boolean onlyAuto, Boolean disableAudio, Boolean reUsePort, Integer tcpMode) { + return ablresTfulUtils.openRtpServer(mediaServer, "rtp", stream, 96, port, tcpMode, disableAudio?1:0); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java index 5895ce2a3..cb55695b2 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java @@ -212,15 +212,24 @@ public class ABLMediaServerStatusManger { // if (mediaServerItem.getHttpSSlPort() == 0) { // mediaServerItem.setHttpSSlPort(ablServerConfig.getHttpSSLport()); // } - if (mediaServerItem.getRtmpPort() == 0) { + if (mediaServerItem.getRtmpPort() == 0 && ablServerConfig.getRtmpPort() != null) { mediaServerItem.setRtmpPort(ablServerConfig.getRtmpPort()); } // if (mediaServerItem.getRtmpSSlPort() == 0) { // mediaServerItem.setRtmpSSlPort(ablServerConfig.getRtmpSslPort()); // } - if (mediaServerItem.getRtspPort() == 0) { + if (mediaServerItem.getRtspPort() == 0 && ablServerConfig.getRtspPort() != null) { mediaServerItem.setRtspPort(ablServerConfig.getRtspPort()); } + if (mediaServerItem.getFlvPort() == 0 && ablServerConfig.getHttpFlvPort() != null) { + mediaServerItem.setFlvPort(ablServerConfig.getHttpFlvPort()); + } + if (mediaServerItem.getWsFlvPort() == 0 && ablServerConfig.getWsPort() != null) { + mediaServerItem.setWsFlvPort(ablServerConfig.getWsPort()); + } + if (mediaServerItem.getRtpProxyPort() == 0 && ablServerConfig.getPsTsRecvPort() != null) { + mediaServerItem.setRtpProxyPort(ablServerConfig.getPsTsRecvPort()); + } // if (mediaServerItem.getRtspSSLPort() == 0) { // mediaServerItem.setRtspSSLPort(ablServerConfig.getRtspSSlport()); // } diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServer高性能流媒体服务器使用说明.txt b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServer高性能流媒体服务器使用说明.txt new file mode 100644 index 000000000..9cffc9830 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServer高性能流媒体服务器使用说明.txt @@ -0,0 +1,1743 @@ +一、功能说明 + ABLMediaServer高性能流媒体服务器,windows平台采用高性能的完成端口网络模型、Linux下采用epoll,加上线程池进行媒体数据 + 的接收、转换、发送。服务器的性能强劲、运行稳定,坚如磐石。经过压力测试比较,转发性能、CPU占有率、运行稳定性优势明显 。可 + 以通过ffmpeg命令或者其他标准的rtsp、rtmp推流函数往ABLMediaServer推送rtsp流、rtmp流,请求服务器代理拉流,请求服务器接收国 + 标GB28181。服务器通过转换,输出标准的rtsp码流、rtmp码流、http-flv、ws-flv 码流(支持H265视频输出)、http-mp4(视频支持H264、 + H265,音频支持AAC)、hls码流输出(视频支持H264、H265,音频支持AAC)、GB28181码流(国标PS流 )输出。 + 流媒体服务器支持录像、支持智能录像删除、录像查询、录像文件点播、录像文件极速下载。http-flv、ws-flv、http-mp4 协议点播时 + 支持暂停继续、支持拖动播放。rtsp点播录像文件时支持慢放(1/16、1/8、1/4、1/2),快放(2、4、8、16 )、正常速度、支持拖动播放。 + 流媒体服务器支秒级(基本上1秒以内)图片抓拍,支持对抓拍的图片进行查找,支持抓拍图片以http协议下载。 + 服务器支持H265转码为H264,转码输出视频支持指定分辨率、宽高、码率大小等等参数。Windows平台支持英伟达显卡硬件加速转码。实 + 测linux 平台能最大并发转码40路H265(硬件环境 至强 E5 2650 V3),实测windows 平台能最大并发转码35路H265(i9 + 英伟达 RTX 2080) + Linux 新增支持英伟达专业显卡,支持硬件解码、硬件编码,支持多个显卡同时进行转码。两张特斯拉T4(16G)显卡可以同时把80路1080P + 的H265视频转码为 1280 x 720 的H264,转码延时低于10毫秒,如果需要更强的转码功能可以多插几张显卡或者集群 。 + 服务器支持转码出来的视频打入自定义水印,支持水印的字符内容、字体大小、 字体颜色、字体位置都可以在配置文件中配置。 + 非常感谢ZLMediaKit和Media-Server 两个工程项目的作者,ABLMediaSever参考复用了ZLMediaKit的http请求函数的参数表(请求的URL + 及请求的参数名及一些初始值)以及整个框架的一些设计思想。直接调用了Media-Server 工程的 rtmp、flv、hls、fmp4 复用与解复用等等。 + 非常崇拜与感谢两位大佬为中国的开源流媒体努力与付出,再次感谢。 + + 【欢迎加入高性能流媒体服务QQ群 873666268 】 + +二、ABLMediaServer主要功能 + + 网络协议媒体输入 + rtsp、rtmp外部主动推流输入 + 1、rtsp外部主动推流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + 2、rtmp外部主动推流 (支持 视频:H264、H265 ,音频:AAC) + 3、国标GB28181输入 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + 4、交通运输部jtt1078 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + + rtsp、rtmp、http-flv、本地mp4文件 拉流输入: + 1、rtsp 拉流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + 2、rtmp 拉流 (支持 视频:H264、H265 ,音频:AAC) + 3、http-flv 拉流 (支持 视频:H264、H265 ,音频:AAC) + 4、本地mp4 拉流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + + websock方式私有协议发送PCM数据进入流媒体服务器(可以在浏览器录音通过websocket以下面的私有协议把语音接入流媒体服务器方便国标对讲、或者其他应用比如语音广播) + 1、数据包格式 + 包头 + 数据类型 + 长度 + 数据包 + 包头4个字节 0xAB 0xCD 0xEF 0xAB + 数据类型  1 个字节 ,[ 0x01 推流音频注册 ] [0x02 发送 PCM 音频数据包] [0x03 断开音频推流 ] + 长度   2 个字节 ,网络字节顺序(大端) + 数据包 音频注册包、pcm音频数据包、注销包 + + 2、数据包类型 + 1)、音频注册包 ,json 格式 + {"method":"register","app":"talk","stream":"xian_1","audioCodec":"pcm","channels":1,"sampleRate":16000,"targetAudioCodec":"g711a"} + + 样例:发送音频注册 + websocket 只要连接上来,就首先发送 音频注册包 + (0xAB 0xCD 0xEF 0xAB) + 0x01 + strlen(音频注册包) + {"method":"register","app":"talk","stream":"xian_1","audioCodec":"pcm","channels":1,"sampleRate":16000,"targetAudioCodec":"g711a"} + + 2) 、音频数据包 只支持 16位采样精度的pcm ,单通道、双通道、常见的采样频率都支持(8000、16000、32000、48000) + 样例:现在只发送纯pcm音频数据 + (0xAB 0xCD 0xEF 0xAB) + 0x02 + strlen(pcm纯音频数据) + pcm纯音频数据 + + 3)、注销包 + {"method":"destruction"} + + 样例:发送注销包 + (0xAB 0xCD 0xEF 0xAB) + 0x03 + strlen({"method":"destruction"} ) + {"method":"destruction"} + + 支持用ffmpeg推纯音频流接入流媒体服务器,支持的音频格式有(g711A、G711U、AAC、MP3) + 1、以rtsp协议推本地aac文件接入流媒体 + ffmpeg -re -stream_loop -1 -i F:\music\xxx.aac -c:a aac -rtsp_transport tcp -f rtsp rtsp://190.15.240.11:554/music/aac1 + + 2、以rtmp协议推本地aac文件接入流媒体 + ffmpeg -re -stream_loop -1 -i F:\music\xxx.aac -c:a aac -f flv rtmp://190.15.240.11:1935/music/aac2 + + 3、以rtsp协议推本地mp3文件接入流媒体 + ffmpeg -re -stream_loop -1 -i F:\music\xxx.mp3 -c:a mp3 -rtsp_transport tcp -f rtsp rtsp://190.15.240.11:554/music/aac3 + + 4、以rtmp协议推本地mp3文件接入流媒体 + ffmpeg -re -stream_loop -1 -i F:\music\xxx.mp3 -c:a mp3 -f flv rtmp://190.15.240.11:1935/music/aac4 + + 5、以rtsp协议推本地mp4文件中的纯音频流接入服务器 + 1) 比如推一个视频格式为h264,音频为aac的mp4文件中的音频流进入服务器,那么服务器接收到的音频流为aac ,视频不做推送 + ffmpeg -re -stream_loop -1 -i F:\video\H264_AAC_2021-02-10_1080P.mp4 -vn -acodec copy -rtsp_transport tcp -f rtsp rtsp://44.35.33.39:554/music/aac5 + + 2) 比如推一个视频格式为h264,音频为g711A的mp4文件中的音频流进入服务器,那么服务器接收到的音频流为g711A ,视频不做推送 + ffmpeg -re -stream_loop -1 -i F:\video\H264-G711A-92017.mp4 -vn -acodec copy -rtsp_transport tcp -f rtsp rtsp://44.35.33.39:554/music/aac6 + + 3) 比如推一个视频格式为h264,音频为g711U的mp4文件中的音频流进入服务器,那么服务器接收到的音频流为g711U ,视频不做推送 + ffmpeg -re -stream_loop -1 -i F:\video\H264-G711U-56434.mp4 -vn -acodec copy -rtsp_transport tcp -f rtsp rtsp://44.35.33.39:554/music/aac7 + + 网络协议媒体 输出: + 被动拉流输出 + 1、rtsp (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + 2、rtmp (支持 视频:H264、H265 ,音频:AAC) + 3、GB28181码流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + 4、http-flv (支持 视频:H264、H265 ,音频:AAC) + 5、http-hls (支持 视频:H264、H265 ,音频:AAC) + 6、http-mp4 (支持 视频:H264、H265 ,音频:AAC) + 7、websocket-flv (支持 视频:H264、H265 ,音频:AAC) + 8、webrtc (支持 视频:H264、H265 ,音频:G711A、G711U、OPUS) + 9、交通运输部jtt1078 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + + rtsp、rtmp、gb28181、jtt1078 主动推流输出: + 1、rtsp推流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + 2、rtmp推流 (支持 视频:H264、H265 ,音频:AAC) + 3、GB28181推流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + 4、交通运输部jtt1078 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) + + +三、简明使用例子 + 1) 首先要配置 ABLMediaServer.ini 里面的 本机的IP地址 localipAddress 、recordPath 项。 + + 1 本机的IP地址,最好需要配置准确(如果不配置程序会自动获取一个地址代替,如果本机有多个地址可能会不准确,如果配置则使用配置的IP地址,这样就准确), + 因为调用 getMediaList 获取可用媒体源的json中,会使用到本机的IP地址来拼接 rtsp、rtmp、http-flv、ws-flv、hls、http-mp4 的播放url 。 + 调用 getMediaList 返回的json串中有如下url子项: + "url": { + "rtsp": "rtsp://10.0.0.239:554/Media/Camera_00001", + "rtmp": "rtmp://10.0.0.239:1935/Media/Camera_00001", + "http-flv": "http://10.0.0.239:8088/Media/Camera_00001.flv", + "ws-flv": "ws://10.0.0.239:6088/Media/Camera_00001.flv", + "http-mp4": "http://10.0.0.239:5088/Media/Camera_00001.mp4", + "http-hls": "http://10.0.0.239:9088/Media/Camera_00001.m3u8" + } + + 其中的 10.0.0.239 就是可以从 localipAddress 配置项 精确获取 。 + + 2、录像路径配置 recordPath,如果不需要录像,可以忽略录像路径配置 + # 录像文件保存路径,如果不配置录像文件保存在应用程序所在的路径下的record子路径,如果配置路径则保存在配置的路径的record里面 + # 注意:如果需要录像存储,存储的硬盘千万不要分区,整个硬盘作为一个区,因为服务器没有执行两个以上的盘符操作。 + # 录像保存路径配置 windows平台的路径配置 比如 D:\video ,Linux 平台配置 /home/video + # 录像路径使用了默认路径,就一直使用默认路径,如果使用了配置路径就一直使用配置路径,确保使用的路径的硬盘空间为最大的,如果需要更换路径,要把原来的录像路径的视频全部删除。 + # 1路高清5M的摄像头,如果录像的话,每小时产生2G大小左右的录像文件。可以根据这个来计算需要购买多大的硬盘,接入多少路摄像头,需要设置录像文件最大的保存时间 + + 2)、 媒体输出规则: [network protocol]://[ip]:[port]/[app]/[stream][.extend] + + 【注:如果自己不想拼接播放url ,可以调用http函数 /index/api/getMediaList,返回可播放媒 + 体源中有各种播放协议的url, 详见下面的函数 /index/api/getMediaList 】 + + 说明: + [network protocol] 有 rtsp、rtmp、http、ws + [ip] 就是服务器所在的IP地址 + [port] 各个网络协议分享时设置的端口号,详见 ABLMediaServer.ini 的配置文件,里面有相应的网络协议配置端口 + [app] 各种网络协议发送过来设置的一级名字 + [stream] 各种网络协议发送过来设置的二级名字 + [.extend] 扩展名字,主要为为了访问服务器时,服务器需要识别网络协议需要客户端发送过来的扩展名。 + rtsp、rtmp 不需要扩展名, + http-flv 、ws-flv 扩展名为 .flv + hls 方式访问时, 扩展名为 .m3u8 + http-mp4访问时 扩展名为 .mp4 + + 比如服务器IP为 190.15.240.11 ,app 为 Media ,stream 为 Camera_00001 ,假定端口都是默认 ,那么各种网络访问url如下: + rtsp: + rtsp://190.15.240.11:554/Media/Camera_00001 + + rtmp: + rtmp://190.15.240.11:1935/Media/Camera_00001 + + http-flv: + http://190.15.240.11:8088/Media/Camera_00001.flv + + http-mp4: + http://190.15.240.11:5088/Media/Camera_00001.mp4 + + websocket-flv: + ws://190.15.240.11:6088/Media/Camera_00001.flv + + http-hls: + http://190.15.240.11:9088/Media/Camera_00001.m3u8 + + 3)、使用ffmpeg往 ABLMediaServer 推送rtsp 码流 【假定 源摄像机rtsp RUL为 rtsp://admin:abldyjh2020@192.168.1.120:554 , ABLMediaServer 所在服务器地址为 190.15.240.11 】 + 【推送rtsp方式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 + + ffmpeg -rtsp_transport tcp -i rtsp://admin:abldyjh2020@192.168.1.120:554 -vcodec copy -acodec copy -f rtsp -rtsp_transport tcp rtsp://190.15.240.11:554/Media/Camera_00001 + + 媒体输出: + rtsp: 【rtsp输出格式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 + rtsp://190.15.240.11:554/Media/Camera_00001 + + rtmp: 【rtmp输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + rtmp://190.15.240.11:1935/Media/Camera_00001 + + http-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + http://190.15.240.11:8088/Media/Camera_00001.flv + + ws-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + ws://190.15.240.11:6088/Media/Camera_00001.flv + + http-hls: 【http-hls输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + http://190.15.240.11:9088/Media/Camera_00001.m3u8 + + 4)、使用ffmpeg往 ABLMediaServer 推送rtmp 码流 【假定 源摄像机rtsp RUL为 rtsp://admin:abldyjh2020@192.168.1.120:554 , ABLMediaServer 所在服务器地址为 190.15.240.11 】 + 【推送rtmp方式说明:视频支持 H264 ,音频支持AAC 】 + + ffmpeg -rtsp_transport tcp -i rtsp://admin:abldyjh2020@192.168.1.120:554 -acodec copy -vcodec copy -f flv rtmp://190.15.240.11:1935/Media/Camera_00001 + + rtsp: 【rtsp输出格式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 + rtsp://190.15.240.11:554/Media/Camera_00001 + + rtmp: 【rtmp输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + rtmp://190.15.240.11:1935/Media/Camera_00001 + + http-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + http://190.15.240.11:8088/Media/Camera_00001.flv + + ws-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + ws://190.15.240.11:6088/Media/Camera_00001.flv + + http-hls: 【http-hls输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + http://190.15.240.11:9088/Media/Camera_00001.m3u8 + + 5)、使用ffmpeg往 ABLMediaServer 推送rtsp的文件码流 【假定媒体文件为:F:\video\MP4有声音\H264_AAC_2021-02-10_1080P.mp4 , ABLMediaServer 所在服务器地址为 190.15.240.11 】 + 【推送rtsp方式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 + + ffmpeg -re -stream_loop -1 -i F:\video\MP4有声音\H264_AAC_2021-02-10_1080P.mp4 -vcodec copy -acodec copy -rtsp_transport tcp -f rtsp rtsp://190.15.240.11:554/Media/Camera_00001 + + 媒体输出: + rtsp: 【rtsp输出格式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 + rtsp://190.15.240.11:554/Media/Camera_00001 + + rtmp: 【rtmp输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + rtmp://190.15.240.11:1935/Media/Camera_00001 + + http-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + http://190.15.240.11:8088/Media/Camera_00001.flv + + ws-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + ws://190.15.240.11:6088/Media/Camera_00001.flv + + http-hls: 【http-hls输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 + http://190.15.240.11:9088/Media/Camera_00001.m3u8 + + 【特别注明:可以往10000 的udp端口推送TS码流,推送成功后,可以调用 http函数getMediaList来获取接入的rtp码流 】 + ffmpeg.exe -re -stream_loop -1 -i F:\video\H264_20191021094432.mp4 -vcodec copy -f rtp_mpegts rtp://127.0.0.1:100000 + + + 6)、流媒体输出播放验证 + 如果视频是rtsp方式,可以采用VLC进行播放验证  +     如果rtmp、http-flv 协议,视频为h264 ,可以采用VLC播放验证、或者B站的 flv.js 播放器验证 + 如果rtmp、http-flv 协议,视频为h265 ,可以采用EasyPlayer.js 播放器验证,【注:VLC 、flv.js 不支持Rtmp的H265视频、也不支持http-flv的265视频 】 + + 7)、申请代理rtsp、rtmp、flv 拉流 、本地mp4文件 ,申请删除代理拉流 + 1) 申请代理rtsp、rtmp、flv 拉流、本地mp4文件 + + URL: /index/api/addStreamProxy + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + vhost 比如 _defaultVhost_ + app 应用名 比如 Media + stream 媒体流名 比如 Camera_00001 【/app/stream 组合起来不能重复】 + url 代理拉流url 比如 rtsp://admin:abldyjh2020@192.168.1.120:554 或者 + rtmp://190.15.240.36:1935/Media/Camera_00001 或者 + http://190.15.240.36:8088/Media/Camera_00001.flv 或者 + d:\\video\\xxxx.mp4 (windows平台) + /home/video/xxxx.mp4 (Linux平台) + isRtspRecordURL 代理拉流的url是否是rtsp录像回放的url 默认0 ,1 是【可选参数】,如果是rtsp录像回放的url,可以进行控制代理拉流,比如 暂停、继续、控制倍速播放,拖动播放等等 ,参考 + 函数 /index/api/controlStreamProxy + optionsHeartbeat options心跳 options 命令作为心跳包 【可选参数】 代理rtsp拉流成后,是否开启发送 0 不开启, 1 开启 ,默认不开启,如果从 ZLMediaKit 拉取rtsp流,建议设置为 1 + enable_mp4 是否录像 1 录像,0 不录像 【可选参数】 + enable_hls 是否hls切片 1 进行hls 切片 ,0 不切片 【可选参数】 + convertOutWidth 转码宽 转码输出宽 如果指定宽、高 【可选参数】[1920 x 1080, 1280 x 720 ,960 x 640 ,800 x 480 ,720 x 576 , 720 x 480 ,640 x 480 ,352 x 288 ] 就说明 H265 进行转码为 H264 + convertOutHeight 转码高 转码输出高 如果指定宽、高 【可选参数】[1920 x 1080, 1280 x 720 ,960 x 640 ,800 x 480 ,720 x 576 , 720 x 480 ,640 x 480 ,352 x 288 ] 就说明 H265 进行转码为 H264 + H264DecodeEncode_enable H264是否解码 H264分辨率高再编码降分辨率,【可选参数】有时候需要H264视频进行先解码再重新编码降低分辨率,可以设置 H264DecodeEncode_enable 为 1 ,降下来的分辨率为 convertOutWidth 、 convertOutHeight + disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 + disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 + + http GET 方式 + 1 请求rtsp拉流样例 + http://190.15.240.11:7088/index/api/addStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001&url=rtsp://admin:abldyjh2020@192.168.1.120:554&enable_mp4=0 + + http POST 方式 + 1 请求rtsp拉流样例 + http请求 url 样例 + http://190.15.240.11:7088/index/api/addStreamProxy + body 参数 , json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","url":"rtsp://admin:abldyjh2020@192.168.1.120:554","enable_mp4":0} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 + "key": 93 # 成功时返回大于0的值,为代理拉流的Key ,删除代理拉流时需要用的 + } + + 2) 控制代理拉流,比如 暂停、继续、控制倍速播放,拖动播放等等 + URL: /index/api/controlStreamProxy + + 参数: + secret 服务器密码 ,比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 比如 93 ,调用 addStreamProxy 返回的 key 的值 + command 比如 pause、resume、seek、scale 对于对应意思:暂停、继续、拖动播放、倍速播放 + value (字符串) 比如 1、2、4、8、16(倍速播放) ,npt方式:360、1800、3600(拖动播放),clock方式:clock=20230625T113000Z-19700101T000001Z(拖动到:2023-06-25 11:30:00执行播放) + value 为可选参数,当 command 为 pause,resume 时,value 不用 ,当 command 为seek,sacale + 是,需要填写value的值 + 命令、值样例列表 + command value 注释 + pause 不需要 暂停回放 + resume 不需要 继续回放 + scale 2 2倍速回放 + seek 360 拖拽从开始点计算起到360秒处再回放 【ntp方式拖拽 ,代表 华为 VCN\3800 】 + seek clock=20230625T113000Z-19700101T000001Z 拖拽到20230625T113000Z处再回放 【clock方式拖拽 ,代表 海康NVR 】 + + http GET 方式 + http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=pause 暂停 + http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=resume 继续 + http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=scale&value=2 2倍速回放 + http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=seek&value=360 拖拽到360秒处继续回放 + http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=seek&value=clock=20230625T113000Z-19700101T000001Z + + http POST 方式 + http URL : + http://190.15.240.11:7088/index/api/controlStreamProxy + + body 参数 Json格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"pause"} + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"resume"} + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"sacale","value":"2"} + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"seek","value":"360"} + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"seek","value":"clock=20230625T113000Z-19700101T000001Z"} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 【注:发送http请求 可以使用curl、postman、或者其他标准的http工具 】 + + + 3) 申请删除代理rtsp、rtmp、flv 拉流 + URL: /index/api/delStreamProxy + + 参数: + secret 服务器密码 ,比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 比如 93 ,调用 addStreamProxy 返回的 key 的值 + + http GET 方式 + http://190.15.240.11:7088/index/api/delStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 + + http POST 方式 + http URL : + http://190.15.240.11:7088/index/api/delStreamProxy + + body 参数 Json格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 【注:发送http请求 可以使用curl、postman、或者其他标准的http工具 】 + + + + 8)、申请代理rtsp、rtmp、推流 、申请删除代理拉流 + 1) 申请代理rtsp、rtmp 推流(注意:不是国标GB28181推流) + + URL: /index/api/addPushProxy + + 参数: 参数说明 参考值 + secret 服务器密码 , 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + vhost 比如 _defaultVhost_ + app 应用名 比如 Media + stream 媒体流名 比如 Camera_00001 + url 代理推流url 比如 rtsp://190.15.240.36:554/Media/Camera_00001 或者 rtmp://190.15.240.36:1935/Media/Camera_00001 + disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 + disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 + + http GET 方式 + http://190.15.240.11:7088/index/api/addPushProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001&url=rtsp://190.15.240.36:554/Media/Camera_00001 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/addPushProxy + + http Body 参数 (json格式) + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","url":"rtsp://190.15.240.36:554/Media/Camera_00001"} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 + "key": 93 # 成功时返回大于0的值,为代理推流的Key ,删除代理推流时需要用的 + } + + 2) 申请删除代理rtsp、rtmp 推流 + URL: /index/api/delPushProxy + + 参数: 参数说明 参数参考值 + secret 服务器密码 , 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 主键ID 比如 93 ,调用 /index/api/addPushProxy 返回的 key 的值 + + http GET 方式 + http://190.15.240.11:7088/index/api/delPushProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/delPushProxy + + http Body json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 9)、创建GB28181\Jtt1078接收端口、删除GB28181\Jtt1078接收端口、国标暂停、继续 + + 1 创建GB28181\Jtt1078接收端口 + + URL: /index/api/openRtpServer + 功能: + 创建GB28181\Jtt1078接收端口,如果该端口接收超时,会自动回收,不用调用 /index/api/closeRtpServer + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + vhost 比如 _defaultVhost_ + app 应用名 比如 gb28181 、rtp 等等 (接入) + stream_id 媒体流名 比如 44030012343220234234 (最好是国标编号)( 接入 ) + payload PS负载值 国标SDP里面PS负载值 ,比如 96,98 ,108 ,一定要从国标SDP里面获取 + port 端口号 0 ,由服务器自动分配,别的值 比如 26324 为指定端口 + enable_tcp 是否为tcp 0 为 udp , 1 为tcp被动方式 ,2 为tcp主动连接方式 + dst_url 目标IP 目标IP地址 【可选参数 ,当 enable_tcp 为 2 时必须填写 】 + dst_port 目标端口 目标端口 【可选参数 ,当 enable_tcp 为 2 时必须填写】 + + enable_mp4 是否录像 1 录像,0 不录像 【可选参数】 + enable_hls 是否hls切片 1 进行hls 切片 ,0 不切片 【可选参数】 + convertOutWidth 转码宽 转码输出宽 如果指定宽、高 【可选参数】[1920 x 1080, 1280 x 720 ,960 x 640 ,800 x 480 ,720 x 576 , 720 x 480 ,640 x 480 ,352 x 288 ] 就说明 H265 进行转码为 H264 + convertOutHeight 转码高 转码输出高 如果指定宽、高 【可选参数】[1920 x 1080, 1280 x 720 ,960 x 640 ,800 x 480 ,720 x 576 , 720 x 480 ,640 x 480 ,352 x 288 ] 就说明 H265 进行转码为 H264 + H264DecodeEncode_enable H264是否解码 H264分辨率高再编码降分辨率,【可选参数】有时候需要H264视频进行先解码再重新编码降低分辨率,可以设置 H264DecodeEncode_enable 为 1 ,降下来的分辨率为 convertOutWidth 、 convertOutHeight + RtpPayloadDataType rtp打包数据格式 rtp打包数据格式 【可选参数 ,默认 1 】 [1 PS 国标gb28181 ]、[ 2 ES 视频支持 H246\H265,音频只支持G711A、G711U ]、[3 XHB (一家公司的打包格式) 只支持视频,音频不能加入打包 ] [ 4 、Jt1078(2016版本)码流接入 ] + disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 + disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 + jtt1078_version 指定1078版本号 2013、2016、2019 【可选参数】 2013 指定为 2013版本 、2016 指定为 2016版本、 2019 指定为 2019 版本 + + send_app 应用名 比如 gb28181 、rtp 等等 【可选参数】 用于把本服务器的码流(send_app/send_stream_id)回复给发送端 + send_stream_id 媒体流名 比如 44030012343220234234 【可选参数】 用于把本服务器的码流(send_app/send_stream_id)回复给发送端 + send_disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 + send_disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 + detectSendAppStream 是否检测发送流ID 0 不检测 ,1 检测 【可选参数】 默认 1 在需要回传码流时,事先检测 send_app、send_stream_id 是否存在。0 不检测,先打开接收成功后,稍后再把send_app、send_stream_id接入流媒体,openRtpServer函数自动回复给下级流媒体。 + + http GET 方式 + http://190.15.240.11:7088/index/api/openRtpServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=gb28181&stream_id=44030012343220234234&payload=96&port=0&enable_tcp=0&enable_mp4=0 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/openRtpServer + + http 参数值 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream_id":"Camera_00001","payload":96,"port":0,"enable_tcp":0,"enable_mp4":0} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "port": 8356, # 端口号 + "memo": "success", # success 为成功 + "key": 93 # 成功时返回大于0的值,GB28181接收实例key ,关闭时需要 + } + + 2 删除 GB28181\Jtt1078接收端口 + URL: /index/api/closeRtpServer + 功能: + 删除GB28181\Jtt1078接收端口 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 主键值ID 比如 93 , 调用 /index/api/openRtpServer 返回的 key 的值 + + http GET 方式 + http://190.15.240.11:7088/index/api/closeRtpServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/closeRtpServer + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 3 暂停 GB28181\Jtt1078接收端口,只是不检测接收端口是否有码流进入。 + URL: /index/api/pauseRtpServer + 功能: + 暂停GB28181\Jtt1078接收 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 主键值ID 比如 93 , 调用 /index/api/openRtpServer 返回的 key 的值 + + http GET 方式 + http://44.35.33.249:7088/index/api/pauseRtpServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=588 + + http POST 方式 + http URL + http://44.35.33.249:7088/index/api/pauseRtpServer + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":588} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 4 继续 GB28181\Jtt1078接收端口,开启检测端口是否有码流到达,如果时长到达最大超时没有码流进入会立即删除接收端口 + URL: /index/api/resumeRtpServer + 功能: + 继续GB28181\Jtt1078接收 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 主键值ID 比如 93 , 调用 /index/api/openRtpServer 返回的 key 的值 + + http GET 方式 + http://44.35.33.249:7088/index/api/resumeRtpServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=588 + + http POST 方式 + http URL + http://44.35.33.249:7088/index/api/resumeRtpServer + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":588} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 10)、创建GB28181\Jtt1078 发送端口、删除GB28181\Jtt1078发送端口 + + 1 创建GB28181\Jtt1078发送端口 + + URL: /index/api/startSendRtp + 功能: + 创建GB28181\Jtt1078发送端口,如果该发送端端口没有数据发送,会自动回收,不用调用 /index/api/stopSendRtp + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + vhost 比如 _defaultVhost_ + app 应用名 比如 gb28181 、rtp 等等 (发送出去) + stream 媒体流名 比如 44030012343220234234 (发送出去) + payload PS负载值 国标SDP里面PS负载值 ,比如 96,98 ,108 ,rtp打包时需要 + ssrc 同步源 ssrc + src_port 发送端绑定的端口号 指定服务器在发送国标流时绑定的端口号,如果为 0 ,由服务器自动分配,别的值 比如 26324 为指定端口 + dst_url 目标IP 目标IP地址 + dst_port 目标端口 目标端口 + is_udp 是否设置udp 0 TCP主动方式,1 udp 方式 ,2 为 TCP 被动方式 + RtpPayloadDataType rtp打包数据格式 【可选参数 ,默认 1 】 [ 1 PS 国标gb28181 ]、[ 2 ES 视频支持 H246\H265,音频只支持G711A、G711U ]、[3 XHB (一家公司的打包格式) 只支持视频,音频不能加入打包 ] [ 4 、Jt1078(2016版本)码流发送 ] + disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 + disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 + jtt1078_version 指定1078版本号 2013、2016、2019 【可选参数】 2013 指定为 2013版本 、2016 指定为 2016版本、 2019 指定为 2019 版本 + + recv_app 应用名 比如 gb28181 、rtp 等等 【可选参数】 接入进来 通过在发送的连接中接收进来的码流 + recv_stream 媒体流名 比如 44030012343220234234 【可选参数】 接入进来 通过在发送的连接中接收进来的码流 + recv_disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 + recv_disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 + + http GET 方式 + http://190.15.240.11:7088/index/api/startSendRtp?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=gb28181&stream=44030012343220234234&payload=96&ssrc=5224&src_port=26324&dst_url=190.15.240.11&dst_port=9824&is_udp=1 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/startSendRtp + + http 参数值 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","payload":96,"ssrc":2432,"src_port":26324,"dst_url":"190.15.240.11","dst_port":9824,"is_udp":1} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "port": 8356, # 端口号 + "memo": "success", # success 为成功 + "key": 93 # 成功时返回大于0的值,GB28181发送码流实例key ,关闭时需要 + } + + 2 删除 GB28181\Jtt1078发送端口 + URL: /index/api/stopSendRtp + 功能: + 删除GB28181\Jtt1078发送端口 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 主键值ID 比如 93 , 调用 /index/api/startSendRtp 返回的 key 的值 + + http GET 方式 + http://190.15.240.11:7088/index/api/stopSendRtp?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/stopSendRtp + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 11)、获取流媒体服务器所有可用的媒体源 + URL: /index/api/getMediaList + + 功能: + 获取流媒体服务器所有媒体源 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【可选参数】 + stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【可选参数】 + + 参数填写样例说明: + 样例1(app、stream 都不填写) + secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc + + 返回所有在线的媒体源 + + 样例2 (只填写 app ) + secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc + app rtp + 返回 app 等于 rtp 的所有媒体源 + + 样例3 (填写 app = rtp , stream = 44303403343034243200234) + secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc + app rtp + stream 44303403343034243200234 + 返回 app 等于 rtp、并且 stream 等于 44303403343034243200234 的所有媒体源 + + 样例4 (填写 stream = 44303403343034243200234) + secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc + stream 44303403343034243200234 + 返回 stream 等于 44303403343034243200234 的所有媒体源 + + http GET 方式 + http://127.0.0.1:7088/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/getMediaList + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} + + 返回Body: + { + "code": 0, + "memo": "success", + "mediaList": [ + { + "key": 34, + "app": "Media", + "stream": "Camera_00001", + "sim": "123456789123", 【1078码流接入这个字段的值不会为空,代表设备的sim卡编码 】 + "status": false , 【 false 尚未录像,true 正在录像 】 + "enable_hls": false, 【 false 尚未启用,true 启用hls回放 】 + "transcodingStatus": false, 【 false 尚未转码,true 正在转码 】 + "sourceURL": "rtsp://10.0.0.239:554/Media/Camera_00001", + "sourceType": 23, + "readerCount": 0, + "videoCodec": "H264", + "width": 1920, + "height": 1080, + "networkType": 24, + "audioCodec": "AAC", + "audioChannels": 1, + "audioSampleRate": 16000, + "url": { + "rtsp": "rtsp://10.0.0.239:554/Media/Camera_00001", + "rtmp": "rtmp://10.0.0.239:1935/Media/Camera_00001", + "http-flv": "http://10.0.0.239:8088/Media/Camera_00001.flv", + "ws-flv": "ws://10.0.0.239:6088/Media/Camera_00001.flv", + "http-mp4": "http://10.0.0.239:5088/Media/Camera_00001.mp4", + "http-hls": "http://10.0.0.239:9088/Media/Camera_00001.m3u8", + "webrtc":"http://10.0.0.239:8892/webrtc-streamer.html?video=/Media/Camera_00001" + } + } + ] + } + + 【注释:可以根据 "networkType": 24, 这个字段值区分 媒体接入的类型 ,具体详见网络类型的对照表 】 + + 12) 删除 某一个媒体源 + URL: /index/api/delMediaStream + 功能: + 某一个媒体源,这媒体源,可以是rtp推流、rtmp推流,各种方式代理拉流接入的,国标接入 等等。 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 主键值ID 比如 93 , 调用 /index/api/getMediaList 返回的 key 的值 + + http GET 方式 + http://190.15.240.11:7088/index/api/delMediaStream?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/delMediaStream + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 13)、获取流媒体服务器所有往外部输出码流列表,包括外部请求的rtsp、rtmp、http-flv、ws-flv、hls 列表 + 也包括服务器代理rtsp推流、rtmp推流列表 + 也包括服务器以国标方式往上级推rtp流列表 + 【必要时可以调用 /index/api/delOutList 接口删除某一个列表对象,比如删除某一路国标推流、删除某一路rtsp推流、 删除某一路rtmp推流】 + URL: /index/api/getOutList + + 功能: + 获取流媒体服务器所有输出流列表 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http GET 方式 + http://44.35.33.239:7088/index/api/getOutList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http POST 方式 + http URL + http://44.35.33.239:7088/index/api/getOutList + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} + + 返回Body: + { + "code": 0, + "memo": "success", + "outList": [ + { + "key": 103, 【请求客户端的标识ID ,可以调用 /index/api/delOutList 删除 该请求】 + "app": "Media", + "stream": "Camera_00001", + "sourceURL": "rtsp://44.35.33.239:554/Media/Camera_00001", 【表示外界以rtsp方式向服务器请求码流】 + "videoCodec": "H264", + "audioCodec": "AAC", + "audioChannels": 1, + "audioSampleRate": 16000, + "networkType": 24, 【网络类型为24 ,标识为rtsp 方式】 + "dst_url": "44.35.33.39", 【 请求码流客户端IP 】 + "dst_port": 43801 【 请求码流客户端端口 】 + }, + { + "key": 85, 【请求客户端的标识ID ,可以调用 /index/api/delOutList 删除 该请求】 + "app": "Media", + "stream": "Camera_00001", + "sourceURL": "http://localhost:8088/Media/Camera_00001.flv",【表示外界以 http-flv 方式向服务器请求码流】 + "videoCodec": "H264", + "audioCodec": "AAC", + "audioChannels": 1, + "audioSampleRate": 16000, + "networkType": 25, 【网络类型为25 ,标识为 http-flv 方式】 + "dst_url": "44.35.33.39", 【 请求码流客户端IP 】 + "dst_port": 43806 【 请求码流客户端端口 】 + } + ] + } + + 【注释:可以根据 "networkType": 24, 这个字段值区分 媒体输出的类型 ,具体详见网络类型的对照表 】 + + 14) 删除 某一个服务器所有往外部输出码流列表 + URL: /index/api/delOutList + 功能: + 删除某一个流媒体服务器所有往外部输出码流列表,包括外部请求的rtsp、rtmp、http-flv、ws-flv、hls 点播 。国标推流、rtsp推流、rtmp 推流 等等 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + key 主键值ID 比如 93 , 调用 /index/api/getOutList 返回的 key 的值 + + http GET 方式 + http://190.15.240.11:7088/index/api/delOutList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/delOutList + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 ,如果失败是其他值 + } + + 15)根据条件组合,删除任意一个或一组或者全部媒体输入列表 + URL: /index/api/close_streams + + 功能 + 删除任意一个或一组或者全部媒体输入列表 + + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + vhost 比如 _defaultVhost_ 【可选参数】 + app 应用名 比如 gb28181 、rtp 等等 【可选参数】 + stream 媒体流名 比如 Camera_00001、dsafdsafassdafadsfas、等等 【可选参数】 + force 是否强制关闭 1 强制关闭,不管是否有人在观看、0 非强制关闭,当有人观看时不关闭。 【必填参数】 + + http GET 方式 + 示例1: http://190.168.24.112:7088/index/api/close_streams?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=live&force=1 + 【表示强行关闭 app 等于 live 的码流接入】 + 示例2: http://190.168.24.112:7088/index/api/close_streams?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=live&stream=Camera_00001&force=1 + 【表示强行关闭 app 等于 live, 并且 stream 等于 Camera_00001 的码流接入 】 + 示例3: http://190.168.24.112:7088/index/api/close_streams?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&force=1 + 【表示强行关闭 所有码流(app全部、stream全部) 接入 】 + + http pos 方式 + 示例1: http URL: + http://190.168.24.112:7088/index/api/close_streams + body: + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","app":"live","force":1} + + 【表示强行关闭 app 等于 live 的码流接入】 + + 示例2: http URL: + http://190.168.24.112:7088/index/api/close_streams + body: + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","app":"live","stream":"Camera_00001","force":1} + + 【表示强行关闭 app 等于 live, 并且 stream 等于 Camera_00001 的码流接入 】 + + 示例3: http URL: + http://190.168.24.112:7088/index/api/close_streams + body: + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","force":1} + + 【 表示强行关闭 所有码流(app全部、stream全部) 接入 】 + + 16)、 开始录像、停止录像 + 1) 申请开始录像 + + URL: /index/api/startRecord + + 参数: 参数说明 参考值 + secret 服务器密码 ,比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + vhost 比如 _defaultVhost_ + app 应用名 比如 Media + stream 媒体流名 比如 Camera_00001 + + http GET 方式 + http://190.15.240.11:7088/index/api/startRecord?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/startRecord + + http Body 参数 (json格式) + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001"} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "MediaSource: /Media/Camera_00001 start Record", # "code": 0 为成功 + } + + 2) 申请停止录像 + URL: /index/api/stopRecord + + 参数: 参数说明 参考值 + secret 服务器密码 ,比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + vhost 比如 _defaultVhost_ + app 应用名 比如 Media + stream 媒体流名 比如 Camera_00001 + + http GET 方式 + http://190.15.240.11:7088/index/api/stopRecord?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/stopRecord + + http Body 参数 (json格式) + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001"} + + 返回Body: + { + "code": 0, # 0为操作成功,其他值为操作失败 + "memo": "success", # success 为成功 + } + + 17 获取系统配置参数 + URL: /index/api/getServerConfig + 功能: + 获取服务器的配置参数 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http GET 方式 + http://190.15.240.11:7088/index/api/getServerConfig?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/getServerConfig + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} + + 返回Body: + { + "code": 0, + "params": [ + + { + "secret": "035c73f7-bb6b-4889-a715-d9eb2d1925cc", + "memo": "server password", + }, + { + "ServerIP": "44.35.33.239", + "memo": "ABLMediaServer ip address" + }, + { + "rtc.listening-ip": "192.168.2.5", + "memo": "Total number of video playback threads ." + }, + { + "mediaServerID": "ABLMediaServer_00001", + "memo": "media Server ID " + }, + { + "hook_enable": 0, + "memo": "hook_enable = 1 open notice , hook_enable = 0 close notice " + }, + { + "enable_audio": 1, + "memo": "enable_audio = 1 open Audio , enable_audio = 0 Close Audio " + }, + { + "httpServerPort": 7088, + "memo": "http api port " + }, + { + "rtspPort": 554, + "memo": "rtsp port " + }, + { + "rtmpPort": 1935, + "memo": "rtmp port " + }, + { + "httpFlvPort": 8088, + "memo": "http-flv port " + }, + { + "hls_enable": 0, + "memo": "hls whether enable " + }, + { + "hlsPort": 9088, + "memo": "hls port" + }, + { + "wsPort": 6088, + "memo": "websocket flv port" + }, + { + "mp4Port": 5088, + "memo": "http mp4 port" + }, + { + "ps_tsRecvPort": 10000, + "memo": "recv ts , ps Stream port " + }, + { + "hlsCutType": 2, + "memo": "hlsCutType = 1 hls cut to Harddisk,hlsCutType = 2 hls cut Media to memory" + }, + { + "h265CutType": 1, + "memo": " 1 h265 cut TS , 2 cut fmp4 " + }, + { + "RecvThreadCount": 128, + "memo": " RecvThreadCount " + }, + { + "SendThreadCount": 128, + "memo": "SendThreadCount" + }, + { + "GB28181RtpTCPHeadType": 2, + "memo": "rtp Length Type" + }, + { + "ReConnectingCount": 40320, + "memo": "Try reconnections times ." + }, + { + "maxTimeNoOneWatch": 9999999, + "memo": "maxTimeNoOneWatch ." + }, + { + "pushEnable_mp4": 0, + "memo": "pushEnable_mp4 ." + }, + { + "fileSecond": 180, + "memo": "fileSecond ." + }, + { + "fileKeepMaxTime": 1, + "memo": "fileKeepMaxTime ." + }, + { + "httpDownloadSpeed": 6, + "memo": "httpDownloadSpeed ." + }, + { + "RecordReplayThread": 32, + "memo": "Total number of video playback threads ." + } + ] + } + + 18)、查询录像列表 + URL: /index/api/queryRecordList + + 功能: + 查询某一路输入源的录像列表(可以查询代理拉流输入、推流输入、国标输入等等 ) + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + vhost 比如 _defaultVhost_ 【可选参数】 + app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【必填参数】 + stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【必填参数】 + starttime 开始时间 比如 20220116154810 年月日时分秒 【必填参数】 + endtime 结束时间 比如 20220116155115 年月日时分秒 【必填参数】 + + 【注意:1、开始时间必须小于 当前时间减去切片时长的时间 2、从 开始时间 至 结束时间 不能超过3天】 + + http GET 方式 + http://10.0.0.239:7088/index/api/queryRecordList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=Media&stream=Camera_00001&starttime=20220116154810&endtime=20220116155115 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/queryRecordList + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","starttime":"20220116154810","endtime":"20220116155115"} + + 返回Body: + { + "code": 0, + "app": "Media", + "stream": "Camera_00001", + "starttime": "20220116154810", + "endtime": "20220116155115", + "recordFileList": [ + { + "file": "20220116154810.mp4", + "duration": 300, 当前录像时间长度,单位 秒 + "url": { + "rtsp": "rtsp://10.0.0.239:554/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810", + "rtmp": "rtmp://10.0.0.239:1935/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810", + "http-flv": "http://10.0.0.239:8088/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810.flv", + "ws-flv": "ws://10.0.0.239:6088/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810.flv", + "http-mp4": "http://10.0.0.239:5088/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810.mp4?download_speed=1", + "download": "http://10.0.0.239:5088/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810.mp4?download_speed=6" + } + }, + { + "file": "20220116155110.mp4", + "duration": 256, 当前录像时间长度,单位 秒 + "url": { + "rtsp": "rtsp://10.0.0.239:554/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110", + "rtmp": "rtmp://10.0.0.239:1935/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110", + "http-flv": "http://10.0.0.239:8088/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110.flv", + "ws-flv": "ws://10.0.0.239:6088/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110.flv", + "http-mp4": "http://10.0.0.239:5088/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110.mp4?download_speed=1", + "download": "http://10.0.0.239:5088/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110.mp4?download_speed=6" + } + } + ] + } + 19)、消息通知使用 + 功能说明:消息通知是流媒体服务器的一些消息比如无人观看、fmp4录像切片完成、播放时流地址不存在等等信息能及时的通知到另外一个http服务器上,需要此功能 + 消息通知功能用在什么地方,比如说无人观看消息通知,当收到无人观看消息时,国标服务器可以关闭国标发流,断开代理拉流,断开推流等等操作 + 要使用此功能把配置文件的参数hook_enable 值设置为 1,同时通知的http服务器地址、端口号一定要设置对,下面列举出配置文件中的相关参数 + + hook_enable=1 #事件通知部分,当 hook_enable=1 时,开启事件通知,hook_enable=0时关闭事件通知 + on_stream_arrive=http://10.0.0.238:7088/index/hook/on_stream_arrive #当某一路的码流达到时会通知一次 + on_stream_none_reader=http://10.0.0.238:8080/index/hook/on_stream_none_reader #当某一路流无人观看时,会触发该通知事件,接收端收到后可以进行断流操作 + on_stream_disconnect=http://10.0.0.238:7088/index/hook/on_stream_disconnect #当某一路码流断开时会通知一次 + on_stream_not_found=http://10.0.0.238:8080/index/hook/on_stream_not_found #播放时,找不到播放的码流,通过配合on_stream_none_reader事件可以完成按需拉流 + on_record_mp4=http://10.0.0.238:8080/index/hook/on_record_mp4 #录制完毕一段mp4文件通知 + + 【注:http url的 IP,端口 是代表消息接收服务器的IP,端口,一定要填写正确,url 地址要合法,不要有空格 】 + 1、当某一路码流到达时会发送通知: + POST /index/hook/on_stream_arrive HTTP/1.1 # 根据 /index/hook/on_stream_arrive 这个可以判断是某一路码流到达 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 105 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-5.2.9(2022-03-28) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + { + "app":"Media", # app + "stream":"Camera_00001", # stream + "mediaServerId":"ABLMediaServer_00001", # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 + "networkType":23, # 媒体流来源网络编号,可参考附表 + "key":130, # 媒体流来源编号,可以根据这个key进行关闭流媒体 可以调用delMediaStream或close_streams 函数进行关闭 + "status":true, + "enable_hls":false, + "transcodingStatus":false, + "sourceURL":"rtsp://admin:abldyjh2020@44.35.33.248:554", + "readerCount":0, + "noneReaderDuration":0, + "videoCodec":"H265", + "videoFrameSpeed":25, + "width":1920, + "height":1080, + "videoBitrate":0, + "audioCodec":"AAC", + "audioChannels":1, + "audioSampleRate":8000, + "audioBitrate":0, + "url": + { + "rtsp":"rtsp://44.35.33.249:554/Media/Camera_00001", + "rtmp":"rtmp://44.35.33.249:1935/Media/Camera_00001", + "http-flv":"http://44.35.33.249:8088/Media/Camera_00001.flv", + "ws-flv":"ws://44.35.33.249:6088/Media/Camera_00001.flv", + "http-mp4":"http://44.35.33.249:5088/Media/Camera_00001.mp4", + "http-hls":"http://44.35.33.249:9088/Media/Camera_00001.m3u8" + } + } + + 2、无人观看消息通知样例: + POST /index/hook/on_stream_none_reader HTTP/1.1 # 根据 /index/hook/on_stream_none_reader 这个可以判断是无人观看消息通知 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 105 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-5.2.9(2022-03-28) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + { + "app":"Media", # app + "stream":"Camera_00001", # stream + "mediaServerId":"ABLMediaServer_00001", # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 + "networkType":23, # 媒体流来源网络编号,可参考附表 + "key":130 # 媒体流来源编号,可以根据这个key进行关闭流媒体 可以调用delMediaStream或close_streams 函数进行关闭 + } + + 3、 fmp4录像切片录像完成一个文件时会发送一个消息通知 + POST /index/hook/on_record_mp4 HTTP/1.1 # 根据 /index/hook/on_record_mp4 这个可以判断是mp4录像切片完毕一个通知 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 127 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-5.2.9(2022-03-28) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + { + "app":"Media", # app + "stream":"Camera_00001", # stream + "mediaServerId":"ABLMediaServer_00001", # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 + "networkType":70, # 媒体流来源网络编号,可参考附表 + "fileName":"20220312212546.mp4" # 录像切片完成的文件名字 + } + + 4、当某一路码流断开时会发送通知: + POST /index/hook/on_stream_disconnect HTTP/1.1 # 根据 /index/hook/on_stream_disconnect 这个可以判断是某一路码流断开 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 105 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-5.2.9(2022-03-28) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + { + "app":"Media", # app + "stream":"Camera_00001", # stream + "mediaServerId":"ABLMediaServer_00001", # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 + "networkType":23, # 媒体流来源网络编号,可参考附表 + "key":130 # 媒体流来源编号,可以根据这个key进行关闭流媒体 可以调用delMediaStream或close_streams 函数进行关闭 + } + + 5、 当播放一个url,如果不存在时,会发出一个消息通知 + POST /index/hook/on_stream_not_found HTTP/1.1 # 根据 /index/hook/on_stream_not_found ,Http接收服务器得知流不不存在 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 127 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-5.2.9(2022-03-28) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + { + "app":"Media", # app 不存在的app + "stream":"Camera_00001", # stream 不存在的stream + "mediaServerId":"ABLMediaServer_00001" # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 + } + 6、ABLMediaServer启动时会发送上线通知 + POST /index/hook/on_server_started HTTP/1.1 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 105 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-6.3.5(2023-04-30) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + {"localipAddress":"44.35.33.249","mediaServerId":"ABLMediaServer_00001","datetime":"2023-04-18 10:04:37"} + + 7、某一个码流接入流媒体服务器时会产生 发布 事件通知 + POST /index/hook/on_publish HTTP/1.1 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 149 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-6.3.5(2023-04-30) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","networkType":50,"key":470,"ip":"44.35.33.248" ,"port":554,"params":""} + + 8、当播放流媒体服务器里面某一个码流时,会触发 播放事件 ,可以通知 parmas 参数值进行播放鉴权 + POST /index/hook/on_play HTTP/1.1 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 135 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-6.3.5(2023-04-30) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","networkType":30,"key":472,"ip":"" ,"port":0,"params":"user=admin&password=safsa234234&token=@#$@#$@#ASDFasfdsa@#$23"} + + 9、如果某一个码流进行MP4录像(enable_mp4=1),会触发录像进度通知事件 + POST /index/hook/on_record_progress HTTP/1.1 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 204 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-6.3.5(2023-04-30) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","networkType":472,"key":470,"fileName":"20230418100440.mp4","currentFileDuration":49,"TotalVideoDuration":49} + + 10、如果某一个码流开启hls(enable_hls=1)并且设置为切片到硬盘(hlsCutType=1 在配置文件中) ,每当切片完成一个ts文件会触发该事件 + POST /index/hook/on_record_ts HTTP/1.1 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 246 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-6.3.5(2023-04-30) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","networkType":30,"key":470,"createDateTime":"2023-04-18 10:05:47","currentFileDuration":3,"fileName":"D:\WorkDir\ABLMediaServer\x64\Debug\www\Media\Camera_00001\23.ts"} + + 11、流媒体服务器每隔60秒会触发心跳事件通知 + POST /index/hook/on_server_keepalive HTTP/1.1 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 105 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-6.3.5(2023-04-30) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + {"localipAddress":"44.35.33.249","mediaServerId":"ABLMediaServer_00001","datetime":"2023-04-18 10:25:40"} + + 12、当代理拉流、国标接入等等 码流不到达时会发出 码流不到达的事件通知 + POST /index/hook/on_stream_not_arrive HTTP/1.1 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 155 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-6.3.5(2023-04-30) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + {"mediaServerId":"ABLMediaServer_00001","app":"gb28181","stream":"440300123432202342349","networkType":60,"key":470} + + 13、如果某一个码流进行MP4录像(enable_mp4=1),当某个MP4文件被删除会触发该事件通知 + POST /index/hook/on_delete_record_mp4 HTTP/1.1 + Accept: */* + Accept-Language: zh-CN,zh;q=0.8 + Connection: keep-alive + Content-Length: 204 + Content-Type: application/json + Host: 127.0.0.1 + Tools: ABLMediaServer-6.3.5(2023-04-30) + User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 + + {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","fileName":"20230418100440.mp4"} + + + + 20) 图片抓拍 + URL: /index/api/getSnap + + 功能: + 查询某一接入的媒体源进行抓拍 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + vhost 比如 _defaultVhost_ 【可选参数】 + app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【必填参数】 + stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【必填参数】 + timeout_sec 超时时长 10 即本次抓拍最大超时时长 单位 秒 【必填参数】 + + http GET 方式 + http://127.0.0.1:7088/index/api/getSnap?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001&timeout_sec=10 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/getSnap + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","timeout_sec":10} + + 抓拍成功返回: + { + "code": 0, + "memo": "success , Catpuring takes time 219 millisecond .", + "url": "http://10.0.0.239:7088/Media/Camera_00001/2022031910034501.jpg" + } + + 21)图片列表查询 + URL: /index/api/queryPictureList + + 功能: + 查询某一路输入源的抓拍图片列表 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + vhost 比如 _defaultVhost_ 【可选参数】 + app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【必填参数】 + stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【必填参数】 + starttime 开始时间 比如 20220317081201 年月日时分秒 【必填参数】 + endtime 结束时间 比如 20220319231201 年月日时分秒 【必填参数】 + + 【注意:1、开始时间必须小于 当前时间减去切片时长的时间 2、从 开始时间 至 结束时间 不能超过7天】 + + http GET 方式 + http://10.0.0.239:7088/index/api/queryPictureList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=Media&stream=Camera_00001&starttime=20220317081201&endtime=20220319231201 + + http POST 方式 + http URL + http://190.15.240.11:7088/index/api/queryPictureList + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","starttime":"20220317081201","endtime":"20220319231201"} + + 成功返回Body值 + { + "code": 0, + "app": "Media", + "stream": "Camera_00001", + "starttime": "20220317081201", + "endtime": "20220319231201", + "PictureFileList": [ + { + "file": "2022031816153857.jpg", + "url": "http://10.0.0.239:7088/Media/Camera_00001/2022031816153857.jpg" + }, + { + "file": "2022031816153958.jpg", + "url": "http://10.0.0.239:7088/Media/Camera_00001/2022031816153958.jpg" + }, + { + "file": "2022031816154059.jpg", + "url": "http://10.0.0.239:7088/Media/Camera_00001/2022031816154059.jpg" + }, + ] + } + + 22、修改某一路的水印相关参数 + + URL: index/api/setTransFilter + + 功能: + 修改某一路的水印相关参数,比水印的内容、颜色、字体大小、字体位置、字体透明度 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + vhost 比如 _defaultVhost_ 【可选参数】 + app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【必填参数】 + stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【必填参数】 + text 水印内容 比如 某某市某某公安局 【必填参数】 + size 字体大小 20、30 、40 、50 【必填参数】 + color 字体颜色 red,green,blue,white,black, + alpha 透明度 0.1 ~ 0.9 , + left 水印x坐标 比如 5 、 10 、20 + top 水印y坐标 比如 5 、 10 、 20 + trans 是否转换 固定为 1 + + http POST 方式 + http://127.0.0.1:7088/index/api/setTransFilter + + Body 参数内容为 + { + "secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc", + "app" : "live", + "stream" : "test", + "text" : "ABL", + "size" : 60, + "color" : "red", + "alpha" : 0.8, + "left" : 40, + "top" : 40, + "trans" : 1 + } + + 23、为了功能更新的需要,增加设置参数值的接口,可以单独设置 ABLMediaServer.ini 的某一个值,并且服务器不用重启,立即起效 + + URL: index/api/setConfigParamValue + + 功能: + 为了功能更新的需要,增加设置参数值的接口,可以单独设置 ABLMediaServer.ini 的某一个值,并且服务器不用重启,立即起效 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + vhost 比如 _defaultVhost_ 【可选参数】 + key 参数名 比如 saveGB28181Rtp (保存接入的国标PS流)、 saveProxyRtspRtp (保存rtsp代理拉流的rtp流) + 还有 ABLMediaServer.ini 里面的配置参数,如果参数值不填就设置空,不是空格 + mediaServerID = ABLMediaServer_00001 + secret = 035c73f7-bb6b-4889-a715-d9eb2d1925cc + localipAddress = + maxTimeNoOneWatch = 9999999 + recordPath = + picturePath = + maxSameTimeSnap = 16 + snapOutPictureWidth = 0 + snapOutPictureHeight = 0 + snapObjectDestroy = 1 + snapObjectDuration = 120 + captureReplayType = 1 + pictureMaxCount = 30 + pushEnable_mp4 = 0 + fileSecond = 300 + videoFileFormat = 1 + fileKeepMaxTime = 3 + httpDownloadSpeed = 6 + fileRepeat = 0 + H265ConvertH264_enable = 0 + H265DecodeCpuGpuType = 0 + H264DecodeEncode_enable = 0 + filterVideo_enable = 0 + filterVideo_text = ABL水印测试123 + FilterFontSize = 30 + FilterFontColor = red + FilterFontLeft = 5 + FilterFontTop = 5 + FilterFontAlpha = 0.6 + convertOutWidth = 720 + convertOutHeight = 480 + convertMaxObject = 26 + convertOutBitrate = 1024 + hook_enable = 0 + noneReaderDuration = 15 + on_server_started = http://10.0.0.238:4088/index/hook/on_server_started + on_server_keepalive = http://10.0.0.238:4088/index/hook/on_server_keepalive + on_stream_arrive = http://10.0.0.238:4088/index/hook/on_stream_arrive + on_stream_not_arrive = http://10.0.0.238:4088/index/hook/on_stream_not_arrive + on_stream_none_reader = http://10.0.0.238:4088/index/hook/on_stream_none_reader + on_stream_disconnect = http://10.0.0.238:4088/index/hook/on_stream_disconnect + on_stream_not_found = + on_record_mp4 = http://10.0.0.238:4088/index/hook/on_record_mp4 + on_delete_record_mp4 = http://10.0.0.238:4088/index/hook/on_delete_record_mp4 + on_record_progress = http://10.0.0.238:4088/index/hook/on_record_progress + on_record_ts = http://10.0.0.238:4088/index/hook/on_record_ts + httpServerPort = 7088 + rtspPort = 554 + rtmpPort = 1935 + httpMp4Port = 5088 + wsFlvPort = 6088 + httpFlvPort = 8088 + ps_tsRecvPort = 10000 + hls_enable = 0 + hlsPort = 9088 + hlsCutTime = 3 + hlsCutType = 2 + h265CutType = 1 + enable_audio = 1 + G711ConvertAAC = 0 + IOContentNumber = 16 + ThreadCountOfIOContent = 8 + RecvThreadCount = 128 + SendThreadCount = 128 + RecordReplayThread = 32 + GB28181RtpTCPHeadType = 2 + ReConnectingCount = 40320 + MaxDiconnectTimeoutSecond = 36 + ForceSendingIFrame = 1 + value 参数值 详见 ABLMediaServer.ini 的参数值及参数值说明 + + http GET 方式 +   比如: + 打开保存国标PS标志 +    http://44.35.33.239:7088/index/api/setConfigParamValue?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=saveGB28181Rtp&value=1 + 关闭存国标PS标志 +    http://44.35.33.239:7088/index/api/setConfigParamValue?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=saveGB28181Rtp&value=0 + + 打开保存代理拉rtsp流标志 +    http://44.35.33.239:7088/index/api/setConfigParamValue?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=saveProxyRtspRtp&value=1 + 关闭保存代理拉rtsp流标志 +    http://44.35.33.239:7088/index/api/setConfigParamValue?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=saveProxyRtspRtp&value=0 + + 24)安全停止服务器 + URL: /index/api/shutdownServer + + 功能: + 安全停止服务器,如果服务器正在录像、抓拍等等操作,需要调用该函数安全停止服务器,这样录制的mp4才能正常播放 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + + http GET 方式 + http://127.0.0.1:7088/index/api/shutdownServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http POST 方式 + http URL + http://127.0.0.1:7088/index/api/shutdownServer + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} + + 返回Body: + { + "code": 0, + "memo": "ABLMediaServer shutdown Successed !" + } + + 25)重新启动服务器 + URL: /index/api/restartServer + + 功能: + 安全重启服务器,如果服务器正在录像、抓拍等等操作,需要调用该函数安全重启服务器,这样录制的mp4才能正常播放 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + + http GET 方式 + http://127.0.0.1:7088/index/api/restartServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http POST 方式 + http URL + http://127.0.0.1:7088/index/api/restartServer + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} + + 返回Body: + { + "code": 0, + "memo": "ABLMediaServer restartServer Successed ! " + } + + 26)获取当前转码的数量 + URL: /index/api/getTranscodingCount + + 功能: + 获取当前正在转码的数量 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + + http GET 方式 + http://127.0.0.1:7088/index/api/getTranscodingCount?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http POST 方式 + http URL + http://127.0.0.1:7088/index/api/getTranscodingCount + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} + + 返回Body: + { + "code": 0, + "currentTranscodingCount": 2 + } + + 27)、列举流媒体服务器所有占用端口 + URL: /index/api/listServerPort + + 功能: + 列举流媒体服务器所有占用端口 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【可选参数】 + stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【可选参数】 + + 参数填写样例说明: + 样例1(app、stream 都不填写) + secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc + + 返回所有在线的媒体源 + + 样例2 (只填写 app ) + secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc + app rtp + 返回 app 等于 rtp 的所有媒体源 + + 样例3 (填写 app = rtp , stream = 44303403343034243200234) + secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc + app rtp + stream 44303403343034243200234 + 返回 app 等于 rtp、并且 stream 等于 44303403343034243200234 的所有媒体源 + + 样例4 (填写 stream = 44303403343034243200234) + secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc + stream 44303403343034243200234 + 返回 stream 等于 44303403343034243200234 的所有媒体源 + + http GET 方式 + http://127.0.0.1:7088/index/api/listServerPort?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc + + http POST 方式 + http URL + http://127.0.0.1:7088/index/api/listServerPort + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} + + 返回Body: + { + "code": 0, + "memo": "success", + "data": [ + { + "key": 478, + "app": "Media", + "stream": "Camera_00003", + "networkType": 23, + "port": 34988 + }, + { + "key": 477, + "app": "Media", + "stream": "Camera_00002", + "networkType": 23, + "port": 34986 + }, + { + "key": 476, + "app": "Media", + "stream": "Camera_00001", + "networkType": 23, + "port": 34984 + }, + { + "key": 456, + "app": "", + "stream": "", + "networkType": 68, + "port": 10000 + } + ] + } + + 【注释:可以根据 "networkType": 23, 这个字段标识对象的网络类型 ,具体详见网络类型的对照表 】 + + 28)、批量设置服务器的配置参数 + URL: /index/api/setServerConfig + + 功能: + 批量设置服务器的配置参数 + + 参数: 参数说明 参数参考值 + secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 + noneReaderDuration 多少秒无人观看通知一次 20 【可选参数】 + on_server_started 服务器启动通知 http://10.0.0.238:4088/index/hook/on_server_started 【可选参数】 + iframeArriveNoticCount i帧达到通知总数 30 【可选参数】 + + http GET 方式 + http://127.0.0.1:7088/index/api/setServerConfig?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&noneReaderDuration=20&on_server_started=http://10.0.0.238:4088/index/hook/on_server_started&iframeArriveNoticCount=30 + + http POST 方式 + http URL + http://127.0.0.1:7088/index/api/setServerConfig + + http Body 参数 json 格式 + {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","noneReaderDuration":20,"iframeArriveNoticCount":30,"on_server_started":"http://10.0.0.238:4088/index/hook/on_server_started"} + + 29) 为了方便某些特殊场合,服务器支持udp的10000 端口接入国标PS码流,就是人们常说的单端口模式,url的命名规则为 /rtp/ssrc ,其中ssrc为下级rtp打包 + 的16进制的值转换为大小的字符串,即可sprintf(url,"rtp/%X",ssrc) ,具体接入的url名字可以调用 getMediaList 查询出接入的国标流 。需要注意的是 + 下级 rtp 打包时每路视频的rtp中的ssrc不能相同。 + + + 30) 网络类型的对照表 + 1 媒体输入网络类型对照表 + + 整形值 代表意义 + 21 以rtmp方式推送接入流媒体服务器 + 23 以rtsp方式推送接入流媒体服务器 + 30 服务器以rtsp方式主动拉流接入 + 31 服务器以rtmp方式主动拉流接入 + 32 服务器以flv方式主动拉流接入 + 33 服务器以hls方式主动拉流接入 + 50 代理拉流接入服务器 + 60 服务器以国标28181的UDP方式接入 + 61 服务器以国标28181的TCP方式接入 + + 80 服务器录像文件点播以读取fmp4文件输入 + 81 服务器录像文件点播以读取TS文件输入 + 82 服务器录像文件点播以读取PS文件输入 + 83 服务器录像文件点播以读取FLV文件输入 + + 2 媒体输出网络类型对照表 + 整形值 代表意义 + 22 服务器以rtsp被动方式往外发送码流 ,即常见的vlc点播 + 24 服务器以rtmp被动方式往外发送码流 ,即常见的vlc点播 + 25 服务器以flv被动方式往外发送码流 ,即常见的vlc点播 、浏览器播放 + 26 服务器以hls被动方式往外发送码流 ,即常见的vlc点播 、浏览器播放 + 27 服务器以ws-flv被动方式往外发送码流 ,EasyPlayer.js插件播放、浏览器播放 + 28 服务器以http-mp4被动方式往外发送码流 ,即常见的vlc点播 、浏览器播放 + + 40 服务器以rtsp主动方式往外发送码流 ,即常见的rtsp推流 + 41 服务器以rtmp主动方式往外发送码流 ,即常见的rtmp推流 + 65 服务器以国标GB28181主动UDP方式往外发送码流 ,即常见的国标以UDP方式往上级推流 + 66 服务器以国标GB28181主动TCP方式往外发送码流 ,即常见的国标以TCP方式往上级推流 + \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java index b2f360290..5eca3bf91 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java @@ -270,67 +270,38 @@ public class ABLRESTfulUtils { } } - public JSONObject getMediaList(MediaServer mediaServerItem, String app, String stream, String schema, RequestCallback callback){ + + public Integer openRtpServer(MediaServer mediaServer, String app, String stream, int payload, Integer port, Integer tcpMode, Integer disableAudio) { Map param = new HashMap<>(); - if (app != null) { - param.put("app",app); + param.put("vhost", "_defaultVhost_"); + param.put("app", app); + param.put("stream_id", stream); + param.put("payload", payload); + if (port != null) { + param.put("port", port); } - if (stream != null) { - param.put("stream",stream); + if (tcpMode != null) { + param.put("enable_tcp", tcpMode); } - if (schema != null) { - param.put("schema",schema); + if (disableAudio != null) { + param.put("disableAudio", disableAudio); + } + + JSONObject jsonObject = sendPost(mediaServer, "openRtpServer", param, null); + if (jsonObject.getInteger("code") == 0) { + return jsonObject.getInteger("port"); + }else { + return 0; } - param.put("vhost","__defaultVhost__"); - return sendPost(mediaServerItem, "getMediaList",param, callback); } - public JSONObject getMediaList(MediaServer mediaServerItem, String app, String stream){ - return getMediaList(mediaServerItem, app, stream,null, null); - } - - public JSONObject getMediaList(MediaServer mediaServerItem, RequestCallback callback){ - return sendPost(mediaServerItem, "getMediaList",null, callback); - } - - public JSONObject getMediaInfo(MediaServer mediaServerItem, String app, String schema, String stream){ + public JSONObject closeStreams(MediaServer mediaServerItem, String app, String stream) { Map param = new HashMap<>(); - param.put("app",app); - param.put("schema",schema); - param.put("stream",stream); - param.put("vhost","__defaultVhost__"); - return sendPost(mediaServerItem, "getMediaInfo",param, null); - } - - public JSONObject getRtpInfo(MediaServer mediaServerItem, String stream_id){ - Map param = new HashMap<>(); - param.put("stream_id",stream_id); - return sendPost(mediaServerItem, "getRtpInfo",param, null); - } - - public JSONObject addFFmpegSource(MediaServer mediaServerItem, String src_url, String dst_url, Integer timeout_ms, - boolean enable_audio, boolean enable_mp4, String ffmpeg_cmd_key){ - logger.info(src_url); - logger.info(dst_url); - Map param = new HashMap<>(); - param.put("src_url", src_url); - param.put("dst_url", dst_url); - param.put("timeout_ms", timeout_ms); - param.put("enable_mp4", enable_mp4); - param.put("ffmpeg_cmd_key", ffmpeg_cmd_key); - return sendPost(mediaServerItem, "addFFmpegSource",param, null); - } - - public JSONObject delFFmpegSource(MediaServer mediaServerItem, String key){ - Map param = new HashMap<>(); - param.put("key", key); - return sendPost(mediaServerItem, "delFFmpegSource",param, null); - } - - public JSONObject delStreamProxy(MediaServer mediaServerItem, String key){ - Map param = new HashMap<>(); - param.put("key", key); - return sendPost(mediaServerItem, "delStreamProxy",param, null); + param.put("vhost", "__defaultVhost__"); + param.put("app", app); + param.put("stream", stream); + param.put("force", 1); + return sendPost(mediaServerItem, "close_streams",param, null); } public JSONObject getServerConfig(MediaServer mediaServerItem){ @@ -343,116 +314,4 @@ public class ABLRESTfulUtils { param.put("value", value); return sendGet(mediaServerItem,"setConfigParamValue", param); } - - public JSONObject openRtpServer(MediaServer mediaServerItem, Map param){ - return sendPost(mediaServerItem, "openRtpServer",param, null); - } - - public JSONObject closeRtpServer(MediaServer mediaServerItem, Map param) { - return sendPost(mediaServerItem, "closeRtpServer",param, null); - } - - public void closeRtpServer(MediaServer mediaServerItem, Map param, RequestCallback callback) { - sendPost(mediaServerItem, "closeRtpServer",param, callback); - } - - public JSONObject listRtpServer(MediaServer mediaServerItem) { - return sendPost(mediaServerItem, "listRtpServer",null, null); - } - - public JSONObject startSendRtp(MediaServer mediaServerItem, Map param) { - return sendPost(mediaServerItem, "startSendRtp",param, null); - } - - public JSONObject startSendRtpPassive(MediaServer mediaServerItem, Map param) { - return sendPost(mediaServerItem, "startSendRtpPassive",param, null); - } - - public JSONObject startSendRtpPassive(MediaServer mediaServerItem, Map param, RequestCallback callback) { - return sendPost(mediaServerItem, "startSendRtpPassive",param, callback); - } - - public JSONObject stopSendRtp(MediaServer mediaServerItem, Map param) { - return sendPost(mediaServerItem, "stopSendRtp",param, null); - } - - public JSONObject restartServer(MediaServer mediaServerItem) { - return sendPost(mediaServerItem, "restartServer",null, null); - } - - public JSONObject addStreamProxy(MediaServer mediaServerItem, String app, String stream, String url, boolean enable_audio, boolean enable_mp4, String rtp_type) { - Map param = new HashMap<>(); - param.put("vhost", "__defaultVhost__"); - param.put("app", app); - param.put("stream", stream); - param.put("url", url); - param.put("enable_mp4", enable_mp4?1:0); - param.put("enable_audio", enable_audio?1:0); - param.put("rtp_type", rtp_type); - return sendPost(mediaServerItem, "addStreamProxy",param, null, 20); - } - - public JSONObject closeStreams(MediaServer mediaServerItem, String app, String stream) { - Map param = new HashMap<>(); - param.put("vhost", "__defaultVhost__"); - param.put("app", app); - param.put("stream", stream); - param.put("force", 1); - return sendPost(mediaServerItem, "close_streams",param, null); - } - - public JSONObject getAllSession(MediaServer mediaServerItem) { - return sendPost(mediaServerItem, "getAllSession",null, null); - } - - public void kickSessions(MediaServer mediaServerItem, String localPortSStr) { - Map param = new HashMap<>(); - param.put("local_port", localPortSStr); - sendPost(mediaServerItem, "kick_sessions",param, null); - } - - public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { - Map param = new HashMap<>(3); - param.put("url", streamUrl); - param.put("timeout_sec", timeout_sec); - param.put("expire_sec", expire_sec); - sendGetForImg(mediaServerItem, "getSnap", param, targetPath, fileName); - } - - public JSONObject pauseRtpCheck(MediaServer mediaServerItem, String streamId) { - Map param = new HashMap<>(1); - param.put("stream_id", streamId); - return sendPost(mediaServerItem, "pauseRtpCheck",param, null); - } - - public JSONObject resumeRtpCheck(MediaServer mediaServerItem, String streamId) { - Map param = new HashMap<>(1); - param.put("stream_id", streamId); - return sendPost(mediaServerItem, "resumeRtpCheck",param, null); - } - - public JSONObject connectRtpServer(MediaServer mediaServerItem, String dst_url, int dst_port, String stream_id) { - Map param = new HashMap<>(1); - param.put("dst_url", dst_url); - param.put("dst_port", dst_port); - param.put("stream_id", stream_id); - return sendPost(mediaServerItem, "connectRtpServer",param, null); - } - - public JSONObject updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { - Map param = new HashMap<>(1); - param.put("ssrc", ssrc); - param.put("stream_id", streamId); - return sendPost(mediaServerItem, "updateRtpServerSSRC",param, null); - } - - public JSONObject deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { - Map param = new HashMap<>(1); - param.put("vhost", "__defaultVhost__"); - param.put("app", app); - param.put("stream", stream); - param.put("period", date); - param.put("name", fileName); - return sendPost(mediaServerItem, "deleteRecordDirectory",param, null); - } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java index 8662085a6..796935ea8 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java @@ -21,7 +21,7 @@ public class ABLHookParam { /** * 媒体流来源网络编号,可参考附表 */ - private String networkType; + private Integer networkType; public String getMediaServerId() { return mediaServerId; @@ -55,11 +55,11 @@ public class ABLHookParam { this.key = key; } - public String getNetworkType() { + public Integer getNetworkType() { return networkType; } - public void setNetworkType(String networkType) { + public void setNetworkType(Integer networkType) { this.networkType = networkType; } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java index 2853cd2a6..8ee0eaf32 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.media.abl.bean.hook.OnStreamArriveABLHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; @@ -186,6 +187,24 @@ public class MediaInfo { mediaInfo.setReaderCount(param.getReaderCount()); mediaInfo.setOnline(true); mediaInfo.setVideoCodec(param.getVideoCodec()); + switch (param.getNetworkType()) { + case 21: + mediaInfo.setOriginType(OriginType.RTMP_PUSH.ordinal()); + break; + case 23: + mediaInfo.setOriginType(OriginType.RTSP_PUSH.ordinal()); + break; + case 30: + case 31: + case 32: + case 33: + mediaInfo.setOriginType(OriginType.PULL.ordinal()); + break; + default: + mediaInfo.setOriginType(OriginType.UNKNOWN.ordinal()); + break; + + } mediaInfo.setWidth(param.getWidth()); mediaInfo.setHeight(param.getHeight()); mediaInfo.setAudioCodec(param.getAudioCodec()); diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java index 5c32ea7af..decbd4e80 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java @@ -32,6 +32,18 @@ public class MediaServer { @Schema(description = "RTMP端口") private int rtmpPort; + @Schema(description = "flv端口") + private int flvPort; + + @Schema(description = "https-flv端口") + private int flvSSLPort; + + @Schema(description = "ws-flv端口") + private int wsFlvPort; + + @Schema(description = "wss-flv端口") + private int wsFlvSSLPort; + @Schema(description = "RTMPS端口") private int rtmpSSlPort; @@ -98,7 +110,11 @@ public class MediaServer { sdpIp = ObjectUtils.isEmpty(zlmServerConfig.getSdpIp())? zlmServerConfig.getIp(): zlmServerConfig.getSdpIp(); streamIp = ObjectUtils.isEmpty(zlmServerConfig.getStreamIp())? zlmServerConfig.getIp(): zlmServerConfig.getStreamIp(); httpPort = zlmServerConfig.getHttpPort(); + flvPort = zlmServerConfig.getHttpPort(); + wsFlvPort = zlmServerConfig.getHttpPort(); httpSSlPort = zlmServerConfig.getHttpSSLport(); + flvSSLPort = zlmServerConfig.getHttpSSLport(); + wsFlvSSLPort = zlmServerConfig.getHttpSSLport(); rtmpPort = zlmServerConfig.getRtmpPort(); rtmpSSlPort = zlmServerConfig.getRtmpSslPort(); rtpProxyPort = zlmServerConfig.getRtpProxyPort(); @@ -328,4 +344,36 @@ public class MediaServer { public void setType(String type) { this.type = type; } + + public int getFlvPort() { + return flvPort; + } + + public void setFlvPort(int flvPort) { + this.flvPort = flvPort; + } + + public int getFlvSSLPort() { + return flvSSLPort; + } + + public void setFlvSSLPort(int flvSSLPort) { + this.flvSSLPort = flvSSLPort; + } + + public int getWsFlvPort() { + return wsFlvPort; + } + + public void setWsFlvPort(int wsFlvPort) { + this.wsFlvPort = wsFlvPort; + } + + public int getWsFlvSSLPort() { + return wsFlvSSLPort; + } + + public void setWsFlvSSLPort(int wsFlvSSLPort) { + this.wsFlvSSLPort = wsFlvSSLPort; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java index 345cc48a6..335365688 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java @@ -35,7 +35,7 @@ public class HookSubscribe { @Async("taskExecutor") @EventListener public void onApplicationEvent(MediaArrivalEvent event) { - if ("rtsp".equals(event.getSchema())) { + if (event.getSchema() == null || "rtsp".equals(event.getSchema())) { sendNotify(HookType.on_media_arrival, event); } @@ -47,7 +47,7 @@ public class HookSubscribe { @Async("taskExecutor") @EventListener public void onApplicationEvent(MediaDepartureEvent event) { - if ("rtsp".equals(event.getSchema())) { + if (event.getSchema() == null || "rtsp".equals(event.getSchema())) { sendNotify(HookType.on_media_departure, event); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 397704575..4b6b2215e 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -10,7 +10,7 @@ import java.util.List; import java.util.Map; public interface IMediaNodeServerService { - int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); + int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean disableAudio, Boolean reUsePort, Integer tcpMode); void closeRtpServer(MediaServer mediaServer, String streamId); diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 2b11c033c..2a72eb433 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -33,9 +33,7 @@ public interface IMediaServerService { void updateVmServer(List mediaServerItemList); SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, - boolean isPlayback, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); - - SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto); + boolean isPlayback, Integer port, Boolean onlyAuto, Boolean disableAudio, Boolean reUsePort, Integer tcpMode); void closeRTPServer(MediaServer mediaServerItem, String streamId); diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index add9d9499..1b5d109e8 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -132,7 +132,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public SSRCInfo openRTPServer(MediaServer mediaServer, String streamId, String presetSsrc, boolean ssrcCheck, - boolean isPlayback, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { + boolean isPlayback, Integer port, Boolean onlyAuto, Boolean disableAudio, Boolean reUsePort, Integer tcpMode) { if (mediaServer == null || mediaServer.getId() == null) { logger.info("[openRTPServer] 失败, mediaServer == null || mediaServer.getId() == null"); return null; @@ -163,19 +163,13 @@ public class MediaServerServiceImpl implements IMediaServerService { logger.info("[openRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); return null; } - rtpServerPort = mediaNodeServerService.createRTPServer(mediaServer, streamId, ssrcCheck ? Long.parseLong(ssrc) : 0, port, onlyAuto, reUsePort, tcpMode); + rtpServerPort = mediaNodeServerService.createRTPServer(mediaServer, streamId, ssrcCheck ? Long.parseLong(ssrc) : 0, port, onlyAuto, disableAudio, reUsePort, tcpMode); } else { rtpServerPort = mediaServer.getRtpProxyPort(); } return new SSRCInfo(rtpServerPort, ssrc, streamId); } - @Override - public SSRCInfo openRTPServer(MediaServer mediaServer, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto) { - return openRTPServer(mediaServer, streamId, ssrc, ssrcCheck, isPlayback, port, onlyAuto, null, 0); - } - - @Override public void closeRTPServer(MediaServer mediaServer, String streamId) { if (mediaServer == null) { @@ -770,7 +764,18 @@ public class MediaServerServiceImpl implements IMediaServerService { String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + + + if ("abl".equals(mediaServer.getType())) { + String flvFile = String.format("%s/%s.flv%s", app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaServer.getFlvPort(),mediaServer.getFlvSSLPort(), flvFile); + streamInfoResult.setWsFlv(addr, mediaServer.getWsFlvPort(),mediaServer.getWsFlvSSLPort(), flvFile); + }else { + String flvFile = String.format("%s/%s.live.flv%s", app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaServer.getFlvPort(),mediaServer.getFlvSSLPort(), flvFile); + streamInfoResult.setWsFlv(addr, mediaServer.getWsFlvPort(),mediaServer.getWsFlvSSLPort(), flvFile); + } + streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 5b566d80c..8fbe5303d 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -39,7 +39,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { private String sipIp; @Override - public int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { + public int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean disableAudio, Boolean reUsePort, Integer tcpMode) { return zlmServerFactory.createRTPServer(mediaServer, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode); } @@ -178,7 +178,9 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); + String flvFile = String.format("%s/%s.live.flv%s", app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile); + streamInfoResult.setWsFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile); streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 2cc4f49ad..e4ddb1206 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -542,7 +542,7 @@ public class PlatformServiceImpl implements IPlatformService { } else { tcpMode = 0; } - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, ssrcCheck, false, null, true, false, tcpMode); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, ssrcCheck, false, null, true, false, false, tcpMode); if (ssrcInfo == null || ssrcInfo.getPort() < 0) { logger.info("[国标级联] 发起语音喊话 开启端口监听失败, platform: {}, channel: {}", platform.getServerGBId(), channelId); SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult<>(); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index c8d6f8625..5c6bca2f8 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -259,7 +259,7 @@ public class PlayServiceImpl implements IPlayService { ); SSRCInfo ssrcInfo = mediaServerService.openRTPServer(event.getMediaServer(), event.getStream(), null, - device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); + device.isSsrcCheck(), true, 0, false, !deviceChannel.isHasAudio(), false, device.getStreamModeForParam()); playBack(event.getMediaServer(), ssrcInfo, deviceId, channelId, startTime, endTime, null); } } @@ -321,7 +321,7 @@ public class PlayServiceImpl implements IPlayService { } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, false, device.getStreamModeForParam()); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.isHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, @@ -762,6 +762,12 @@ public class PlayServiceImpl implements IPlayService { throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到设备:" + deviceId); } + DeviceChannel channel = channelService.getOne(deviceId, channelId); + if (channel == null) { + logger.warn("[录像回放] 未找到通道 deviceId: {},channelId:{}", deviceId, channelId); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到通道:" + channelId); + } + MediaServer newMediaServerItem = getNewMediaServerItem(device); if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE") && ! newMediaServerItem.isRtpEnable()) { logger.warn("[录像回放] 单端口收流时不支持TCP主动方式收流 deviceId: {},channelId:{}", deviceId, channelId); @@ -774,7 +780,7 @@ public class PlayServiceImpl implements IPlayService { .replace(":", "") .replace(" ", ""); String stream = deviceId + "_" + channelId + "_" + startTimeStr + "_" + endTimeTimeStr; - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, !channel.isHasAudio(), false, device.getStreamModeForParam()); playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, callback); } @@ -959,6 +965,10 @@ public class PlayServiceImpl implements IPlayService { if (device == null) { return; } + DeviceChannel channel = channelService.getOne(deviceId, channelId); + if (channel == null) { + return; + } MediaServer newMediaServerItem = this.getNewMediaServerItem(device); if (newMediaServerItem == null) { callback.run(InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getCode(), @@ -967,7 +977,7 @@ public class PlayServiceImpl implements IPlayService { return; } // 录像下载不使用固定流地址,固定流地址会导致如果开始时间与结束时间一致时文件错误的叠加在一起 - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,false, device.getStreamModeForParam()); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,!channel.isHasAudio(), false, device.getStreamModeForParam()); download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, callback); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java index 1ea22548d..6473c42f8 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java @@ -24,6 +24,10 @@ public interface MediaServerMapper { "rtmp_ssl_port,"+ "rtp_proxy_port,"+ "rtsp_port,"+ + "flv_port," + + "flv_ssl_port," + + "ws_flv_port," + + "ws_flv_ssl__port," + "rtsp_ssl_port,"+ "auto_config,"+ "secret,"+ @@ -51,6 +55,10 @@ public interface MediaServerMapper { "#{rtmpSSlPort}, " + "#{rtpProxyPort}, " + "#{rtspPort}, " + + "#{flvPort}, " + + "#{flvSSLPort}, " + + "#{wsFlvPort}, " + + "#{wsFlvSSLPort}, " + "#{rtspSSLPort}, " + "#{autoConfig}, " + "#{secret}, " + @@ -81,6 +89,10 @@ public interface MediaServerMapper { ", rtp_proxy_port=#{rtpProxyPort}" + ", rtsp_port=#{rtspPort}" + ", rtsp_ssl_port=#{rtspSSLPort}" + + ", flv_port=#{flvPort}" + + ", flv_ssl_port=#{flvSSLPort}" + + ", ws_flv_port=#{wsFlvPort}" + + ", ws_flv_ssl_port=#{wsFlvSSLPort}" + ", auto_config=#{autoConfig}" + ", rtp_enable=#{rtpEnable}" + ", rtp_port_range=#{rtpPortRange}" + @@ -108,6 +120,10 @@ public interface MediaServerMapper { ", rtp_proxy_port=#{rtpProxyPort}" + ", rtsp_port=#{rtspPort}" + ", rtsp_ssl_port=#{rtspSSLPort}" + + ", flv_port=#{flvPort}" + + ", flv_ssl_port=#{flvSSLPort}" + + ", ws_flv_port=#{wsFlvPort}" + + ", ws_flv_ssl_port=#{wsFlvSSLPort}" + ", auto_config=#{autoConfig}" + ", rtp_enable=#{rtpEnable}" + ", rtp_port_range=#{rtpPortRange}" + diff --git a/数据库/abl/初始化-mysql-2.7.0.sql b/数据库/abl/初始化-mysql-2.7.0.sql index 7fece768a..0290a06c2 100644 --- a/数据库/abl/初始化-mysql-2.7.0.sql +++ b/数据库/abl/初始化-mysql-2.7.0.sql @@ -155,6 +155,10 @@ create table wvp_media_server ( rtp_proxy_port integer, rtsp_port integer, rtsp_ssl_port integer, + flv_port integer, + flv_ssl_port integer, + ws_flv_port integer, + ws_flv_ssl_port integer, auto_config bool default false, secret character varying(50), type character varying(50) default 'zlm', diff --git a/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql b/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql index 656f7a006..b2fbea550 100644 --- a/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql +++ b/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql @@ -155,6 +155,10 @@ create table wvp_media_server ( rtp_proxy_port integer, rtsp_port integer, rtsp_ssl_port integer, + flv_port integer, + flv_ssl_port integer, + ws_flv_port integer, + ws_flv_ssl_port integer, auto_config bool default false, secret character varying(50), type character varying(50) default 'zlm', diff --git a/数据库/abl/更新-mysql-2.7.0.sql b/数据库/abl/更新-mysql-2.7.0.sql index de92cb2cd..851365874 100644 --- a/数据库/abl/更新-mysql-2.7.0.sql +++ b/数据库/abl/更新-mysql-2.7.0.sql @@ -1,2 +1,11 @@ alter table wvp_media_server add type character varying(50) default 'zlm'; + +alter table wvp_media_server + add flv_port integer; +alter table wvp_media_server + add flv_ssl_port integer; +alter table wvp_media_server + add ws_flv_port integer; +alter table wvp_media_server + add ws_flv_ssl_port integer; diff --git a/数据库/abl/更新-postgresql-kingbase-2.7.0.sql b/数据库/abl/更新-postgresql-kingbase-2.7.0.sql index 45f695938..9a527cb3f 100644 --- a/数据库/abl/更新-postgresql-kingbase-2.7.0.sql +++ b/数据库/abl/更新-postgresql-kingbase-2.7.0.sql @@ -1,2 +1,11 @@ alter table wvp_media_server - add type character varying(50) default 'zlm',; \ No newline at end of file + add type character varying(50) default 'zlm'; + +alter table wvp_media_server + add flv_port integer; +alter table wvp_media_server + add flv_ssl_port integer; +alter table wvp_media_server + add ws_flv_port integer; +alter table wvp_media_server + add ws_flv_ssl_port integer; \ No newline at end of file From 969ff86ebeeb62358472cd4dc99497f646811fbf Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 2 Apr 2024 09:53:47 +0800 Subject: [PATCH 46/58] =?UTF-8?q?=E6=94=BE=E8=A1=8Cabl=20hook=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java | 2 +- .../genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java index ad959d622..b035fcb92 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java @@ -117,7 +117,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .authorizeRequests() .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() .antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll() - .antMatchers("/api/user/login", "/index/hook/**", "/swagger-ui/**", "/doc.html").permitAll() + .antMatchers("/api/user/login", "/index/hook/**","/index/hook/abl/**", "/swagger-ui/**", "/doc.html").permitAll() .anyRequest().authenticated() // 异常处理器 .and() diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index 89a772451..21822317b 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -181,6 +181,8 @@ public class PlayController { throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); } } + // 关闭收流 + inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); storager.stopPlay(deviceId, channelId); From 86a35f3612e47475e7f7dde14d13b93916ec8f02 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 2 Apr 2024 11:25:19 +0800 Subject: [PATCH 47/58] =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=BC=80=E6=BA=90?= =?UTF-8?q?=E4=B8=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/vmanager/gb28181/play/PlayController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index f43aeb488..efb3b6636 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.vmanager.gb28181.play; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -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.UserSetting; @@ -14,8 +13,8 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.bean.MediaServer; +import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; From a1c02605c18a069a4ca3ad2c5562853c37c0d14e Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 2 Apr 2024 14:41:02 +0800 Subject: [PATCH 48/58] =?UTF-8?q?abl-=E5=AE=9E=E7=8E=B0closeRtpServer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../media/abl/ABLMediaNodeServerService.java | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index 644be2430..110c0cbb5 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -1,20 +1,26 @@ package com.genersoft.iot.vmp.media.abl; +import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.bean.MediaServer; +import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.HashMap; import java.util.List; import java.util.Map; @Service("abl") public class ABLMediaNodeServerService implements IMediaNodeServerService { + private final static Logger logger = LoggerFactory.getLogger(ABLMediaNodeServerService.class); + @Autowired private ABLRESTfulUtils ablresTfulUtils; @@ -24,13 +30,28 @@ public class ABLMediaNodeServerService implements IMediaNodeServerService { } @Override - public void closeRtpServer(MediaServer mediaServerItem, String streamId) { - + public void closeRtpServer(MediaServer mediaServer, String streamId) { + closeRtpServer(mediaServer, streamId, null); } @Override - public void closeRtpServer(MediaServer mediaServerItem, String streamId, CommonCallback callback) { - + public void closeRtpServer(MediaServer serverItem, String streamId, CommonCallback callback) { + if (serverItem == null) { + return; + } + Map param = new HashMap<>(); + param.put("stream_id", streamId); + param.put("force", 1); + JSONObject jsonObject = ablresTfulUtils.closeStreams(serverItem, "rtp", streamId); + logger.info("关闭RTP Server " + jsonObject); + if (jsonObject != null ) { + if (jsonObject.getInteger("code") != 0) { + logger.error("关闭RTP Server 失败: " + jsonObject.getString("msg")); + } + }else { + // 检查ZLM状态 + logger.error("关闭RTP Server 失败: 请检查ZLM服务"); + } } @Override From 0b2f635176c71706d5dc33555497445367dc243b Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 10:30:00 +0800 Subject: [PATCH 49/58] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=9D=9E=E4=B8=BB?= =?UTF-8?q?=E7=BA=BF=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/media/abl/ABLHttpHookListener.java | 413 ---- .../media/abl/ABLMediaNodeServerService.java | 151 -- .../media/abl/ABLMediaServerStatusManger.java | 362 ---- ...LMediaServer高性能流媒体服务器使用说明.txt | 1743 ----------------- .../iot/vmp/media/abl/ABLRESTfulUtils.java | 317 --- .../vmp/media/abl/bean/AblServerConfig.java | 812 -------- .../iot/vmp/media/abl/bean/AblUrls.java | 58 - .../iot/vmp/media/abl/bean/ConfigKeyId.java | 10 - .../vmp/media/abl/bean/hook/ABLHookParam.java | 65 - .../abl/bean/hook/OnPlayABLHookParam.java | 31 - .../abl/bean/hook/OnPublishABLHookParam.java | 31 - .../bean/hook/OnRecordMp4ABLHookParam.java | 13 - .../hook/OnRecordProgressABLHookParam.java | 22 - .../hook/OnServerKeepaliveABLHookParam.java | 32 - .../bean/hook/OnServerStaredABLHookParam.java | 32 - .../bean/hook/OnStreamArriveABLHookParam.java | 245 --- .../event/HookAblServerKeepaliveEvent.java | 24 - .../abl/event/HookAblServerStartEvent.java | 24 - 18 files changed, 4385 deletions(-) delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServer高性能流媒体服务器使用说明.txt delete mode 100755 src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblUrls.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/ConfigKeyId.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPlayABLHookParam.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPublishABLHookParam.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordMp4ABLHookParam.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordProgressABLHookParam.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerKeepaliveABLHookParam.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerStaredABLHookParam.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnStreamArriveABLHookParam.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java deleted file mode 100755 index 69e6d8cda..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java +++ /dev/null @@ -1,413 +0,0 @@ -package com.genersoft.iot.vmp.media.abl; - -import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; -import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; -import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.media.abl.bean.hook.*; -import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; -import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent; -import com.genersoft.iot.vmp.media.bean.MediaServer; -import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; -import com.genersoft.iot.vmp.media.event.media.MediaNotFoundEvent; -import com.genersoft.iot.vmp.media.event.media.MediaRtpServerTimeoutEvent; -import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResult; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookResultForOnPublish; -import com.genersoft.iot.vmp.service.*; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.util.ObjectUtils; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import java.util.HashMap; -import java.util.Map; - -/** - * ABL 的hook事件监听 - */ -@RestController -@RequestMapping("/index/hook/abl") -public class ABLHttpHookListener { - - private final static Logger logger = LoggerFactory.getLogger(ABLHttpHookListener.class); - - @Autowired - private ABLRESTfulUtils ablresTfulUtils; - - @Autowired - private ISIPCommanderForPlatform commanderFroPlatform; - - @Autowired - private AudioBroadcastManager audioBroadcastManager; - - @Autowired - private IPlayService playService; - - @Autowired - private IVideoManagerStorage storager; - - @Autowired - private IRedisCatchStorage redisCatchStorage; - - @Autowired - private IInviteStreamService inviteStreamService; - - @Autowired - private IDeviceService deviceService; - - @Autowired - private IMediaServerService mediaServerService; - - @Autowired - private IStreamProxyService streamProxyService; - - @Autowired - private DeferredResultHolder resultHolder; - - @Autowired - private IMediaService mediaService; - - @Autowired - private EventPublisher eventPublisher; - - @Autowired - private ZLMMediaListManager zlmMediaListManager; - - @Autowired - private HookSubscribe subscribe; - - @Autowired - private UserSetting userSetting; - - @Autowired - private IUserService userService; - - @Autowired - private ICloudRecordService cloudRecordService; - - @Autowired - private VideoStreamSessionManager sessionManager; - - @Autowired - private SSRCFactory ssrcFactory; - - @Qualifier("taskExecutor") - @Autowired - private ThreadPoolTaskExecutor taskExecutor; - - @Autowired - private RedisTemplate redisTemplate; - - @Autowired - private ApplicationEventPublisher applicationEventPublisher; - - /** - * 服务器定时上报时间,上报间隔可配置,默认10s上报一次 - */ - @ResponseBody - @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") - public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveABLHookParam param) { - try { - HookAblServerKeepaliveEvent event = new HookAblServerKeepaliveEvent(this); - MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); - if (mediaServerItem != null) { - event.setMediaServerItem(mediaServerItem); - applicationEventPublisher.publishEvent(event); - } - }catch (Exception e) { - logger.info("[ZLM-HOOK-心跳] 发送通知失败 ", e); - } - return HookResult.SUCCESS(); - } - - /** - * 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件。 - */ - @ResponseBody - @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") - public HookResult onPlay(@RequestBody OnPlayABLHookParam param) { - - MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); - if (mediaServer == null) { - return new HookResultForOnPublish(0, "success"); - } - - Map paramMap = urlParamToMap(param.getParams()); - // 对于播放流进行鉴权 - boolean authenticateResult = mediaService.authenticatePlay(param.getApp(), param.getStream(), paramMap.get("callId")); - if (!authenticateResult) { - logger.info("[ABL HOOK] 播放鉴权 失败:{}->{}", param.getMediaServerId(), param); - ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream()); - - } - logger.info("[ABL HOOK] 播放鉴权成功:{}->{}", param.getMediaServerId(), param); - return HookResult.SUCCESS(); - } - - /** - * rtsp/rtmp/rtp推流鉴权事件。 - */ - @ResponseBody - @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8") - public HookResult onPublish(@RequestBody OnPublishABLHookParam param) { - - - logger.info("[ABL HOOK]推流鉴权:{}->{}", param.getMediaServerId(), param); - // TODO 加快处理速度 - - MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); - if (mediaServer == null) { - return new HookResultForOnPublish(0, "success"); - } - - ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams()); - if (resultForOnPublish == null) { - logger.info("[ABL HOOK]推流鉴权 拒绝 响应:{}->{}", param.getMediaServerId(), param); - ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream()); - } - return HookResult.SUCCESS(); - } - - /** - * 如果某一个码流进行MP4录像(enable_mp4=1),会触发录像进度通知事件 - */ - @ResponseBody - @PostMapping(value = "/on_record_progress", produces = "application/json;charset=UTF-8") - public HookResult onRecordProgress(@RequestBody OnRecordProgressABLHookParam param) { - - - logger.info("[ABL HOOK] 录像进度通知:{}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration()); - - // TODO 这里用来做录像进度 -// MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); -// if (mediaServer == null) { -// return new HookResultForOnPublish(0, "success"); -// } -// -// ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams()); -// if (resultForOnPublish == null) { -// logger.info("[ABL HOOK]推流鉴权 拒绝 响应:{}->{}", param.getMediaServerId(), param); -// ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream()); -// } - return HookResult.SUCCESS(); - } - - /** - * 当代理拉流、国标接入等等 码流不到达时会发出 码流不到达的事件通知 - */ - @ResponseBody - @PostMapping(value = "/on_stream_not_arrive", produces = "application/json;charset=UTF-8") - public HookResult onStreamNotArrive(@RequestBody ABLHookParam param) { - - - logger.info("[ABL HOOK] 码流不到达通知:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); - try { - if ("rtp".equals(param.getApp())) { - return HookResult.SUCCESS(); - } - MediaRtpServerTimeoutEvent event = new MediaRtpServerTimeoutEvent(this); - MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); - if (mediaServerItem != null) { - event.setMediaServer(mediaServerItem); - event.setApp("rtp"); - applicationEventPublisher.publishEvent(event); - } - }catch (Exception e) { - logger.info("[ABL-HOOK-码流不到达通知] 发送通知失败 ", e); - } - - return HookResult.SUCCESS(); - } - - /** - * 如果某一个码流进行MP4录像(enable_mp4=1),当某个MP4文件被删除会触发该事件通知 - */ - @ResponseBody - @PostMapping(value = "/on_delete_record_mp4", produces = "application/json;charset=UTF-8") - public HookResult onDeleteRecordMp4(@RequestBody OnRecordMp4ABLHookParam param) { - - - logger.info("[ABL HOOK] MP4文件被删除通知:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); - - - return HookResult.SUCCESS(); - } - - - /** - * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 - */ - @ResponseBody - @PostMapping(value = "/on_stream_arrive", produces = "application/json;charset=UTF-8") - public HookResult onStreamArrive(@RequestBody OnStreamArriveABLHookParam param) { - - MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); - if (mediaServer == null) { - return HookResult.SUCCESS(); - } - - logger.info("[ABL HOOK] 码流到达, {}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); - MediaArrivalEvent mediaArrivalEvent = MediaArrivalEvent.getInstance(this, param, mediaServer); - applicationEventPublisher.publishEvent(mediaArrivalEvent); - return HookResult.SUCCESS(); - } - - /** - * 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 - */ - @ResponseBody - @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") - public JSONObject onStreamNoneReader(@RequestBody ABLHookParam param) { - - logger.info("[ZLM HOOK]流无人观看:{}->{}/{}", param.getMediaServerId(), - param.getApp(), param.getStream()); - JSONObject ret = new JSONObject(); - - boolean close = mediaService.closeStreamOnNoneReader(param.getMediaServerId(), param.getApp(), param.getStream(), null); - ret.put("code", close); - return ret; - } - - /** - * 当播放一个url,如果不存在时,会发出一个消息通知 - */ - @ResponseBody - @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") - public HookResult onStreamNotFound(@RequestBody ABLHookParam param) { - logger.info("[ABL HOOK] 流未找到:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); - - - MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); - if (!userSetting.isAutoApplyPlay() || mediaServer == null) { - return HookResult.SUCCESS(); - } - MediaNotFoundEvent mediaNotFoundEvent = MediaNotFoundEvent.getInstance(this, param, mediaServer); - applicationEventPublisher.publishEvent(mediaNotFoundEvent); - return HookResult.SUCCESS(); - } - - /** - * ABLMediaServer启动时会发送上线通知 - */ - @ResponseBody - @PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8") - public HookResult onServerStarted(HttpServletRequest request, @RequestBody OnServerStaredABLHookParam param) { - - logger.info("[ABL HOOK] 启动 " + param.getMediaServerId()); - try { - HookAblServerStartEvent event = new HookAblServerStartEvent(this); - MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); - if (mediaServerItem != null) { - event.setMediaServerItem(mediaServerItem); - applicationEventPublisher.publishEvent(event); - } - }catch (Exception e) { - logger.info("[ABL-HOOK-启动] 发送通知失败 ", e); - } - - return HookResult.SUCCESS(); - } - - /** - * TODO 发送rtp(startSendRtp)被动关闭时回调 - */ -// @ResponseBody -// @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8") -// public HookResult onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param) { -// -// logger.info("[ZLM HOOK] rtp发送关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); -// -// // 查找对应的上级推流,发送停止 -// if (!"rtp".equals(param.getApp())) { -// return HookResult.SUCCESS(); -// } -// try { -// MediaSendRtpStoppedEvent event = new MediaSendRtpStoppedEvent(this); -// MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); -// if (mediaServerItem != null) { -// event.setMediaServer(mediaServerItem); -// applicationEventPublisher.publishEvent(event); -// } -// }catch (Exception e) { -// logger.info("[ZLM-HOOK-rtp发送关闭] 发送通知失败 ", e); -// } -// -// return HookResult.SUCCESS(); -// } - - /** - * TODO 录像完成事件 - */ - @ResponseBody - @PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8") - public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4ABLHookParam param) { - logger.info("[ABL HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFileName()); - -// try { -// MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); -// if (mediaServerItem != null) { -// MediaRecordMp4Event event = MediaRecordMp4Event.getInstance(this, param, mediaServerItem); -// event.setMediaServer(mediaServerItem); -// applicationEventPublisher.publishEvent(event); -// } -// }catch (Exception e) { -// logger.info("[ZLM-HOOK-rtpServer收流超时] 发送通知失败 ", e); -// } - - return HookResult.SUCCESS(); - } - - /** - * 当某一路码流断开时会发送通知 - */ - @ResponseBody - @PostMapping(value = "/on_stream_disconnect", produces = "application/json;charset=UTF-8") - public HookResult onRecordMp4(HttpServletRequest request, @RequestBody ABLHookParam param) { - logger.info("[ABL HOOK] 码流断开事件, {}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); - - MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); - if (mediaServer == null) { - return HookResult.SUCCESS(); - } - - MediaDepartureEvent mediaDepartureEvent = MediaDepartureEvent.getInstance(this, param, mediaServer); - applicationEventPublisher.publishEvent(mediaDepartureEvent); - - return HookResult.SUCCESS(); - } - - private Map urlParamToMap(String params) { - HashMap map = new HashMap<>(); - if (ObjectUtils.isEmpty(params)) { - return map; - } - String[] paramsArray = params.split("&"); - if (paramsArray.length == 0) { - return map; - } - for (String param : paramsArray) { - String[] paramArray = param.split("="); - if (paramArray.length == 2) { - map.put(paramArray[0], paramArray[1]); - } - } - return map; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java deleted file mode 100644 index 110c0cbb5..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.genersoft.iot.vmp.media.abl; - -import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.common.CommonCallback; -import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.bean.MediaServer; -import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Service("abl") -public class ABLMediaNodeServerService implements IMediaNodeServerService { - - private final static Logger logger = LoggerFactory.getLogger(ABLMediaNodeServerService.class); - - @Autowired - private ABLRESTfulUtils ablresTfulUtils; - - @Override - public int createRTPServer(MediaServer mediaServer, String stream, long ssrc, Integer port, Boolean onlyAuto, Boolean disableAudio, Boolean reUsePort, Integer tcpMode) { - return ablresTfulUtils.openRtpServer(mediaServer, "rtp", stream, 96, port, tcpMode, disableAudio?1:0); - } - - @Override - public void closeRtpServer(MediaServer mediaServer, String streamId) { - closeRtpServer(mediaServer, streamId, null); - } - - @Override - public void closeRtpServer(MediaServer serverItem, String streamId, CommonCallback callback) { - if (serverItem == null) { - return; - } - Map param = new HashMap<>(); - param.put("stream_id", streamId); - param.put("force", 1); - JSONObject jsonObject = ablresTfulUtils.closeStreams(serverItem, "rtp", streamId); - logger.info("关闭RTP Server " + jsonObject); - if (jsonObject != null ) { - if (jsonObject.getInteger("code") != 0) { - logger.error("关闭RTP Server 失败: " + jsonObject.getString("msg")); - } - }else { - // 检查ZLM状态 - logger.error("关闭RTP Server 失败: 请检查ZLM服务"); - } - } - - @Override - public void closeStreams(MediaServer mediaServerItem, String rtp, String streamId) { - - } - - @Override - public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { - return null; - } - - @Override - public boolean checkNodeId(MediaServer mediaServerItem) { - return false; - } - - @Override - public void online(MediaServer mediaServerItem) { - - } - - @Override - public MediaServer checkMediaServer(String ip, int port, String secret) { - return null; - } - - @Override - public boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) { - return false; - } - - @Override - public boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { - return false; - } - - @Override - public List getMediaList(MediaServer mediaServerItem, String app, String stream, String callId) { - return null; - } - - @Override - public Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream) { - return null; - } - - @Override - public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { - - } - - @Override - public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { - return null; - } - - @Override - public Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey) { - return null; - } - - @Override - public Boolean resumeRtpCheck(MediaServer mediaServer, String streamKey) { - return null; - } - - @Override - public String getFfmpegCmd(MediaServer mediaServer, String cmdKey) { - return null; - } - - @Override - public WVPResult addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey) { - return null; - } - - @Override - public WVPResult addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType) { - return null; - } - - @Override - public Boolean delFFmpegSource(MediaServer mediaServer, String streamKey) { - return null; - } - - @Override - public Boolean delStreamProxy(MediaServer mediaServer, String streamKey) { - return null; - } - - @Override - public Map getFFmpegCMDs(MediaServer mediaServer) { - return null; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java deleted file mode 100644 index cb55695b2..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java +++ /dev/null @@ -1,362 +0,0 @@ -package com.genersoft.iot.vmp.media.abl; - -import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.conf.DynamicTask; -import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.media.abl.bean.AblServerConfig; -import com.genersoft.iot.vmp.media.abl.bean.ConfigKeyId; -import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent; -import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent; -import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; -import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent; -import com.genersoft.iot.vmp.media.service.IMediaServerService; -import com.genersoft.iot.vmp.media.bean.MediaServer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.event.EventListener; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.lang.reflect.Field; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 管理zlm流媒体节点的状态 - */ -@Component -public class ABLMediaServerStatusManger { - - private final static Logger logger = LoggerFactory.getLogger(ABLMediaServerStatusManger.class); - - private final Map offlineABLPrimaryMap = new ConcurrentHashMap<>(); - private final Map offlineAblsecondaryMap = new ConcurrentHashMap<>(); - private final Map offlineAblTimeMap = new ConcurrentHashMap<>(); - - @Autowired - private ABLRESTfulUtils ablResTfulUtils; - - @Autowired - private IMediaServerService mediaServerService; - - @Autowired - private DynamicTask dynamicTask; - - @Value("${server.ssl.enabled:false}") - private boolean sslEnabled; - - @Value("${server.port}") - private Integer serverPort; - - @Autowired - private UserSetting userSetting; - - private final String type = "abl"; - - @Async("taskExecutor") - @EventListener - public void onApplicationEvent(MediaServerChangeEvent event) { - if (event.getMediaServerItemList() == null - || event.getMediaServerItemList().isEmpty()) { - return; - } - for (MediaServer mediaServerItem : event.getMediaServerItemList()) { - if (!type.equals(mediaServerItem.getType())) { - continue; - } - logger.info("[ABL-添加待上线节点] ID:" + mediaServerItem.getId()); - offlineABLPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); - offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); - } - } - - @Async("taskExecutor") - @EventListener - public void onApplicationEvent(HookAblServerStartEvent event) { - if (event.getMediaServerItem() == null - || !type.equals(event.getMediaServerItem().getType()) - || event.getMediaServerItem().isStatus()) { - return; - } - MediaServer serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); - if (serverItem == null) { - return; - } - logger.info("[ABL-HOOK事件-服务启动] ID:" + event.getMediaServerItem().getId()); - online(serverItem, null); - } - - @Async("taskExecutor") - @EventListener - public void onApplicationEvent(HookAblServerKeepaliveEvent event) { - if (event.getMediaServerItem() == null) { - return; - } - MediaServer serverItem = mediaServerService.getOne(event.getMediaServerItem().getId()); - if (serverItem == null) { - return; - } - logger.info("[ABL-HOOK事件-心跳] ID:" + event.getMediaServerItem().getId()); - online(serverItem, null); - } - - @Async("taskExecutor") - @EventListener - public void onApplicationEvent(MediaServerDeleteEvent event) { - if (event.getMediaServerId() == null) { - return; - } - logger.info("[ABL-节点被移除] ID:" + event.getMediaServerId()); - offlineABLPrimaryMap.remove(event.getMediaServerId()); - offlineAblsecondaryMap.remove(event.getMediaServerId()); - offlineAblTimeMap.remove(event.getMediaServerId()); - } - - @Scheduled(fixedDelay = 10*1000) //每隔10秒检查一次 - public void execute(){ - // 初次加入的离线节点会在30分钟内,每间隔十秒尝试一次,30分钟后如果仍然没有上线,则每隔30分钟尝试一次连接 - if (offlineABLPrimaryMap.isEmpty() && offlineAblsecondaryMap.isEmpty()) { - return; - } - if (!offlineABLPrimaryMap.isEmpty()) { - for (MediaServer mediaServerItem : offlineABLPrimaryMap.values()) { - if (offlineAblTimeMap.get(mediaServerItem.getId()) < System.currentTimeMillis() - 30*60*1000) { - offlineAblsecondaryMap.put(mediaServerItem.getId(), mediaServerItem); - offlineABLPrimaryMap.remove(mediaServerItem.getId()); - continue; - } - logger.info("[ABL-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - JSONObject responseJson = ablResTfulUtils.getServerConfig(mediaServerItem); - AblServerConfig ablServerConfig = null; - if (responseJson == null) { - logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - continue; - } - JSONArray data = responseJson.getJSONArray("params"); - if (data == null || data.isEmpty()) { - logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - }else { - ablServerConfig = AblServerConfig.getInstance(data); - initPort(mediaServerItem, ablServerConfig); - online(mediaServerItem, ablServerConfig); - } - } - } - if (!offlineAblsecondaryMap.isEmpty()) { - for (MediaServer mediaServerItem : offlineAblsecondaryMap.values()) { - if (offlineAblTimeMap.get(mediaServerItem.getId()) < System.currentTimeMillis() - 30*60*1000) { - continue; - } - logger.info("[ABL-尝试连接] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - JSONObject responseJson = ablResTfulUtils.getServerConfig(mediaServerItem); - AblServerConfig ablServerConfig = null; - if (responseJson == null) { - logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); - continue; - } - JSONArray data = responseJson.getJSONArray("params"); - if (data == null || data.isEmpty()) { - logger.info("[ABL-尝试连接]失败, ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); - }else { - ablServerConfig = AblServerConfig.getInstance(data); - initPort(mediaServerItem, ablServerConfig); - online(mediaServerItem, ablServerConfig); - } - } - } - } - - private void online(MediaServer mediaServerItem, AblServerConfig config) { - offlineABLPrimaryMap.remove(mediaServerItem.getId()); - offlineAblsecondaryMap.remove(mediaServerItem.getId()); - offlineAblTimeMap.remove(mediaServerItem.getId()); - if (!mediaServerItem.isStatus()) { - logger.info("[ABL-连接成功] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - mediaServerItem.setStatus(true); - mediaServerItem.setHookAliveInterval(10F); - mediaServerService.update(mediaServerItem); - if(mediaServerItem.isAutoConfig()) { - if (config == null) { - JSONObject responseJSON = ablResTfulUtils.getServerConfig(mediaServerItem); - JSONArray data = responseJSON.getJSONArray("params"); - if (data != null && !data.isEmpty()) { - config = AblServerConfig.getInstance(data); - } - } - if (config != null) { - initPort(mediaServerItem, config); - setAblConfig(mediaServerItem, false, config); - } - } - mediaServerService.update(mediaServerItem); - } - // 设置两次心跳未收到则认为zlm离线 - String key = "ABL-keepalive-" + mediaServerItem.getId(); - dynamicTask.startDelay(key, ()->{ - logger.warn("[ABL-心跳超时] ID:{}", mediaServerItem.getId()); - mediaServerItem.setStatus(false); - offlineABLPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); - offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); - // TODO 发送离线通知 - mediaServerService.update(mediaServerItem); - }, (int)(mediaServerItem.getHookAliveInterval() * 2 * 1000)); - } - private void initPort(MediaServer mediaServerItem, AblServerConfig ablServerConfig) { - // 端口只会从配置中读取一次,一旦自己配置或者读取过了将不在配置 -// if (mediaServerItem.getHttpSSlPort() == 0) { -// mediaServerItem.setHttpSSlPort(ablServerConfig.getHttpSSLport()); -// } - if (mediaServerItem.getRtmpPort() == 0 && ablServerConfig.getRtmpPort() != null) { - mediaServerItem.setRtmpPort(ablServerConfig.getRtmpPort()); - } -// if (mediaServerItem.getRtmpSSlPort() == 0) { -// mediaServerItem.setRtmpSSlPort(ablServerConfig.getRtmpSslPort()); -// } - if (mediaServerItem.getRtspPort() == 0 && ablServerConfig.getRtspPort() != null) { - mediaServerItem.setRtspPort(ablServerConfig.getRtspPort()); - } - if (mediaServerItem.getFlvPort() == 0 && ablServerConfig.getHttpFlvPort() != null) { - mediaServerItem.setFlvPort(ablServerConfig.getHttpFlvPort()); - } - if (mediaServerItem.getWsFlvPort() == 0 && ablServerConfig.getWsPort() != null) { - mediaServerItem.setWsFlvPort(ablServerConfig.getWsPort()); - } - if (mediaServerItem.getRtpProxyPort() == 0 && ablServerConfig.getPsTsRecvPort() != null) { - mediaServerItem.setRtpProxyPort(ablServerConfig.getPsTsRecvPort()); - } -// if (mediaServerItem.getRtspSSLPort() == 0) { -// mediaServerItem.setRtspSSLPort(ablServerConfig.getRtspSSlport()); -// } -// if (mediaServerItem.getRtpProxyPort() == 0) { -// mediaServerItem.setRtpProxyPort(ablServerConfig.getRtpProxyPort()); -// } - mediaServerItem.setHookAliveInterval(10F); - } - - public void setAblConfig(MediaServer mediaServerItem, boolean restart, AblServerConfig config) { - try { - if (config.getHookEnable() == 0) { - logger.info("[媒体服务节点-ABL] 开启HOOK功能 :{}", mediaServerItem.getId()); - JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, "hook_enable", "1"); - if (responseJSON.getInteger("code") == 0) { - logger.info("[媒体服务节点-ABL] 开启HOOK功能成功 :{}", mediaServerItem.getId()); - }else { - logger.info("[媒体服务节点-ABL] 开启HOOK功能失败 :{}->{}", mediaServerItem.getId(), responseJSON.getString("memo")); - } - } - }catch (Exception e) { - logger.info("[媒体服务节点-ABL] 开启HOOK功能失败 :{}", mediaServerItem.getId(), e); - } - // 设置相关的HOOK - String[] hookUrlArray = { - "on_stream_arrive", - "on_stream_none_reader", - "on_record_mp4", - "on_stream_disconnect", - "on_stream_not_found", - "on_server_started", - "on_publish", - "on_play", - "on_record_progress", - "on_server_keepalive", - "on_stream_not_arrive", - "on_delete_record_mp4", - }; - - String protocol = sslEnabled ? "https" : "http"; - String hookPrefix = String.format("%s://%s:%s/index/hook/abl", protocol, mediaServerItem.getHookIp(), serverPort); - Field[] fields = AblServerConfig.class.getDeclaredFields(); - for (Field field : fields) { - try { - if (field.isAnnotationPresent(ConfigKeyId.class)) { - ConfigKeyId configKeyId = field.getAnnotation(ConfigKeyId.class); - for (String hook : hookUrlArray) { - if (configKeyId.value().equals(hook)) { - String hookUrl = String.format("%s/%s", hookPrefix, hook); - field.setAccessible(true); - // 利用反射获取值后对比是否与配置中相同,不同则进行设置 - if (!hookUrl.equals(field.get(config))) { - JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, hook, hookUrl); - if (responseJSON.getInteger("code") == 0) { - logger.info("[媒体服务节点-ABL] 设置HOOK {} 成功 :{}", hook, mediaServerItem.getId()); - }else { - logger.info("[媒体服务节点-ABL] 设置HOOK {} 失败 :{}->{}", hook, mediaServerItem.getId(), responseJSON.getString("memo")); - } - } - } - } - } - }catch (Exception e) { - logger.info("[媒体服务节点-ABL] 设置HOOK 失败 :{}", mediaServerItem.getId(), e); - } - } - - - - -// Map param = new HashMap<>(); -// param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline -// if (mediaServerItem.getRtspPort() != 0) { -// param.put("ffmpeg.snap", "%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s"); -// } -// param.put("hook.enable","1"); -// param.put("hook.on_flow_report",""); -// param.put("hook.on_play",String.format("%s/on_play", hookPrefix)); -// param.put("hook.on_http_access",""); -// param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix)); -// param.put("hook.on_record_ts",""); -// param.put("hook.on_rtsp_auth",""); -// param.put("hook.on_rtsp_realm",""); -// param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix)); -// param.put("hook.on_shell_login",""); -// param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix)); -// param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix)); -// param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix)); -// param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix)); -// param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix)); -// param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix)); -// param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix)); -// param.put("hook.timeoutSec","30"); -// param.put("hook.alive_interval", mediaServerItem.getHookAliveInterval()); -// // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 -// // 置0关闭此特性(推流断开会导致立即断开播放器) -// // 此参数不应大于播放器超时时间 -// // 优化此消息以更快的收到流注销事件 -// param.put("protocol.continue_push_ms", "3000" ); -// // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流, -// // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项 -// if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) { -// param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-")); -// } -// -// if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) { -// File recordPathFile = new File(mediaServerItem.getRecordPath()); -// param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath()); -// param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath()); -// param.put("record.appName", recordPathFile.getName()); -// } -// -// JSONObject responseJSON = ablResTfulUtils.setConfigParamValue(mediaServerItem, param); -// -// if (responseJSON != null && responseJSON.getInteger("code") == 0) { -// if (restart) { -// logger.info("[媒体服务节点] 设置成功,开始重启以保证配置生效 {} -> {}:{}", -// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); -// ablResTfulUtils.restartServer(mediaServerItem); -// }else { -// logger.info("[媒体服务节点] 设置成功 {} -> {}:{}", -// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); -// } -// }else { -// logger.info("[媒体服务节点] 设置媒体服务节点失败 {} -> {}:{}", -// mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); -// } - } - -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServer高性能流媒体服务器使用说明.txt b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServer高性能流媒体服务器使用说明.txt deleted file mode 100644 index 9cffc9830..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServer高性能流媒体服务器使用说明.txt +++ /dev/null @@ -1,1743 +0,0 @@ -一、功能说明 - ABLMediaServer高性能流媒体服务器,windows平台采用高性能的完成端口网络模型、Linux下采用epoll,加上线程池进行媒体数据 - 的接收、转换、发送。服务器的性能强劲、运行稳定,坚如磐石。经过压力测试比较,转发性能、CPU占有率、运行稳定性优势明显 。可 - 以通过ffmpeg命令或者其他标准的rtsp、rtmp推流函数往ABLMediaServer推送rtsp流、rtmp流,请求服务器代理拉流,请求服务器接收国 - 标GB28181。服务器通过转换,输出标准的rtsp码流、rtmp码流、http-flv、ws-flv 码流(支持H265视频输出)、http-mp4(视频支持H264、 - H265,音频支持AAC)、hls码流输出(视频支持H264、H265,音频支持AAC)、GB28181码流(国标PS流 )输出。 - 流媒体服务器支持录像、支持智能录像删除、录像查询、录像文件点播、录像文件极速下载。http-flv、ws-flv、http-mp4 协议点播时 - 支持暂停继续、支持拖动播放。rtsp点播录像文件时支持慢放(1/16、1/8、1/4、1/2),快放(2、4、8、16 )、正常速度、支持拖动播放。 - 流媒体服务器支秒级(基本上1秒以内)图片抓拍,支持对抓拍的图片进行查找,支持抓拍图片以http协议下载。 - 服务器支持H265转码为H264,转码输出视频支持指定分辨率、宽高、码率大小等等参数。Windows平台支持英伟达显卡硬件加速转码。实 - 测linux 平台能最大并发转码40路H265(硬件环境 至强 E5 2650 V3),实测windows 平台能最大并发转码35路H265(i9 + 英伟达 RTX 2080) - Linux 新增支持英伟达专业显卡,支持硬件解码、硬件编码,支持多个显卡同时进行转码。两张特斯拉T4(16G)显卡可以同时把80路1080P - 的H265视频转码为 1280 x 720 的H264,转码延时低于10毫秒,如果需要更强的转码功能可以多插几张显卡或者集群 。 - 服务器支持转码出来的视频打入自定义水印,支持水印的字符内容、字体大小、 字体颜色、字体位置都可以在配置文件中配置。 - 非常感谢ZLMediaKit和Media-Server 两个工程项目的作者,ABLMediaSever参考复用了ZLMediaKit的http请求函数的参数表(请求的URL - 及请求的参数名及一些初始值)以及整个框架的一些设计思想。直接调用了Media-Server 工程的 rtmp、flv、hls、fmp4 复用与解复用等等。 - 非常崇拜与感谢两位大佬为中国的开源流媒体努力与付出,再次感谢。 - - 【欢迎加入高性能流媒体服务QQ群 873666268 】 - -二、ABLMediaServer主要功能 - - 网络协议媒体输入 - rtsp、rtmp外部主动推流输入 - 1、rtsp外部主动推流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - 2、rtmp外部主动推流 (支持 视频:H264、H265 ,音频:AAC) - 3、国标GB28181输入 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - 4、交通运输部jtt1078 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - - rtsp、rtmp、http-flv、本地mp4文件 拉流输入: - 1、rtsp 拉流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - 2、rtmp 拉流 (支持 视频:H264、H265 ,音频:AAC) - 3、http-flv 拉流 (支持 视频:H264、H265 ,音频:AAC) - 4、本地mp4 拉流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - - websock方式私有协议发送PCM数据进入流媒体服务器(可以在浏览器录音通过websocket以下面的私有协议把语音接入流媒体服务器方便国标对讲、或者其他应用比如语音广播) - 1、数据包格式 - 包头 + 数据类型 + 长度 + 数据包 - 包头4个字节 0xAB 0xCD 0xEF 0xAB - 数据类型  1 个字节 ,[ 0x01 推流音频注册 ] [0x02 发送 PCM 音频数据包] [0x03 断开音频推流 ] - 长度   2 个字节 ,网络字节顺序(大端) - 数据包 音频注册包、pcm音频数据包、注销包 - - 2、数据包类型 - 1)、音频注册包 ,json 格式 - {"method":"register","app":"talk","stream":"xian_1","audioCodec":"pcm","channels":1,"sampleRate":16000,"targetAudioCodec":"g711a"} - - 样例:发送音频注册 - websocket 只要连接上来,就首先发送 音频注册包 - (0xAB 0xCD 0xEF 0xAB) + 0x01 + strlen(音频注册包) + {"method":"register","app":"talk","stream":"xian_1","audioCodec":"pcm","channels":1,"sampleRate":16000,"targetAudioCodec":"g711a"} - - 2) 、音频数据包 只支持 16位采样精度的pcm ,单通道、双通道、常见的采样频率都支持(8000、16000、32000、48000) - 样例:现在只发送纯pcm音频数据 - (0xAB 0xCD 0xEF 0xAB) + 0x02 + strlen(pcm纯音频数据) + pcm纯音频数据 - - 3)、注销包 - {"method":"destruction"} - - 样例:发送注销包 - (0xAB 0xCD 0xEF 0xAB) + 0x03 + strlen({"method":"destruction"} ) + {"method":"destruction"} - - 支持用ffmpeg推纯音频流接入流媒体服务器,支持的音频格式有(g711A、G711U、AAC、MP3) - 1、以rtsp协议推本地aac文件接入流媒体 - ffmpeg -re -stream_loop -1 -i F:\music\xxx.aac -c:a aac -rtsp_transport tcp -f rtsp rtsp://190.15.240.11:554/music/aac1 - - 2、以rtmp协议推本地aac文件接入流媒体 - ffmpeg -re -stream_loop -1 -i F:\music\xxx.aac -c:a aac -f flv rtmp://190.15.240.11:1935/music/aac2 - - 3、以rtsp协议推本地mp3文件接入流媒体 - ffmpeg -re -stream_loop -1 -i F:\music\xxx.mp3 -c:a mp3 -rtsp_transport tcp -f rtsp rtsp://190.15.240.11:554/music/aac3 - - 4、以rtmp协议推本地mp3文件接入流媒体 - ffmpeg -re -stream_loop -1 -i F:\music\xxx.mp3 -c:a mp3 -f flv rtmp://190.15.240.11:1935/music/aac4 - - 5、以rtsp协议推本地mp4文件中的纯音频流接入服务器 - 1) 比如推一个视频格式为h264,音频为aac的mp4文件中的音频流进入服务器,那么服务器接收到的音频流为aac ,视频不做推送 - ffmpeg -re -stream_loop -1 -i F:\video\H264_AAC_2021-02-10_1080P.mp4 -vn -acodec copy -rtsp_transport tcp -f rtsp rtsp://44.35.33.39:554/music/aac5 - - 2) 比如推一个视频格式为h264,音频为g711A的mp4文件中的音频流进入服务器,那么服务器接收到的音频流为g711A ,视频不做推送 - ffmpeg -re -stream_loop -1 -i F:\video\H264-G711A-92017.mp4 -vn -acodec copy -rtsp_transport tcp -f rtsp rtsp://44.35.33.39:554/music/aac6 - - 3) 比如推一个视频格式为h264,音频为g711U的mp4文件中的音频流进入服务器,那么服务器接收到的音频流为g711U ,视频不做推送 - ffmpeg -re -stream_loop -1 -i F:\video\H264-G711U-56434.mp4 -vn -acodec copy -rtsp_transport tcp -f rtsp rtsp://44.35.33.39:554/music/aac7 - - 网络协议媒体 输出: - 被动拉流输出 - 1、rtsp (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - 2、rtmp (支持 视频:H264、H265 ,音频:AAC) - 3、GB28181码流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - 4、http-flv (支持 视频:H264、H265 ,音频:AAC) - 5、http-hls (支持 视频:H264、H265 ,音频:AAC) - 6、http-mp4 (支持 视频:H264、H265 ,音频:AAC) - 7、websocket-flv (支持 视频:H264、H265 ,音频:AAC) - 8、webrtc (支持 视频:H264、H265 ,音频:G711A、G711U、OPUS) - 9、交通运输部jtt1078 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - - rtsp、rtmp、gb28181、jtt1078 主动推流输出: - 1、rtsp推流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - 2、rtmp推流 (支持 视频:H264、H265 ,音频:AAC) - 3、GB28181推流 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - 4、交通运输部jtt1078 (支持 视频:H264、H265 ,音频:AAC、G711A、G711U) - - -三、简明使用例子 - 1) 首先要配置 ABLMediaServer.ini 里面的 本机的IP地址 localipAddress 、recordPath 项。 - - 1 本机的IP地址,最好需要配置准确(如果不配置程序会自动获取一个地址代替,如果本机有多个地址可能会不准确,如果配置则使用配置的IP地址,这样就准确), - 因为调用 getMediaList 获取可用媒体源的json中,会使用到本机的IP地址来拼接 rtsp、rtmp、http-flv、ws-flv、hls、http-mp4 的播放url 。 - 调用 getMediaList 返回的json串中有如下url子项: - "url": { - "rtsp": "rtsp://10.0.0.239:554/Media/Camera_00001", - "rtmp": "rtmp://10.0.0.239:1935/Media/Camera_00001", - "http-flv": "http://10.0.0.239:8088/Media/Camera_00001.flv", - "ws-flv": "ws://10.0.0.239:6088/Media/Camera_00001.flv", - "http-mp4": "http://10.0.0.239:5088/Media/Camera_00001.mp4", - "http-hls": "http://10.0.0.239:9088/Media/Camera_00001.m3u8" - } - - 其中的 10.0.0.239 就是可以从 localipAddress 配置项 精确获取 。 - - 2、录像路径配置 recordPath,如果不需要录像,可以忽略录像路径配置 - # 录像文件保存路径,如果不配置录像文件保存在应用程序所在的路径下的record子路径,如果配置路径则保存在配置的路径的record里面 - # 注意:如果需要录像存储,存储的硬盘千万不要分区,整个硬盘作为一个区,因为服务器没有执行两个以上的盘符操作。 - # 录像保存路径配置 windows平台的路径配置 比如 D:\video ,Linux 平台配置 /home/video - # 录像路径使用了默认路径,就一直使用默认路径,如果使用了配置路径就一直使用配置路径,确保使用的路径的硬盘空间为最大的,如果需要更换路径,要把原来的录像路径的视频全部删除。 - # 1路高清5M的摄像头,如果录像的话,每小时产生2G大小左右的录像文件。可以根据这个来计算需要购买多大的硬盘,接入多少路摄像头,需要设置录像文件最大的保存时间 - - 2)、 媒体输出规则: [network protocol]://[ip]:[port]/[app]/[stream][.extend] - - 【注:如果自己不想拼接播放url ,可以调用http函数 /index/api/getMediaList,返回可播放媒 - 体源中有各种播放协议的url, 详见下面的函数 /index/api/getMediaList 】 - - 说明: - [network protocol] 有 rtsp、rtmp、http、ws - [ip] 就是服务器所在的IP地址 - [port] 各个网络协议分享时设置的端口号,详见 ABLMediaServer.ini 的配置文件,里面有相应的网络协议配置端口 - [app] 各种网络协议发送过来设置的一级名字 - [stream] 各种网络协议发送过来设置的二级名字 - [.extend] 扩展名字,主要为为了访问服务器时,服务器需要识别网络协议需要客户端发送过来的扩展名。 - rtsp、rtmp 不需要扩展名, - http-flv 、ws-flv 扩展名为 .flv - hls 方式访问时, 扩展名为 .m3u8 - http-mp4访问时 扩展名为 .mp4 - - 比如服务器IP为 190.15.240.11 ,app 为 Media ,stream 为 Camera_00001 ,假定端口都是默认 ,那么各种网络访问url如下: - rtsp: - rtsp://190.15.240.11:554/Media/Camera_00001 - - rtmp: - rtmp://190.15.240.11:1935/Media/Camera_00001 - - http-flv: - http://190.15.240.11:8088/Media/Camera_00001.flv - - http-mp4: - http://190.15.240.11:5088/Media/Camera_00001.mp4 - - websocket-flv: - ws://190.15.240.11:6088/Media/Camera_00001.flv - - http-hls: - http://190.15.240.11:9088/Media/Camera_00001.m3u8 - - 3)、使用ffmpeg往 ABLMediaServer 推送rtsp 码流 【假定 源摄像机rtsp RUL为 rtsp://admin:abldyjh2020@192.168.1.120:554 , ABLMediaServer 所在服务器地址为 190.15.240.11 】 - 【推送rtsp方式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 - - ffmpeg -rtsp_transport tcp -i rtsp://admin:abldyjh2020@192.168.1.120:554 -vcodec copy -acodec copy -f rtsp -rtsp_transport tcp rtsp://190.15.240.11:554/Media/Camera_00001 - - 媒体输出: - rtsp: 【rtsp输出格式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 - rtsp://190.15.240.11:554/Media/Camera_00001 - - rtmp: 【rtmp输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - rtmp://190.15.240.11:1935/Media/Camera_00001 - - http-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - http://190.15.240.11:8088/Media/Camera_00001.flv - - ws-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - ws://190.15.240.11:6088/Media/Camera_00001.flv - - http-hls: 【http-hls输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - http://190.15.240.11:9088/Media/Camera_00001.m3u8 - - 4)、使用ffmpeg往 ABLMediaServer 推送rtmp 码流 【假定 源摄像机rtsp RUL为 rtsp://admin:abldyjh2020@192.168.1.120:554 , ABLMediaServer 所在服务器地址为 190.15.240.11 】 - 【推送rtmp方式说明:视频支持 H264 ,音频支持AAC 】 - - ffmpeg -rtsp_transport tcp -i rtsp://admin:abldyjh2020@192.168.1.120:554 -acodec copy -vcodec copy -f flv rtmp://190.15.240.11:1935/Media/Camera_00001 - - rtsp: 【rtsp输出格式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 - rtsp://190.15.240.11:554/Media/Camera_00001 - - rtmp: 【rtmp输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - rtmp://190.15.240.11:1935/Media/Camera_00001 - - http-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - http://190.15.240.11:8088/Media/Camera_00001.flv - - ws-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - ws://190.15.240.11:6088/Media/Camera_00001.flv - - http-hls: 【http-hls输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - http://190.15.240.11:9088/Media/Camera_00001.m3u8 - - 5)、使用ffmpeg往 ABLMediaServer 推送rtsp的文件码流 【假定媒体文件为:F:\video\MP4有声音\H264_AAC_2021-02-10_1080P.mp4 , ABLMediaServer 所在服务器地址为 190.15.240.11 】 - 【推送rtsp方式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 - - ffmpeg -re -stream_loop -1 -i F:\video\MP4有声音\H264_AAC_2021-02-10_1080P.mp4 -vcodec copy -acodec copy -rtsp_transport tcp -f rtsp rtsp://190.15.240.11:554/Media/Camera_00001 - - 媒体输出: - rtsp: 【rtsp输出格式说明:视频支持 H264、H265 ,音频支持AAC、G711A、G711U 】 - rtsp://190.15.240.11:554/Media/Camera_00001 - - rtmp: 【rtmp输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - rtmp://190.15.240.11:1935/Media/Camera_00001 - - http-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - http://190.15.240.11:8088/Media/Camera_00001.flv - - ws-flv: 【http-flv输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - ws://190.15.240.11:6088/Media/Camera_00001.flv - - http-hls: 【http-hls输出格式说明:视频支持 H264、H265 ,音频支持AAC 】 - http://190.15.240.11:9088/Media/Camera_00001.m3u8 - - 【特别注明:可以往10000 的udp端口推送TS码流,推送成功后,可以调用 http函数getMediaList来获取接入的rtp码流 】 - ffmpeg.exe -re -stream_loop -1 -i F:\video\H264_20191021094432.mp4 -vcodec copy -f rtp_mpegts rtp://127.0.0.1:100000 - - - 6)、流媒体输出播放验证 - 如果视频是rtsp方式,可以采用VLC进行播放验证  -     如果rtmp、http-flv 协议,视频为h264 ,可以采用VLC播放验证、或者B站的 flv.js 播放器验证 - 如果rtmp、http-flv 协议,视频为h265 ,可以采用EasyPlayer.js 播放器验证,【注:VLC 、flv.js 不支持Rtmp的H265视频、也不支持http-flv的265视频 】 - - 7)、申请代理rtsp、rtmp、flv 拉流 、本地mp4文件 ,申请删除代理拉流 - 1) 申请代理rtsp、rtmp、flv 拉流、本地mp4文件 - - URL: /index/api/addStreamProxy - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - vhost 比如 _defaultVhost_ - app 应用名 比如 Media - stream 媒体流名 比如 Camera_00001 【/app/stream 组合起来不能重复】 - url 代理拉流url 比如 rtsp://admin:abldyjh2020@192.168.1.120:554 或者 - rtmp://190.15.240.36:1935/Media/Camera_00001 或者 - http://190.15.240.36:8088/Media/Camera_00001.flv 或者 - d:\\video\\xxxx.mp4 (windows平台) - /home/video/xxxx.mp4 (Linux平台) - isRtspRecordURL 代理拉流的url是否是rtsp录像回放的url 默认0 ,1 是【可选参数】,如果是rtsp录像回放的url,可以进行控制代理拉流,比如 暂停、继续、控制倍速播放,拖动播放等等 ,参考 - 函数 /index/api/controlStreamProxy - optionsHeartbeat options心跳 options 命令作为心跳包 【可选参数】 代理rtsp拉流成后,是否开启发送 0 不开启, 1 开启 ,默认不开启,如果从 ZLMediaKit 拉取rtsp流,建议设置为 1 - enable_mp4 是否录像 1 录像,0 不录像 【可选参数】 - enable_hls 是否hls切片 1 进行hls 切片 ,0 不切片 【可选参数】 - convertOutWidth 转码宽 转码输出宽 如果指定宽、高 【可选参数】[1920 x 1080, 1280 x 720 ,960 x 640 ,800 x 480 ,720 x 576 , 720 x 480 ,640 x 480 ,352 x 288 ] 就说明 H265 进行转码为 H264 - convertOutHeight 转码高 转码输出高 如果指定宽、高 【可选参数】[1920 x 1080, 1280 x 720 ,960 x 640 ,800 x 480 ,720 x 576 , 720 x 480 ,640 x 480 ,352 x 288 ] 就说明 H265 进行转码为 H264 - H264DecodeEncode_enable H264是否解码 H264分辨率高再编码降分辨率,【可选参数】有时候需要H264视频进行先解码再重新编码降低分辨率,可以设置 H264DecodeEncode_enable 为 1 ,降下来的分辨率为 convertOutWidth 、 convertOutHeight - disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 - disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 - - http GET 方式 - 1 请求rtsp拉流样例 - http://190.15.240.11:7088/index/api/addStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001&url=rtsp://admin:abldyjh2020@192.168.1.120:554&enable_mp4=0 - - http POST 方式 - 1 请求rtsp拉流样例 - http请求 url 样例 - http://190.15.240.11:7088/index/api/addStreamProxy - body 参数 , json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","url":"rtsp://admin:abldyjh2020@192.168.1.120:554","enable_mp4":0} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 - "key": 93 # 成功时返回大于0的值,为代理拉流的Key ,删除代理拉流时需要用的 - } - - 2) 控制代理拉流,比如 暂停、继续、控制倍速播放,拖动播放等等 - URL: /index/api/controlStreamProxy - - 参数: - secret 服务器密码 ,比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 比如 93 ,调用 addStreamProxy 返回的 key 的值 - command 比如 pause、resume、seek、scale 对于对应意思:暂停、继续、拖动播放、倍速播放 - value (字符串) 比如 1、2、4、8、16(倍速播放) ,npt方式:360、1800、3600(拖动播放),clock方式:clock=20230625T113000Z-19700101T000001Z(拖动到:2023-06-25 11:30:00执行播放) - value 为可选参数,当 command 为 pause,resume 时,value 不用 ,当 command 为seek,sacale - 是,需要填写value的值 - 命令、值样例列表 - command value 注释 - pause 不需要 暂停回放 - resume 不需要 继续回放 - scale 2 2倍速回放 - seek 360 拖拽从开始点计算起到360秒处再回放 【ntp方式拖拽 ,代表 华为 VCN\3800 】 - seek clock=20230625T113000Z-19700101T000001Z 拖拽到20230625T113000Z处再回放 【clock方式拖拽 ,代表 海康NVR 】 - - http GET 方式 - http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=pause 暂停 - http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=resume 继续 - http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=scale&value=2 2倍速回放 - http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=seek&value=360 拖拽到360秒处继续回放 - http://190.15.240.11:7088/index/api/controlStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93&command=seek&value=clock=20230625T113000Z-19700101T000001Z - - http POST 方式 - http URL : - http://190.15.240.11:7088/index/api/controlStreamProxy - - body 参数 Json格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"pause"} - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"resume"} - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"sacale","value":"2"} - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"seek","value":"360"} - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93,"command":"seek","value":"clock=20230625T113000Z-19700101T000001Z"} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 【注:发送http请求 可以使用curl、postman、或者其他标准的http工具 】 - - - 3) 申请删除代理rtsp、rtmp、flv 拉流 - URL: /index/api/delStreamProxy - - 参数: - secret 服务器密码 ,比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 比如 93 ,调用 addStreamProxy 返回的 key 的值 - - http GET 方式 - http://190.15.240.11:7088/index/api/delStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 - - http POST 方式 - http URL : - http://190.15.240.11:7088/index/api/delStreamProxy - - body 参数 Json格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 【注:发送http请求 可以使用curl、postman、或者其他标准的http工具 】 - - - - 8)、申请代理rtsp、rtmp、推流 、申请删除代理拉流 - 1) 申请代理rtsp、rtmp 推流(注意:不是国标GB28181推流) - - URL: /index/api/addPushProxy - - 参数: 参数说明 参考值 - secret 服务器密码 , 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - vhost 比如 _defaultVhost_ - app 应用名 比如 Media - stream 媒体流名 比如 Camera_00001 - url 代理推流url 比如 rtsp://190.15.240.36:554/Media/Camera_00001 或者 rtmp://190.15.240.36:1935/Media/Camera_00001 - disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 - disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 - - http GET 方式 - http://190.15.240.11:7088/index/api/addPushProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001&url=rtsp://190.15.240.36:554/Media/Camera_00001 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/addPushProxy - - http Body 参数 (json格式) - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","url":"rtsp://190.15.240.36:554/Media/Camera_00001"} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 - "key": 93 # 成功时返回大于0的值,为代理推流的Key ,删除代理推流时需要用的 - } - - 2) 申请删除代理rtsp、rtmp 推流 - URL: /index/api/delPushProxy - - 参数: 参数说明 参数参考值 - secret 服务器密码 , 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 主键ID 比如 93 ,调用 /index/api/addPushProxy 返回的 key 的值 - - http GET 方式 - http://190.15.240.11:7088/index/api/delPushProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/delPushProxy - - http Body json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 9)、创建GB28181\Jtt1078接收端口、删除GB28181\Jtt1078接收端口、国标暂停、继续 - - 1 创建GB28181\Jtt1078接收端口 - - URL: /index/api/openRtpServer - 功能: - 创建GB28181\Jtt1078接收端口,如果该端口接收超时,会自动回收,不用调用 /index/api/closeRtpServer - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - vhost 比如 _defaultVhost_ - app 应用名 比如 gb28181 、rtp 等等 (接入) - stream_id 媒体流名 比如 44030012343220234234 (最好是国标编号)( 接入 ) - payload PS负载值 国标SDP里面PS负载值 ,比如 96,98 ,108 ,一定要从国标SDP里面获取 - port 端口号 0 ,由服务器自动分配,别的值 比如 26324 为指定端口 - enable_tcp 是否为tcp 0 为 udp , 1 为tcp被动方式 ,2 为tcp主动连接方式 - dst_url 目标IP 目标IP地址 【可选参数 ,当 enable_tcp 为 2 时必须填写 】 - dst_port 目标端口 目标端口 【可选参数 ,当 enable_tcp 为 2 时必须填写】 - - enable_mp4 是否录像 1 录像,0 不录像 【可选参数】 - enable_hls 是否hls切片 1 进行hls 切片 ,0 不切片 【可选参数】 - convertOutWidth 转码宽 转码输出宽 如果指定宽、高 【可选参数】[1920 x 1080, 1280 x 720 ,960 x 640 ,800 x 480 ,720 x 576 , 720 x 480 ,640 x 480 ,352 x 288 ] 就说明 H265 进行转码为 H264 - convertOutHeight 转码高 转码输出高 如果指定宽、高 【可选参数】[1920 x 1080, 1280 x 720 ,960 x 640 ,800 x 480 ,720 x 576 , 720 x 480 ,640 x 480 ,352 x 288 ] 就说明 H265 进行转码为 H264 - H264DecodeEncode_enable H264是否解码 H264分辨率高再编码降分辨率,【可选参数】有时候需要H264视频进行先解码再重新编码降低分辨率,可以设置 H264DecodeEncode_enable 为 1 ,降下来的分辨率为 convertOutWidth 、 convertOutHeight - RtpPayloadDataType rtp打包数据格式 rtp打包数据格式 【可选参数 ,默认 1 】 [1 PS 国标gb28181 ]、[ 2 ES 视频支持 H246\H265,音频只支持G711A、G711U ]、[3 XHB (一家公司的打包格式) 只支持视频,音频不能加入打包 ] [ 4 、Jt1078(2016版本)码流接入 ] - disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 - disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 - jtt1078_version 指定1078版本号 2013、2016、2019 【可选参数】 2013 指定为 2013版本 、2016 指定为 2016版本、 2019 指定为 2019 版本 - - send_app 应用名 比如 gb28181 、rtp 等等 【可选参数】 用于把本服务器的码流(send_app/send_stream_id)回复给发送端 - send_stream_id 媒体流名 比如 44030012343220234234 【可选参数】 用于把本服务器的码流(send_app/send_stream_id)回复给发送端 - send_disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 - send_disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 - detectSendAppStream 是否检测发送流ID 0 不检测 ,1 检测 【可选参数】 默认 1 在需要回传码流时,事先检测 send_app、send_stream_id 是否存在。0 不检测,先打开接收成功后,稍后再把send_app、send_stream_id接入流媒体,openRtpServer函数自动回复给下级流媒体。 - - http GET 方式 - http://190.15.240.11:7088/index/api/openRtpServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=gb28181&stream_id=44030012343220234234&payload=96&port=0&enable_tcp=0&enable_mp4=0 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/openRtpServer - - http 参数值 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream_id":"Camera_00001","payload":96,"port":0,"enable_tcp":0,"enable_mp4":0} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "port": 8356, # 端口号 - "memo": "success", # success 为成功 - "key": 93 # 成功时返回大于0的值,GB28181接收实例key ,关闭时需要 - } - - 2 删除 GB28181\Jtt1078接收端口 - URL: /index/api/closeRtpServer - 功能: - 删除GB28181\Jtt1078接收端口 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 主键值ID 比如 93 , 调用 /index/api/openRtpServer 返回的 key 的值 - - http GET 方式 - http://190.15.240.11:7088/index/api/closeRtpServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/closeRtpServer - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 3 暂停 GB28181\Jtt1078接收端口,只是不检测接收端口是否有码流进入。 - URL: /index/api/pauseRtpServer - 功能: - 暂停GB28181\Jtt1078接收 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 主键值ID 比如 93 , 调用 /index/api/openRtpServer 返回的 key 的值 - - http GET 方式 - http://44.35.33.249:7088/index/api/pauseRtpServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=588 - - http POST 方式 - http URL - http://44.35.33.249:7088/index/api/pauseRtpServer - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":588} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 4 继续 GB28181\Jtt1078接收端口,开启检测端口是否有码流到达,如果时长到达最大超时没有码流进入会立即删除接收端口 - URL: /index/api/resumeRtpServer - 功能: - 继续GB28181\Jtt1078接收 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 主键值ID 比如 93 , 调用 /index/api/openRtpServer 返回的 key 的值 - - http GET 方式 - http://44.35.33.249:7088/index/api/resumeRtpServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=588 - - http POST 方式 - http URL - http://44.35.33.249:7088/index/api/resumeRtpServer - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":588} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 10)、创建GB28181\Jtt1078 发送端口、删除GB28181\Jtt1078发送端口 - - 1 创建GB28181\Jtt1078发送端口 - - URL: /index/api/startSendRtp - 功能: - 创建GB28181\Jtt1078发送端口,如果该发送端端口没有数据发送,会自动回收,不用调用 /index/api/stopSendRtp - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - vhost 比如 _defaultVhost_ - app 应用名 比如 gb28181 、rtp 等等 (发送出去) - stream 媒体流名 比如 44030012343220234234 (发送出去) - payload PS负载值 国标SDP里面PS负载值 ,比如 96,98 ,108 ,rtp打包时需要 - ssrc 同步源 ssrc - src_port 发送端绑定的端口号 指定服务器在发送国标流时绑定的端口号,如果为 0 ,由服务器自动分配,别的值 比如 26324 为指定端口 - dst_url 目标IP 目标IP地址 - dst_port 目标端口 目标端口 - is_udp 是否设置udp 0 TCP主动方式,1 udp 方式 ,2 为 TCP 被动方式 - RtpPayloadDataType rtp打包数据格式 【可选参数 ,默认 1 】 [ 1 PS 国标gb28181 ]、[ 2 ES 视频支持 H246\H265,音频只支持G711A、G711U ]、[3 XHB (一家公司的打包格式) 只支持视频,音频不能加入打包 ] [ 4 、Jt1078(2016版本)码流发送 ] - disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 - disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 - jtt1078_version 指定1078版本号 2013、2016、2019 【可选参数】 2013 指定为 2013版本 、2016 指定为 2016版本、 2019 指定为 2019 版本 - - recv_app 应用名 比如 gb28181 、rtp 等等 【可选参数】 接入进来 通过在发送的连接中接收进来的码流 - recv_stream 媒体流名 比如 44030012343220234234 【可选参数】 接入进来 通过在发送的连接中接收进来的码流 - recv_disableVideo 是否过滤掉视频 0 不过滤 ,1 过滤视频 【可选参数】 默认 0 不过滤视频,国家电网协议中需要摄像头和摄像头直接需要对接,摄像头推上来的媒体流中过滤掉视频(disableVideo=1)再发给对方才能完成对讲 - recv_disableAudio 是否过滤掉音频 0 不过滤 ,1 过滤音频 【可选参数】 默认 0 不过滤音频,有时候不需要音频、或者由于敏感原因禁止收听音频,可以过滤掉音频流接入流媒体服务器,只需要设置 disableAudio = 1即可过滤音频 - - http GET 方式 - http://190.15.240.11:7088/index/api/startSendRtp?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=gb28181&stream=44030012343220234234&payload=96&ssrc=5224&src_port=26324&dst_url=190.15.240.11&dst_port=9824&is_udp=1 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/startSendRtp - - http 参数值 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","payload":96,"ssrc":2432,"src_port":26324,"dst_url":"190.15.240.11","dst_port":9824,"is_udp":1} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "port": 8356, # 端口号 - "memo": "success", # success 为成功 - "key": 93 # 成功时返回大于0的值,GB28181发送码流实例key ,关闭时需要 - } - - 2 删除 GB28181\Jtt1078发送端口 - URL: /index/api/stopSendRtp - 功能: - 删除GB28181\Jtt1078发送端口 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 主键值ID 比如 93 , 调用 /index/api/startSendRtp 返回的 key 的值 - - http GET 方式 - http://190.15.240.11:7088/index/api/stopSendRtp?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/stopSendRtp - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 11)、获取流媒体服务器所有可用的媒体源 - URL: /index/api/getMediaList - - 功能: - 获取流媒体服务器所有媒体源 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【可选参数】 - stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【可选参数】 - - 参数填写样例说明: - 样例1(app、stream 都不填写) - secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc - - 返回所有在线的媒体源 - - 样例2 (只填写 app ) - secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc - app rtp - 返回 app 等于 rtp 的所有媒体源 - - 样例3 (填写 app = rtp , stream = 44303403343034243200234) - secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc - app rtp - stream 44303403343034243200234 - 返回 app 等于 rtp、并且 stream 等于 44303403343034243200234 的所有媒体源 - - 样例4 (填写 stream = 44303403343034243200234) - secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc - stream 44303403343034243200234 - 返回 stream 等于 44303403343034243200234 的所有媒体源 - - http GET 方式 - http://127.0.0.1:7088/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/getMediaList - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} - - 返回Body: - { - "code": 0, - "memo": "success", - "mediaList": [ - { - "key": 34, - "app": "Media", - "stream": "Camera_00001", - "sim": "123456789123", 【1078码流接入这个字段的值不会为空,代表设备的sim卡编码 】 - "status": false , 【 false 尚未录像,true 正在录像 】 - "enable_hls": false, 【 false 尚未启用,true 启用hls回放 】 - "transcodingStatus": false, 【 false 尚未转码,true 正在转码 】 - "sourceURL": "rtsp://10.0.0.239:554/Media/Camera_00001", - "sourceType": 23, - "readerCount": 0, - "videoCodec": "H264", - "width": 1920, - "height": 1080, - "networkType": 24, - "audioCodec": "AAC", - "audioChannels": 1, - "audioSampleRate": 16000, - "url": { - "rtsp": "rtsp://10.0.0.239:554/Media/Camera_00001", - "rtmp": "rtmp://10.0.0.239:1935/Media/Camera_00001", - "http-flv": "http://10.0.0.239:8088/Media/Camera_00001.flv", - "ws-flv": "ws://10.0.0.239:6088/Media/Camera_00001.flv", - "http-mp4": "http://10.0.0.239:5088/Media/Camera_00001.mp4", - "http-hls": "http://10.0.0.239:9088/Media/Camera_00001.m3u8", - "webrtc":"http://10.0.0.239:8892/webrtc-streamer.html?video=/Media/Camera_00001" - } - } - ] - } - - 【注释:可以根据 "networkType": 24, 这个字段值区分 媒体接入的类型 ,具体详见网络类型的对照表 】 - - 12) 删除 某一个媒体源 - URL: /index/api/delMediaStream - 功能: - 某一个媒体源,这媒体源,可以是rtp推流、rtmp推流,各种方式代理拉流接入的,国标接入 等等。 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 主键值ID 比如 93 , 调用 /index/api/getMediaList 返回的 key 的值 - - http GET 方式 - http://190.15.240.11:7088/index/api/delMediaStream?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/delMediaStream - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 13)、获取流媒体服务器所有往外部输出码流列表,包括外部请求的rtsp、rtmp、http-flv、ws-flv、hls 列表 - 也包括服务器代理rtsp推流、rtmp推流列表 - 也包括服务器以国标方式往上级推rtp流列表 - 【必要时可以调用 /index/api/delOutList 接口删除某一个列表对象,比如删除某一路国标推流、删除某一路rtsp推流、 删除某一路rtmp推流】 - URL: /index/api/getOutList - - 功能: - 获取流媒体服务器所有输出流列表 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http GET 方式 - http://44.35.33.239:7088/index/api/getOutList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http POST 方式 - http URL - http://44.35.33.239:7088/index/api/getOutList - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} - - 返回Body: - { - "code": 0, - "memo": "success", - "outList": [ - { - "key": 103, 【请求客户端的标识ID ,可以调用 /index/api/delOutList 删除 该请求】 - "app": "Media", - "stream": "Camera_00001", - "sourceURL": "rtsp://44.35.33.239:554/Media/Camera_00001", 【表示外界以rtsp方式向服务器请求码流】 - "videoCodec": "H264", - "audioCodec": "AAC", - "audioChannels": 1, - "audioSampleRate": 16000, - "networkType": 24, 【网络类型为24 ,标识为rtsp 方式】 - "dst_url": "44.35.33.39", 【 请求码流客户端IP 】 - "dst_port": 43801 【 请求码流客户端端口 】 - }, - { - "key": 85, 【请求客户端的标识ID ,可以调用 /index/api/delOutList 删除 该请求】 - "app": "Media", - "stream": "Camera_00001", - "sourceURL": "http://localhost:8088/Media/Camera_00001.flv",【表示外界以 http-flv 方式向服务器请求码流】 - "videoCodec": "H264", - "audioCodec": "AAC", - "audioChannels": 1, - "audioSampleRate": 16000, - "networkType": 25, 【网络类型为25 ,标识为 http-flv 方式】 - "dst_url": "44.35.33.39", 【 请求码流客户端IP 】 - "dst_port": 43806 【 请求码流客户端端口 】 - } - ] - } - - 【注释:可以根据 "networkType": 24, 这个字段值区分 媒体输出的类型 ,具体详见网络类型的对照表 】 - - 14) 删除 某一个服务器所有往外部输出码流列表 - URL: /index/api/delOutList - 功能: - 删除某一个流媒体服务器所有往外部输出码流列表,包括外部请求的rtsp、rtmp、http-flv、ws-flv、hls 点播 。国标推流、rtsp推流、rtmp 推流 等等 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - key 主键值ID 比如 93 , 调用 /index/api/getOutList 返回的 key 的值 - - http GET 方式 - http://190.15.240.11:7088/index/api/delOutList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=93 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/delOutList - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","key":93} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 ,如果失败是其他值 - } - - 15)根据条件组合,删除任意一个或一组或者全部媒体输入列表 - URL: /index/api/close_streams - - 功能 - 删除任意一个或一组或者全部媒体输入列表 - - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - vhost 比如 _defaultVhost_ 【可选参数】 - app 应用名 比如 gb28181 、rtp 等等 【可选参数】 - stream 媒体流名 比如 Camera_00001、dsafdsafassdafadsfas、等等 【可选参数】 - force 是否强制关闭 1 强制关闭,不管是否有人在观看、0 非强制关闭,当有人观看时不关闭。 【必填参数】 - - http GET 方式 - 示例1: http://190.168.24.112:7088/index/api/close_streams?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=live&force=1 - 【表示强行关闭 app 等于 live 的码流接入】 - 示例2: http://190.168.24.112:7088/index/api/close_streams?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=live&stream=Camera_00001&force=1 - 【表示强行关闭 app 等于 live, 并且 stream 等于 Camera_00001 的码流接入 】 - 示例3: http://190.168.24.112:7088/index/api/close_streams?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&force=1 - 【表示强行关闭 所有码流(app全部、stream全部) 接入 】 - - http pos 方式 - 示例1: http URL: - http://190.168.24.112:7088/index/api/close_streams - body: - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","app":"live","force":1} - - 【表示强行关闭 app 等于 live 的码流接入】 - - 示例2: http URL: - http://190.168.24.112:7088/index/api/close_streams - body: - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","app":"live","stream":"Camera_00001","force":1} - - 【表示强行关闭 app 等于 live, 并且 stream 等于 Camera_00001 的码流接入 】 - - 示例3: http URL: - http://190.168.24.112:7088/index/api/close_streams - body: - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","force":1} - - 【 表示强行关闭 所有码流(app全部、stream全部) 接入 】 - - 16)、 开始录像、停止录像 - 1) 申请开始录像 - - URL: /index/api/startRecord - - 参数: 参数说明 参考值 - secret 服务器密码 ,比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - vhost 比如 _defaultVhost_ - app 应用名 比如 Media - stream 媒体流名 比如 Camera_00001 - - http GET 方式 - http://190.15.240.11:7088/index/api/startRecord?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/startRecord - - http Body 参数 (json格式) - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001"} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "MediaSource: /Media/Camera_00001 start Record", # "code": 0 为成功 - } - - 2) 申请停止录像 - URL: /index/api/stopRecord - - 参数: 参数说明 参考值 - secret 服务器密码 ,比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - vhost 比如 _defaultVhost_ - app 应用名 比如 Media - stream 媒体流名 比如 Camera_00001 - - http GET 方式 - http://190.15.240.11:7088/index/api/stopRecord?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/stopRecord - - http Body 参数 (json格式) - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001"} - - 返回Body: - { - "code": 0, # 0为操作成功,其他值为操作失败 - "memo": "success", # success 为成功 - } - - 17 获取系统配置参数 - URL: /index/api/getServerConfig - 功能: - 获取服务器的配置参数 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http GET 方式 - http://190.15.240.11:7088/index/api/getServerConfig?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/getServerConfig - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} - - 返回Body: - { - "code": 0, - "params": [ - - { - "secret": "035c73f7-bb6b-4889-a715-d9eb2d1925cc", - "memo": "server password", - }, - { - "ServerIP": "44.35.33.239", - "memo": "ABLMediaServer ip address" - }, - { - "rtc.listening-ip": "192.168.2.5", - "memo": "Total number of video playback threads ." - }, - { - "mediaServerID": "ABLMediaServer_00001", - "memo": "media Server ID " - }, - { - "hook_enable": 0, - "memo": "hook_enable = 1 open notice , hook_enable = 0 close notice " - }, - { - "enable_audio": 1, - "memo": "enable_audio = 1 open Audio , enable_audio = 0 Close Audio " - }, - { - "httpServerPort": 7088, - "memo": "http api port " - }, - { - "rtspPort": 554, - "memo": "rtsp port " - }, - { - "rtmpPort": 1935, - "memo": "rtmp port " - }, - { - "httpFlvPort": 8088, - "memo": "http-flv port " - }, - { - "hls_enable": 0, - "memo": "hls whether enable " - }, - { - "hlsPort": 9088, - "memo": "hls port" - }, - { - "wsPort": 6088, - "memo": "websocket flv port" - }, - { - "mp4Port": 5088, - "memo": "http mp4 port" - }, - { - "ps_tsRecvPort": 10000, - "memo": "recv ts , ps Stream port " - }, - { - "hlsCutType": 2, - "memo": "hlsCutType = 1 hls cut to Harddisk,hlsCutType = 2 hls cut Media to memory" - }, - { - "h265CutType": 1, - "memo": " 1 h265 cut TS , 2 cut fmp4 " - }, - { - "RecvThreadCount": 128, - "memo": " RecvThreadCount " - }, - { - "SendThreadCount": 128, - "memo": "SendThreadCount" - }, - { - "GB28181RtpTCPHeadType": 2, - "memo": "rtp Length Type" - }, - { - "ReConnectingCount": 40320, - "memo": "Try reconnections times ." - }, - { - "maxTimeNoOneWatch": 9999999, - "memo": "maxTimeNoOneWatch ." - }, - { - "pushEnable_mp4": 0, - "memo": "pushEnable_mp4 ." - }, - { - "fileSecond": 180, - "memo": "fileSecond ." - }, - { - "fileKeepMaxTime": 1, - "memo": "fileKeepMaxTime ." - }, - { - "httpDownloadSpeed": 6, - "memo": "httpDownloadSpeed ." - }, - { - "RecordReplayThread": 32, - "memo": "Total number of video playback threads ." - } - ] - } - - 18)、查询录像列表 - URL: /index/api/queryRecordList - - 功能: - 查询某一路输入源的录像列表(可以查询代理拉流输入、推流输入、国标输入等等 ) - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - vhost 比如 _defaultVhost_ 【可选参数】 - app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【必填参数】 - stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【必填参数】 - starttime 开始时间 比如 20220116154810 年月日时分秒 【必填参数】 - endtime 结束时间 比如 20220116155115 年月日时分秒 【必填参数】 - - 【注意:1、开始时间必须小于 当前时间减去切片时长的时间 2、从 开始时间 至 结束时间 不能超过3天】 - - http GET 方式 - http://10.0.0.239:7088/index/api/queryRecordList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=Media&stream=Camera_00001&starttime=20220116154810&endtime=20220116155115 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/queryRecordList - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","starttime":"20220116154810","endtime":"20220116155115"} - - 返回Body: - { - "code": 0, - "app": "Media", - "stream": "Camera_00001", - "starttime": "20220116154810", - "endtime": "20220116155115", - "recordFileList": [ - { - "file": "20220116154810.mp4", - "duration": 300, 当前录像时间长度,单位 秒 - "url": { - "rtsp": "rtsp://10.0.0.239:554/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810", - "rtmp": "rtmp://10.0.0.239:1935/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810", - "http-flv": "http://10.0.0.239:8088/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810.flv", - "ws-flv": "ws://10.0.0.239:6088/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810.flv", - "http-mp4": "http://10.0.0.239:5088/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810.mp4?download_speed=1", - "download": "http://10.0.0.239:5088/Media/Camera_00001__ReplayFMP4RecordFile__20220116154810.mp4?download_speed=6" - } - }, - { - "file": "20220116155110.mp4", - "duration": 256, 当前录像时间长度,单位 秒 - "url": { - "rtsp": "rtsp://10.0.0.239:554/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110", - "rtmp": "rtmp://10.0.0.239:1935/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110", - "http-flv": "http://10.0.0.239:8088/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110.flv", - "ws-flv": "ws://10.0.0.239:6088/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110.flv", - "http-mp4": "http://10.0.0.239:5088/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110.mp4?download_speed=1", - "download": "http://10.0.0.239:5088/Media/Camera_00001__ReplayFMP4RecordFile__20220116155110.mp4?download_speed=6" - } - } - ] - } - 19)、消息通知使用 - 功能说明:消息通知是流媒体服务器的一些消息比如无人观看、fmp4录像切片完成、播放时流地址不存在等等信息能及时的通知到另外一个http服务器上,需要此功能 - 消息通知功能用在什么地方,比如说无人观看消息通知,当收到无人观看消息时,国标服务器可以关闭国标发流,断开代理拉流,断开推流等等操作 - 要使用此功能把配置文件的参数hook_enable 值设置为 1,同时通知的http服务器地址、端口号一定要设置对,下面列举出配置文件中的相关参数 - - hook_enable=1 #事件通知部分,当 hook_enable=1 时,开启事件通知,hook_enable=0时关闭事件通知 - on_stream_arrive=http://10.0.0.238:7088/index/hook/on_stream_arrive #当某一路的码流达到时会通知一次 - on_stream_none_reader=http://10.0.0.238:8080/index/hook/on_stream_none_reader #当某一路流无人观看时,会触发该通知事件,接收端收到后可以进行断流操作 - on_stream_disconnect=http://10.0.0.238:7088/index/hook/on_stream_disconnect #当某一路码流断开时会通知一次 - on_stream_not_found=http://10.0.0.238:8080/index/hook/on_stream_not_found #播放时,找不到播放的码流,通过配合on_stream_none_reader事件可以完成按需拉流 - on_record_mp4=http://10.0.0.238:8080/index/hook/on_record_mp4 #录制完毕一段mp4文件通知 - - 【注:http url的 IP,端口 是代表消息接收服务器的IP,端口,一定要填写正确,url 地址要合法,不要有空格 】 - 1、当某一路码流到达时会发送通知: - POST /index/hook/on_stream_arrive HTTP/1.1 # 根据 /index/hook/on_stream_arrive 这个可以判断是某一路码流到达 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 105 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-5.2.9(2022-03-28) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - { - "app":"Media", # app - "stream":"Camera_00001", # stream - "mediaServerId":"ABLMediaServer_00001", # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 - "networkType":23, # 媒体流来源网络编号,可参考附表 - "key":130, # 媒体流来源编号,可以根据这个key进行关闭流媒体 可以调用delMediaStream或close_streams 函数进行关闭 - "status":true, - "enable_hls":false, - "transcodingStatus":false, - "sourceURL":"rtsp://admin:abldyjh2020@44.35.33.248:554", - "readerCount":0, - "noneReaderDuration":0, - "videoCodec":"H265", - "videoFrameSpeed":25, - "width":1920, - "height":1080, - "videoBitrate":0, - "audioCodec":"AAC", - "audioChannels":1, - "audioSampleRate":8000, - "audioBitrate":0, - "url": - { - "rtsp":"rtsp://44.35.33.249:554/Media/Camera_00001", - "rtmp":"rtmp://44.35.33.249:1935/Media/Camera_00001", - "http-flv":"http://44.35.33.249:8088/Media/Camera_00001.flv", - "ws-flv":"ws://44.35.33.249:6088/Media/Camera_00001.flv", - "http-mp4":"http://44.35.33.249:5088/Media/Camera_00001.mp4", - "http-hls":"http://44.35.33.249:9088/Media/Camera_00001.m3u8" - } - } - - 2、无人观看消息通知样例: - POST /index/hook/on_stream_none_reader HTTP/1.1 # 根据 /index/hook/on_stream_none_reader 这个可以判断是无人观看消息通知 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 105 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-5.2.9(2022-03-28) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - { - "app":"Media", # app - "stream":"Camera_00001", # stream - "mediaServerId":"ABLMediaServer_00001", # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 - "networkType":23, # 媒体流来源网络编号,可参考附表 - "key":130 # 媒体流来源编号,可以根据这个key进行关闭流媒体 可以调用delMediaStream或close_streams 函数进行关闭 - } - - 3、 fmp4录像切片录像完成一个文件时会发送一个消息通知 - POST /index/hook/on_record_mp4 HTTP/1.1 # 根据 /index/hook/on_record_mp4 这个可以判断是mp4录像切片完毕一个通知 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 127 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-5.2.9(2022-03-28) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - { - "app":"Media", # app - "stream":"Camera_00001", # stream - "mediaServerId":"ABLMediaServer_00001", # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 - "networkType":70, # 媒体流来源网络编号,可参考附表 - "fileName":"20220312212546.mp4" # 录像切片完成的文件名字 - } - - 4、当某一路码流断开时会发送通知: - POST /index/hook/on_stream_disconnect HTTP/1.1 # 根据 /index/hook/on_stream_disconnect 这个可以判断是某一路码流断开 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 105 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-5.2.9(2022-03-28) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - { - "app":"Media", # app - "stream":"Camera_00001", # stream - "mediaServerId":"ABLMediaServer_00001", # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 - "networkType":23, # 媒体流来源网络编号,可参考附表 - "key":130 # 媒体流来源编号,可以根据这个key进行关闭流媒体 可以调用delMediaStream或close_streams 函数进行关闭 - } - - 5、 当播放一个url,如果不存在时,会发出一个消息通知 - POST /index/hook/on_stream_not_found HTTP/1.1 # 根据 /index/hook/on_stream_not_found ,Http接收服务器得知流不不存在 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 127 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-5.2.9(2022-03-28) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - { - "app":"Media", # app 不存在的app - "stream":"Camera_00001", # stream 不存在的stream - "mediaServerId":"ABLMediaServer_00001" # 流媒体服务器编号 ,在配置文件可以配置,如果集群流媒体服务器时,可以给每台流媒体服务器起个编号 - } - 6、ABLMediaServer启动时会发送上线通知 - POST /index/hook/on_server_started HTTP/1.1 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 105 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-6.3.5(2023-04-30) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - {"localipAddress":"44.35.33.249","mediaServerId":"ABLMediaServer_00001","datetime":"2023-04-18 10:04:37"} - - 7、某一个码流接入流媒体服务器时会产生 发布 事件通知 - POST /index/hook/on_publish HTTP/1.1 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 149 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-6.3.5(2023-04-30) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","networkType":50,"key":470,"ip":"44.35.33.248" ,"port":554,"params":""} - - 8、当播放流媒体服务器里面某一个码流时,会触发 播放事件 ,可以通知 parmas 参数值进行播放鉴权 - POST /index/hook/on_play HTTP/1.1 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 135 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-6.3.5(2023-04-30) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","networkType":30,"key":472,"ip":"" ,"port":0,"params":"user=admin&password=safsa234234&token=@#$@#$@#ASDFasfdsa@#$23"} - - 9、如果某一个码流进行MP4录像(enable_mp4=1),会触发录像进度通知事件 - POST /index/hook/on_record_progress HTTP/1.1 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 204 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-6.3.5(2023-04-30) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","networkType":472,"key":470,"fileName":"20230418100440.mp4","currentFileDuration":49,"TotalVideoDuration":49} - - 10、如果某一个码流开启hls(enable_hls=1)并且设置为切片到硬盘(hlsCutType=1 在配置文件中) ,每当切片完成一个ts文件会触发该事件 - POST /index/hook/on_record_ts HTTP/1.1 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 246 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-6.3.5(2023-04-30) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","networkType":30,"key":470,"createDateTime":"2023-04-18 10:05:47","currentFileDuration":3,"fileName":"D:\WorkDir\ABLMediaServer\x64\Debug\www\Media\Camera_00001\23.ts"} - - 11、流媒体服务器每隔60秒会触发心跳事件通知 - POST /index/hook/on_server_keepalive HTTP/1.1 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 105 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-6.3.5(2023-04-30) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - {"localipAddress":"44.35.33.249","mediaServerId":"ABLMediaServer_00001","datetime":"2023-04-18 10:25:40"} - - 12、当代理拉流、国标接入等等 码流不到达时会发出 码流不到达的事件通知 - POST /index/hook/on_stream_not_arrive HTTP/1.1 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 155 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-6.3.5(2023-04-30) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - {"mediaServerId":"ABLMediaServer_00001","app":"gb28181","stream":"440300123432202342349","networkType":60,"key":470} - - 13、如果某一个码流进行MP4录像(enable_mp4=1),当某个MP4文件被删除会触发该事件通知 - POST /index/hook/on_delete_record_mp4 HTTP/1.1 - Accept: */* - Accept-Language: zh-CN,zh;q=0.8 - Connection: keep-alive - Content-Length: 204 - Content-Type: application/json - Host: 127.0.0.1 - Tools: ABLMediaServer-6.3.5(2023-04-30) - User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 - - {"app":"Media","stream":"Camera_00001","mediaServerId":"ABLMediaServer_00001","fileName":"20230418100440.mp4"} - - - - 20) 图片抓拍 - URL: /index/api/getSnap - - 功能: - 查询某一接入的媒体源进行抓拍 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - vhost 比如 _defaultVhost_ 【可选参数】 - app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【必填参数】 - stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【必填参数】 - timeout_sec 超时时长 10 即本次抓拍最大超时时长 单位 秒 【必填参数】 - - http GET 方式 - http://127.0.0.1:7088/index/api/getSnap?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=_defaultVhost_&app=Media&stream=Camera_00001&timeout_sec=10 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/getSnap - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","timeout_sec":10} - - 抓拍成功返回: - { - "code": 0, - "memo": "success , Catpuring takes time 219 millisecond .", - "url": "http://10.0.0.239:7088/Media/Camera_00001/2022031910034501.jpg" - } - - 21)图片列表查询 - URL: /index/api/queryPictureList - - 功能: - 查询某一路输入源的抓拍图片列表 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - vhost 比如 _defaultVhost_ 【可选参数】 - app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【必填参数】 - stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【必填参数】 - starttime 开始时间 比如 20220317081201 年月日时分秒 【必填参数】 - endtime 结束时间 比如 20220319231201 年月日时分秒 【必填参数】 - - 【注意:1、开始时间必须小于 当前时间减去切片时长的时间 2、从 开始时间 至 结束时间 不能超过7天】 - - http GET 方式 - http://10.0.0.239:7088/index/api/queryPictureList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=Media&stream=Camera_00001&starttime=20220317081201&endtime=20220319231201 - - http POST 方式 - http URL - http://190.15.240.11:7088/index/api/queryPictureList - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","vhost":"_defaultVhost_","app":"Media","stream":"Camera_00001","starttime":"20220317081201","endtime":"20220319231201"} - - 成功返回Body值 - { - "code": 0, - "app": "Media", - "stream": "Camera_00001", - "starttime": "20220317081201", - "endtime": "20220319231201", - "PictureFileList": [ - { - "file": "2022031816153857.jpg", - "url": "http://10.0.0.239:7088/Media/Camera_00001/2022031816153857.jpg" - }, - { - "file": "2022031816153958.jpg", - "url": "http://10.0.0.239:7088/Media/Camera_00001/2022031816153958.jpg" - }, - { - "file": "2022031816154059.jpg", - "url": "http://10.0.0.239:7088/Media/Camera_00001/2022031816154059.jpg" - }, - ] - } - - 22、修改某一路的水印相关参数 - - URL: index/api/setTransFilter - - 功能: - 修改某一路的水印相关参数,比水印的内容、颜色、字体大小、字体位置、字体透明度 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - vhost 比如 _defaultVhost_ 【可选参数】 - app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【必填参数】 - stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【必填参数】 - text 水印内容 比如 某某市某某公安局 【必填参数】 - size 字体大小 20、30 、40 、50 【必填参数】 - color 字体颜色 red,green,blue,white,black, - alpha 透明度 0.1 ~ 0.9 , - left 水印x坐标 比如 5 、 10 、20 - top 水印y坐标 比如 5 、 10 、 20 - trans 是否转换 固定为 1 - - http POST 方式 - http://127.0.0.1:7088/index/api/setTransFilter - - Body 参数内容为 - { - "secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc", - "app" : "live", - "stream" : "test", - "text" : "ABL", - "size" : 60, - "color" : "red", - "alpha" : 0.8, - "left" : 40, - "top" : 40, - "trans" : 1 - } - - 23、为了功能更新的需要,增加设置参数值的接口,可以单独设置 ABLMediaServer.ini 的某一个值,并且服务器不用重启,立即起效 - - URL: index/api/setConfigParamValue - - 功能: - 为了功能更新的需要,增加设置参数值的接口,可以单独设置 ABLMediaServer.ini 的某一个值,并且服务器不用重启,立即起效 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - vhost 比如 _defaultVhost_ 【可选参数】 - key 参数名 比如 saveGB28181Rtp (保存接入的国标PS流)、 saveProxyRtspRtp (保存rtsp代理拉流的rtp流) - 还有 ABLMediaServer.ini 里面的配置参数,如果参数值不填就设置空,不是空格 - mediaServerID = ABLMediaServer_00001 - secret = 035c73f7-bb6b-4889-a715-d9eb2d1925cc - localipAddress = - maxTimeNoOneWatch = 9999999 - recordPath = - picturePath = - maxSameTimeSnap = 16 - snapOutPictureWidth = 0 - snapOutPictureHeight = 0 - snapObjectDestroy = 1 - snapObjectDuration = 120 - captureReplayType = 1 - pictureMaxCount = 30 - pushEnable_mp4 = 0 - fileSecond = 300 - videoFileFormat = 1 - fileKeepMaxTime = 3 - httpDownloadSpeed = 6 - fileRepeat = 0 - H265ConvertH264_enable = 0 - H265DecodeCpuGpuType = 0 - H264DecodeEncode_enable = 0 - filterVideo_enable = 0 - filterVideo_text = ABL水印测试123 - FilterFontSize = 30 - FilterFontColor = red - FilterFontLeft = 5 - FilterFontTop = 5 - FilterFontAlpha = 0.6 - convertOutWidth = 720 - convertOutHeight = 480 - convertMaxObject = 26 - convertOutBitrate = 1024 - hook_enable = 0 - noneReaderDuration = 15 - on_server_started = http://10.0.0.238:4088/index/hook/on_server_started - on_server_keepalive = http://10.0.0.238:4088/index/hook/on_server_keepalive - on_stream_arrive = http://10.0.0.238:4088/index/hook/on_stream_arrive - on_stream_not_arrive = http://10.0.0.238:4088/index/hook/on_stream_not_arrive - on_stream_none_reader = http://10.0.0.238:4088/index/hook/on_stream_none_reader - on_stream_disconnect = http://10.0.0.238:4088/index/hook/on_stream_disconnect - on_stream_not_found = - on_record_mp4 = http://10.0.0.238:4088/index/hook/on_record_mp4 - on_delete_record_mp4 = http://10.0.0.238:4088/index/hook/on_delete_record_mp4 - on_record_progress = http://10.0.0.238:4088/index/hook/on_record_progress - on_record_ts = http://10.0.0.238:4088/index/hook/on_record_ts - httpServerPort = 7088 - rtspPort = 554 - rtmpPort = 1935 - httpMp4Port = 5088 - wsFlvPort = 6088 - httpFlvPort = 8088 - ps_tsRecvPort = 10000 - hls_enable = 0 - hlsPort = 9088 - hlsCutTime = 3 - hlsCutType = 2 - h265CutType = 1 - enable_audio = 1 - G711ConvertAAC = 0 - IOContentNumber = 16 - ThreadCountOfIOContent = 8 - RecvThreadCount = 128 - SendThreadCount = 128 - RecordReplayThread = 32 - GB28181RtpTCPHeadType = 2 - ReConnectingCount = 40320 - MaxDiconnectTimeoutSecond = 36 - ForceSendingIFrame = 1 - value 参数值 详见 ABLMediaServer.ini 的参数值及参数值说明 - - http GET 方式 -   比如: - 打开保存国标PS标志 -    http://44.35.33.239:7088/index/api/setConfigParamValue?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=saveGB28181Rtp&value=1 - 关闭存国标PS标志 -    http://44.35.33.239:7088/index/api/setConfigParamValue?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=saveGB28181Rtp&value=0 - - 打开保存代理拉rtsp流标志 -    http://44.35.33.239:7088/index/api/setConfigParamValue?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=saveProxyRtspRtp&value=1 - 关闭保存代理拉rtsp流标志 -    http://44.35.33.239:7088/index/api/setConfigParamValue?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=saveProxyRtspRtp&value=0 - - 24)安全停止服务器 - URL: /index/api/shutdownServer - - 功能: - 安全停止服务器,如果服务器正在录像、抓拍等等操作,需要调用该函数安全停止服务器,这样录制的mp4才能正常播放 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - - http GET 方式 - http://127.0.0.1:7088/index/api/shutdownServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http POST 方式 - http URL - http://127.0.0.1:7088/index/api/shutdownServer - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} - - 返回Body: - { - "code": 0, - "memo": "ABLMediaServer shutdown Successed !" - } - - 25)重新启动服务器 - URL: /index/api/restartServer - - 功能: - 安全重启服务器,如果服务器正在录像、抓拍等等操作,需要调用该函数安全重启服务器,这样录制的mp4才能正常播放 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - - http GET 方式 - http://127.0.0.1:7088/index/api/restartServer?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http POST 方式 - http URL - http://127.0.0.1:7088/index/api/restartServer - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} - - 返回Body: - { - "code": 0, - "memo": "ABLMediaServer restartServer Successed ! " - } - - 26)获取当前转码的数量 - URL: /index/api/getTranscodingCount - - 功能: - 获取当前正在转码的数量 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - - http GET 方式 - http://127.0.0.1:7088/index/api/getTranscodingCount?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http POST 方式 - http URL - http://127.0.0.1:7088/index/api/getTranscodingCount - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} - - 返回Body: - { - "code": 0, - "currentTranscodingCount": 2 - } - - 27)、列举流媒体服务器所有占用端口 - URL: /index/api/listServerPort - - 功能: - 列举流媒体服务器所有占用端口 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - app 应用名 比如 rtp、gb28181、Media 等等 ,自己起的名字 【可选参数】 - stream 媒体流名 比如 Camera_00001、44303403343034243200234 等等 【可选参数】 - - 参数填写样例说明: - 样例1(app、stream 都不填写) - secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc - - 返回所有在线的媒体源 - - 样例2 (只填写 app ) - secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc - app rtp - 返回 app 等于 rtp 的所有媒体源 - - 样例3 (填写 app = rtp , stream = 44303403343034243200234) - secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc - app rtp - stream 44303403343034243200234 - 返回 app 等于 rtp、并且 stream 等于 44303403343034243200234 的所有媒体源 - - 样例4 (填写 stream = 44303403343034243200234) - secret 035c73f7-bb6b-4889-a715-d9eb2d1925cc - stream 44303403343034243200234 - 返回 stream 等于 44303403343034243200234 的所有媒体源 - - http GET 方式 - http://127.0.0.1:7088/index/api/listServerPort?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc - - http POST 方式 - http URL - http://127.0.0.1:7088/index/api/listServerPort - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc"} - - 返回Body: - { - "code": 0, - "memo": "success", - "data": [ - { - "key": 478, - "app": "Media", - "stream": "Camera_00003", - "networkType": 23, - "port": 34988 - }, - { - "key": 477, - "app": "Media", - "stream": "Camera_00002", - "networkType": 23, - "port": 34986 - }, - { - "key": 476, - "app": "Media", - "stream": "Camera_00001", - "networkType": 23, - "port": 34984 - }, - { - "key": 456, - "app": "", - "stream": "", - "networkType": 68, - "port": 10000 - } - ] - } - - 【注释:可以根据 "networkType": 23, 这个字段标识对象的网络类型 ,具体详见网络类型的对照表 】 - - 28)、批量设置服务器的配置参数 - URL: /index/api/setServerConfig - - 功能: - 批量设置服务器的配置参数 - - 参数: 参数说明 参数参考值 - secret 服务器密码 比如 035c73f7-bb6b-4889-a715-d9eb2d1925cc 【必填参数】 - noneReaderDuration 多少秒无人观看通知一次 20 【可选参数】 - on_server_started 服务器启动通知 http://10.0.0.238:4088/index/hook/on_server_started 【可选参数】 - iframeArriveNoticCount i帧达到通知总数 30 【可选参数】 - - http GET 方式 - http://127.0.0.1:7088/index/api/setServerConfig?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&noneReaderDuration=20&on_server_started=http://10.0.0.238:4088/index/hook/on_server_started&iframeArriveNoticCount=30 - - http POST 方式 - http URL - http://127.0.0.1:7088/index/api/setServerConfig - - http Body 参数 json 格式 - {"secret":"035c73f7-bb6b-4889-a715-d9eb2d1925cc","noneReaderDuration":20,"iframeArriveNoticCount":30,"on_server_started":"http://10.0.0.238:4088/index/hook/on_server_started"} - - 29) 为了方便某些特殊场合,服务器支持udp的10000 端口接入国标PS码流,就是人们常说的单端口模式,url的命名规则为 /rtp/ssrc ,其中ssrc为下级rtp打包 - 的16进制的值转换为大小的字符串,即可sprintf(url,"rtp/%X",ssrc) ,具体接入的url名字可以调用 getMediaList 查询出接入的国标流 。需要注意的是 - 下级 rtp 打包时每路视频的rtp中的ssrc不能相同。 - - - 30) 网络类型的对照表 - 1 媒体输入网络类型对照表 - - 整形值 代表意义 - 21 以rtmp方式推送接入流媒体服务器 - 23 以rtsp方式推送接入流媒体服务器 - 30 服务器以rtsp方式主动拉流接入 - 31 服务器以rtmp方式主动拉流接入 - 32 服务器以flv方式主动拉流接入 - 33 服务器以hls方式主动拉流接入 - 50 代理拉流接入服务器 - 60 服务器以国标28181的UDP方式接入 - 61 服务器以国标28181的TCP方式接入 - - 80 服务器录像文件点播以读取fmp4文件输入 - 81 服务器录像文件点播以读取TS文件输入 - 82 服务器录像文件点播以读取PS文件输入 - 83 服务器录像文件点播以读取FLV文件输入 - - 2 媒体输出网络类型对照表 - 整形值 代表意义 - 22 服务器以rtsp被动方式往外发送码流 ,即常见的vlc点播 - 24 服务器以rtmp被动方式往外发送码流 ,即常见的vlc点播 - 25 服务器以flv被动方式往外发送码流 ,即常见的vlc点播 、浏览器播放 - 26 服务器以hls被动方式往外发送码流 ,即常见的vlc点播 、浏览器播放 - 27 服务器以ws-flv被动方式往外发送码流 ,EasyPlayer.js插件播放、浏览器播放 - 28 服务器以http-mp4被动方式往外发送码流 ,即常见的vlc点播 、浏览器播放 - - 40 服务器以rtsp主动方式往外发送码流 ,即常见的rtsp推流 - 41 服务器以rtmp主动方式往外发送码流 ,即常见的rtmp推流 - 65 服务器以国标GB28181主动UDP方式往外发送码流 ,即常见的国标以UDP方式往上级推流 - 66 服务器以国标GB28181主动TCP方式往外发送码流 ,即常见的国标以TCP方式往上级推流 - \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java deleted file mode 100755 index 5eca3bf91..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java +++ /dev/null @@ -1,317 +0,0 @@ -package com.genersoft.iot.vmp.media.abl; - -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.bean.MediaServer; -import okhttp3.*; -import okhttp3.logging.HttpLoggingInterceptor; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.ConnectException; -import java.net.SocketTimeoutException; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -@Component -public class ABLRESTfulUtils { - - private final static Logger logger = LoggerFactory.getLogger(ABLRESTfulUtils.class); - - private OkHttpClient client; - - public interface RequestCallback{ - void run(JSONObject response); - } - - private OkHttpClient getClient(){ - return getClient(null); - } - - private OkHttpClient getClient(Integer readTimeOut){ - if (client == null) { - if (readTimeOut == null) { - readTimeOut = 10; - } - OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); - //todo 暂时写死超时时间 均为5s - // 设置连接超时时间 - httpClientBuilder.connectTimeout(8,TimeUnit.SECONDS); - // 设置读取超时时间 - httpClientBuilder.readTimeout(readTimeOut,TimeUnit.SECONDS); - // 设置连接池 - httpClientBuilder.connectionPool(new ConnectionPool(16, 5, TimeUnit.MINUTES)); - if (logger.isDebugEnabled()) { - HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> { - logger.debug("http请求参数:" + message); - }); - logging.setLevel(HttpLoggingInterceptor.Level.BASIC); - // OkHttp進行添加攔截器loggingInterceptor - httpClientBuilder.addInterceptor(logging); - } - client = httpClientBuilder.build(); - } - return client; - - } - - public JSONObject sendPost(MediaServer mediaServerItem, String api, Map param, RequestCallback callback) { - return sendPost(mediaServerItem, api, param, callback, null); - } - - - public JSONObject sendPost(MediaServer mediaServerItem, String api, Map param, RequestCallback callback, Integer readTimeOut) { - OkHttpClient client = getClient(readTimeOut); - - if (mediaServerItem == null) { - return null; - } - String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); - JSONObject responseJSON = new JSONObject(); - //-2自定义流媒体 调用错误码 - responseJSON.put("code",-2); - responseJSON.put("msg","流媒体调用失败"); - - FormBody.Builder builder = new FormBody.Builder(); - builder.add("secret",mediaServerItem.getSecret()); - if (param != null && param.keySet().size() > 0) { - for (String key : param.keySet()){ - if (param.get(key) != null) { - builder.add(key, param.get(key).toString()); - } - } - } - - FormBody body = builder.build(); - - Request request = new Request.Builder() - .post(body) - .url(url) - .build(); - if (callback == null) { - try { - Response response = client.newCall(request).execute(); - - if (response.isSuccessful()) { - ResponseBody responseBody = response.body(); - if (responseBody != null) { - String responseStr = responseBody.string(); - responseJSON = JSON.parseObject(responseStr); - } - }else { - System.out.println( 2222); - System.out.println( response.code()); - response.close(); - Objects.requireNonNull(response.body()).close(); - } - }catch (IOException e) { - logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); - - if(e instanceof SocketTimeoutException){ - //读取超时超时异常 - logger.error(String.format("读取ABL数据超时失败: %s, %s", url, e.getMessage())); - } - if(e instanceof ConnectException){ - //判断连接异常,我这里是报Failed to connect to 10.7.5.144 - logger.error(String.format("连接ABL连接失败: %s, %s", url, e.getMessage())); - } - - }catch (Exception e){ - logger.error(String.format("访问ABL失败: %s, %s", url, e.getMessage())); - } - }else { - client.newCall(request).enqueue(new Callback(){ - - @Override - public void onResponse(@NotNull Call call, @NotNull Response response){ - if (response.isSuccessful()) { - try { - String responseStr = Objects.requireNonNull(response.body()).string(); - callback.run(JSON.parseObject(responseStr)); - } catch (IOException e) { - logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); - } - - }else { - response.close(); - Objects.requireNonNull(response.body()).close(); - } - } - - @Override - public void onFailure(@NotNull Call call, @NotNull IOException e) { - logger.error(String.format("连接ABL失败: %s, %s", call.request().toString(), e.getMessage())); - - if(e instanceof SocketTimeoutException){ - //读取超时超时异常 - logger.error(String.format("读取ABL数据失败: %s, %s", call.request().toString(), e.getMessage())); - } - if(e instanceof ConnectException){ - //判断连接异常,我这里是报Failed to connect to 10.7.5.144 - logger.error(String.format("连接ABL失败: %s, %s", call.request().toString(), e.getMessage())); - } - } - }); - } - - - - return responseJSON; - } - - public JSONObject sendGet(MediaServer mediaServerItem, String api, Map param) { - OkHttpClient client = getClient(); - - if (mediaServerItem == null) { - return null; - } - JSONObject responseJSON = null; - StringBuilder stringBuffer = new StringBuilder(); - stringBuffer.append(String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api)); - if (param != null && !param.keySet().isEmpty()) { - stringBuffer.append("?secret=").append(mediaServerItem.getSecret()).append("&"); - int index = 1; - for (String key : param.keySet()){ - if (param.get(key) != null) { - stringBuffer.append(key + "=" + param.get(key)); - if (index < param.size()) { - stringBuffer.append("&"); - } - } - index++; - } - } - String url = stringBuffer.toString(); - logger.info("[访问ABL]: {}", url); - Request request = new Request.Builder() - .get() - .url(url) - .build(); - try { - Response response = client.newCall(request).execute(); - if (response.isSuccessful()) { - ResponseBody responseBody = response.body(); - if (responseBody != null) { - String responseStr = responseBody.string(); - responseJSON = JSON.parseObject(responseStr); - } - }else { - response.close(); - Objects.requireNonNull(response.body()).close(); - } - } catch (ConnectException e) { - logger.error(String.format("连接ABL失败: %s, %s", e.getCause().getMessage(), e.getMessage())); - logger.info("请检查media配置并确认ABL已启动..."); - }catch (IOException e) { - logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); - } - - - - return responseJSON; - } - - public void sendGetForImg(MediaServer mediaServerItem, String api, Map params, String targetPath, String fileName) { - String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); - HttpUrl parseUrl = HttpUrl.parse(url); - if (parseUrl == null) { - return; - } - HttpUrl.Builder httpBuilder = parseUrl.newBuilder(); - - httpBuilder.addQueryParameter("secret", mediaServerItem.getSecret()); - if (params != null) { - for (Map.Entry param : params.entrySet()) { - httpBuilder.addQueryParameter(param.getKey(), param.getValue().toString()); - } - } - - Request request = new Request.Builder() - .url(httpBuilder.build()) - .build(); - logger.info(request.toString()); - try { - OkHttpClient client = getClient(); - Response response = client.newCall(request).execute(); - if (response.isSuccessful()) { - if (targetPath != null) { - File snapFolder = new File(targetPath); - if (!snapFolder.exists()) { - if (!snapFolder.mkdirs()) { - logger.warn("{}路径创建失败", snapFolder.getAbsolutePath()); - } - - } - File snapFile = new File(targetPath + File.separator + fileName); - FileOutputStream outStream = new FileOutputStream(snapFile); - - outStream.write(Objects.requireNonNull(response.body()).bytes()); - outStream.flush(); - outStream.close(); - } else { - logger.error(String.format("[ %s ]请求失败: %s %s", url, response.code(), response.message())); - } - } else { - logger.error(String.format("[ %s ]请求失败: %s %s", url, response.code(), response.message())); - } - Objects.requireNonNull(response.body()).close(); - } catch (ConnectException e) { - logger.error(String.format("连接ABL失败: %s, %s", e.getCause().getMessage(), e.getMessage())); - logger.info("请检查media配置并确认ABL已启动..."); - } catch (IOException e) { - logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage())); - } - } - - - public Integer openRtpServer(MediaServer mediaServer, String app, String stream, int payload, Integer port, Integer tcpMode, Integer disableAudio) { - Map param = new HashMap<>(); - param.put("vhost", "_defaultVhost_"); - param.put("app", app); - param.put("stream_id", stream); - param.put("payload", payload); - if (port != null) { - param.put("port", port); - } - if (tcpMode != null) { - param.put("enable_tcp", tcpMode); - } - if (disableAudio != null) { - param.put("disableAudio", disableAudio); - } - - JSONObject jsonObject = sendPost(mediaServer, "openRtpServer", param, null); - if (jsonObject.getInteger("code") == 0) { - return jsonObject.getInteger("port"); - }else { - return 0; - } - } - - public JSONObject closeStreams(MediaServer mediaServerItem, String app, String stream) { - Map param = new HashMap<>(); - param.put("vhost", "__defaultVhost__"); - param.put("app", app); - param.put("stream", stream); - param.put("force", 1); - return sendPost(mediaServerItem, "close_streams",param, null); - } - - public JSONObject getServerConfig(MediaServer mediaServerItem){ - return sendPost(mediaServerItem, "getServerConfig",null, null); - } - - public JSONObject setConfigParamValue(MediaServer mediaServerItem, String key, Object value){ - Map param = new HashMap<>(); - param.put("key", key); - param.put("value", value); - return sendGet(mediaServerItem,"setConfigParamValue", param); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java deleted file mode 100644 index dc0edecda..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblServerConfig.java +++ /dev/null @@ -1,812 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean; - -import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -public class AblServerConfig { - - @ConfigKeyId("secret") - private String secret; - - @ConfigKeyId("ServerIP") - private String serverIp; - - @ConfigKeyId("mediaServerID") - private String mediaServerId; - - @ConfigKeyId("hook_enable") - private Integer hookEnable; - - @ConfigKeyId("enable_audio") - private Integer enableAudio; - - @ConfigKeyId("httpServerPort") - private Integer httpServerPort; - - @ConfigKeyId("rtspPort") - private Integer rtspPort; - - @ConfigKeyId("rtmpPort") - private Integer rtmpPort; - - @ConfigKeyId("httpFlvPort") - private Integer httpFlvPort; - - @ConfigKeyId("hls_enable") - private Integer hlsEnable; - - @ConfigKeyId("hlsPort") - private Integer hlsPort; - - @ConfigKeyId("wsPort") - private Integer wsPort; - - @ConfigKeyId("mp4Port") - private Integer mp4Port; - - @ConfigKeyId("ps_tsRecvPort") - private Integer psTsRecvPort; - - @ConfigKeyId("hlsCutType") - private Integer hlsCutType; - - @ConfigKeyId("h265CutType") - private Integer h265CutType; - - @ConfigKeyId("RecvThreadCount") - private Integer RecvThreadCount; - - @ConfigKeyId("SendThreadCount") - private Integer SendThreadCount; - - @ConfigKeyId("GB28181RtpTCPHeadType") - private Integer GB28181RtpTCPHeadType; - - @ConfigKeyId("ReConnectingCount") - private Integer ReConnectingCount; - - @ConfigKeyId("maxTimeNoOneWatch") - private Integer maxTimeNoOneWatch; - - @ConfigKeyId("pushEnable_mp4") - private Integer pushEnableMp4; - - @ConfigKeyId("fileSecond") - private Integer fileSecond; - - @ConfigKeyId("fileKeepMaxTime") - private Integer fileKeepMaxTime; - - @ConfigKeyId("httpDownloadSpeed") - private Integer httpDownloadSpeed; - - @ConfigKeyId("RecordReplayThread") - private Integer RecordReplayThread; - - @ConfigKeyId("convertMaxObject") - private Integer convertMaxObject; - - @ConfigKeyId("version") - private String version; - - @ConfigKeyId("recordPath") - private String recordPath; - - @ConfigKeyId("picturePath") - private String picturePath; - - @ConfigKeyId("noneReaderDuration") - private Integer noneReaderDuration; - - @ConfigKeyId("on_server_started") - private String onServerStarted; - - @ConfigKeyId("on_server_keepalive") - private String onServerKeepalive; - - @ConfigKeyId("on_play") - private String onPlay; - - @ConfigKeyId("on_publish") - private String onPublish; - - @ConfigKeyId("on_stream_arrive") - private String onStreamArrive; - - @ConfigKeyId("on_stream_not_arrive") - private String onStreamNotArrive; - - @ConfigKeyId("on_stream_none_reader") - private String onStreamNoneReader; - - @ConfigKeyId("on_stream_disconnect") - private String onStreamDisconnect; - - @ConfigKeyId("on_stream_not_found") - private String onStreamNotFound; - - @ConfigKeyId("on_record_mp4") - private String onRecordMp4; - - @ConfigKeyId("on_delete_record_mp4") - private String onDeleteRecordMp4; - - @ConfigKeyId("on_record_progress") - private String onRecordProgress; - - @ConfigKeyId("on_record_ts") - private String onRecordTs; - - @ConfigKeyId("enable_GetFileDuration") - private Integer enableGetFileDuration; - - @ConfigKeyId("keepaliveDuration") - private Integer keepaliveDuration; - - @ConfigKeyId("captureReplayType") - private Integer captureReplayType; - - @ConfigKeyId("pictureMaxCount") - private Integer pictureMaxCount; - - @ConfigKeyId("videoFileFormat") - private Integer videoFileFormat; - - @ConfigKeyId("MaxDiconnectTimeoutSecond") - private Integer maxDiconnectTimeoutSecond; - - @ConfigKeyId("G711ConvertAAC") - private Integer g711ConvertAAC; - - @ConfigKeyId("filterVideo_enable") - private Integer filterVideoEnable; - - @ConfigKeyId("filterVideo_text") - private String filterVideoText; - - @ConfigKeyId("FilterFontSize") - private Integer filterFontSize; - - @ConfigKeyId("FilterFontColor") - private String filterFontColor; - - @ConfigKeyId("FilterFontLeft") - private Integer filterFontLeft; - - @ConfigKeyId("FilterFontTop") - private Integer filterFontTop; - - @ConfigKeyId("FilterFontAlpha") - private Double filterFontAlpha; - - @ConfigKeyId("convertOutWidth") - private Integer convertOutWidth; - - @ConfigKeyId("convertOutHeight") - private Integer convertOutHeight; - - @ConfigKeyId("convertOutBitrate") - private Integer convertOutBitrate; - - @ConfigKeyId("flvPlayAddMute") - private Integer flvPlayAddMute; - - @ConfigKeyId("gb28181LibraryUse") - private Integer gb28181LibraryUse; - - @ConfigKeyId("rtc.listening-ip") - private String rtcListeningIp; - - @ConfigKeyId("rtc.listening-port") - private Integer rtcListeningIpPort; - - @ConfigKeyId("rtc.external-ip") - private String rtcExternalIp; - - @ConfigKeyId("rtc.realm") - private String rtcRealm; - - @ConfigKeyId("rtc.user") - private String rtcUser; - - @ConfigKeyId("rtc.min-port") - private Integer rtcMinPort; - - @ConfigKeyId("rtc.max-port") - private Integer rtcMaxPort; - - public static AblServerConfig getInstance(JSONArray jsonArray) { - if (jsonArray == null || jsonArray.isEmpty()) { - return null; - } - AblServerConfig ablServerConfig = new AblServerConfig(); - Field[] fields = AblServerConfig.class.getDeclaredFields(); - Map fieldMap = new HashMap<>(); - for (Field field : fields) { - if (field.isAnnotationPresent(ConfigKeyId.class)) { - ConfigKeyId configKeyId = field.getAnnotation(ConfigKeyId.class); - fieldMap.put(configKeyId.value(), field); - } - } - for (int i = 0; i < jsonArray.size(); i++) { - JSONObject jsonObject = jsonArray.getJSONObject(i); - if (jsonObject == null) { - continue; - } - for (String key : fieldMap.keySet()) { - if (jsonObject.containsKey(key)) { - Field field = fieldMap.get(key); - field.setAccessible(true); - try { - field.set(ablServerConfig, jsonObject.getObject(key, fieldMap.get(key).getType())); - } catch (IllegalAccessException e) {} - } - } - } - return ablServerConfig; - } - - public String getSecret() { - return secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - public String getServerIp() { - return serverIp; - } - - public void setServerIp(String serverIp) { - this.serverIp = serverIp; - } - - public String getMediaServerId() { - return mediaServerId; - } - - public void setMediaServerId(String mediaServerId) { - this.mediaServerId = mediaServerId; - } - - public Integer getHookEnable() { - return hookEnable; - } - - public void setHookEnable(Integer hookEnable) { - this.hookEnable = hookEnable; - } - - public Integer getEnableAudio() { - return enableAudio; - } - - public void setEnableAudio(Integer enableAudio) { - this.enableAudio = enableAudio; - } - - public Integer getHttpServerPort() { - return httpServerPort; - } - - public void setHttpServerPort(Integer httpServerPort) { - this.httpServerPort = httpServerPort; - } - - public Integer getRtspPort() { - return rtspPort; - } - - public void setRtspPort(Integer rtspPort) { - this.rtspPort = rtspPort; - } - - public Integer getRtmpPort() { - return rtmpPort; - } - - public void setRtmpPort(Integer rtmpPort) { - this.rtmpPort = rtmpPort; - } - - public Integer getHttpFlvPort() { - return httpFlvPort; - } - - public void setHttpFlvPort(Integer httpFlvPort) { - this.httpFlvPort = httpFlvPort; - } - - public Integer getHlsEnable() { - return hlsEnable; - } - - public void setHlsEnable(Integer hlsEnable) { - this.hlsEnable = hlsEnable; - } - - public Integer getHlsPort() { - return hlsPort; - } - - public void setHlsPort(Integer hlsPort) { - this.hlsPort = hlsPort; - } - - public Integer getWsPort() { - return wsPort; - } - - public void setWsPort(Integer wsPort) { - this.wsPort = wsPort; - } - - public Integer getMp4Port() { - return mp4Port; - } - - public void setMp4Port(Integer mp4Port) { - this.mp4Port = mp4Port; - } - - public Integer getPsTsRecvPort() { - return psTsRecvPort; - } - - public void setPsTsRecvPort(Integer psTsRecvPort) { - this.psTsRecvPort = psTsRecvPort; - } - - public Integer getHlsCutType() { - return hlsCutType; - } - - public void setHlsCutType(Integer hlsCutType) { - this.hlsCutType = hlsCutType; - } - - public Integer getH265CutType() { - return h265CutType; - } - - public void setH265CutType(Integer h265CutType) { - this.h265CutType = h265CutType; - } - - public Integer getRecvThreadCount() { - return RecvThreadCount; - } - - public void setRecvThreadCount(Integer recvThreadCount) { - RecvThreadCount = recvThreadCount; - } - - public Integer getSendThreadCount() { - return SendThreadCount; - } - - public void setSendThreadCount(Integer sendThreadCount) { - SendThreadCount = sendThreadCount; - } - - public Integer getGB28181RtpTCPHeadType() { - return GB28181RtpTCPHeadType; - } - - public void setGB28181RtpTCPHeadType(Integer GB28181RtpTCPHeadType) { - this.GB28181RtpTCPHeadType = GB28181RtpTCPHeadType; - } - - public Integer getReConnectingCount() { - return ReConnectingCount; - } - - public void setReConnectingCount(Integer reConnectingCount) { - ReConnectingCount = reConnectingCount; - } - - public Integer getMaxTimeNoOneWatch() { - return maxTimeNoOneWatch; - } - - public void setMaxTimeNoOneWatch(Integer maxTimeNoOneWatch) { - this.maxTimeNoOneWatch = maxTimeNoOneWatch; - } - - public Integer getPushEnableMp4() { - return pushEnableMp4; - } - - public void setPushEnableMp4(Integer pushEnableMp4) { - this.pushEnableMp4 = pushEnableMp4; - } - - public Integer getFileSecond() { - return fileSecond; - } - - public void setFileSecond(Integer fileSecond) { - this.fileSecond = fileSecond; - } - - public Integer getFileKeepMaxTime() { - return fileKeepMaxTime; - } - - public void setFileKeepMaxTime(Integer fileKeepMaxTime) { - this.fileKeepMaxTime = fileKeepMaxTime; - } - - public Integer getHttpDownloadSpeed() { - return httpDownloadSpeed; - } - - public void setHttpDownloadSpeed(Integer httpDownloadSpeed) { - this.httpDownloadSpeed = httpDownloadSpeed; - } - - public Integer getRecordReplayThread() { - return RecordReplayThread; - } - - public void setRecordReplayThread(Integer recordReplayThread) { - RecordReplayThread = recordReplayThread; - } - - public Integer getConvertMaxObject() { - return convertMaxObject; - } - - public void setConvertMaxObject(Integer convertMaxObject) { - this.convertMaxObject = convertMaxObject; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public String getRecordPath() { - return recordPath; - } - - public void setRecordPath(String recordPath) { - this.recordPath = recordPath; - } - - public String getPicturePath() { - return picturePath; - } - - public void setPicturePath(String picturePath) { - this.picturePath = picturePath; - } - - public Integer getNoneReaderDuration() { - return noneReaderDuration; - } - - public void setNoneReaderDuration(Integer noneReaderDuration) { - this.noneReaderDuration = noneReaderDuration; - } - - public String getOnServerStarted() { - return onServerStarted; - } - - public void setOnServerStarted(String onServerStarted) { - this.onServerStarted = onServerStarted; - } - - public String getOnServerKeepalive() { - return onServerKeepalive; - } - - public void setOnServerKeepalive(String onServerKeepalive) { - this.onServerKeepalive = onServerKeepalive; - } - - public String getOnPlay() { - return onPlay; - } - - public void setOnPlay(String onPlay) { - this.onPlay = onPlay; - } - - public String getOnPublish() { - return onPublish; - } - - public void setOnPublish(String onPublish) { - this.onPublish = onPublish; - } - - public String getOnStreamArrive() { - return onStreamArrive; - } - - public void setOnStreamArrive(String onStreamArrive) { - this.onStreamArrive = onStreamArrive; - } - - public String getOnStreamNotArrive() { - return onStreamNotArrive; - } - - public void setOnStreamNotArrive(String onStreamNotArrive) { - this.onStreamNotArrive = onStreamNotArrive; - } - - public String getOnStreamNoneReader() { - return onStreamNoneReader; - } - - public void setOnStreamNoneReader(String onStreamNoneReader) { - this.onStreamNoneReader = onStreamNoneReader; - } - - public String getOnStreamDisconnect() { - return onStreamDisconnect; - } - - public void setOnStreamDisconnect(String onStreamDisconnect) { - this.onStreamDisconnect = onStreamDisconnect; - } - - public String getOnDeleteRecordMp4() { - return onDeleteRecordMp4; - } - - public void setOnDeleteRecordMp4(String onDeleteRecordMp4) { - this.onDeleteRecordMp4 = onDeleteRecordMp4; - } - - public String getOnRecordProgress() { - return onRecordProgress; - } - - public void setOnRecordProgress(String onRecordProgress) { - this.onRecordProgress = onRecordProgress; - } - - public String getOnRecordTs() { - return onRecordTs; - } - - public void setOnRecordTs(String onRecordTs) { - this.onRecordTs = onRecordTs; - } - - public Integer getEnableGetFileDuration() { - return enableGetFileDuration; - } - - public void setEnableGetFileDuration(Integer enableGetFileDuration) { - this.enableGetFileDuration = enableGetFileDuration; - } - - public Integer getKeepaliveDuration() { - return keepaliveDuration; - } - - public void setKeepaliveDuration(Integer keepaliveDuration) { - this.keepaliveDuration = keepaliveDuration; - } - - public Integer getCaptureReplayType() { - return captureReplayType; - } - - public void setCaptureReplayType(Integer captureReplayType) { - this.captureReplayType = captureReplayType; - } - - public Integer getVideoFileFormat() { - return videoFileFormat; - } - - public void setVideoFileFormat(Integer videoFileFormat) { - this.videoFileFormat = videoFileFormat; - } - - public Integer getMaxDiconnectTimeoutSecond() { - return maxDiconnectTimeoutSecond; - } - - public void setMaxDiconnectTimeoutSecond(Integer maxDiconnectTimeoutSecond) { - this.maxDiconnectTimeoutSecond = maxDiconnectTimeoutSecond; - } - - public Integer getG711ConvertAAC() { - return g711ConvertAAC; - } - - public void setG711ConvertAAC(Integer g711ConvertAAC) { - this.g711ConvertAAC = g711ConvertAAC; - } - - public Integer getFilterVideoEnable() { - return filterVideoEnable; - } - - public void setFilterVideoEnable(Integer filterVideoEnable) { - this.filterVideoEnable = filterVideoEnable; - } - - public String getFilterVideoText() { - return filterVideoText; - } - - public void setFilterVideoText(String filterVideoText) { - this.filterVideoText = filterVideoText; - } - - public Integer getFilterFontSize() { - return filterFontSize; - } - - public void setFilterFontSize(Integer filterFontSize) { - this.filterFontSize = filterFontSize; - } - - public String getFilterFontColor() { - return filterFontColor; - } - - public void setFilterFontColor(String filterFontColor) { - this.filterFontColor = filterFontColor; - } - - public Integer getFilterFontLeft() { - return filterFontLeft; - } - - public void setFilterFontLeft(Integer filterFontLeft) { - this.filterFontLeft = filterFontLeft; - } - - public Integer getFilterFontTop() { - return filterFontTop; - } - - public void setFilterFontTop(Integer filterFontTop) { - this.filterFontTop = filterFontTop; - } - - public Double getFilterFontAlpha() { - return filterFontAlpha; - } - - public void setFilterFontAlpha(Double filterFontAlpha) { - this.filterFontAlpha = filterFontAlpha; - } - - public Integer getConvertOutWidth() { - return convertOutWidth; - } - - public void setConvertOutWidth(Integer convertOutWidth) { - this.convertOutWidth = convertOutWidth; - } - - public Integer getConvertOutHeight() { - return convertOutHeight; - } - - public void setConvertOutHeight(Integer convertOutHeight) { - this.convertOutHeight = convertOutHeight; - } - - public Integer getConvertOutBitrate() { - return convertOutBitrate; - } - - public void setConvertOutBitrate(Integer convertOutBitrate) { - this.convertOutBitrate = convertOutBitrate; - } - - public Integer getFlvPlayAddMute() { - return flvPlayAddMute; - } - - public void setFlvPlayAddMute(Integer flvPlayAddMute) { - this.flvPlayAddMute = flvPlayAddMute; - } - - public Integer getGb28181LibraryUse() { - return gb28181LibraryUse; - } - - public void setGb28181LibraryUse(Integer gb28181LibraryUse) { - this.gb28181LibraryUse = gb28181LibraryUse; - } - - public String getRtcListeningIp() { - return rtcListeningIp; - } - - public void setRtcListeningIp(String rtcListeningIp) { - this.rtcListeningIp = rtcListeningIp; - } - - public Integer getRtcListeningIpPort() { - return rtcListeningIpPort; - } - - public void setRtcListeningIpPort(Integer rtcListeningIpPort) { - this.rtcListeningIpPort = rtcListeningIpPort; - } - - public String getRtcExternalIp() { - return rtcExternalIp; - } - - public void setRtcExternalIp(String rtcExternalIp) { - this.rtcExternalIp = rtcExternalIp; - } - - public String getRtcRealm() { - return rtcRealm; - } - - public void setRtcRealm(String rtcRealm) { - this.rtcRealm = rtcRealm; - } - - public String getRtcUser() { - return rtcUser; - } - - public void setRtcUser(String rtcUser) { - this.rtcUser = rtcUser; - } - - public Integer getRtcMinPort() { - return rtcMinPort; - } - - public void setRtcMinPort(Integer rtcMinPort) { - this.rtcMinPort = rtcMinPort; - } - - public Integer getRtcMaxPort() { - return rtcMaxPort; - } - - public void setRtcMaxPort(Integer rtcMaxPort) { - this.rtcMaxPort = rtcMaxPort; - } - - public String getOnRecordMp4() { - return onRecordMp4; - } - - public void setOnRecordMp4(String onRecordMp4) { - this.onRecordMp4 = onRecordMp4; - } - - public Integer getPictureMaxCount() { - return pictureMaxCount; - } - - public void setPictureMaxCount(Integer pictureMaxCount) { - this.pictureMaxCount = pictureMaxCount; - } - - public String getOnStreamNotFound() { - return onStreamNotFound; - } - - public void setOnStreamNotFound(String onStreamNotFound) { - this.onStreamNotFound = onStreamNotFound; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblUrls.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblUrls.java deleted file mode 100644 index 42e05a04d..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/AblUrls.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean; - -public class AblUrls { - private String rtsp; - private String rtmp; - private String httpFlv; - private String wsFlv; - private String httpMp4; - private String httpHls; - - public String getRtsp() { - return rtsp; - } - - public void setRtsp(String rtsp) { - this.rtsp = rtsp; - } - - public String getRtmp() { - return rtmp; - } - - public void setRtmp(String rtmp) { - this.rtmp = rtmp; - } - - public String getHttpFlv() { - return httpFlv; - } - - public void setHttpFlv(String httpFlv) { - this.httpFlv = httpFlv; - } - - public String getWsFlv() { - return wsFlv; - } - - public void setWsFlv(String wsFlv) { - this.wsFlv = wsFlv; - } - - public String getHttpMp4() { - return httpMp4; - } - - public void setHttpMp4(String httpMp4) { - this.httpMp4 = httpMp4; - } - - public String getHttpHls() { - return httpHls; - } - - public void setHttpHls(String httpHls) { - this.httpHls = httpHls; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/ConfigKeyId.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/ConfigKeyId.java deleted file mode 100644 index 244bb9495..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/ConfigKeyId.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean; - -import java.lang.annotation.*; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface ConfigKeyId { - String value(); -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java deleted file mode 100644 index 796935ea8..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/ABLHookParam.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean.hook; - -public class ABLHookParam { - private String mediaServerId; - - /** - * 应用名 - */ - private String app; - - /** - * 流id - */ - private String stream; - - /** - * 媒体流来源编号,可以根据这个key进行关闭流媒体 可以调用delMediaStream或close_streams 函数进行关闭 - */ - private String key; - - /** - * 媒体流来源网络编号,可参考附表 - */ - private Integer networkType; - - public String getMediaServerId() { - return mediaServerId; - } - - public void setMediaServerId(String mediaServerId) { - this.mediaServerId = mediaServerId; - } - - public String getApp() { - return app; - } - - public void setApp(String app) { - this.app = app; - } - - public String getStream() { - return stream; - } - - public void setStream(String stream) { - this.stream = stream; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public Integer getNetworkType() { - return networkType; - } - - public void setNetworkType(Integer networkType) { - this.networkType = networkType; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPlayABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPlayABLHookParam.java deleted file mode 100644 index af18210e6..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPlayABLHookParam.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean.hook; - -public class OnPlayABLHookParam extends ABLHookParam{ - private String ip; - private Integer port; - private String params; - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public Integer getPort() { - return port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public String getParams() { - return params; - } - - public void setParams(String params) { - this.params = params; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPublishABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPublishABLHookParam.java deleted file mode 100644 index 11da2740b..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnPublishABLHookParam.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean.hook; - -public class OnPublishABLHookParam extends ABLHookParam{ - private String ip; - private Integer port; - private String params; - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public Integer getPort() { - return port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public String getParams() { - return params; - } - - public void setParams(String params) { - this.params = params; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordMp4ABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordMp4ABLHookParam.java deleted file mode 100644 index 0fb819fae..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordMp4ABLHookParam.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean.hook; - -public class OnRecordMp4ABLHookParam extends ABLHookParam{ - private String fileName; - - public String getFileName() { - return fileName; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordProgressABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordProgressABLHookParam.java deleted file mode 100644 index 8f70781b7..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnRecordProgressABLHookParam.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean.hook; - -public class OnRecordProgressABLHookParam extends OnRecordMp4ABLHookParam{ - private Integer currentFileDuration; - private Integer TotalVideoDuration; - - public Integer getCurrentFileDuration() { - return currentFileDuration; - } - - public void setCurrentFileDuration(Integer currentFileDuration) { - this.currentFileDuration = currentFileDuration; - } - - public Integer getTotalVideoDuration() { - return TotalVideoDuration; - } - - public void setTotalVideoDuration(Integer totalVideoDuration) { - TotalVideoDuration = totalVideoDuration; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerKeepaliveABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerKeepaliveABLHookParam.java deleted file mode 100644 index ea1ac9702..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerKeepaliveABLHookParam.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean.hook; - -public class OnServerKeepaliveABLHookParam { - private String localipAddress; - private String mediaServerId; - private String datetime; - - - public String getLocalipAddress() { - return localipAddress; - } - - public void setLocalipAddress(String localipAddress) { - this.localipAddress = localipAddress; - } - - public String getMediaServerId() { - return mediaServerId; - } - - public void setMediaServerId(String mediaServerId) { - this.mediaServerId = mediaServerId; - } - - public String getDatetime() { - return datetime; - } - - public void setDatetime(String datetime) { - this.datetime = datetime; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerStaredABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerStaredABLHookParam.java deleted file mode 100644 index a9ec44c0c..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnServerStaredABLHookParam.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean.hook; - -public class OnServerStaredABLHookParam { - private String localipAddress; - private String mediaServerId; - private String datetime; - - - public String getLocalipAddress() { - return localipAddress; - } - - public void setLocalipAddress(String localipAddress) { - this.localipAddress = localipAddress; - } - - public String getMediaServerId() { - return mediaServerId; - } - - public void setMediaServerId(String mediaServerId) { - this.mediaServerId = mediaServerId; - } - - public String getDatetime() { - return datetime; - } - - public void setDatetime(String datetime) { - this.datetime = datetime; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnStreamArriveABLHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnStreamArriveABLHookParam.java deleted file mode 100644 index efe9b1269..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/bean/hook/OnStreamArriveABLHookParam.java +++ /dev/null @@ -1,245 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.bean.hook; - -import com.genersoft.iot.vmp.media.abl.bean.AblUrls; - -/** - * 流到来的事件 - */ -public class OnStreamArriveABLHookParam extends ABLHookParam{ - - - - /** - * 推流鉴权Id - */ - private String callId; - - /** - * 状态 - */ - private Boolean status; - - - /** - * - */ - private Boolean enableHls; - - - /** - * - */ - private Boolean transcodingStatus; - - - /** - * - */ - private String sourceURL; - - - /** - * - */ - private Integer readerCount; - - - /** - * - */ - private Integer noneReaderDuration; - - - /** - * - */ - private String videoCodec; - - - /** - * - */ - private Integer videoFrameSpeed; - - - /** - * - */ - private Integer width; - - - /** - * - */ - private Integer height; - - - /** - * - */ - private Integer videoBitrate; - - - /** - * - */ - private String audioCodec; - - - /** - * - */ - private Integer audioChannels; - - - /** - * - */ - private Integer audioSampleRate; - - - /** - * - */ - private Integer audioBitrate; - - - private AblUrls url; - - - public String getCallId() { - return callId; - } - - public void setCallId(String callId) { - this.callId = callId; - } - - public Boolean getStatus() { - return status; - } - - public void setStatus(Boolean status) { - this.status = status; - } - - public Boolean getEnableHls() { - return enableHls; - } - - public void setEnableHls(Boolean enableHls) { - this.enableHls = enableHls; - } - - public Boolean getTranscodingStatus() { - return transcodingStatus; - } - - public void setTranscodingStatus(Boolean transcodingStatus) { - this.transcodingStatus = transcodingStatus; - } - - public String getSourceURL() { - return sourceURL; - } - - public void setSourceURL(String sourceURL) { - this.sourceURL = sourceURL; - } - - public Integer getReaderCount() { - return readerCount; - } - - public void setReaderCount(Integer readerCount) { - this.readerCount = readerCount; - } - - public Integer getNoneReaderDuration() { - return noneReaderDuration; - } - - public void setNoneReaderDuration(Integer noneReaderDuration) { - this.noneReaderDuration = noneReaderDuration; - } - - public String getVideoCodec() { - return videoCodec; - } - - public void setVideoCodec(String videoCodec) { - this.videoCodec = videoCodec; - } - - public Integer getVideoFrameSpeed() { - return videoFrameSpeed; - } - - public void setVideoFrameSpeed(Integer videoFrameSpeed) { - this.videoFrameSpeed = videoFrameSpeed; - } - - public Integer getWidth() { - return width; - } - - public void setWidth(Integer width) { - this.width = width; - } - - public Integer getHeight() { - return height; - } - - public void setHeight(Integer height) { - this.height = height; - } - - public Integer getVideoBitrate() { - return videoBitrate; - } - - public void setVideoBitrate(Integer videoBitrate) { - this.videoBitrate = videoBitrate; - } - - public String getAudioCodec() { - return audioCodec; - } - - public void setAudioCodec(String audioCodec) { - this.audioCodec = audioCodec; - } - - public Integer getAudioChannels() { - return audioChannels; - } - - public void setAudioChannels(Integer audioChannels) { - this.audioChannels = audioChannels; - } - - public Integer getAudioSampleRate() { - return audioSampleRate; - } - - public void setAudioSampleRate(Integer audioSampleRate) { - this.audioSampleRate = audioSampleRate; - } - - public Integer getAudioBitrate() { - return audioBitrate; - } - - public void setAudioBitrate(Integer audioBitrate) { - this.audioBitrate = audioBitrate; - } - - public AblUrls getUrl() { - return url; - } - - public void setUrl(AblUrls url) { - this.url = url; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java deleted file mode 100644 index 74465e4c1..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerKeepaliveEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.event; - -import com.genersoft.iot.vmp.media.bean.MediaServer; -import org.springframework.context.ApplicationEvent; - -/** - * zlm 心跳事件 - */ -public class HookAblServerKeepaliveEvent extends ApplicationEvent { - - public HookAblServerKeepaliveEvent(Object source) { - super(source); - } - - private MediaServer mediaServerItem; - - public MediaServer getMediaServerItem() { - return mediaServerItem; - } - - public void setMediaServerItem(MediaServer mediaServerItem) { - this.mediaServerItem = mediaServerItem; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java b/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java deleted file mode 100644 index 12bdac06f..000000000 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/event/HookAblServerStartEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.genersoft.iot.vmp.media.abl.event; - -import com.genersoft.iot.vmp.media.bean.MediaServer; -import org.springframework.context.ApplicationEvent; - -/** - * zlm server_start事件 - */ -public class HookAblServerStartEvent extends ApplicationEvent { - - public HookAblServerStartEvent(Object source) { - super(source); - } - - private MediaServer mediaServerItem; - - public MediaServer getMediaServerItem() { - return mediaServerItem; - } - - public void setMediaServerItem(MediaServer mediaServerItem) { - this.mediaServerItem = mediaServerItem; - } -} From bbf19c79091c46ac5465909429caef6e79c02e55 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 10:40:16 +0800 Subject: [PATCH 50/58] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=B8=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/impl/InviteRequestProcessor.java | 11 ++++-- .../iot/vmp/media/bean/MediaInfo.java | 38 ------------------- .../iot/vmp/media/bean/RecordInfo.java | 7 ---- .../media/event/media/MediaArrivalEvent.java | 10 ----- .../event/media/MediaDepartureEvent.java | 9 ----- .../media/event/media/MediaNotFoundEvent.java | 9 ----- .../event/media/MediaRecordMp4Event.java | 12 ------ .../media/zlm/ZLMMediaServerStatusManger.java | 1 + .../RedisPushStreamCloseResponseListener.java | 6 ++- .../cloudRecord/CloudRecordController.java | 1 - 10 files changed, 13 insertions(+), 91 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index b5296cea1..b1a6611c7 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -20,13 +20,18 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.*; -import com.genersoft.iot.vmp.service.*; +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; +import com.genersoft.iot.vmp.service.IInviteStreamService; +import com.genersoft.iot.vmp.service.IPlayService; +import com.genersoft.iot.vmp.service.IStreamProxyService; +import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java index 8ee0eaf32..f1c3d5853 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java @@ -2,9 +2,7 @@ package com.genersoft.iot.vmp.media.bean; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.media.abl.bean.hook.OnStreamArriveABLHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; @@ -178,42 +176,6 @@ public class MediaInfo { return mediaInfo; } - public static MediaInfo getInstance(OnStreamArriveABLHookParam param, MediaServer mediaServer) { - - MediaInfo mediaInfo = new MediaInfo(); - mediaInfo.setApp(param.getApp()); - mediaInfo.setStream(param.getStream()); - mediaInfo.setMediaServer(mediaServer); - mediaInfo.setReaderCount(param.getReaderCount()); - mediaInfo.setOnline(true); - mediaInfo.setVideoCodec(param.getVideoCodec()); - switch (param.getNetworkType()) { - case 21: - mediaInfo.setOriginType(OriginType.RTMP_PUSH.ordinal()); - break; - case 23: - mediaInfo.setOriginType(OriginType.RTSP_PUSH.ordinal()); - break; - case 30: - case 31: - case 32: - case 33: - mediaInfo.setOriginType(OriginType.PULL.ordinal()); - break; - default: - mediaInfo.setOriginType(OriginType.UNKNOWN.ordinal()); - break; - - } - mediaInfo.setWidth(param.getWidth()); - mediaInfo.setHeight(param.getHeight()); - mediaInfo.setAudioCodec(param.getAudioCodec()); - mediaInfo.setAudioChannels(param.getAudioChannels()); - mediaInfo.setAudioSampleRate(param.getAudioSampleRate()); - - return mediaInfo; - } - public Integer getReaderCount() { return readerCount; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java index eb60ed91f..aafc5db10 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.media.bean; -import com.genersoft.iot.vmp.media.abl.bean.hook.OnRecordMp4ABLHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; public class RecordInfo { @@ -24,12 +23,6 @@ public class RecordInfo { return recordInfo; } - public static RecordInfo getInstance(OnRecordMp4ABLHookParam hookParam) { - RecordInfo recordInfo = new RecordInfo(); - recordInfo.setFileName(hookParam.getFileName()); - return recordInfo; - } - public String getFileName() { return fileName; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java index cebcccdf1..2379321a4 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.abl.bean.hook.OnStreamArriveABLHookParam; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; @@ -23,15 +22,6 @@ public class MediaArrivalEvent extends MediaEvent { mediaArrivalEvent.setCallId(hookParam.getCallId()); return mediaArrivalEvent; } - public static MediaArrivalEvent getInstance(Object source, OnStreamArriveABLHookParam hookParam, MediaServer mediaServer){ - MediaArrivalEvent mediaArrivalEvent = new MediaArrivalEvent(source); - mediaArrivalEvent.setMediaInfo(MediaInfo.getInstance(hookParam, mediaServer)); - mediaArrivalEvent.setApp(hookParam.getApp()); - mediaArrivalEvent.setStream(hookParam.getStream()); - mediaArrivalEvent.setMediaServer(mediaServer); - mediaArrivalEvent.setCallId(hookParam.getCallId()); - return mediaArrivalEvent; - } private MediaInfo mediaInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java index 02b99f31c..edd945ad4 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.abl.bean.hook.ABLHookParam; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; @@ -20,12 +19,4 @@ public class MediaDepartureEvent extends MediaEvent { mediaDepartureEven.setMediaServer(mediaServer); return mediaDepartureEven; } - - public static MediaDepartureEvent getInstance(Object source, ABLHookParam hookParam, MediaServer mediaServer){ - MediaDepartureEvent mediaDepartureEven = new MediaDepartureEvent(source); - mediaDepartureEven.setApp(hookParam.getApp()); - mediaDepartureEven.setStream(hookParam.getStream()); - mediaDepartureEven.setMediaServer(mediaServer); - return mediaDepartureEven; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java index 675d6e9d5..2415566a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.abl.bean.hook.ABLHookParam; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam; @@ -20,12 +19,4 @@ public class MediaNotFoundEvent extends MediaEvent { mediaDepartureEven.setMediaServer(mediaServer); return mediaDepartureEven; } - - public static MediaNotFoundEvent getInstance(Object source, ABLHookParam hookParam, MediaServer mediaServer){ - MediaNotFoundEvent mediaDepartureEven = new MediaNotFoundEvent(source); - mediaDepartureEven.setApp(hookParam.getApp()); - mediaDepartureEven.setStream(hookParam.getStream()); - mediaDepartureEven.setMediaServer(mediaServer); - return mediaDepartureEven; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java index 9fd6defc8..093c3c255 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java @@ -1,7 +1,5 @@ package com.genersoft.iot.vmp.media.event.media; -import com.genersoft.iot.vmp.media.abl.ABLHttpHookListener; -import com.genersoft.iot.vmp.media.abl.bean.hook.OnRecordMp4ABLHookParam; import com.genersoft.iot.vmp.media.bean.RecordInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; @@ -26,16 +24,6 @@ public class MediaRecordMp4Event extends MediaEvent { return mediaRecordMp4Event; } - public static MediaRecordMp4Event getInstance(ABLHttpHookListener source, OnRecordMp4ABLHookParam hookParam, MediaServer mediaServer) { - MediaRecordMp4Event mediaRecordMp4Event = new MediaRecordMp4Event(source); - mediaRecordMp4Event.setApp(hookParam.getApp()); - mediaRecordMp4Event.setStream(hookParam.getStream()); - RecordInfo recordInfo = RecordInfo.getInstance(hookParam); - mediaRecordMp4Event.setRecordInfo(recordInfo); - mediaRecordMp4Event.setMediaServer(mediaServer); - return mediaRecordMp4Event; - } - public RecordInfo getRecordInfo() { return recordInfo; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index d4d65636a..d744850dc 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -74,6 +74,7 @@ public class ZLMMediaServerStatusManger { logger.info("[ZLM-添加待上线节点] ID:" + mediaServerItem.getId()); offlineZlmPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); offlineZlmTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + execute(); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java index 208bfac36..e7cba6ba8 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java @@ -2,13 +2,14 @@ package com.genersoft.iot.vmp.service.redisMsg; import com.alibaba.fastjson2.JSON; import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.bean.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse; @@ -24,6 +25,7 @@ import org.springframework.stereotype.Component; import javax.sip.InvalidArgumentException; import javax.sip.SipException; import java.text.ParseException; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java index 2e3aa710a..da8bbc8ca 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -4,7 +4,6 @@ import com.alibaba.fastjson2.JSONArray; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.media.bean.MediaServer; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.ICloudRecordService; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; From 6dd870e74c90d39c6ef2443f2f6c058f5973af62 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 10:59:59 +0800 Subject: [PATCH 51/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=82=B9=E6=92=AD?= =?UTF-8?q?=E7=AB=AF=E5=8F=A3=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/conf/MediaConfig.java | 83 +++++++++++-------- .../vmp/storager/dao/MediaServerMapper.java | 2 +- src/main/resources/application.yml | 2 +- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java index 0dc1ba98a..eac7c1138 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java @@ -212,41 +212,58 @@ public class MediaConfig{ } public MediaServer getMediaSerItem(){ - MediaServer mediaServerItem = new MediaServer(); - mediaServerItem.setId(id); - mediaServerItem.setIp(ip); - mediaServerItem.setDefaultServer(true); - mediaServerItem.setHookIp(getHookIp()); - mediaServerItem.setSdpIp(getSdpIp()); - mediaServerItem.setStreamIp(getStreamIp()); - mediaServerItem.setHttpPort(httpPort); - mediaServerItem.setFlvPort(flvPort); - mediaServerItem.setWsFlvPort(wsFlvPort); - mediaServerItem.setHttpSSlPort(httpSSlPort); - mediaServerItem.setFlvSSLPort(flvSSlPort); - mediaServerItem.setWsFlvSSLPort(wsFlvSSlPort); - mediaServerItem.setRtmpPort(rtmpPort); - mediaServerItem.setRtmpSSlPort(rtmpSSlPort); - mediaServerItem.setRtpProxyPort(getRtpProxyPort()); - mediaServerItem.setRtspPort(rtspPort); - mediaServerItem.setRtspSSLPort(rtspSSLPort); - mediaServerItem.setAutoConfig(autoConfig); - mediaServerItem.setSecret(secret); - mediaServerItem.setRtpEnable(rtpEnable); - mediaServerItem.setRtpPortRange(rtpPortRange); - mediaServerItem.setSendRtpPortRange(rtpSendPortRange); - mediaServerItem.setRecordAssistPort(recordAssistPort); - mediaServerItem.setHookAliveInterval(10f); - mediaServerItem.setRecordDay(recordDay); - mediaServerItem.setStatus(false); - mediaServerItem.setType(type); - if (recordPath != null) { - mediaServerItem.setRecordPath(recordPath); + MediaServer mediaServer = new MediaServer(); + mediaServer.setId(id); + mediaServer.setIp(ip); + mediaServer.setDefaultServer(true); + mediaServer.setHookIp(getHookIp()); + mediaServer.setSdpIp(getSdpIp()); + mediaServer.setStreamIp(getStreamIp()); + mediaServer.setHttpPort(httpPort); + if (flvPort == 0) { + mediaServer.setFlvPort(httpPort); + }else { + mediaServer.setFlvPort(flvPort); + } + if (wsFlvPort == 0) { + mediaServer.setWsFlvPort(httpPort); + }else { + mediaServer.setWsFlvPort(wsFlvPort); + } + if (flvSSlPort == 0) { + mediaServer.setFlvSSLPort(httpSSlPort); + }else { + mediaServer.setFlvSSLPort(flvSSlPort); + } + if (wsFlvSSlPort == 0) { + mediaServer.setWsFlvSSLPort(httpSSlPort); + }else { + mediaServer.setWsFlvSSLPort(wsFlvSSlPort); } - mediaServerItem.setCreateTime(DateUtil.getNow()); - mediaServerItem.setUpdateTime(DateUtil.getNow()); - return mediaServerItem; + mediaServer.setHttpSSlPort(httpSSlPort); + mediaServer.setRtmpPort(rtmpPort); + mediaServer.setRtmpSSlPort(rtmpSSlPort); + mediaServer.setRtpProxyPort(getRtpProxyPort()); + mediaServer.setRtspPort(rtspPort); + mediaServer.setRtspSSLPort(rtspSSLPort); + mediaServer.setAutoConfig(autoConfig); + mediaServer.setSecret(secret); + mediaServer.setRtpEnable(rtpEnable); + mediaServer.setRtpPortRange(rtpPortRange); + mediaServer.setSendRtpPortRange(rtpSendPortRange); + mediaServer.setRecordAssistPort(recordAssistPort); + mediaServer.setHookAliveInterval(10f); + mediaServer.setRecordDay(recordDay); + mediaServer.setStatus(false); + mediaServer.setType(type); + if (recordPath != null) { + mediaServer.setRecordPath(recordPath); + } + mediaServer.setCreateTime(DateUtil.getNow()); + mediaServer.setUpdateTime(DateUtil.getNow()); + + return mediaServer; } public Integer getRecordDay() { diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java index 6473c42f8..d34657f56 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java @@ -27,7 +27,7 @@ public interface MediaServerMapper { "flv_port," + "flv_ssl_port," + "ws_flv_port," + - "ws_flv_ssl__port," + + "ws_flv_ssl_port," + "rtsp_ssl_port,"+ "auto_config,"+ "secret,"+ diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3d36b8474..3f478442e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,4 +2,4 @@ spring: application: name: wvp profiles: - active: abl \ No newline at end of file + active: local \ No newline at end of file From ab318fcf70c3c6df325e328fdcba4a905c198ede Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 14:53:11 +0800 Subject: [PATCH 52/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=82=B9=E6=92=AD?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=97=B6=E5=85=B3=E9=97=ADrtpserver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gb28181/transmit/cmd/impl/SIPCommander.java | 1 - .../request/impl/InviteRequestProcessor.java | 15 ++++++--------- .../vmp/media/zlm/ZLMMediaNodeServerService.java | 2 +- .../iot/vmp/media/zlm/ZLMRESTfulUtils.java | 2 -- .../iot/vmp/service/impl/PlatformServiceImpl.java | 1 - .../iot/vmp/service/impl/PlayServiceImpl.java | 3 +-- .../iot/vmp/storager/IRedisCatchStorage.java | 3 ++- .../vmp/storager/impl/RedisCatchStorageImpl.java | 11 ++++++----- 8 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 0099aafb1..dab039f79 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -278,7 +278,6 @@ public class SIPCommander implements ISIPCommander { logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, "rtp", stream, mediaServerItem.getId()); - System.out.println("rtpHook: " + rtpHook.toString()); subscribe.addSubscribe(rtpHook, (hookData) -> { if (event != null) { event.response(hookData); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index b1a6611c7..7303594b7 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -27,7 +27,6 @@ import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.IStreamProxyService; @@ -493,12 +492,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements } }; ErrorCallback errorEvent = ((statusCode, msg, data) -> { + logger.info("[上级Invite] {}, 失败, 平台:{}, 通道:{}, code: {}, msg;{}", sessionName, username, channelId, statusCode, msg); // 未知错误。直接转发设备点播的错误 try { - if (statusCode > 0) { - Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); - sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); - } + Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); + sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); } catch (ParseException | SipException e) { logger.error("未处理的异常 ", e); } @@ -589,12 +587,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements if ("push".equals(gbStream.getStreamType())) { if (streamPushItem != null) { // 从redis查询是否正在接收这个推流 - OnStreamChangedHookParam pushListItem = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream()); + StreamPushItem pushListItem = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream()); if (pushListItem != null) { - StreamPushItem transform = streamPushService.transform(pushListItem); - transform.setSelf(userSetting.getServerId().equals(pushListItem.getSeverId())); + pushListItem.setSelf(userSetting.getServerId().equals(pushListItem.getServerId())); // 推流状态 - pushStream(evt, request, gbStream, transform, platform, callIdHeader, mediaServerItem, port, tcpActive, + pushStream(evt, request, gbStream, pushListItem, platform, callIdHeader, mediaServerItem, port, tcpActive, mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); }else { // 未推流 拉起 diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 8fbe5303d..72f3ba127 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -45,7 +45,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { @Override public void closeRtpServer(MediaServer mediaServer, String streamId) { - zlmresTfulUtils.closeStreams(mediaServer, "rtp", streamId); + zlmServerFactory.closeRtpServer(mediaServer, streamId); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index e06eb42a5..285b9e6b8 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -104,8 +104,6 @@ public class ZLMRESTfulUtils { responseJSON = JSON.parseObject(responseStr); } }else { - System.out.println( 2222); - System.out.println( response.code()); response.close(); Objects.requireNonNull(response.body()).close(); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index e4ddb1206..822b54e96 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -646,7 +646,6 @@ public class PlatformServiceImpl implements IPlatformService { inviteInfo.setStatus(InviteSessionStatus.ok); ResponseEvent responseEvent = (ResponseEvent) eventResult.event; String contentString = new String(responseEvent.getResponse().getRawContent()); - System.out.println(1111); System.out.println(contentString); String ssrcInResponse = SipUtils.getSsrcFromSdp(contentString); // 兼容回复的消息中缺少ssrc(y字段)的情况 diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index f53752208..816f17fb1 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -581,8 +581,7 @@ public class PlayServiceImpl implements IPlayService { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); - callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_ERROR.getCode(), - String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null); + callback.run(event.statusCode, event.msg, null); inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null, InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(), String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index 3f6a526a2..c483db64a 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; @@ -212,7 +213,7 @@ public interface IRedisCatchStorage { void addPushListItem(String app, String stream, MediaArrivalEvent param); - OnStreamChangedHookParam getPushListItem(String app, String stream); + StreamPushItem getPushListItem(String app, String stream); void removePushListItem(String app, String stream, String mediaServerId); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 033a20413..b17b4d743 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -12,6 +12,7 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; @@ -447,7 +448,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @Override public StreamAuthorityInfo getStreamAuthorityInfo(String app, String stream) { String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ; - System.out.println(key); return JsonUtil.redisJsonToObject(redisTemplate, key, StreamAuthorityInfo.class); } @@ -655,19 +655,20 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @Override public void addPushListItem(String app, String stream, MediaArrivalEvent event) { String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream; - redisTemplate.opsForValue().set(key, event); + StreamPushItem streamPushItem = StreamPushItem.getInstance(event, userSetting.getServerId()); + redisTemplate.opsForValue().set(key, streamPushItem); } @Override - public OnStreamChangedHookParam getPushListItem(String app, String stream) { + public StreamPushItem getPushListItem(String app, String stream) { String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream; - return (OnStreamChangedHookParam)redisTemplate.opsForValue().get(key); + return (StreamPushItem)redisTemplate.opsForValue().get(key); } @Override public void removePushListItem(String app, String stream, String mediaServerId) { String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream; - OnStreamChangedHookParam param = (OnStreamChangedHookParam)redisTemplate.opsForValue().get(key); + StreamPushItem param = (StreamPushItem)redisTemplate.opsForValue().get(key); if (param != null && param.getMediaServerId().equalsIgnoreCase(mediaServerId)) { redisTemplate.delete(key); } From de5d025cee3b2e8e80ff406c57bd1a5d2a275540 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 16:10:02 +0800 Subject: [PATCH 53/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=95=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E6=94=B6=E6=B5=81=E6=97=B6=E9=9F=B3=E9=A2=91=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 6076db4bf..65685aa17 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -260,7 +260,6 @@ public class ZLMHttpHookListener { if ("rtp".equals(param.getApp())) { InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); - // 单端口模式下修改流 ID if (!mediaInfo.isRtpEnable() && inviteInfo == null) { String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16)); @@ -268,6 +267,8 @@ public class ZLMHttpHookListener { if (inviteInfo != null) { result.setStream_replace(inviteInfo.getStream()); logger.info("[ZLM HOOK]推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream()); + // 单端口模式下修改流ID为目标流ID,不然其他地方可能都无法对应 + param.setStream(inviteInfo.getStream()); } } From 7a59acc8e694a64d6ae9ca31449eb65823597e52 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 17:30:18 +0800 Subject: [PATCH 54/58] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=B8=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 8dba01be2..5c819e592 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -158,6 +158,7 @@ public class MediaServiceImpl implements IMediaService { if (inviteInfo != null) { result.setStream_replace(inviteInfo.getStream()); logger.info("[ZLM HOOK]推流鉴权 stream: {} 替换为 {}", stream, inviteInfo.getStream()); + stream = inviteInfo.getStream(); } } From a1861038e5cb80e609f22ec99b0da8c0a3371342 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 19:53:43 +0800 Subject: [PATCH 55/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BD=95=E5=83=8F?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/event/hook/HookSubscribe.java | 13 +++++++++---- .../iot/vmp/service/impl/PlatformServiceImpl.java | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java index 335365688..907e904c0 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java @@ -1,9 +1,6 @@ package com.genersoft.iot.vmp.media.event.hook; -import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; -import com.genersoft.iot.vmp.media.event.media.MediaEvent; -import com.genersoft.iot.vmp.media.event.media.MediaPublishEvent; +import com.genersoft.iot.vmp.media.event.media.*; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; @@ -60,6 +57,14 @@ public class HookSubscribe { public void onApplicationEvent(MediaPublishEvent event) { sendNotify(HookType.on_publish, event); } + /** + * 推流鉴权事件 + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaRecordMp4Event event) { + sendNotify(HookType.on_record_mp4, event); + } private final Map allSubscribes = new ConcurrentHashMap<>(); private final Map allHook = new ConcurrentHashMap<>(); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index 822b54e96..fb728bc0a 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -135,7 +135,7 @@ public class PlatformServiceImpl implements IPlatformService { @EventListener public void onApplicationEvent(MediaSendRtpStoppedEvent event) { List sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream()); - if (!sendRtpItems.isEmpty()) { + if (sendRtpItems != null && !sendRtpItems.isEmpty()) { for (SendRtpItem sendRtpItem : sendRtpItems) { ParentPlatform parentPlatform = platformMapper.getParentPlatByServerGBId(sendRtpItem.getPlatformId()); ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); From 54b878d2e1e089cdeb7a957b78aa1f4cbdd6da6c Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 22:43:45 +0800 Subject: [PATCH 56/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=8C=E5=8D=87=E7=BA=A7=E7=89=88=E6=9C=AC=E5=8F=B7=E4=B8=BA?= =?UTF-8?q?2.7.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../request/impl/AckRequestProcessor.java | 78 ++--- .../request/impl/InviteRequestProcessor.java | 6 +- .../service/IMediaNodeServerService.java | 5 + .../media/service/IMediaServerService.java | 10 +- .../service/impl/MediaServerServiceImpl.java | 50 +++ .../vmp/media/zlm/ZLMMediaListManager.java | 2 +- .../media/zlm/ZLMMediaNodeServerService.java | 48 +++ .../iot/vmp/service/IPlayService.java | 3 +- .../vmp/service/impl/PlatformServiceImpl.java | 2 +- .../iot/vmp/service/impl/PlayServiceImpl.java | 164 +++------ .../service/impl/StreamProxyServiceImpl.java | 2 +- .../redisMsg/RedisGbPlayMsgListener.java | 2 +- .../iot/vmp/vmanager/ps/PsController.java | 2 +- .../iot/vmp/vmanager/rtp/RtpController.java | 2 +- src/main/resources/application.yml | 2 +- 数据库/{abl => 2.7.1}/初始化-mysql-2.7.0.sql | 1 + .../初始化-postgresql-kingbase-2.7.0.sql | 1 + .../更新-mysql-2.7.0.sql} | 0 .../更新-postgresql-kingbase-2.7.0.sql} | 2 +- 数据库/初始化-mysql.sql | 324 ------------------ 数据库/初始化-postgresql-kingbase.sql | 324 ------------------ 22 files changed, 196 insertions(+), 836 deletions(-) rename 数据库/{abl => 2.7.1}/初始化-mysql-2.7.0.sql (99%) rename 数据库/{abl => 2.7.1}/初始化-postgresql-kingbase-2.7.0.sql (99%) rename 数据库/{abl/更新-postgresql-kingbase-2.7.0.sql => 2.7.1/更新-mysql-2.7.0.sql} (100%) rename 数据库/{abl/更新-mysql-2.7.0.sql => 2.7.1/更新-postgresql-kingbase-2.7.0.sql} (89%) delete mode 100644 数据库/初始化-mysql.sql delete mode 100644 数据库/初始化-postgresql-kingbase.sql diff --git a/pom.xml b/pom.xml index 7ec73b81c..df841d521 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ com.genersoft wvp-pro - 2.7.0 + 2.7.1 web video platform 国标28181视频平台 ${project.packaging} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index d1eb5d303..5410d67dc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -3,6 +3,9 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.DynamicTask; 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.AudioBroadcastCatch; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; @@ -25,12 +28,15 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.SipException; import javax.sip.address.SipURI; import javax.sip.header.CallIdHeader; import javax.sip.header.FromHeader; import javax.sip.header.HeaderAddress; import javax.sip.header.ToHeader; +import java.text.ParseException; import java.util.HashMap; import java.util.Map; @@ -115,19 +121,24 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(fromUserId); if (parentPlatform != null) { - Map param = getSendRtpParam(sendRtpItem); if (!userSetting.getServerId().equals(sendRtpItem.getServerId())) { RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isTcp(), sendRtpItem.getLocalPort(), sendRtpItem.getPt(), sendRtpItem.isUsePs(), sendRtpItem.isOnlyAudio()); redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, json -> { - playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, json, param, callIdHeader); + playService.startSendRtpStreamFailHand(sendRtpItem, parentPlatform, callIdHeader); }); } else { - JSONObject startSendRtpStreamResult = sendRtp(sendRtpItem, mediaInfo, param); - if (startSendRtpStreamResult != null) { - playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, startSendRtpStreamResult, param, callIdHeader); + try { + if (sendRtpItem.isTcpActive()) { + mediaServerService.startSendRtpPassive(mediaInfo, parentPlatform, sendRtpItem, null); + } else { + mediaServerService.startSendRtpStream(mediaInfo, parentPlatform, sendRtpItem); + } + }catch (ControllerException e) { + logger.error("RTP推流失败: {}", e.getMessage()); + playService.startSendRtpStreamFailHand(sendRtpItem, parentPlatform, callIdHeader); } } }else { @@ -144,56 +155,17 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In logger.warn("[收到ACK]:来自{},目标为({})的推流信息为找到流体服务[{}]信息",fromUserId, toUserId, sendRtpItem.getMediaServerId()); return; } - Map param = getSendRtpParam(sendRtpItem); - JSONObject startSendRtpStreamResult = sendRtp(sendRtpItem, mediaInfo, param); - if (startSendRtpStreamResult != null) { - playService.startSendRtpStreamHand(sendRtpItem, device, startSendRtpStreamResult, param, callIdHeader); + try { + if (sendRtpItem.isTcpActive()) { + mediaServerService.startSendRtpPassive(mediaInfo, null, sendRtpItem, null); + } else { + mediaServerService.startSendRtpStream(mediaInfo, null, sendRtpItem); + } + }catch (ControllerException e) { + logger.error("RTP推流失败: {}", e.getMessage()); + playService.startSendRtpStreamFailHand(sendRtpItem, null, callIdHeader); } } } - private Map getSendRtpParam(SendRtpItem sendRtpItem) { - String isUdp = sendRtpItem.isTcp() ? "0" : "1"; - Map param = new HashMap<>(12); - param.put("vhost","__defaultVhost__"); - param.put("app",sendRtpItem.getApp()); - param.put("stream",sendRtpItem.getStream()); - param.put("ssrc", sendRtpItem.getSsrc()); - param.put("dst_url",sendRtpItem.getIp()); - param.put("dst_port", sendRtpItem.getPort()); - param.put("src_port", sendRtpItem.getLocalPort()); - param.put("pt", sendRtpItem.getPt()); - param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); - param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); - param.put("is_udp", isUdp); - if (!sendRtpItem.isTcp()) { - // udp模式下开启rtcp保活 - param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0"); - } - return param; - } - - private JSONObject sendRtp(SendRtpItem sendRtpItem, MediaServer mediaInfo, Map param){ - JSONObject startSendRtpStreamResult = null; - if (sendRtpItem.getLocalPort() != 0) { - if (sendRtpItem.isTcpActive()) { - startSendRtpStreamResult = zlmServerFactory.startSendRtpPassive(mediaInfo, param); - }else { - param.put("dst_url", sendRtpItem.getIp()); - param.put("dst_port", sendRtpItem.getPort()); - startSendRtpStreamResult = zlmServerFactory.startSendRtpStream(mediaInfo, param); - } - }else { - if (sendRtpItem.isTcpActive()) { - startSendRtpStreamResult = zlmServerFactory.startSendRtpPassive(mediaInfo, param); - }else { - param.put("dst_url", sendRtpItem.getIp()); - param.put("dst_port", sendRtpItem.getPort()); - startSendRtpStreamResult = zlmServerFactory.startSendRtpStream(mediaInfo, param); - } - } - return startSendRtpStreamResult; - - } - } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 7303594b7..b4d183ed6 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -641,7 +641,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements CallIdHeader callIdHeader, MediaServer mediaServerItem, int port, Boolean tcpActive, boolean mediaTransmissionTCP, String channelId, String addressStr, String ssrc, String requesterId) { - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); if (streamReady != null && streamReady) { // 自平台内容 SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, @@ -681,7 +681,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements String channelId, String addressStr, String ssrc, String requesterId) { // 推流 if (streamPushItem.isSelf()) { - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); if (streamReady != null && streamReady) { // 自平台内容 SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, @@ -1108,7 +1108,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements redisCatchStorage.updateSendRTPSever(sendRtpItem); - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, broadcastCatch.getApp(), broadcastCatch.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, broadcastCatch.getApp(), broadcastCatch.getStream()); if (streamReady) { sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, gb28181Sdp.getSsrc()); } else { diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 4b6b2215e..873993826 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; @@ -53,4 +54,8 @@ public interface IMediaNodeServerService { Boolean delStreamProxy(MediaServer mediaServer, String streamKey); Map getFFmpegCMDs(MediaServer mediaServer); + + void startSendRtpPassive(MediaServer mediaServer, SendRtpItem sendRtpItem, Integer timeout); + + void startSendRtpStream(MediaServer mediaServer, SendRtpItem sendRtpItem); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 2a72eb433..fb56ab6f4 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.media.service; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; @@ -133,5 +135,11 @@ public interface IMediaServerService { * @param stream * @return */ - StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay); + StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay); + + Boolean isStreamReady(MediaServer mediaServer, String rtp, String streamId); + + void startSendRtpPassive(MediaServer mediaServer, ParentPlatform platform, SendRtpItem sendRtpItem, Integer timeout); + + void startSendRtpStream(MediaServer mediaServer, ParentPlatform platform, SendRtpItem sendRtpItem); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 1b5d109e8..5e9115177 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -7,6 +7,9 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType; +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; @@ -19,6 +22,7 @@ import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; +import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; @@ -784,4 +788,50 @@ public class MediaServerServiceImpl implements IMediaServerService { streamInfoResult.setMediaInfo(mediaInfo); return streamInfoResult; } + + @Override + public Boolean isStreamReady(MediaServer mediaServer, String rtp, String streamId) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[isStreamReady] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + return false; + } + MediaInfo mediaInfo = mediaNodeServerService.getMediaInfo(mediaServer, rtp, streamId); + return mediaInfo != null; + } + + @Override + public void startSendRtpPassive(MediaServer mediaServer, ParentPlatform platform, SendRtpItem sendRtpItem, Integer timeout) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[startSendRtpPassive] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类"); + } + mediaNodeServerService.startSendRtpPassive(mediaServer, sendRtpItem, timeout); + sendPlatformStartPlayMsg(platform, sendRtpItem); + } + + @Override + public void startSendRtpStream(MediaServer mediaServer, ParentPlatform platform, SendRtpItem sendRtpItem) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + logger.info("[startSendRtpStream] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类"); + } + logger.info("[开始推流] rtp/{}, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), + sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); + mediaNodeServerService.startSendRtpStream(mediaServer, sendRtpItem); + sendPlatformStartPlayMsg(platform, sendRtpItem); + + } + + private void sendPlatformStartPlayMsg(ParentPlatform platform, SendRtpItem sendRtpItem) { + if (sendRtpItem.getPlayType() == InviteStreamType.PUSH && platform != null) { + MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, sendRtpItem.getApp(), sendRtpItem.getStream(), + sendRtpItem.getChannelId(), platform.getServerGBId(), platform.getName(), userSetting.getServerId(), + sendRtpItem.getMediaServerId()); + messageForPushChannel.setPlatFormIndex(platform.getId()); + redisCatchStorage.sendPlatformStartPlayMsg(messageForPushChannel); + } + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 8c5f80e2b..84df2e785 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -92,7 +92,7 @@ public class ZLMMediaListManager { public void sendStreamEvent(String app, String stream, String mediaServerId) { MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); // 查看推流状态 - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, app, stream); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, app, stream); if (streamReady != null && streamReady) { ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(app, stream); if (channelOnlineEventLister != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 72f3ba127..707ea01c0 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -6,6 +6,7 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; import com.genersoft.iot.vmp.media.bean.MediaServer; @@ -298,4 +299,51 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } return result; } + + @Override + public void startSendRtpPassive(MediaServer mediaServer, SendRtpItem sendRtpItem, Integer timeout) { + Map param = new HashMap<>(12); + param.put("vhost","__defaultVhost__"); + param.put("app", sendRtpItem.getApp()); + param.put("stream", sendRtpItem.getStream()); + param.put("ssrc", sendRtpItem.getSsrc()); + param.put("src_port", sendRtpItem.getLocalPort()); + param.put("pt", sendRtpItem.getPt()); + param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); + param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); + param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1"); + param.put("recv_stream_id", sendRtpItem.getReceiveStream()); + if (timeout != null) { + param.put("close_delay_ms", timeout); + } + + JSONObject jsonObject = zlmServerFactory.startSendRtpPassive(mediaServer, param, null); + if (jsonObject == null || jsonObject.getInteger("code") != 0 ) { + throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg")); + } + } + + @Override + public void startSendRtpStream(MediaServer mediaServer, SendRtpItem sendRtpItem) { + Map param = new HashMap<>(12); + param.put("vhost", "__defaultVhost__"); + param.put("app", sendRtpItem.getApp()); + param.put("stream", sendRtpItem.getStream()); + param.put("ssrc", sendRtpItem.getSsrc()); + param.put("src_port", sendRtpItem.getLocalPort()); + param.put("pt", sendRtpItem.getPt()); + param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); + param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); + param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1"); + if (!sendRtpItem.isTcp()) { + // udp模式下开启rtcp保活 + param.put("udp_rtcp_timeout", sendRtpItem.isRtcp() ? "1" : "0"); + } + param.put("dst_url", sendRtpItem.getIp()); + param.put("dst_port", sendRtpItem.getPort()); + JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, param); + if (jsonObject == null || jsonObject.getInteger("code") != 0 ) { + throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg")); + } + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java index e4f80af0e..b3cab0e84 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java @@ -59,8 +59,7 @@ public interface IPlayService { void startPushStream(SendRtpItem sendRtpItem, SIPResponse sipResponse, ParentPlatform platform, CallIdHeader callIdHeader); - void startSendRtpStreamHand(SendRtpItem sendRtpItem, Object correlationInfo, - JSONObject jsonObject, Map param, CallIdHeader callIdHeader); + void startSendRtpStreamFailHand(SendRtpItem sendRtpItem,ParentPlatform platform, CallIdHeader callIdHeader); void talkCmd(Device device, String channelId, MediaServer mediaServerItem, String stream, AudioBroadcastEvent event); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java index fb728bc0a..aa39f4186 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java @@ -512,7 +512,7 @@ public class PlatformServiceImpl implements IPlatformService { // 如果zlm不存在这个流,则删除数据即可 MediaServer mediaServerItemForStreamInfo = mediaServerService.getOne(inviteInfoForOld.getStreamInfo().getMediaServerId()); if (mediaServerItemForStreamInfo != null) { - Boolean ready = zlmServerFactory.isStreamReady(mediaServerItemForStreamInfo, inviteInfoForOld.getStreamInfo().getApp(), inviteInfoForOld.getStreamInfo().getStream()); + Boolean ready = mediaServerService.isStreamReady(mediaServerItemForStreamInfo, inviteInfoForOld.getStreamInfo().getApp(), inviteInfoForOld.getStreamInfo().getStream()); if (!ready) { // 错误存在于redis中的数据 inviteStreamService.removeInviteInfo(inviteInfoForOld); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 816f17fb1..7406483d7 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -84,9 +84,6 @@ public class PlayServiceImpl implements IPlayService { @Autowired private IRedisCatchStorage redisCatchStorage; - @Autowired - private ZLMServerFactory zlmServerFactory; - @Autowired private IInviteStreamService inviteStreamService; @@ -302,8 +299,7 @@ public class PlayServiceImpl implements IPlayService { } String mediaServerId = streamInfo.getMediaServerId(); MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); - - Boolean ready = zlmServerFactory.isStreamReady(mediaInfo, "rtp", streamId); + Boolean ready = mediaServerService.isStreamReady(mediaInfo, "rtp", streamId); if (ready != null && ready) { callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo); inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, @@ -391,28 +387,15 @@ public class PlayServiceImpl implements IPlayService { } }, userSetting.getPlayTimeout()); - Map param = new HashMap<>(12); - param.put("vhost","__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStream()); - param.put("ssrc", sendRtpItem.getSsrc()); - param.put("src_port", sendRtpItem.getLocalPort()); - param.put("pt", sendRtpItem.getPt()); - param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); - param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); - param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1"); - param.put("recv_stream_id", sendRtpItem.getReceiveStream()); - param.put("close_delay_ms", userSetting.getPlayTimeout() * 1000); - - zlmServerFactory.startSendRtpPassive(mediaServerItem, param, jsonObject -> { - if (jsonObject == null || jsonObject.getInteger("code") != 0 ) { - mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc()); - logger.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channelId); - audioEvent.call("失败, " + jsonObject.getString("msg")); - // 查看是否已经建立了通道,存在则发送bye - stopTalk(device, channelId); - } - }); + try { + mediaServerService.startSendRtpPassive(mediaServerItem, null, sendRtpItem, userSetting.getPlayTimeout() * 1000); + }catch (ControllerException e) { + mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc()); + logger.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channelId); + audioEvent.call("失败, " + e.getMessage()); + // 查看是否已经建立了通道,存在则发送bye + stopTalk(device, channelId); + } // 查看设备是否已经在推流 @@ -1238,7 +1221,7 @@ public class PlayServiceImpl implements IPlayService { SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 查询流是否存在,不存在则认为是异常状态 - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("语音广播已经开启: {}", channelId); event.call("语音广播已经开启"); @@ -1248,18 +1231,6 @@ public class PlayServiceImpl implements IPlayService { } } } -// SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); -// if (sendRtpItem != null) { -// MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); -// Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); -// if (streamReady) { -// logger.warn("[语音对讲] 进行中: {}", channelId); -// event.call("语音对讲进行中"); -// return false; -// } else { -// stopTalk(device, channelId); -// } -// } // 发送通知 cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> { @@ -1291,7 +1262,7 @@ public class PlayServiceImpl implements IPlayService { if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 查询流是否存在,不存在则认为是异常状态 MediaServer mediaServerServiceOne = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerServiceOne, sendRtpItem.getApp(), sendRtpItem.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerServiceOne, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("语音广播通道使用中: {}", channelId); return true; @@ -1447,24 +1418,7 @@ public class PlayServiceImpl implements IPlayService { @Override public void startPushStream(SendRtpItem sendRtpItem, SIPResponse sipResponse, ParentPlatform platform, CallIdHeader callIdHeader) { // 开始发流 - String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - logger.info("[开始推流] rtp/{}, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), - sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); - Map param = new HashMap<>(12); - param.put("vhost", "__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStream()); - param.put("ssrc", sendRtpItem.getSsrc()); - param.put("src_port", sendRtpItem.getLocalPort()); - param.put("pt", sendRtpItem.getPt()); - param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); - param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); - param.put("is_udp", is_Udp); - if (!sendRtpItem.isTcp()) { - // udp模式下开启rtcp保活 - param.put("udp_rtcp_timeout", sendRtpItem.isRtcp() ? "1" : "0"); - } if (mediaInfo == null) { RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( @@ -1472,75 +1426,50 @@ public class PlayServiceImpl implements IPlayService { sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isTcp(), sendRtpItem.getLocalPort(), sendRtpItem.getPt(), sendRtpItem.isUsePs(), sendRtpItem.isOnlyAudio()); redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, json -> { - startSendRtpStreamHand(sendRtpItem, platform, json, param, callIdHeader); + startSendRtpStreamFailHand(sendRtpItem, platform, callIdHeader); }); } else { - // 如果是严格模式,需要关闭端口占用 - JSONObject startSendRtpStreamResult = null; - if (sendRtpItem.getLocalPort() != 0) { + try { if (sendRtpItem.isTcpActive()) { - startSendRtpStreamResult = zlmServerFactory.startSendRtpPassive(mediaInfo, param); + mediaServerService.startSendRtpPassive(mediaInfo, platform, sendRtpItem, null); } else { - param.put("dst_url", sendRtpItem.getIp()); - param.put("dst_port", sendRtpItem.getPort()); - startSendRtpStreamResult = zlmServerFactory.startSendRtpStream(mediaInfo, param); - } - } else { - if (sendRtpItem.isTcpActive()) { - startSendRtpStreamResult = zlmServerFactory.startSendRtpPassive(mediaInfo, param); - } else { - param.put("dst_url", sendRtpItem.getIp()); - param.put("dst_port", sendRtpItem.getPort()); - startSendRtpStreamResult = zlmServerFactory.startSendRtpStream(mediaInfo, param); + mediaServerService.startSendRtpStream(mediaInfo, platform, sendRtpItem); } + }catch (ControllerException e) { + logger.error("RTP推流失败: {}", e.getMessage()); + startSendRtpStreamFailHand(sendRtpItem, platform, callIdHeader); + return; } - if (startSendRtpStreamResult != null) { - startSendRtpStreamHand(sendRtpItem, platform, startSendRtpStreamResult, param, callIdHeader); - } + + logger.info("RTP推流成功[ {}/{} ],{}, ", sendRtpItem.getApp(), sendRtpItem.getStream(), + sendRtpItem.isTcpActive()?"被动发流": sendRtpItem.getIp() + ":" + sendRtpItem.getPort()); + } } @Override - public void startSendRtpStreamHand(SendRtpItem sendRtpItem, Object correlationInfo, - JSONObject jsonObject, Map param, CallIdHeader callIdHeader) { - if (jsonObject == null) { - logger.error("RTP推流失败: 请检查ZLM服务"); - } else if (jsonObject.getInteger("code") == 0) { - logger.info("调用ZLM推流接口, 结果: {}", jsonObject); - logger.info("RTP推流成功[ {}/{} ],{}->{}, ", param.get("app"), param.get("stream"), jsonObject.getString("local_port"), - sendRtpItem.isTcpActive()?"被动发流": param.get("dst_url") + ":" + param.get("dst_port")); - if (sendRtpItem.getPlayType() == InviteStreamType.PUSH && correlationInfo instanceof ParentPlatform) { - ParentPlatform platform = (ParentPlatform)correlationInfo; - MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, sendRtpItem.getApp(), sendRtpItem.getStream(), - sendRtpItem.getChannelId(), platform.getServerGBId(), platform.getName(), userSetting.getServerId(), - sendRtpItem.getMediaServerId()); - messageForPushChannel.setPlatFormIndex(platform.getId()); - redisCatchStorage.sendPlatformStartPlayMsg(messageForPushChannel); + public void startSendRtpStreamFailHand(SendRtpItem sendRtpItem, ParentPlatform platform, CallIdHeader callIdHeader) { + if (sendRtpItem.isOnlyAudio()) { + Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + if (audioBroadcastCatch != null) { + try { + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); + } catch (SipException | ParseException | InvalidArgumentException | + SsrcTransactionNotFoundException exception) { + logger.error("[命令发送失败] 停止语音对讲: {}", exception.getMessage()); + } } } else { - logger.error("RTP推流失败: {}, 参数:{}", jsonObject.getString("msg"), JSONObject.toJSONString(param)); - if (sendRtpItem.isOnlyAudio()) { - Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); - AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - if (audioBroadcastCatch != null) { - try { - cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); - } catch (SipException | ParseException | InvalidArgumentException | - SsrcTransactionNotFoundException e) { - logger.error("[命令发送失败] 停止语音对讲: {}", e.getMessage()); - } - } - } else { + if (platform != null) { // 向上级平台 - if (correlationInfo instanceof ParentPlatform) { - try { - ParentPlatform parentPlatform = (ParentPlatform)correlationInfo; - commanderForPlatform.streamByeCmd(parentPlatform, callIdHeader.getCallId()); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); - } + try { + commanderForPlatform.streamByeCmd(platform, callIdHeader.getCallId()); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); } } + } } @@ -1563,7 +1492,7 @@ public class PlayServiceImpl implements IPlayService { if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 查询流是否存在,不存在则认为是异常状态 MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("[语音对讲] 正在语音广播,无法开启语音通话: {}", channelId); event.call("正在语音广播"); @@ -1577,7 +1506,7 @@ public class PlayServiceImpl implements IPlayService { SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, stream, null); if (sendRtpItem != null) { MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream()); if (streamReady) { logger.warn("[语音对讲] 进行中: {}", channelId); event.call("语音对讲进行中"); @@ -1624,12 +1553,7 @@ public class PlayServiceImpl implements IPlayService { MediaServer mediaServer = mediaServerService.getOne(mediaServerId); if (streamIsReady == null || streamIsReady) { - Map param = new HashMap<>(); - param.put("vhost", "__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStream()); - param.put("ssrc", sendRtpItem.getSsrc()); - zlmServerFactory.stopSendRtpStream(mediaServer, param); + mediaServerService.stopSendRtp(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc()); } ssrcFactory.releaseSsrc(mediaServerId, sendRtpItem.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 0669ff37f..6692aa8f9 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -349,7 +349,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { if (mediaServer == null) { return null; } - if (zlmServerFactory.isStreamReady(mediaServer, param.getApp(), param.getStream())) { + if (mediaServerService.isStreamReady(mediaServer, param.getApp(), param.getStream())) { mediaServerService.closeStreams(mediaServer, param.getApp(), param.getStream()); } String msgResult; diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index fd59704f6..14287e005 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -274,7 +274,7 @@ public class RedisGbPlayMsgListener implements MessageListener { return; } // 确定流是否在线 - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, content.getApp(), content.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, content.getApp(), content.getStream()); if (streamReady != null && streamReady) { logger.info("[回复推流信息] {}/{}", content.getApp(), content.getStream()); responseSendItem(mediaServerItem, content, toId, serial); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index f7807b9c9..6401a8c91 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -224,7 +224,7 @@ public class PsController { param.put("src_port", sendInfo.getSendLocalPort()); - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, app, stream); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, app, stream); if (streamReady) { JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, param); if (jsonObject.getInteger("code") == 0) { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index 7bd231062..f42d153cf 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -275,7 +275,7 @@ public class RtpController { paramForVideo = null; } - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, app, stream); + Boolean streamReady = mediaServerService.isStreamReady(mediaServer, app, stream); if (streamReady) { if (paramForVideo != null) { JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForVideo); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3f478442e..3d36b8474 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,4 +2,4 @@ spring: application: name: wvp profiles: - active: local \ No newline at end of file + active: abl \ No newline at end of file diff --git a/数据库/abl/初始化-mysql-2.7.0.sql b/数据库/2.7.1/初始化-mysql-2.7.0.sql similarity index 99% rename from 数据库/abl/初始化-mysql-2.7.0.sql rename to 数据库/2.7.1/初始化-mysql-2.7.0.sql index 0290a06c2..d59256b51 100644 --- a/数据库/abl/初始化-mysql-2.7.0.sql +++ b/数据库/2.7.1/初始化-mysql-2.7.0.sql @@ -203,6 +203,7 @@ create table wvp_platform ( update_time character varying(50), as_message_channel bool default false, auto_push_channel bool default false, + send_stream_ip character varying(50), constraint uk_platform_unique_server_gb_id unique (server_gb_id) ); diff --git a/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql b/数据库/2.7.1/初始化-postgresql-kingbase-2.7.0.sql similarity index 99% rename from 数据库/abl/初始化-postgresql-kingbase-2.7.0.sql rename to 数据库/2.7.1/初始化-postgresql-kingbase-2.7.0.sql index b2fbea550..992a3cf99 100644 --- a/数据库/abl/初始化-postgresql-kingbase-2.7.0.sql +++ b/数据库/2.7.1/初始化-postgresql-kingbase-2.7.0.sql @@ -203,6 +203,7 @@ create table wvp_platform ( update_time character varying(50), as_message_channel bool default false, auto_push_channel bool default false, + send_stream_ip character varying(50), constraint uk_platform_unique_server_gb_id unique (server_gb_id) ); diff --git a/数据库/abl/更新-postgresql-kingbase-2.7.0.sql b/数据库/2.7.1/更新-mysql-2.7.0.sql similarity index 100% rename from 数据库/abl/更新-postgresql-kingbase-2.7.0.sql rename to 数据库/2.7.1/更新-mysql-2.7.0.sql diff --git a/数据库/abl/更新-mysql-2.7.0.sql b/数据库/2.7.1/更新-postgresql-kingbase-2.7.0.sql similarity index 89% rename from 数据库/abl/更新-mysql-2.7.0.sql rename to 数据库/2.7.1/更新-postgresql-kingbase-2.7.0.sql index 851365874..9a527cb3f 100644 --- a/数据库/abl/更新-mysql-2.7.0.sql +++ b/数据库/2.7.1/更新-postgresql-kingbase-2.7.0.sql @@ -8,4 +8,4 @@ alter table wvp_media_server alter table wvp_media_server add ws_flv_port integer; alter table wvp_media_server - add ws_flv_ssl_port integer; + add ws_flv_ssl_port integer; \ No newline at end of file diff --git a/数据库/初始化-mysql.sql b/数据库/初始化-mysql.sql deleted file mode 100644 index a3f4a1d9a..000000000 --- a/数据库/初始化-mysql.sql +++ /dev/null @@ -1,324 +0,0 @@ -/*建表*/ -create table wvp_device ( - id serial primary key , - device_id character varying(50) not null , - name character varying(255), - manufacturer character varying(255), - model character varying(255), - firmware character varying(255), - transport character varying(50), - stream_mode character varying(50), - on_line bool default false, - register_time character varying(50), - keepalive_time character varying(50), - ip character varying(50), - create_time character varying(50), - update_time character varying(50), - port integer, - expires integer, - subscribe_cycle_for_catalog integer DEFAULT 0, - subscribe_cycle_for_mobile_position integer DEFAULT 0, - mobile_position_submission_interval integer DEFAULT 5, - subscribe_cycle_for_alarm integer DEFAULT 0, - host_address character varying(50), - charset character varying(50), - ssrc_check bool default false, - geo_coord_sys character varying(50), - media_server_id character varying(50), - custom_name character varying(255), - sdp_ip character varying(50), - local_ip character varying(50), - password character varying(255), - as_message_channel bool default false, - keepalive_interval_time integer, - switch_primary_sub_stream bool default false, - broadcast_push_after_ack bool default false, - constraint uk_device_device unique (device_id) -); - -create table wvp_device_alarm ( - id serial primary key , - device_id character varying(50) not null, - channel_id character varying(50) not null, - alarm_priority character varying(50), - alarm_method character varying(50), - alarm_time character varying(50), - alarm_description character varying(255), - longitude double precision, - latitude double precision, - alarm_type character varying(50), - create_time character varying(50) not null -); - -create table wvp_device_channel ( - id serial primary key , - channel_id character varying(50) not null, - name character varying(255), - custom_name character varying(255), - manufacture character varying(50), - model character varying(50), - owner character varying(50), - civil_code character varying(50), - block character varying(50), - address character varying(50), - parent_id character varying(50), - safety_way integer, - register_way integer, - cert_num character varying(50), - certifiable integer, - err_code integer, - end_time character varying(50), - secrecy character varying(50), - ip_address character varying(50), - port integer, - password character varying(255), - ptz_type integer, - custom_ptz_type integer, - status bool default false, - longitude double precision, - custom_longitude double precision, - latitude double precision, - custom_latitude double precision, - stream_id character varying(255), - device_id character varying(50) not null, - parental character varying(50), - has_audio bool default false, - create_time character varying(50) not null, - update_time character varying(50) not null, - sub_count integer, - longitude_gcj02 double precision, - latitude_gcj02 double precision, - longitude_wgs84 double precision, - latitude_wgs84 double precision, - business_group_id character varying(50), - gps_time character varying(50), - stream_identification character varying(50), - constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) -); - -create table wvp_device_mobile_position ( - id serial primary key, - device_id character varying(50) not null, - channel_id character varying(50) not null, - device_name character varying(255), - time character varying(50), - longitude double precision, - latitude double precision, - altitude double precision, - speed double precision, - direction double precision, - report_source character varying(50), - longitude_gcj02 double precision, - latitude_gcj02 double precision, - longitude_wgs84 double precision, - latitude_wgs84 double precision, - create_time character varying(50) -); - -create table wvp_gb_stream ( - gb_stream_id serial primary key, - app character varying(255) not null, - stream character varying(255) not null, - gb_id character varying(50) not null, - name character varying(255), - longitude double precision, - latitude double precision, - stream_type character varying(50), - media_server_id character varying(50), - create_time character varying(50), - constraint uk_gb_stream_unique_gb_id unique (gb_id), - constraint uk_gb_stream_unique_app_stream unique (app, stream) -); - -create table wvp_log ( - id serial primary key , - name character varying(50), - type character varying(50), - uri character varying(200), - address character varying(50), - result character varying(50), - timing bigint, - username character varying(50), - create_time character varying(50) -); - -create table wvp_media_server ( - id character varying(255) primary key , - ip character varying(50), - hook_ip character varying(50), - sdp_ip character varying(50), - stream_ip character varying(50), - http_port integer, - http_ssl_port integer, - rtmp_port integer, - rtmp_ssl_port integer, - rtp_proxy_port integer, - rtsp_port integer, - rtsp_ssl_port integer, - auto_config bool default false, - secret character varying(50), - rtp_enable bool default false, - rtp_port_range character varying(50), - send_rtp_port_range character varying(50), - record_assist_port integer, - default_server bool default false, - create_time character varying(50), - update_time character varying(50), - hook_alive_interval integer, - record_path character varying(255), - record_day integer default 7, - constraint uk_media_server_unique_ip_http_port unique (ip, http_port) -); - -create table wvp_platform ( - id serial primary key , - enable bool default false, - name character varying(255), - server_gb_id character varying(50), - server_gb_domain character varying(50), - server_ip character varying(50), - server_port integer, - device_gb_id character varying(50), - device_ip character varying(50), - device_port character varying(50), - username character varying(255), - password character varying(50), - expires character varying(50), - keep_timeout character varying(50), - transport character varying(50), - character_set character varying(50), - catalog_id character varying(50), - ptz bool default false, - rtcp bool default false, - status bool default false, - start_offline_push bool default false, - administrative_division character varying(50), - catalog_group integer, - create_time character varying(50), - update_time character varying(50), - as_message_channel bool default false, - auto_push_channel bool default false, - constraint uk_platform_unique_server_gb_id unique (server_gb_id) -); - -create table wvp_platform_catalog ( - id character varying(50), - platform_id character varying(50), - name character varying(255), - parent_id character varying(50), - civil_code character varying(50), - business_group_id character varying(50), - constraint uk_platform_catalog_id_platform_id unique (id, platform_id) -); - -create table wvp_platform_gb_channel ( - id serial primary key , - platform_id character varying(50), - catalog_id character varying(50), - device_channel_id integer, - constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id) -); - -create table wvp_platform_gb_stream ( - id serial primary key, - platform_id character varying(50), - catalog_id character varying(50), - gb_stream_id integer, - constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id) -); - -create table wvp_stream_proxy ( - id serial primary key, - type character varying(50), - app character varying(255), - stream character varying(255), - url character varying(255), - src_url character varying(255), - dst_url character varying(255), - timeout_ms integer, - ffmpeg_cmd_key character varying(255), - rtp_type character varying(50), - media_server_id character varying(50), - enable_audio bool default false, - enable_mp4 bool default false, - enable bool default false, - status boolean, - enable_remove_none_reader bool default false, - create_time character varying(50), - name character varying(255), - update_time character varying(50), - stream_key character varying(255), - enable_disable_none_reader bool default false, - constraint uk_stream_proxy_app_stream unique (app, stream) -); - -create table wvp_stream_push ( - id serial primary key, - app character varying(255), - stream character varying(255), - total_reader_count character varying(50), - origin_type integer, - origin_type_str character varying(50), - create_time character varying(50), - alive_second integer, - media_server_id character varying(50), - server_id character varying(50), - push_time character varying(50), - status bool default false, - update_time character varying(50), - push_ing bool default false, - self bool default false, - constraint uk_stream_push_app_stream unique (app, stream) -); -create table wvp_cloud_record ( - id serial primary key, - app character varying(255), - stream character varying(255), - call_id character varying(255), - start_time bigint, - end_time bigint, - media_server_id character varying(50), - file_name character varying(255), - folder character varying(255), - file_path character varying(255), - collect bool default false, - file_size bigint, - time_len bigint, - constraint uk_stream_push_app_stream_path unique (app, stream, file_path) -); - -create table wvp_user ( - id serial primary key, - username character varying(255), - password character varying(255), - role_id integer, - create_time character varying(50), - update_time character varying(50), - push_key character varying(50), - constraint uk_user_username unique (username) -); - -create table wvp_user_role ( - id serial primary key, - name character varying(50), - authority character varying(50), - create_time character varying(50), - update_time character varying(50) -); -create table wvp_resources_tree ( - id serial primary key , - is_catalog bool default true, - device_channel_id integer , - gb_stream_id integer, - name character varying(255), - parentId integer, - path character varying(255) -); - - -/*初始数据*/ -INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); -INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); - - - diff --git a/数据库/初始化-postgresql-kingbase.sql b/数据库/初始化-postgresql-kingbase.sql deleted file mode 100644 index 9f41667a7..000000000 --- a/数据库/初始化-postgresql-kingbase.sql +++ /dev/null @@ -1,324 +0,0 @@ -/*建表*/ -create table wvp_device ( - id serial primary key , - device_id character varying(50) not null , - name character varying(255), - manufacturer character varying(255), - model character varying(255), - firmware character varying(255), - transport character varying(50), - stream_mode character varying(50), - on_line bool default false, - register_time character varying(50), - keepalive_time character varying(50), - ip character varying(50), - create_time character varying(50), - update_time character varying(50), - port integer, - expires integer, - subscribe_cycle_for_catalog integer DEFAULT 0, - subscribe_cycle_for_mobile_position integer DEFAULT 0, - mobile_position_submission_interval integer DEFAULT 5, - subscribe_cycle_for_alarm integer DEFAULT 0, - host_address character varying(50), - charset character varying(50), - ssrc_check bool default false, - geo_coord_sys character varying(50), - media_server_id character varying(50), - custom_name character varying(255), - sdp_ip character varying(50), - local_ip character varying(50), - password character varying(255), - as_message_channel bool default false, - keepalive_interval_time integer, - switch_primary_sub_stream bool default false, - broadcast_push_after_ack bool default false, - constraint uk_device_device unique (device_id) -); - -create table wvp_device_alarm ( - id serial primary key , - device_id character varying(50) not null, - channel_id character varying(50) not null, - alarm_priority character varying(50), - alarm_method character varying(50), - alarm_time character varying(50), - alarm_description character varying(255), - longitude double precision, - latitude double precision, - alarm_type character varying(50), - create_time character varying(50) not null -); - -create table wvp_device_channel ( - id serial primary key , - channel_id character varying(50) not null, - name character varying(255), - custom_name character varying(255), - manufacture character varying(50), - model character varying(50), - owner character varying(50), - civil_code character varying(50), - block character varying(50), - address character varying(50), - parent_id character varying(50), - safety_way integer, - register_way integer, - cert_num character varying(50), - certifiable integer, - err_code integer, - end_time character varying(50), - secrecy character varying(50), - ip_address character varying(50), - port integer, - password character varying(255), - ptz_type integer, - custom_ptz_type integer, - status bool default false, - longitude double precision, - custom_longitude double precision, - latitude double precision, - custom_latitude double precision, - stream_id character varying(255), - device_id character varying(50) not null, - parental character varying(50), - has_audio bool default false, - create_time character varying(50) not null, - update_time character varying(50) not null, - sub_count integer, - longitude_gcj02 double precision, - latitude_gcj02 double precision, - longitude_wgs84 double precision, - latitude_wgs84 double precision, - business_group_id character varying(50), - gps_time character varying(50), - stream_identification character varying(50), - constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) -); - -create table wvp_device_mobile_position ( - id serial primary key, - device_id character varying(50) not null, - channel_id character varying(50) not null, - device_name character varying(255), - time character varying(50), - longitude double precision, - latitude double precision, - altitude double precision, - speed double precision, - direction double precision, - report_source character varying(50), - longitude_gcj02 double precision, - latitude_gcj02 double precision, - longitude_wgs84 double precision, - latitude_wgs84 double precision, - create_time character varying(50) -); - -create table wvp_gb_stream ( - gb_stream_id serial primary key, - app character varying(255) not null, - stream character varying(255) not null, - gb_id character varying(50) not null, - name character varying(255), - longitude double precision, - latitude double precision, - stream_type character varying(50), - media_server_id character varying(50), - create_time character varying(50), - constraint uk_gb_stream_unique_gb_id unique (gb_id), - constraint uk_gb_stream_unique_app_stream unique (app, stream) -); - -create table wvp_log ( - id serial primary key , - name character varying(50), - type character varying(50), - uri character varying(200), - address character varying(50), - result character varying(50), - timing bigint, - username character varying(50), - create_time character varying(50) -); - -create table wvp_media_server ( - id character varying(255) primary key , - ip character varying(50), - hook_ip character varying(50), - sdp_ip character varying(50), - stream_ip character varying(50), - http_port integer, - http_ssl_port integer, - rtmp_port integer, - rtmp_ssl_port integer, - rtp_proxy_port integer, - rtsp_port integer, - rtsp_ssl_port integer, - auto_config bool default false, - secret character varying(50), - rtp_enable bool default false, - rtp_port_range character varying(50), - send_rtp_port_range character varying(50), - record_assist_port integer, - default_server bool default false, - create_time character varying(50), - update_time character varying(50), - hook_alive_interval integer, - record_path character varying(255), - record_day integer default 7, - constraint uk_media_server_unique_ip_http_port unique (ip, http_port) -); - -create table wvp_platform ( - id serial primary key , - enable bool default false, - name character varying(255), - server_gb_id character varying(50), - server_gb_domain character varying(50), - server_ip character varying(50), - server_port integer, - device_gb_id character varying(50), - device_ip character varying(50), - device_port character varying(50), - username character varying(255), - password character varying(50), - expires character varying(50), - keep_timeout character varying(50), - transport character varying(50), - character_set character varying(50), - catalog_id character varying(50), - ptz bool default false, - rtcp bool default false, - status bool default false, - start_offline_push bool default false, - administrative_division character varying(50), - catalog_group integer, - create_time character varying(50), - update_time character varying(50), - as_message_channel bool default false, - auto_push_channel bool default false, - constraint uk_platform_unique_server_gb_id unique (server_gb_id) -); - -create table wvp_platform_catalog ( - id character varying(50), - platform_id character varying(50), - name character varying(255), - parent_id character varying(50), - civil_code character varying(50), - business_group_id character varying(50), - constraint uk_platform_catalog_id_platform_id unique (id, platform_id) -); - -create table wvp_platform_gb_channel ( - id serial primary key , - platform_id character varying(50), - catalog_id character varying(50), - device_channel_id integer, - constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id) -); - -create table wvp_platform_gb_stream ( - id serial primary key, - platform_id character varying(50), - catalog_id character varying(50), - gb_stream_id integer, - constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id) -); - -create table wvp_stream_proxy ( - id serial primary key, - type character varying(50), - app character varying(255), - stream character varying(255), - url character varying(255), - src_url character varying(255), - dst_url character varying(255), - timeout_ms integer, - ffmpeg_cmd_key character varying(255), - rtp_type character varying(50), - media_server_id character varying(50), - enable_audio bool default false, - enable_mp4 bool default false, - enable bool default false, - status boolean, - enable_remove_none_reader bool default false, - create_time character varying(50), - name character varying(255), - update_time character varying(50), - stream_key character varying(255), - enable_disable_none_reader bool default false, - constraint uk_stream_proxy_app_stream unique (app, stream) -); - -create table wvp_stream_push ( - id serial primary key, - app character varying(255), - stream character varying(255), - total_reader_count character varying(50), - origin_type integer, - origin_type_str character varying(50), - create_time character varying(50), - alive_second integer, - media_server_id character varying(50), - server_id character varying(50), - push_time character varying(50), - status bool default false, - update_time character varying(50), - push_ing bool default false, - self bool default false, - constraint uk_stream_push_app_stream unique (app, stream) -); -create table wvp_cloud_record ( - id serial primary key, - app character varying(255), - stream character varying(255), - call_id character varying(255), - start_time int8, - end_time int8, - media_server_id character varying(50), - file_name character varying(255), - folder character varying(255), - file_path character varying(255), - collect bool default false, - file_size int8, - time_len int8, - constraint uk_stream_push_app_stream_path unique (app, stream, file_path) -); - -create table wvp_user ( - id serial primary key, - username character varying(255), - password character varying(255), - role_id integer, - create_time character varying(50), - update_time character varying(50), - push_key character varying(50), - constraint uk_user_username unique (username) -); - -create table wvp_user_role ( - id serial primary key, - name character varying(50), - authority character varying(50), - create_time character varying(50), - update_time character varying(50) -); -create table wvp_resources_tree ( - id serial primary key , - is_catalog bool default true, - device_channel_id integer , - gb_stream_id integer, - name character varying(255), - parentId integer, - path character varying(255) -); - - -/*初始数据*/ -INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); -INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); - - - From 82ca3a778ac9a796189d0cd3312f2fbd68edbded Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 9 Apr 2024 22:52:06 +0800 Subject: [PATCH 57/58] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E8=8A=82=E7=82=B9redis=E6=95=B0=E6=8D=AE=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/common/VideoManagerConstants.java | 4 +-- .../service/impl/MediaServerServiceImpl.java | 28 +++++++++---------- src/main/resources/application.yml | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index bfd39c25d..df230d441 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -12,9 +12,9 @@ public class VideoManagerConstants { public static final String WVP_SERVER_STREAM_PREFIX = "VMP_SIGNALLING_STREAM_"; - public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_INFO_"; + public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER:"; - public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_"; + public static final String ONLINE_MEDIA_SERVERS_PREFIX = "VMP_ONLINE_MEDIA_SERVERS:"; public static final String DEVICE_PREFIX = "VMP_DEVICE_"; diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 5e9115177..6214ccbac 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -125,7 +125,7 @@ public class MediaServerServiceImpl implements IMediaServerService { ssrcFactory.initMediaServerSSRC(mediaServer.getId(), null); } // 查询redis是否存在此mediaServer - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServer.getId(); + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + ":" + mediaServer.getId(); Boolean hasKey = redisTemplate.hasKey(key); if (hasKey != null && ! hasKey) { redisTemplate.opsForValue().set(key, mediaServer); @@ -261,7 +261,7 @@ public class MediaServerServiceImpl implements IMediaServerService { if (mediaServerInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerInDataBase.getId())) { ssrcFactory.initMediaServerSSRC(mediaServerInDataBase.getId(),null); } - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerInDataBase.getId(); + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + ":" + mediaServerInDataBase.getId(); redisTemplate.opsForValue().set(key, mediaServerInDataBase); if (mediaServerInDataBase.isStatus()) { resetOnlineServerItem(mediaServerInDataBase); @@ -277,8 +277,8 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public List getAllOnlineList() { List result = new ArrayList<>(); - List mediaServerKeys = RedisUtil.scan(redisTemplate, String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX+ userSetting.getServerId() + "_" )); - String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); + List mediaServerKeys = RedisUtil.scan(redisTemplate, String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX+ userSetting.getServerId() + ":" )); + String onlineKey = VideoManagerConstants.ONLINE_MEDIA_SERVERS_PREFIX + userSetting.getServerId(); for (Object mediaServerKey : mediaServerKeys) { String key = (String) mediaServerKey; MediaServer mediaServer = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServer.class); @@ -326,14 +326,14 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public List getAllOnline() { - String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); + String key = VideoManagerConstants.ONLINE_MEDIA_SERVERS_PREFIX + userSetting.getServerId(); Set mediaServerIdSet = redisTemplate.opsForZSet().reverseRange(key, 0, -1); List result = new ArrayList<>(); if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) { for (Object mediaServerId : mediaServerIdSet) { String mediaServerIdStr = (String) mediaServerId; - String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerIdStr; + String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + ":" + mediaServerIdStr; result.add((MediaServer) redisTemplate.opsForValue().get(serverKey)); } } @@ -351,7 +351,7 @@ public class MediaServerServiceImpl implements IMediaServerService { if (mediaServerId == null) { return null; } - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerId; + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + ":" + mediaServerId; return JsonUtil.redisJsonToObject(redisTemplate, key, MediaServer.class); } @@ -363,7 +363,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public void clearMediaServerForOnline() { - String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); + String key = VideoManagerConstants.ONLINE_MEDIA_SERVERS_PREFIX + userSetting.getServerId(); redisTemplate.delete(key); } @@ -401,7 +401,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public void resetOnlineServerItem(MediaServer serverItem) { // 更新缓存 - String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); + String key = VideoManagerConstants.ONLINE_MEDIA_SERVERS_PREFIX + userSetting.getServerId(); // 使用zset的分数作为当前并发量, 默认值设置为0 if (redisTemplate.opsForZSet().score(key, serverItem.getId()) == null) { // 不存在则设置默认值 已存在则重置 redisTemplate.opsForZSet().add(key, serverItem.getId(), 0L); @@ -424,14 +424,14 @@ public class MediaServerServiceImpl implements IMediaServerService { if (mediaServerId == null) { return; } - String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); + String key = VideoManagerConstants.ONLINE_MEDIA_SERVERS_PREFIX + userSetting.getServerId(); redisTemplate.opsForZSet().incrementScore(key, mediaServerId, 1); } @Override public void removeCount(String mediaServerId) { - String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); + String key = VideoManagerConstants.ONLINE_MEDIA_SERVERS_PREFIX + userSetting.getServerId(); redisTemplate.opsForZSet().incrementScore(key, mediaServerId, - 1); } @@ -441,7 +441,7 @@ public class MediaServerServiceImpl implements IMediaServerService { */ @Override public MediaServer getMediaServerForMinimumLoad(Boolean hasAssist) { - String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); + String key = VideoManagerConstants.ONLINE_MEDIA_SERVERS_PREFIX + userSetting.getServerId(); Long size = redisTemplate.opsForZSet().zCard(key); if (size == null || size == 0) { logger.info("获取负载最低的节点时无在线节点"); @@ -520,8 +520,8 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public void delete(String id) { mediaServerMapper.delOne(id); - redisTemplate.opsForZSet().remove(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(), id); - String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + id; + redisTemplate.opsForZSet().remove(VideoManagerConstants.ONLINE_MEDIA_SERVERS_PREFIX + userSetting.getServerId(), id); + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + ":" + id; redisTemplate.delete(key); // 发送节点移除通知 MediaServerDeleteEvent event = new MediaServerDeleteEvent(this); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3d36b8474..3f478442e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,4 +2,4 @@ spring: application: name: wvp profiles: - active: abl \ No newline at end of file + active: local \ No newline at end of file From 10e2180c72d0f683cf08a4bc586aa8960b2a6d5c Mon Sep 17 00:00:00 2001 From: leesam Date: Wed, 10 Apr 2024 19:07:37 +0800 Subject: [PATCH 58/58] =?UTF-8?q?[bugfix]=E6=94=AF=E6=8C=81context-path?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/zlm/ZLMMediaServerStatusManger.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java index d744850dc..cdf1e3f27 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java @@ -55,6 +55,9 @@ public class ZLMMediaServerStatusManger { @Value("${server.port}") private Integer serverPort; + @Value("${server.servlet.context-path:}") + private String serverServletContextPath; + @Autowired private UserSetting userSetting; @@ -239,7 +242,7 @@ public class ZLMMediaServerStatusManger { logger.info("[媒体服务节点] 正在设置 :{} -> {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); String protocol = sslEnabled ? "https" : "http"; - String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); + String hookPrefix = String.format("%s://%s:%s%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort, (serverServletContextPath == null || "/".equals(serverServletContextPath)) ? "" : serverServletContextPath); Map param = new HashMap<>(); param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline