From 3281fd4bcf9437c83d664d1f3b07840b33b0c0f7 Mon Sep 17 00:00:00 2001
From: 64850858 <648540858@qq.com>
Date: Fri, 16 Jul 2021 16:34:51 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0zlm=E9=9B=86=E7=BE=A4?=
=?UTF-8?q?=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 10 +
sql/mysql.sql | 27 +-
.../genersoft/iot/vmp/common/StreamInfo.java | 9 +
.../iot/vmp/common/VideoManagerConstants.java | 26 +-
.../genersoft/iot/vmp/conf/MediaConfig.java | 204 +++++++++--
.../iot/vmp/conf/ProxyServletConfig.java | 91 ++++-
.../genersoft/iot/vmp/gb28181/SipLayer.java | 39 +-
.../iot/vmp/gb28181/bean/Device.java | 13 +
.../iot/vmp/gb28181/bean/GbStream.java | 9 +
.../iot/vmp/gb28181/bean/SendRtpItem.java | 13 +
.../PlatformNotRegisterEventLister.java | 25 +-
.../gb28181/transmit/SIPProcessorFactory.java | 7 +
.../gb28181/transmit/cmd/ISIPCommander.java | 14 +-
.../transmit/cmd/impl/SIPCommander.java | 213 ++++++-----
.../request/SIPRequestAbstractProcessor.java | 8 +-
.../request/impl/AckRequestProcessor.java | 27 +-
.../request/impl/ByeRequestProcessor.java | 17 +-
.../request/impl/InviteRequestProcessor.java | 57 ++-
.../request/impl/MessageRequestProcessor.java | 10 +-
.../iot/vmp/gb28181/utils/XmlUtil.java | 14 +-
.../vmp/media/zlm/ZLMHTTPProxyController.java | 54 ---
.../vmp/media/zlm/ZLMHttpHookListener.java | 92 +++--
.../vmp/media/zlm/ZLMHttpHookSubscribe.java | 4 +-
.../vmp/media/zlm/ZLMMediaListManager.java | 85 ++---
.../iot/vmp/media/zlm/ZLMRESTfulUtils.java | 95 +++--
.../vmp/media/zlm/ZLMRTPServerFactory.java | 76 ++--
.../iot/vmp/media/zlm/ZLMRunner.java | 196 +++++-----
.../iot/vmp/media/zlm/ZLMServerConfig.java | 60 ++--
.../iot/vmp/media/zlm/ZLMServerManger.java | 45 ---
.../vmp/media/zlm/dto/IMediaServerItem.java | 92 +++++
.../iot/vmp/media/zlm/dto/MediaItem.java | 12 +
.../vmp/media/zlm/dto/MediaServerItem.java | 254 +++++++++++++
.../vmp/media/zlm/dto/StreamProxyItem.java | 20 ++
.../iot/vmp/media/zlm/dto/StreamPushItem.java | 14 +
.../iot/vmp/media/zlm/dto/ZLMRunInfo.java | 33 ++
.../iot/vmp/service/IMediaServerService.java | 44 +++
.../iot/vmp/service/IMediaService.java | 37 +-
.../iot/vmp/service/IPlayService.java | 11 +-
.../iot/vmp/service/IStreamProxyService.java | 4 +-
.../iot/vmp/service/IStreamPushService.java | 3 +-
.../service/impl/MediaServerServiceImpl.java | 340 ++++++++++++++++++
.../vmp/service/impl/MediaServiceImpl.java | 53 +--
.../iot/vmp/service/impl/PlayServiceImpl.java | 76 ++--
.../service/impl/StreamProxyServiceImpl.java | 66 +++-
.../service/impl/StreamPushServiceImpl.java | 16 +-
.../iot/vmp/storager/IRedisCatchStorage.java | 23 +-
.../vmp/storager/IVideoManagerStorager.java | 10 +
.../iot/vmp/storager/dao/GbStreamMapper.java | 9 +-
.../vmp/storager/dao/MediaServerMapper.java | 99 +++++
.../vmp/storager/dao/StreamProxyMapper.java | 20 +-
.../vmp/storager/dao/StreamPushMapper.java | 9 +-
.../storager/impl/RedisCatchStorageImpl.java | 25 +-
.../impl/VideoManagerStoragerImpl.java | 24 ++
.../vmanager/gb28181/device/DeviceConfig.java | 13 +-
.../gb28181/device/DeviceControl.java | 13 +-
.../gb28181/media/MediaController.java | 6 +-
.../vmanager/gb28181/play/PlayController.java | 74 ++--
.../gb28181/playback/PlaybackController.java | 15 +-
.../vmanager/gb28181/ptz/PtzController.java | 7 +-
.../record/RecoderProxyController.java | 11 +-
.../vmp/vmanager/server/ServerController.java | 27 +-
.../streamProxy/StreamProxyController.java | 27 +-
.../iot/vmp/web/ApiControlController.java | 2 +-
.../genersoft/iot/vmp/web/ApiController.java | 2 +-
.../iot/vmp/web/ApiDeviceController.java | 2 +-
.../iot/vmp/web/ApiStreamController.java | 2 +-
src/main/resources/all-application.yml | 4 +
src/main/resources/wvp.sqlite | Bin 114688 -> 122880 bytes
web_src/src/components/CloudRecord.vue | 36 +-
web_src/src/components/PushVideoList.vue | 9 +-
web_src/src/components/StreamProxyList.vue | 15 +-
web_src/src/components/control.vue | 124 ++++---
.../src/components/dialog/StreamProxyEdit.vue | 75 ++--
.../src/components/dialog/devicePlayer.vue | 15 +-
web_src/src/components/service/MediaServer.js | 32 ++
75 files changed, 2431 insertions(+), 914 deletions(-)
delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java
delete mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerManger.java
create mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java
create mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
create mode 100644 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ZLMRunInfo.java
create mode 100644 src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
create mode 100644 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
create mode 100644 src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
create mode 100644 web_src/src/components/service/MediaServer.js
diff --git a/pom.xml b/pom.xml
index 074f9fe4..62239457 100644
--- a/pom.xml
+++ b/pom.xml
@@ -196,6 +196,16 @@
1.12
+
+
+
+
+
+
+
+
+
+
be.teletask
diff --git a/sql/mysql.sql b/sql/mysql.sql
index 21d7a52e..0bb4c03a 100644
--- a/sql/mysql.sql
+++ b/sql/mysql.sql
@@ -138,6 +138,7 @@ create table stream_proxy
timeout_ms int null,
ffmpeg_cmd_key varchar(255) null,
rtp_type varchar(50) null,
+ mediaServerId varchar(50) null,
enable_hls bit(1) null,
enable_mp4 bit(1) null,
enable bit(1) not null,
@@ -166,4 +167,28 @@ create table user
create_time varchar(50) not null
);
-insert into user (username, password, roleId, create_time) values ('admin', '21232f297a57a5a743894a0e4a801fc3', '0', '2021-04-13 14:14:57');
\ No newline at end of file
+insert into user (username, password, roleId, create_time) values ('admin', '21232f297a57a5a743894a0e4a801fc3', '0', '2021-04-13 14:14:57');
+
+create table media_server (
+ id varchar(255)
+ primary key,
+ ip varchar(50) NOT NULL,
+ hookIp varchar(50) NOT NULL,
+ sdpIp varchar(50) NOT NULL,
+ streamIp varchar(50) NOT NULL,
+ httpPort int NOT NULL,
+ httpSSlPort int NOT NULL,
+ rtmpPort int NOT NULL,
+ rtmpSSlPort int NOT NULL,
+ rtpProxyPort int NOT NULL,
+ rtspPort int NOT NULL,
+ rtspSSLPort int NOT NULL,
+ autoConfig int NOT NULL,
+ secret varchar(50) NOT NULL,
+ streamNoneReaderDelayMS int NOT NULL,
+ rtpEnable int NOT NULL,
+ rtpPortRange varchar(50) NOT NULL,
+ recordAssistPort int NOT NULL,
+ createTime varchar(50) not null,
+ updateTime varchar(50) not null
+);
\ No newline at end of file
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 1336d051..771838d6 100644
--- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
+++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
@@ -19,6 +19,7 @@ public class StreamInfo {
private String rtmp;
private String rtsp;
private String rtc;
+ private String mediaServerId;
private JSONArray tracks;
public static class TransactionInfo{
@@ -165,4 +166,12 @@ public class StreamInfo {
public void setTransactionInfo(TransactionInfo transactionInfo) {
this.transactionInfo = transactionInfo;
}
+
+ public String getMediaServerId() {
+ return mediaServerId;
+ }
+
+ public void setMediaServerId(String mediaServerId) {
+ this.mediaServerId = mediaServerId;
+ }
}
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 f4e895f0..57493143 100644
--- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
+++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -10,33 +10,31 @@ public class VideoManagerConstants {
public static final String WVP_SERVER_PREFIX = "VMP_wvp_server";
- public static final String MEDIA_SERVER_PREFIX = "VMP_media_server";
+ public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_";
- public static final String MEDIA_STREAM_PREFIX = "VMP_media_stream";
+ public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM";
- public static final String DEVICE_PREFIX = "VMP_device_";
+ public static final String DEVICE_PREFIX = "VMP_DEVICE_";
- public static final String CACHEKEY_PREFIX = "VMP_channel_";
+ public static final String CACHEKEY_PREFIX = "VMP_CHANNEL_";
public static final String KEEPLIVEKEY_PREFIX = "VMP_keeplive_";
- public static final String PLAYER_PREFIX = "VMP_player_";
+ public static final String PLAYER_PREFIX = "VMP_PLAYER_";
- public static final String PLAY_BLACK_PREFIX = "VMP_playback_";
+ public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_";
- public static final String PLATFORM_PREFIX = "VMP_platform";
+ public static final String PLATFORM_KEEPLIVEKEY_PREFIX = "VMP_PLATFORM_KEEPLIVE_";
- public static final String PLATFORM_KEEPLIVEKEY_PREFIX = "VMP_platform_keeplive_";
+ public static final String PLATFORM_CATCH_PREFIX = "VMP_PLATFORM_CATCH_";
- public static final String PLATFORM_CATCH_PREFIX = "VMP_platform_catch_";
+ public static final String PLATFORM_REGISTER_PREFIX = "VMP_PLATFORM_REGISTER_";
- public static final String PLATFORM_REGISTER_PREFIX = "VMP_platform_register_";
+ public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_PLATFORM_REGISTER_INFO_";
- public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_platform_register_info_";
+ public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_PLATFORM_SEND_RTP_INFO_";
- public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_platform_send_rtp_info_";
-
- public static final String Pattern_Topic = "VMP_keeplive_platform_";
+ public static final String Pattern_Topic = "VMP_KEEPLIVE_PLATFORM_";
public static final String EVENT_ONLINE_REGISTER = "1";
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 52292a57..88e8a64d 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
@@ -1,11 +1,16 @@
package com.genersoft.iot.vmp.conf;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
@Configuration("mediaConfig")
-public class MediaConfig {
+public class MediaConfig implements IMediaServerItem {
+
+ @Value("${media.id:}")
+ private String id;
@Value("${media.ip}")
private String ip;
@@ -25,22 +30,22 @@ public class MediaConfig {
@Value("${media.http-port}")
private Integer httpPort;
- @Value("${media.http-ssl-port:}")
+ @Value("${media.http-ssl-port:0}")
private Integer httpSSlPort;
- @Value("${media.rtmp-port:}")
+ @Value("${media.rtmp-port:0}")
private Integer rtmpPort;
- @Value("${media.rtmp-ssl-port:}")
+ @Value("${media.rtmp-ssl-port:0}")
private Integer rtmpSSlPort;
- @Value("${media.rtp-proxy-port:}")
+ @Value("${media.rtp-proxy-port:0}")
private Integer rtpProxyPort;
- @Value("${media.rtsp-port:}")
+ @Value("${media.rtsp-port:0}")
private Integer rtspPort;
- @Value("${media.rtsp-ssl-port:}")
+ @Value("${media.rtsp-ssl-port:0}")
private Integer rtspSSLPort;
@Value("${media.auto-config:true}")
@@ -61,6 +66,23 @@ public class MediaConfig {
@Value("${media.record-assist-port:0}")
private Integer recordAssistPort;
+ private String updateTime;
+
+ private String createTime;
+
+ private boolean docker = false;
+
+ private int count;
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
public String getIp() {
return ip;
}
@@ -82,82 +104,114 @@ public class MediaConfig {
this.hookIp = hookIp;
}
- public String getSdpIp() {
- if (StringUtils.isEmpty(sdpIp)){
- return ip;
- }else {
- return sdpIp;
- }
+ public String getSipIp() {
+ return sipIp;
+ }
+
+ public void setSipIp(String sipIp) {
+ this.sipIp = sipIp;
}
public void setSdpIp(String sdpIp) {
this.sdpIp = sdpIp;
}
- public String getStreamIp() {
- if (StringUtils.isEmpty(streamIp)){
- return ip;
- }else {
- return streamIp;
- }
- }
-
public void setStreamIp(String streamIp) {
this.streamIp = streamIp;
}
- public Integer getHttpPort() {
+ public int getHttpPort() {
return httpPort;
}
+ @Override
+ public void setHttpPort(int httpPort) {
+
+ }
+
public void setHttpPort(Integer httpPort) {
this.httpPort = httpPort;
}
- public Integer getHttpSSlPort() {
+ public int getHttpSSlPort() {
return httpSSlPort;
}
+ @Override
+ public void setHttpSSlPort(int httpSSlPort) {
+
+ }
+
public void setHttpSSlPort(Integer httpSSlPort) {
this.httpSSlPort = httpSSlPort;
}
- public Integer getRtmpPort() {
+ public int getRtmpPort() {
return rtmpPort;
}
+ @Override
+ public void setRtmpPort(int rtmpPort) {
+
+ }
+
public void setRtmpPort(Integer rtmpPort) {
this.rtmpPort = rtmpPort;
}
- public Integer getRtmpSSlPort() {
+ public int getRtmpSSlPort() {
return rtmpSSlPort;
}
+ @Override
+ public void setRtmpSSlPort(int rtmpSSlPort) {
+
+ }
+
public void setRtmpSSlPort(Integer rtmpSSlPort) {
this.rtmpSSlPort = rtmpSSlPort;
}
- public Integer getRtpProxyPort() {
- return rtpProxyPort;
+ public int getRtpProxyPort() {
+ if (rtpProxyPort == null) {
+ return 0;
+ }else {
+ return rtpProxyPort;
+ }
+
+ }
+
+ @Override
+ public void setRtpProxyPort(int rtpProxyPort) {
+
}
public void setRtpProxyPort(Integer rtpProxyPort) {
this.rtpProxyPort = rtpProxyPort;
}
- public Integer getRtspPort() {
+ public int getRtspPort() {
return rtspPort;
}
+ @Override
+ public void setRtspPort(int rtspPort) {
+
+ }
+
public void setRtspPort(Integer rtspPort) {
this.rtspPort = rtspPort;
}
- public Integer getRtspSSLPort() {
+ public int getRtspSSLPort() {
return rtspSSLPort;
}
+ @Override
+ public void setRtspSSLPort(int rtspSSLPort) {
+
+ }
+
public void setRtspSSLPort(Integer rtspSSLPort) {
this.rtspSSLPort = rtspSSLPort;
}
@@ -202,11 +256,101 @@ public class MediaConfig {
this.rtpPortRange = rtpPortRange;
}
- public Integer getRecordAssistPort() {
+ public int getRecordAssistPort() {
return recordAssistPort;
}
+ @Override
+ public void setRecordAssistPort(int recordAssistPort) {
+
+ }
+
public void setRecordAssistPort(Integer recordAssistPort) {
this.recordAssistPort = recordAssistPort;
}
+
+ @Override
+ public boolean isDocker() {
+ return docker;
+ }
+
+ @Override
+ public void setDocker(boolean docker) {
+ this.docker = docker;
+ }
+
+ public String getSdpIp() {
+ if (StringUtils.isEmpty(sdpIp)){
+ return ip;
+ }else {
+ return sdpIp;
+ }
+ }
+
+ public String getStreamIp() {
+ if (StringUtils.isEmpty(streamIp)){
+ return ip;
+ }else {
+ return streamIp;
+ }
+ }
+
+
+
+ public MediaServerItem getMediaSerItem(){
+ MediaServerItem mediaServerItem = new MediaServerItem();
+ mediaServerItem.setId(id);
+ mediaServerItem.setIp(ip);
+ mediaServerItem.setDocker(true);
+ mediaServerItem.setHookIp(hookIp);
+ mediaServerItem.setSdpIp(sdpIp);
+ mediaServerItem.setStreamIp(streamIp);
+ mediaServerItem.setHttpPort(httpPort);
+ mediaServerItem.setHttpSSlPort(httpSSlPort);
+ mediaServerItem.setRtmpPort(rtmpPort);
+ mediaServerItem.setRtmpSSlPort(rtmpSSlPort);
+ mediaServerItem.setRtpProxyPort(rtpProxyPort);
+ mediaServerItem.setRtspPort(rtspPort);
+ mediaServerItem.setRtspSSLPort(rtspSSLPort);
+ mediaServerItem.setAutoConfig(autoConfig);
+ mediaServerItem.setSecret(secret);
+ mediaServerItem.setStreamNoneReaderDelayMS(streamNoneReaderDelayMS);
+ mediaServerItem.setRtpEnable(rtpEnable);
+ mediaServerItem.setRtpPortRange(rtpPortRange);
+ mediaServerItem.setRecordAssistPort(recordAssistPort);
+ mediaServerItem.setCreateTime(createTime);
+ mediaServerItem.setUpdateTime(updateTime);
+ mediaServerItem.setCount(count);
+ return mediaServerItem;
+ }
+
+ @Override
+ public String getUpdateTime() {
+ return updateTime;
+ }
+
+ @Override
+ public void setUpdateTime(String updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ @Override
+ public String getCreateTime() {
+ return createTime;
+ }
+
+ @Override
+ public void setCreateTime(String createTime) {
+ this.createTime = createTime;
+ }
+
+ @Override
+ public int getCount() {
+ return count;
+ }
+
+ @Override
+ public void setCount(int count) {
+ this.count = count;
+ }
}
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 3c4ea172..c543e6ec 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
@@ -1,12 +1,16 @@
package com.genersoft.iot.vmp.conf;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.service.IMediaServerService;
+import org.apache.catalina.connector.ClientAbortException;
+import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
-import org.apache.catalina.connector.ClientAbortException;
import org.mitre.dsmiley.httpproxy.ProxyServlet;
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.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -24,13 +28,16 @@ public class ProxyServletConfig {
private final static Logger logger = LoggerFactory.getLogger(ProxyServletConfig.class);
@Autowired
- private MediaConfig mediaConfig;
+ private IMediaServerService mediaServerService;
+
+ @Value("${server.port}")
+ private int serverPort;
@Bean
public ServletRegistrationBean zlmServletRegistrationBean(){
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ZLMProxySerlet(),"/zlm/*");
servletRegistrationBean.setName("zlm_Proxy");
- servletRegistrationBean.addInitParameter("targetUri", String.format("http://%s:%s", mediaConfig.getIp(), mediaConfig.getHttpPort()));
+ servletRegistrationBean.addInitParameter("targetUri", "http://127.0.0.1:6080");
servletRegistrationBean.addUrlMappings();
if (logger.isDebugEnabled()) {
servletRegistrationBean.addInitParameter("log", "true");
@@ -38,24 +45,26 @@ public class ProxyServletConfig {
return servletRegistrationBean;
}
- class ZLMProxySerlet extends ProxyServlet{
-
-
-
+ class ZLMProxySerlet extends ProxyServlet{
@Override
protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
- if (!StringUtils.isEmpty(queryStr)) {
- queryStr += "&secret=" + mediaConfig.getSecret();
- }else {
- queryStr = "secret=" + mediaConfig.getSecret();
+ IMediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
+ if (mediaInfo != null) {
+ if (!StringUtils.isEmpty(queryStr)) {
+ queryStr += "&secret=" + mediaInfo.getSecret();
+ }else {
+ queryStr = "secret=" + mediaInfo.getSecret();
+ }
}
return queryStr;
}
+ /**
+ * 异常处理
+ */
@Override
protected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResonse, Exception e){
- //System.out.println(e.getMessage());
try {
super.handleRequestException(proxyRequest, proxyResonse, e);
} catch (ServletException servletException) {
@@ -72,6 +81,64 @@ public class ProxyServletConfig {
logger.error("zlm 代理失败: ", e);
}
}
+
+ /**
+ * 对于为按照格式请求的可以直接返回404
+ */
+ @Override
+ protected String getTargetUri(HttpServletRequest servletRequest) {
+ String requestURI = servletRequest.getRequestURI();
+ IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
+
+ String uri = null;
+ if (mediaInfo != null) {
+// String realRequestURI = requestURI.substring(requestURI.indexOf(mediaInfo.getId())+ mediaInfo.getId().length());
+ uri = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getHttpPort());
+ }else {
+ uri = "http://127.0.0.1:" + serverPort +"/index/hook/null"; // 只是一个能返回404的请求而已, 其他的也可以
+ }
+ return uri;
+ }
+
+ /**
+ * 动态替换请求目标
+ */
+ @Override
+ protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
+ String requestURI = servletRequest.getRequestURI();
+ IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
+ HttpHost host;
+ if (mediaInfo != null) {
+ host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort());
+ }else {
+ host = new HttpHost("127.0.0.1", serverPort);
+ }
+ return host;
+
+ }
+
+ /**
+ * 根据uri获取流媒体信息
+ */
+ IMediaServerItem getMediaInfoByUri(String uri){
+ String[] split = uri.split("/");
+ String mediaServerId = split[2];
+ return mediaServerService.getOne(mediaServerId);
+ }
+
+ /**
+ * 去掉url中的标志信息
+ */
+ @Override
+ protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
+ String requestURI = servletRequest.getRequestURI();
+ IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
+ String url = super.rewriteUrlFromRequest(servletRequest);
+ if (mediaInfo == null) {
+ return url;
+ }
+ return url.replace(mediaInfo.getId() + "/", "");
+ }
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
index 0dca4af6..0a76f698 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -95,20 +95,43 @@ public class SipLayer implements SipListener {
tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "TCP");
tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
tcpSipProvider.addSipListener(this);
- logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getSipPort() + "}");
- } catch (TransportNotSupportedException | InvalidArgumentException | TooManyListenersException | ObjectInUseException e) {
- logger.error(String.format("创建SIP服务失败: %s", e.getMessage()));
+ logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getSipPort() + "}");
+// } catch (TransportNotSupportedException | InvalidArgumentException | TooManyListenersException | ObjectInUseException e) {
+// logger.error(String.format("创建SIP服务失败: %s", e.getMessage()));
+// }
+ } catch (TransportNotSupportedException e) {
+ e.printStackTrace();
+ } catch (InvalidArgumentException e) {
+ logger.error("无法使用 [ {}:{} ]作为SIP[ TCP ]服务,可排查: 1. sip.monitor-ip 是否为本机网卡IP; 2. sip.port 是否已被占用"
+ , sipConfig.getMonitorIp(), sipConfig.getSipPort());
+ } catch (TooManyListenersException e) {
+ e.printStackTrace();
+ } catch (ObjectInUseException e) {
+ e.printStackTrace();
}
return tcpSipProvider;
}
@Bean("udpSipProvider")
@DependsOn("sipStack")
- private SipProvider startUdpListener() throws Exception {
- ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP");
- SipProvider udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
- udpSipProvider.addSipListener(this);
- logger.info("Sip Server UDP 启动成功 port {" + sipConfig.getSipPort() + "}");
+ private SipProvider startUdpListener() {
+ ListeningPoint udpListeningPoint = null;
+ SipProvider udpSipProvider = null;
+ try {
+ udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP");
+ udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
+ udpSipProvider.addSipListener(this);
+ } catch (TransportNotSupportedException e) {
+ e.printStackTrace();
+ } catch (InvalidArgumentException e) {
+ logger.error("无法使用 [ {}:{} ]作为SIP[ UDP ]服务,可排查: 1. sip.monitor-ip 是否为本机网卡IP; 2. sip.port 是否已被占用"
+ , sipConfig.getMonitorIp(), sipConfig.getSipPort());
+ } catch (TooManyListenersException e) {
+ e.printStackTrace();
+ } catch (ObjectInUseException e) {
+ e.printStackTrace();
+ }
+ logger.info("Sip Server UDP 启动成功 port [" + sipConfig.getMonitorIp() + ":" + sipConfig.getSipPort() + "]");
return udpSipProvider;
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
index 6f3d4d73..cf939cfe 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -94,6 +94,11 @@ public class Device {
*/
private String updateTime;
+ /**
+ * 设备使用的媒体id, 默认为null
+ */
+ private String mediaServerId;
+
public String getDeviceId() {
return deviceId;
}
@@ -229,4 +234,12 @@ public class Device {
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
+
+ public String getMediaServerId() {
+ return mediaServerId;
+ }
+
+ public void setMediaServerId(String mediaServerId) {
+ this.mediaServerId = mediaServerId;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java
index fd469474..a1ce8ca9 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java
@@ -9,6 +9,7 @@ public class GbStream extends PlatformGbStream{
private String stream;
private String gbId;
private String name;
+ private String mediaServerId;
private double longitude;
private double latitude;
private String streamType;
@@ -77,4 +78,12 @@ public class GbStream extends PlatformGbStream{
public void setStatus(boolean status) {
this.status = status;
}
+
+ public String getMediaServerId() {
+ return mediaServerId;
+ }
+
+ public void setMediaServerId(String mediaServerId) {
+ this.mediaServerId = mediaServerId;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
index 15e6f1e9..2c9c494c 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
@@ -66,6 +66,11 @@ public class SendRtpItem {
*/
private int localPort;
+ /**
+ * 使用的流媒体
+ */
+ private String mediaServerId;
+
public String getIp() {
return ip;
}
@@ -161,4 +166,12 @@ public class SendRtpItem {
public void setTcpActive(boolean tcpActive) {
this.tcpActive = tcpActive;
}
+
+ public String getMediaServerId() {
+ return mediaServerId;
+ }
+
+ public void setMediaServerId(String mediaServerId) {
+ this.mediaServerId = mediaServerId;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
index a475a1ba..aed21009 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
@@ -6,6 +6,9 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import org.slf4j.Logger;
@@ -32,6 +35,8 @@ public class PlatformNotRegisterEventLister implements ApplicationListener param = new HashMap<>();
+ param.put("vhost", "__defaultVhost__");
+ param.put("app", app.toString());
+ param.put("stream", stream.toString());
+ zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
}
- Map param = new HashMap<>();
- param.put("vhost","__defaultVhost__");
- param.put("app", app.toString());
- param.put("stream", stream.toString());
- zlmrtpServerFactory.stopSendRtpStream(param);
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
index dcfbf576..e2ff0f4f 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -9,6 +9,7 @@ import javax.sip.message.Response;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
import com.genersoft.iot.vmp.service.IPlayService;
@@ -104,6 +105,9 @@ public class SIPProcessorFactory {
@Autowired
private ZLMRTPServerFactory zlmrtpServerFactory;
+ @Autowired
+ private IMediaServerService mediaServerService;
+
// 注:这里使用注解会导致循环依赖注入,暂用springBean
private SipProvider tcpSipProvider;
@@ -128,6 +132,7 @@ public class SIPProcessorFactory {
processor.setStorager(storager);
processor.setRedisCatchStorage(redisCatchStorage);
processor.setZlmrtpServerFactory(zlmrtpServerFactory);
+ processor.setMediaServerService(mediaServerService);
return processor;
} else if (Request.REGISTER.equals(method)) {
RegisterRequestProcessor processor = new RegisterRequestProcessor();
@@ -148,6 +153,7 @@ public class SIPProcessorFactory {
processor.setRequestEvent(evt);
processor.setRedisCatchStorage(redisCatchStorage);
processor.setZlmrtpServerFactory(zlmrtpServerFactory);
+ processor.setMediaServerService(mediaServerService);
return processor;
} else if (Request.BYE.equals(method)) {
ByeRequestProcessor processor = new ByeRequestProcessor();
@@ -155,6 +161,7 @@ public class SIPProcessorFactory {
processor.setRedisCatchStorage(redisCatchStorage);
processor.setZlmrtpServerFactory(zlmrtpServerFactory);
processor.setSIPCommander(cmder);
+ processor.setMediaServerService(mediaServerService);
return processor;
} else if (Request.CANCEL.equals(method)) {
CancelRequestProcessor processor = new CancelRequestProcessor();
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 4e111d64..b06fa773 100644
--- 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
@@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
/**
* @Description:设备能力接口,用于定义设备的控制、查询能力
@@ -90,7 +92,7 @@ public interface ISIPCommander {
* @param device 视频设备
* @param channelId 预览通道
*/
- void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
+ void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
/**
* 请求回放视频流
@@ -100,7 +102,7 @@ public interface ISIPCommander {
* @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss
* @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
*/
- void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
+ void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
/**
* 视频流停止
@@ -288,12 +290,4 @@ public interface ISIPCommander {
* @return true = 命令发送成功
*/
boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
-
-
- /**
- * 释放rtpserver
- * @param device
- * @param channelId
- */
- void closeRTPServer(Device device, String channelId);
}
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 2c9339cc..5c2fa32d 100644
--- 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
@@ -13,11 +13,10 @@ import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.conf.UserSetup;
-import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
+import com.genersoft.iot.vmp.media.zlm.*;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
-import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
-import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
-import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import gov.nist.javax.sip.message.SIPRequest;
@@ -37,6 +36,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
+import org.springframework.util.StringUtils;
/**
* @Description:设备能力接口,用于定义设备的控制、查询能力
@@ -77,12 +77,6 @@ public class SIPCommander implements ISIPCommander {
@Autowired
private ZLMRTPServerFactory zlmrtpServerFactory;
- @Autowired
- private ZLMRESTfulUtils zlmresTfulUtils;
-
- @Autowired
- private MediaConfig mediaConfig;
-
@Autowired
private UserSetup userSetup;
@@ -340,48 +334,45 @@ public class SIPCommander implements ISIPCommander {
* @param errorEvent sip错误订阅
*/
@Override
- public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
+ public void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
String streamId = null;
try {
if (device == null) return;
+ String streamMode = device.getStreamMode().toUpperCase();
+
String ssrc = streamSession.createPlaySsrc();
- if (mediaConfig.isRtpEnable()) {
+ if (mediaServerItem.isRtpEnable()) {
streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
}else {
streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
}
- String streamMode = device.getStreamMode().toUpperCase();
- ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
- if (mediaInfo == null) {
- logger.warn("点播时发现ZLM尚未连接...");
- return;
- }
Integer mediaPort = null;
// 使用动态udp端口
- if (mediaConfig.isRtpEnable()) {
- mediaPort = zlmrtpServerFactory.createRTPServer(streamId);
+ if (mediaServerItem.isRtpEnable()) {
+ mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId);
}else {
- mediaPort = mediaInfo.getRtpProxyPort();
+ mediaPort = mediaServerItem.getRtpProxyPort();
}
-
+ logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort);
// 添加订阅
JSONObject subscribeKey = new JSONObject();
subscribeKey.put("app", "rtp");
subscribeKey.put("stream", streamId);
subscribeKey.put("regist", true);
-
- subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, json->{
+ subscribeKey.put("mediaServerId", mediaServerItem.getId());
+ subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
+ (IMediaServerItem mediaServerItemInUse, JSONObject json)->{
if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;
- event.response(json);
+ event.response(mediaServerItemInUse, json);
subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
});
//
StringBuffer content = new StringBuffer(200);
content.append("v=0\r\n");
// content.append("o=" + sipConfig.getSipId() + " 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
- content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getSdpIp()+"\r\n");
+ content.append("o="+"00000"+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
content.append("s=Play\r\n");
- content.append("c=IN IP4 "+mediaInfo.getSdpIp()+"\r\n");
+ content.append("c=IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
content.append("t=0 0\r\n");
if (userSetup.isSeniorSdp()) {
@@ -459,21 +450,32 @@ public class SIPCommander implements ISIPCommander {
* @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
*/
@Override
- public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event
+ public void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event
, SipSubscribe.Event errorEvent) {
try {
- ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
String ssrc = streamSession.createPlayBackSsrc();
String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
+
+ Integer mediaPort = null;
+ // 使用动态udp端口
+ if (mediaServerItem.isRtpEnable()) {
+ mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId);
+ }else {
+ mediaPort = mediaServerItem.getRtpProxyPort();
+ }
+ logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort);
+
// 添加订阅
JSONObject subscribeKey = new JSONObject();
subscribeKey.put("app", "rtp");
subscribeKey.put("stream", streamId);
subscribeKey.put("regist", true);
+ subscribeKey.put("mediaServerId", mediaServerItem.getId());
logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
- subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, json->{
+ subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
+ (IMediaServerItem mediaServerItemInUse, JSONObject json)->{
if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;
- event.response(json);
+ event.response(mediaServerItemInUse, json);
subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
});
@@ -482,16 +484,12 @@ public class SIPCommander implements ISIPCommander {
content.append("o="+sipConfig.getSipId()+" 0 0 IN IP4 "+sipConfig.getSipIp()+"\r\n");
content.append("s=Playback\r\n");
content.append("u="+channelId+":0\r\n");
- content.append("c=IN IP4 "+mediaInfo.getSdpIp()+"\r\n");
+ content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" "
+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n");
- Integer mediaPort = null;
- // 使用动态udp端口
- if (mediaConfig.isRtpEnable()) {
- mediaPort = zlmrtpServerFactory.createRTPServer(streamId);
- }else {
- mediaPort = mediaInfo.getRtpProxyPort();
- }
+
+
+
String streamMode = device.getStreamMode().toUpperCase();
if (userSetup.isSeniorSdp()) {
@@ -560,56 +558,63 @@ public class SIPCommander implements ISIPCommander {
/**
- * 视频流停止
- *
+ * 视频流停止, 不使用回调
*/
@Override
public void streamByeCmd(String deviceId, String channelId) {
streamByeCmd(deviceId, channelId, null);
}
+
+ /**
+ * 视频流停止
+ */
@Override
public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) {
-
+ StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
try {
ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId);
// 服务重启后, 无法直接发送bye, 通过手动构建发送
+// if (transaction == null) {
+//
+// if (streamInfo != null) {
+// MediaServerItem mediaServerItem = redisCatchStorage.getMediaInfo(streamInfo.getMediaServerId());
+// JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem,streamInfo.getApp(), streamInfo.getStreamId());
+// if (mediaList != null) { // 仍在推流才发送
+// if (mediaList.getInteger("code") == 0) {
+// JSONArray data = mediaList.getJSONArray("data");
+// if (data != null && data.size() > 0) {
+// Device device = storager.queryVideoDevice(deviceId);
+// if (device != null) {
+// StreamInfo.TransactionInfo transactionInfo = streamInfo.getTransactionInfo();
+// try {
+// Request byteRequest = headerProvider.createByteRequest(device, channelId,
+// transactionInfo.branch,
+// transactionInfo.localTag,
+// transactionInfo.remoteTag,
+// transactionInfo.callId);
+// transmitRequest(device, byteRequest);
+// } catch (InvalidArgumentException e) {
+// e.printStackTrace();
+// }
+// }
+// }
+// }
+// }
+// redisCatchStorage.stopPlay(streamInfo);
+// }
+//
+// if (okEvent != null) {
+// okEvent.response(null);
+// }
+// return;
+// }
if (transaction == null) {
-
- StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
- if (streamInfo != null) {
- JSONObject mediaList = zlmresTfulUtils.getMediaList(streamInfo.getApp(), streamInfo.getStreamId());
- if (mediaList != null) { // 仍在推流才发送
- if (mediaList.getInteger("code") == 0) {
- JSONArray data = mediaList.getJSONArray("data");
- if (data != null && data.size() > 0) {
- Device device = storager.queryVideoDevice(deviceId);
- if (device != null) {
- StreamInfo.TransactionInfo transactionInfo = streamInfo.getTransactionInfo();
- try {
- Request byteRequest = headerProvider.createByteRequest(device, channelId,
- transactionInfo.branch,
- transactionInfo.localTag,
- transactionInfo.remoteTag,
- transactionInfo.callId);
- transmitRequest(device, byteRequest);
- } catch (InvalidArgumentException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
- redisCatchStorage.stopPlay(streamInfo);
- }
-
- if (okEvent != null) {
- okEvent.response(null);
- }
+ logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId);
return;
}
-
Dialog dialog = transaction.getDialog();
if (dialog == null) {
+ logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId);
return;
}
Request byeRequest = dialog.createRequest(Request.BYE);
@@ -632,7 +637,7 @@ public class SIPCommander implements ISIPCommander {
}
dialog.sendRequest(clientTransaction);
- zlmrtpServerFactory.closeRTPServer(streamSession.getStreamId(deviceId, channelId));
+
streamSession.remove(deviceId, channelId);
} catch (SipException | ParseException e) {
e.printStackTrace();
@@ -721,7 +726,7 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("\r\n");
cmdXml.append("DeviceControl\r\n");
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
- if (XmlUtil.isEmpty(channelId)) {
+ if (StringUtils.isEmpty(channelId)) {
cmdXml.append("" + device.getDeviceId() + "\r\n");
} else {
cmdXml.append("" + channelId + "\r\n");
@@ -821,16 +826,16 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
cmdXml.append("" + device.getDeviceId() + "\r\n");
cmdXml.append("ResetAlarm\r\n");
- if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) {
+ if (!StringUtils.isEmpty(alarmMethod) || !StringUtils.isEmpty(alarmType)) {
cmdXml.append("\r\n");
}
- if (!XmlUtil.isEmpty(alarmMethod)) {
+ if (!StringUtils.isEmpty(alarmMethod)) {
cmdXml.append("" + alarmMethod + "\r\n");
}
- if (!XmlUtil.isEmpty(alarmType)) {
+ if (!StringUtils.isEmpty(alarmType)) {
cmdXml.append("" + alarmType + "\r\n");
}
- if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) {
+ if (!StringUtils.isEmpty(alarmMethod) || !StringUtils.isEmpty(alarmType)) {
cmdXml.append("\r\n");
}
cmdXml.append("\r\n");
@@ -863,7 +868,7 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("\r\n");
cmdXml.append("DeviceControl\r\n");
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
- if (XmlUtil.isEmpty(channelId)) {
+ if (StringUtils.isEmpty(channelId)) {
cmdXml.append("" + device.getDeviceId() + "\r\n");
} else {
cmdXml.append("" + channelId + "\r\n");
@@ -901,7 +906,7 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("\r\n");
cmdXml.append("DeviceControl\r\n");
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
- if (XmlUtil.isEmpty(channelId)) {
+ if (StringUtils.isEmpty(channelId)) {
cmdXml.append("" + device.getDeviceId() + "\r\n");
} else {
cmdXml.append("" + channelId + "\r\n");
@@ -969,13 +974,13 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("\r\n");
cmdXml.append("DeviceConfig\r\n");
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
- if (XmlUtil.isEmpty(channelId)) {
+ if (StringUtils.isEmpty(channelId)) {
cmdXml.append("" + device.getDeviceId() + "\r\n");
} else {
cmdXml.append("" + channelId + "\r\n");
}
cmdXml.append("\r\n");
- if (!XmlUtil.isEmpty(name)) {
+ if (!StringUtils.isEmpty(name)) {
cmdXml.append("" + name + "\r\n");
}
if (NumericUtil.isInteger(expiration)) {
@@ -1169,22 +1174,22 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("Alarm\r\n");
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
cmdXml.append("" + device.getDeviceId() + "\r\n");
- if (!XmlUtil.isEmpty(startPriority)) {
+ if (!StringUtils.isEmpty(startPriority)) {
cmdXml.append("" + startPriority + "\r\n");
}
- if (!XmlUtil.isEmpty(endPriority)) {
+ if (!StringUtils.isEmpty(endPriority)) {
cmdXml.append("" + endPriority + "\r\n");
}
- if (!XmlUtil.isEmpty(alarmMethod)) {
+ if (!StringUtils.isEmpty(alarmMethod)) {
cmdXml.append("" + alarmMethod + "\r\n");
}
- if (!XmlUtil.isEmpty(alarmType)) {
+ if (!StringUtils.isEmpty(alarmType)) {
cmdXml.append("" + alarmType + "\r\n");
}
- if (!XmlUtil.isEmpty(startTime)) {
+ if (!StringUtils.isEmpty(startTime)) {
cmdXml.append("" + startTime + "\r\n");
}
- if (!XmlUtil.isEmpty(endTime)) {
+ if (!StringUtils.isEmpty(endTime)) {
cmdXml.append("" + endTime + "\r\n");
}
cmdXml.append("\r\n");
@@ -1218,7 +1223,7 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("\r\n");
cmdXml.append("ConfigDownload\r\n");
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
- if (XmlUtil.isEmpty(channelId)) {
+ if (StringUtils.isEmpty(channelId)) {
cmdXml.append("" + device.getDeviceId() + "\r\n");
} else {
cmdXml.append("" + channelId + "\r\n");
@@ -1253,7 +1258,7 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("\r\n");
cmdXml.append("PresetQuery\r\n");
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
- if (XmlUtil.isEmpty(channelId)) {
+ if (StringUtils.isEmpty(channelId)) {
cmdXml.append("" + device.getDeviceId() + "\r\n");
} else {
cmdXml.append("" + channelId + "\r\n");
@@ -1365,22 +1370,22 @@ public class SIPCommander implements ISIPCommander {
cmdXml.append("Alarm\r\n");
cmdXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n");
cmdXml.append("" + device.getDeviceId() + "\r\n");
- if (!XmlUtil.isEmpty(startPriority)) {
+ if (!StringUtils.isEmpty(startPriority)) {
cmdXml.append("" + startPriority + "\r\n");
}
- if (!XmlUtil.isEmpty(endPriority)) {
+ if (!StringUtils.isEmpty(endPriority)) {
cmdXml.append("" + endPriority + "\r\n");
}
- if (!XmlUtil.isEmpty(alarmMethod)) {
+ if (!StringUtils.isEmpty(alarmMethod)) {
cmdXml.append("" + alarmMethod + "\r\n");
}
- if (!XmlUtil.isEmpty(alarmType)) {
+ if (!StringUtils.isEmpty(alarmType)) {
cmdXml.append("" + alarmType + "\r\n");
}
- if (!XmlUtil.isEmpty(startTime)) {
+ if (!StringUtils.isEmpty(startTime)) {
cmdXml.append("" + startTime + "\r\n");
}
- if (!XmlUtil.isEmpty(endTime)) {
+ if (!StringUtils.isEmpty(endTime)) {
cmdXml.append("" + endTime + "\r\n");
}
cmdXml.append("\r\n");
@@ -1431,16 +1436,4 @@ public class SIPCommander implements ISIPCommander {
clientTransaction.sendRequest();
return clientTransaction;
}
-
-
-
-
- @Override
- public void closeRTPServer(Device device, String channelId) {
- if (mediaConfig.isRtpEnable()) {
- String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
- zlmrtpServerFactory.closeRTPServer(streamId);
- }
- streamSession.remove(device.getDeviceId(), channelId);
- }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java
index 54108208..12290d2a 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java
@@ -16,6 +16,8 @@ import javax.sip.message.Request;
import gov.nist.javax.sip.SipStackImpl;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.stack.SIPServerTransaction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* @Description:处理接收IPCamera发来的SIP协议请求消息
@@ -24,6 +26,8 @@ import gov.nist.javax.sip.stack.SIPServerTransaction;
*/
public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcessor {
+ private final static Logger logger = LoggerFactory.getLogger(SIPRequestAbstractProcessor.class);
+
protected RequestEvent evt;
private SipProvider tcpSipProvider;
@@ -64,9 +68,9 @@ public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcesso
}
}
} catch (TransactionAlreadyExistsException e) {
- e.printStackTrace();
+ logger.error(e.getMessage());
} catch (TransactionUnavailableException e) {
- e.printStackTrace();
+ logger.error(e.getMessage());
}
}
return serverTransaction;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
index 413f0d14..6f809718 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
@@ -13,6 +13,9 @@ import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,6 +33,8 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
private ZLMRTPServerFactory zlmrtpServerFactory;
+ private IMediaServerService mediaServerService;
+
/**
* 处理 ACK请求
*
@@ -76,18 +81,22 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
while (!rtpPushed) {
try {
if (System.currentTimeMillis() - startTime < 30 * 1000) {
- if (zlmrtpServerFactory.isStreamReady(streamInfo.getApp(), streamInfo.getStreamId())) {
+ IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+ if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) {
rtpPushed = true;
- logger.info("已获取设备推流,开始向上级推流");
- zlmrtpServerFactory.startSendRtpStream(param);
+ logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",
+ streamInfo.getApp() ,streamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort());
+ zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
} else {
- logger.info("等待设备推流.......");
+ logger.info("等待设备推流[{}/{}].......",
+ streamInfo.getApp() ,streamInfo.getStreamId());
Thread.sleep(1000);
continue;
}
} else {
rtpPushed = true;
- logger.info("设备推流超时,终止向上级推流");
+ logger.info("设备推流[{}/{}]超时,终止向上级推流",
+ streamInfo.getApp() ,streamInfo.getStreamId());
}
} catch (InterruptedException e) {
e.printStackTrace();
@@ -123,4 +132,12 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
this.zlmrtpServerFactory = zlmrtpServerFactory;
}
+
+ public IMediaServerService getMediaServerService() {
+ return mediaServerService;
+ }
+
+ public void setMediaServerService(IMediaServerService mediaServerService) {
+ this.mediaServerService = mediaServerService;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
index fdb7c0b2..50e8c323 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
@@ -15,6 +15,9 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,6 +41,8 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
private ZLMRTPServerFactory zlmrtpServerFactory;
+ private IMediaServerService mediaServerService;
+
/**
* 处理BYE请求
* @param evt
@@ -60,9 +65,10 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
param.put("stream",streamId);
param.put("ssrc",sendRtpItem.getSsrc());
logger.info("停止向上级推流:" + streamId);
- zlmrtpServerFactory.stopSendRtpStream(param);
+ IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+ zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
- if (zlmrtpServerFactory.totalReaderCount(sendRtpItem.getApp(), streamId) == 0) {
+ if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) {
logger.info(streamId + "无其它观看者,通知设备停止推流");
cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId);
}
@@ -112,4 +118,11 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
this.cmder = cmder;
}
+ public IMediaServerService getMediaServerService() {
+ return mediaServerService;
+ }
+
+ public void setMediaServerService(IMediaServerService mediaServerService) {
+ this.mediaServerService = mediaServerService;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
index 5f356b0d..7219dbb3 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
@@ -11,12 +11,16 @@ import javax.sip.header.*;
import javax.sip.message.Request;
import javax.sip.message.Response;
+import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
@@ -51,6 +55,8 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
private ZLMRTPServerFactory zlmrtpServerFactory;
+ private IMediaServerService mediaServerService;
+
public ZLMRTPServerFactory getZlmrtpServerFactory() {
return zlmrtpServerFactory;
}
@@ -91,6 +97,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
// 查询平台下是否有该通道
DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
+ IMediaServerItem mediaServerItem = null;
// 不是通道可能是直播流
if (channel != null && gbStream == null ) {
if (channel.getStatus() == 0) {
@@ -100,8 +107,15 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
}
responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
}else if(channel == null && gbStream != null){
- Boolean streamReady = zlmrtpServerFactory.isStreamReady(gbStream.getApp(), gbStream.getStream());
- if (!streamReady) {
+ String mediaServerId = gbStream.getMediaServerId();
+ mediaServerItem = mediaServerService.getOne(mediaServerId);
+ if (mediaServerItem == null) {
+ logger.info("[ app={}, stream={} ]zlm找不到,返回410",gbStream.getApp(), gbStream.getStream());
+ responseAck(evt, Response.GONE, "media server not found");
+ return;
+ }
+ Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
+ if (!streamReady ) {
logger.info("[ app={}, stream={} ]通道离线,返回400",gbStream.getApp(), gbStream.getStream());
responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
return;
@@ -130,8 +144,8 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
//boolean recvonly = false;
boolean mediaTransmissionTCP = false;
Boolean tcpActive = null;
- for (int i = 0; i < mediaDescriptions.size(); i++) {
- MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
+ for (Object description : mediaDescriptions) {
+ MediaDescription mediaDescription = (MediaDescription) description;
Media media = mediaDescription.getMedia();
Vector mediaFormats = media.getMediaFormats(false);
@@ -147,7 +161,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
mediaTransmissionTCP = true;
if ("active".equals(setup)) {
tcpActive = true;
- }else if ("passive".equals(setup)) {
+ } else if ("passive".equals(setup)) {
tcpActive = false;
}
}
@@ -174,7 +188,13 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
responseAck(evt, Response.SERVER_INTERNAL_ERROR);
return;
}
- SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId,
+ mediaServerItem = playService.getNewMediaServerItem(device);
+ if (mediaServerItem == null) {
+ logger.warn("未找到可用的zlm");
+ responseAck(evt, Response.BUSY_HERE);
+ return;
+ }
+ SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
device.getDeviceId(), channelId,
mediaTransmissionTCP);
if (tcpActive != null) {
@@ -189,18 +209,18 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
// 写入redis, 超时时回复
redisCatchStorage.updateSendRTPSever(sendRtpItem);
// 通知下级推流,
- PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{
+ PlayResult playResult = playService.play(mediaServerItem,device.getDeviceId(), channelId, (mediaServerItemInUSe, responseJSON)->{
// 收到推流, 回复200OK, 等待ack
// if (sendRtpItem == null) return;
sendRtpItem.setStatus(1);
redisCatchStorage.updateSendRTPSever(sendRtpItem);
// TODO 添加对tcp的支持
- ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
+
StringBuffer content = new StringBuffer(200);
content.append("v=0\r\n");
- content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getSdpIp()+"\r\n");
+ content.append("o="+"00000"+" 0 0 IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n");
content.append("s=Play\r\n");
- content.append("c=IN IP4 "+mediaInfo.getSdpIp()+"\r\n");
+ content.append("c=IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n");
content.append("t=0 0\r\n");
content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
content.append("a=sendonly\r\n");
@@ -217,7 +237,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
} catch (ParseException e) {
e.printStackTrace();
}
- } ,(event -> {
+ } ,((event) -> {
// 未知错误。直接转发设备点播的错误
Response response = null;
try {
@@ -232,7 +252,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
}
}else if (gbStream != null) {
- SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId,
+ SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
gbStream.getApp(), gbStream.getStream(), channelId,
mediaTransmissionTCP);
@@ -251,12 +271,11 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
sendRtpItem.setStatus(1);
redisCatchStorage.updateSendRTPSever(sendRtpItem);
// TODO 添加对tcp的支持
- ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
StringBuffer content = new StringBuffer(200);
content.append("v=0\r\n");
- content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getSdpIp()+"\r\n");
+ content.append("o="+"00000"+" 0 0 IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
content.append("s=Play\r\n");
- content.append("c=IN IP4 "+mediaInfo.getSdpIp()+"\r\n");
+ content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
content.append("t=0 0\r\n");
content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
content.append("a=sendonly\r\n");
@@ -444,4 +463,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
this.redisCatchStorage = redisCatchStorage;
}
+
+ public IMediaServerService getMediaServerService() {
+ return mediaServerService;
+ }
+
+ public void setMediaServerService(IMediaServerService mediaServerService) {
+ this.mediaServerService = mediaServerService;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
index 9d282c68..70e64a5e 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -282,7 +282,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
//String result = XmlUtil.getText(rootElement, "Result");
// 回复200 OK
responseAck(evt);
- if (rootElement.getName().equals("Response")) {//} !XmlUtil.isEmpty(result)) {
+ if (rootElement.getName().equals("Response")) {//} !StringUtils.isEmpty(result)) {
// 此处是对本平台发出DeviceControl指令的应答
JSONObject json = new JSONObject();
XmlUtil.node2Json(rootElement, json);
@@ -299,7 +299,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
// 远程启动功能
- if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) {
+ if (!StringUtils.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) {
if (deviceId.equals(targetGBId)) {
// 远程启动本平台:需要在重新启动程序后先对SipStack解绑
logger.info("执行远程启动本平台命令");
@@ -337,7 +337,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
}
}
// 云台/前端控制命令
- if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) {
+ if (!StringUtils.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) {
String cmdString = XmlUtil.getText(rootElement,"PTZCmd");
Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId);
cmder.fronEndCmd(device, deviceId, cmdString);
@@ -421,7 +421,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
String deviceId = XmlUtil.getText(rootElement, "DeviceID");
// 回复200 OK
responseAck(evt);
- if (rootElement.getName().equals("Response")) {// !XmlUtil.isEmpty(result)) {
+ if (rootElement.getName().equals("Response")) {// !StringUtils.isEmpty(result)) {
// 此处是对本平台发出DeviceControl指令的应答
JSONObject json = new JSONObject();
XmlUtil.node2Json(rootElement, json);
@@ -718,7 +718,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
deviceAlarm.setLatitude(0.00);
}
- if (!XmlUtil.isEmpty(deviceAlarm.getAlarmMethod())) {
+ if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
if ( deviceAlarm.getAlarmMethod().equals("4")) {
MobilePosition mobilePosition = new MobilePosition();
mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
index c82ba600..4220d816 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
@@ -17,6 +17,7 @@ import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
/**
* 基于dom4j的工具包
@@ -114,12 +115,12 @@ public class XmlUtil {
// 如果是属性
for (Object o : element.attributes()) {
Attribute attr = (Attribute) o;
- if (!isEmpty(attr.getValue())) {
+ if (!StringUtils.isEmpty(attr.getValue())) {
json.put("@" + attr.getName(), attr.getValue());
}
}
List chdEl = element.elements();
- if (chdEl.isEmpty() && !isEmpty(element.getText())) {// 如果没有子元素,只有一个值
+ if (chdEl.isEmpty() && !StringUtils.isEmpty(element.getText())) {// 如果没有子元素,只有一个值
json.put(element.getName(), element.getText());
}
@@ -150,7 +151,7 @@ public class XmlUtil {
} else { // 子元素没有子元素
for (Object o : element.attributes()) {
Attribute attr = (Attribute) o;
- if (!isEmpty(attr.getValue())) {
+ if (!StringUtils.isEmpty(attr.getValue())) {
json.put("@" + attr.getName(), attr.getValue());
}
}
@@ -160,11 +161,4 @@ public class XmlUtil {
}
}
}
-
- public static boolean isEmpty(String str) {
- if (str == null || str.trim().isEmpty() || "null".equals(str)) {
- return true;
- }
- return false;
- }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java
deleted file mode 100644
index a00bc2a5..00000000
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java
+++ /dev/null
@@ -1,54 +0,0 @@
-//package com.genersoft.iot.vmp.media.zlm;
-//
-//import com.genersoft.iot.vmp.conf.MediaConfig;
-//import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.beans.factory.annotation.Value;
-//import org.springframework.web.bind.annotation.*;
-//import org.springframework.web.client.HttpClientErrorException;
-//import org.springframework.web.client.RestTemplate;
-//
-//import javax.servlet.http.HttpServletRequest;
-//import javax.servlet.http.HttpServletResponse;
-//
-//@RestController
-//@RequestMapping("/zlm")
-//public class ZLMHTTPProxyController {
-//
-//
-// // private final static Logger logger = LoggerFactory.getLogger(ZLMHTTPProxyController.class);
-//
-// @Autowired
-// private IRedisCatchStorage redisCatchStorage;
-//
-// @Autowired
-// private MediaConfig mediaConfig;
-//
-// @ResponseBody
-// @RequestMapping(value = "/**/**/**", produces = "application/json;charset=UTF-8")
-// public Object proxy(HttpServletRequest request, HttpServletResponse response){
-//
-// if (redisCatchStorage.getMediaInfo() == null) {
-// return "未接入流媒体";
-// }
-// ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
-// String requestURI = String.format("http://%s:%s%s?%s&%s",
-// mediaInfo.getLocalIP(),
-// mediaConfig.getHttpPort(),
-// request.getRequestURI().replace("/zlm",""),
-// mediaInfo.getHookAdminParams(),
-// request.getQueryString()
-// );
-// // 发送请求
-// RestTemplate restTemplate = new RestTemplate();
-// //将指定的url返回的参数自动封装到自定义好的对应类对象中
-// Object result = null;
-// try {
-// result = restTemplate.getForObject(requestURI,Object.class);
-//
-// }catch (HttpClientErrorException httpClientErrorException) {
-// response.setStatus(httpClientErrorException.getStatusCode().value());
-// }
-// return result;
-// }
-//}
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 bd8485d1..b7aebf42 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -9,6 +9,9 @@ import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.conf.UserSetup;
import com.genersoft.iot.vmp.gb28181.bean.Device;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.service.IPlayService;
@@ -53,10 +56,10 @@ public class ZLMHttpHookListener {
private IRedisCatchStorage redisCatchStorage;
@Autowired
- private ZLMRESTfulUtils zlmresTfulUtils;
+ private IMediaServerService mediaServerService;
@Autowired
- private ZLMServerManger zlmServerManger;
+ private ZLMRESTfulUtils zlmresTfulUtils;
@Autowired
private ZLMMediaListManager zlmMediaListManager;
@@ -81,6 +84,7 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_flow_report API调用,参数:" + json.toString());
}
+ String mediaServerId = json.getString("mediaServerId");
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("msg", "success");
@@ -98,6 +102,7 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_http_access API 调用,参数:" + json.toString());
}
+ String mediaServerId = json.getString("mediaServerId");
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("err", "");
@@ -117,9 +122,14 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_play API调用,参数:" + json.toString());
}
+ String mediaServerId = json.getString("mediaServerId");
ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json);
if (subscribe != null ) {
- subscribe.response(json);
+ IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
+ if (mediaInfo != null) {
+ subscribe.response(mediaInfo, json);
+ }
+
}
JSONObject ret = new JSONObject();
ret.put("code", 0);
@@ -133,20 +143,25 @@ public class ZLMHttpHookListener {
*/
@ResponseBody
@PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8")
- public ResponseEntity onPublish(@RequestBody JSONObject json){
+ public ResponseEntity onPublish(@RequestBody JSONObject json) {
logger.debug("ZLM HOOK on_publish API调用,参数:" + json.toString());
+ String mediaServerId = json.getString("mediaServerId");
ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json);
- if (subscribe != null) subscribe.response(json);
-
+ if (subscribe != null) {
+ IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
+ if (mediaInfo != null) {
+ subscribe.response(mediaInfo, json);
+ }
+ }
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("msg", "success");
ret.put("enableHls", true);
ret.put("enableMP4", userSetup.isRecordPushLive());
ret.put("enableRtxp", true);
- return new ResponseEntity(ret.toString(),HttpStatus.OK);
+ return new ResponseEntity(ret.toString(), HttpStatus.OK);
}
/**
@@ -160,6 +175,7 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_record_mp4 API调用,参数:" + json.toString());
}
+ String mediaServerId = json.getString("mediaServerId");
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("msg", "success");
@@ -177,6 +193,7 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_rtsp_realm API调用,参数:" + json.toString());
}
+ String mediaServerId = json.getString("mediaServerId");
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("realm", "");
@@ -195,6 +212,7 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_rtsp_auth API调用,参数:" + json.toString());
}
+ String mediaServerId = json.getString("mediaServerId");
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("encrypted", false);
@@ -216,9 +234,15 @@ public class ZLMHttpHookListener {
// TODO 如果是带有rtpstream则开启按需拉流
// String app = json.getString("app");
// String stream = json.getString("stream");
-
+ String mediaServerId = json.getString("mediaServerId");
ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json);
- if (subscribe != null) subscribe.response(json);
+ if (subscribe != null ) {
+ IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
+ if (mediaInfo != null) {
+ subscribe.response(mediaInfo, json);
+ }
+
+ }
JSONObject ret = new JSONObject();
ret.put("code", 0);
@@ -237,9 +261,15 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_stream_changed API调用,参数:" + json.toString());
}
-
+ String mediaServerId = json.getString("mediaServerId");
ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json);
- if (subscribe != null) subscribe.response(json);
+ if (subscribe != null ) {
+ IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
+ if (mediaInfo != null) {
+ subscribe.response(mediaInfo, json);
+ }
+
+ }
// 流消失移除redis play
String app = json.getString("app");
@@ -251,6 +281,11 @@ public class ZLMHttpHookListener {
logger.info("[stream: " + streamId + "] on_stream_changed->>" + schema);
}
if ("rtmp".equals(schema)){
+ if (regist) {
+ mediaServerService.addCount(mediaServerId);
+ }else {
+ mediaServerService.removeCount(mediaServerId);
+ }
if ("rtp".equals(app) && !regist ) {
StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
if (streamInfo!=null){
@@ -262,10 +297,11 @@ public class ZLMHttpHookListener {
}
}else {
if (!"rtp".equals(app) ){
+ IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
if (regist) {
- zlmMediaListManager.addMedia(app, streamId);
+ zlmMediaListManager.addMedia(mediaServerItem, app, streamId);
}else {
- zlmMediaListManager.removeMedia(app, streamId);
+ zlmMediaListManager.removeMedia( app, streamId);
}
}
}
@@ -288,7 +324,7 @@ public class ZLMHttpHookListener {
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_stream_none_reader API调用,参数:" + json.toString());
}
-
+ String mediaServerId = json.getString("mediaServerId");
String streamId = json.getString("stream");
String app = json.getString("app");
@@ -329,11 +365,12 @@ public class ZLMHttpHookListener {
@ResponseBody
@PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8")
public ResponseEntity onStreamNotFound(@RequestBody JSONObject json){
-
if (logger.isDebugEnabled()) {
logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString());
}
- if (userSetup.isAutoApplyPlay()) {
+ String mediaServerId = json.getString("mediaServerId");
+ IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
+ if (userSetup.isAutoApplyPlay() && mediaInfo != null) {
String app = json.getString("app");
String streamId = json.getString("stream");
if ("rtp".equals(app) && streamId.contains("gb_play") ) {
@@ -344,9 +381,9 @@ public class ZLMHttpHookListener {
Device device = storager.queryVideoDevice(deviceId);
if (device != null) {
UUID uuid = UUID.randomUUID();
- cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
+ cmder.playStreamCmd(mediaInfo, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> {
logger.info("收到订阅消息: " + response.toJSONString());
- playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
+ playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());
}, null);
}
@@ -367,26 +404,19 @@ public class ZLMHttpHookListener {
*/
@ResponseBody
@PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8")
- public ResponseEntity onServerStarted(HttpServletRequest request, @RequestBody JSONObject json){
+ public ResponseEntity onServerStarted(HttpServletRequest request, @RequestBody JSONObject jsonObject){
if (logger.isDebugEnabled()) {
- logger.debug("ZLM HOOK on_server_started API调用,参数:" + json.toString());
+ logger.debug("ZLM HOOK on_server_started API调用,参数:" + jsonObject.toString());
}
-
-// String data = json.getString("data");
-// List mediaServerConfigs = JSON.parseArray(JSON.toJSONString(json), MediaServerConfig.class);
-// MediaServerConfig mediaServerConfig = mediaServerConfigs.get(0);
-
+ String remoteAddr = request.getRemoteAddr();
+ jsonObject.put("ip", remoteAddr);
List subscribes = this.subscribe.getSubscribes(ZLMHttpHookSubscribe.HookType.on_server_started);
- if (subscribes != null && subscribes.size() > 0) {
+ if (subscribes != null && subscribes.size() > 0) {
for (ZLMHttpHookSubscribe.Event subscribe : subscribes) {
- subscribe.response(json);
+ subscribe.response(null, jsonObject);
}
}
- ZLMServerConfig ZLMServerConfig = JSON.toJavaObject(json, ZLMServerConfig.class);
- zlmServerManger.updateServerCatch(ZLMServerConfig);
- // 重新发起代理
-
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("msg", "success");
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 4f832aee..62b18f5b 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
@@ -1,6 +1,8 @@
package com.genersoft.iot.vmp.media.zlm;
import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import org.springframework.stereotype.Component;
import java.util.*;
@@ -30,7 +32,7 @@ public class ZLMHttpHookSubscribe {
}
public interface Event{
- void response(JSONObject response);
+ void response(IMediaServerItem mediaServerItem, JSONObject response);
}
private Map> allSubscribes = new ConcurrentHashMap<>();
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 ed407d29..38763094 100644
--- 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,8 @@ package com.genersoft.iot.vmp.media.zlm;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+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.StreamPushItem;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
@@ -45,11 +47,11 @@ public class ZLMMediaListManager {
private ZLMHttpHookSubscribe subscribe;
- public void updateMediaList() {
+ public void updateMediaList(MediaServerItem mediaServerItem) {
storager.clearMediaList();
// 使用异步的当时更新媒体流列表
- zlmresTfulUtils.getMediaList((mediaList ->{
+ zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{
if (mediaList == null) return;
String dataStr = mediaList.getString("data");
@@ -57,10 +59,10 @@ public class ZLMMediaListManager {
Map result = new HashMap<>();
List streamPushItems = null;
// 获取所有的国标关联
- List gbStreams = gbStreamMapper.selectAll();
+// List gbStreams = gbStreamMapper.selectAllByMediaServerId(mediaServerItem.getId());
if (code == 0 ) {
if (dataStr != null) {
- streamPushItems = streamPushService.handleJSON(dataStr);
+ streamPushItems = streamPushService.handleJSON(dataStr, mediaServerItem);
}
}else {
logger.warn("更新视频流失败,错误code: " + code);
@@ -72,24 +74,27 @@ public class ZLMMediaListManager {
JSONObject jsonObject = new JSONObject();
jsonObject.put("app", streamPushItem.getApp());
jsonObject.put("stream", streamPushItem.getStream());
- subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject,(response)->{
- updateMedia(response.getString("app"), response.getString("stream"));
- });
+ jsonObject.put("mediaServerId", mediaServerItem.getId());
+ subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject,
+ (IMediaServerItem mediaServerItemInuse, JSONObject response)->{
+ updateMedia(mediaServerItem, response.getString("app"), response.getString("stream"));
+ }
+ );
}
}
}));
}
- public void addMedia(String app, String streamId) {
+ public void addMedia(IMediaServerItem mediaServerItem, String app, String streamId) {
//使用异步更新推流
- updateMedia(app, streamId);
+ updateMedia(mediaServerItem, app, streamId);
}
- public void updateMedia(String app, String streamId) {
+ public void updateMedia(IMediaServerItem mediaServerItem, String app, String streamId) {
//使用异步更新推流
- zlmresTfulUtils.getMediaList(app, streamId, "rtmp", json->{
+ zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{
if (json == null) return;
String dataStr = json.getString("data");
@@ -99,7 +104,7 @@ public class ZLMMediaListManager {
List streamPushItems = null;
if (code == 0 ) {
if (dataStr != null) {
- streamPushItems = streamPushService.handleJSON(dataStr);
+ streamPushItems = streamPushService.handleJSON(dataStr, mediaServerItem);
}
}else {
logger.warn("更新视频流失败,错误code: " + code);
@@ -122,32 +127,32 @@ public class ZLMMediaListManager {
}
}
- public void clearAllSessions() {
- logger.info("清空所有国标相关的session");
- JSONObject allSessionJSON = zlmresTfulUtils.getAllSession();
- ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
- HashSet allLocalPorts = new HashSet();
- if (allSessionJSON.getInteger("code") == 0) {
- JSONArray data = allSessionJSON.getJSONArray("data");
- if (data.size() > 0) {
- for (int i = 0; i < data.size(); i++) {
- JSONObject sessionJOSN = data.getJSONObject(i);
- Integer local_port = sessionJOSN.getInteger("local_port");
- if (!local_port.equals(Integer.valueOf(mediaInfo.getHttpPort())) &&
- !local_port.equals(Integer.valueOf(mediaInfo.getHttpSSLport())) &&
- !local_port.equals(Integer.valueOf(mediaInfo.getRtmpPort())) &&
- !local_port.equals(Integer.valueOf(mediaInfo.getRtspPort())) &&
- !local_port.equals(Integer.valueOf(mediaInfo.getRtspSSlport())) &&
- !local_port.equals(Integer.valueOf(mediaInfo.getHookOnFlowReport()))){
- allLocalPorts.add(sessionJOSN.getInteger("local_port") + "");
- }
- }
- }
- }
- if (allLocalPorts.size() > 0) {
- List result = new ArrayList<>(allLocalPorts);
- String localPortSStr = String.join(",", result);
- zlmresTfulUtils.kickSessions(localPortSStr);
- }
- }
+// public void clearAllSessions() {
+// logger.info("清空所有国标相关的session");
+// JSONObject allSessionJSON = zlmresTfulUtils.getAllSession();
+// ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
+// HashSet allLocalPorts = new HashSet();
+// if (allSessionJSON.getInteger("code") == 0) {
+// JSONArray data = allSessionJSON.getJSONArray("data");
+// if (data.size() > 0) {
+// for (int i = 0; i < data.size(); i++) {
+// JSONObject sessionJOSN = data.getJSONObject(i);
+// Integer local_port = sessionJOSN.getInteger("local_port");
+// if (!local_port.equals(Integer.valueOf(mediaInfo.getHttpPort())) &&
+// !local_port.equals(Integer.valueOf(mediaInfo.getHttpSSLport())) &&
+// !local_port.equals(Integer.valueOf(mediaInfo.getRtmpPort())) &&
+// !local_port.equals(Integer.valueOf(mediaInfo.getRtspPort())) &&
+// !local_port.equals(Integer.valueOf(mediaInfo.getRtspSSlport())) &&
+// !local_port.equals(Integer.valueOf(mediaInfo.getHookOnFlowReport()))){
+// allLocalPorts.add(sessionJOSN.getInteger("local_port") + "");
+// }
+// }
+// }
+// }
+// if (allLocalPorts.size() > 0) {
+// List result = new ArrayList<>(allLocalPorts);
+// String localPortSStr = String.join(",", result);
+// zlmresTfulUtils.kickSessions(localPortSStr);
+// }
+// }
}
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 8425d039..8e12e574 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.media.zlm;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.conf.MediaConfig;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
@@ -21,23 +23,18 @@ public class ZLMRESTfulUtils {
private final static Logger logger = LoggerFactory.getLogger(ZLMRESTfulUtils.class);
- @Autowired
- private MediaConfig mediaConfig;
-
-
-
public interface RequestCallback{
void run(JSONObject response);
}
- public JSONObject sendPost(String api, Map param, RequestCallback callback) {
+ public JSONObject sendPost(IMediaServerItem mediaServerItem, String api, Map param, RequestCallback callback) {
OkHttpClient client = new OkHttpClient();
- String url = String.format("http://%s:%s/index/api/%s", mediaConfig.getIp(), mediaConfig.getHttpPort(), api);
+ String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
JSONObject responseJSON = null;
logger.debug(url);
FormBody.Builder builder = new FormBody.Builder();
- builder.add("secret",mediaConfig.getSecret());
+ builder.add("secret",mediaServerItem.getSecret());
if (param != null && param.keySet().size() > 0) {
for (String key : param.keySet()){
if (param.get(key) != null) {
@@ -96,14 +93,14 @@ public class ZLMRESTfulUtils {
}
- public void sendPostForImg(String api, Map param, String targetPath, String fileName) {
+ public void sendPostForImg(IMediaServerItem mediaServerItem, String api, Map param, String targetPath, String fileName) {
OkHttpClient client = new OkHttpClient();
- String url = String.format("http://%s:%s/index/api/%s", mediaConfig.getIp(), mediaConfig.getHttpPort(), api);
+ String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
JSONObject responseJSON = null;
logger.debug(url);
FormBody.Builder builder = new FormBody.Builder();
- builder.add("secret",mediaConfig.getSecret());
+ builder.add("secret",mediaServerItem.getSecret());
if (param != null && param.keySet().size() > 0) {
for (String key : param.keySet()){
if (param.get(key) != null) {
@@ -142,39 +139,39 @@ public class ZLMRESTfulUtils {
}
- public JSONObject getMediaList(String app, String stream, String schema, RequestCallback callback){
+ public JSONObject getMediaList(IMediaServerItem 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("getMediaList",param, callback);
+ return sendPost(mediaServerItem, "getMediaList",param, callback);
}
- public JSONObject getMediaList(String app, String stream){
- return getMediaList(app, stream,null, null);
+ public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream){
+ return getMediaList(mediaServerItem, app, stream,null, null);
}
- public JSONObject getMediaList(RequestCallback callback){
- return sendPost("getMediaList",null, callback);
+ public JSONObject getMediaList(IMediaServerItem mediaServerItem,RequestCallback callback){
+ return sendPost(mediaServerItem, "getMediaList",null, callback);
}
- public JSONObject getMediaInfo(String app, String schema, String stream){
+ public JSONObject getMediaInfo(IMediaServerItem 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("getMediaInfo",param, null);
+ return sendPost(mediaServerItem, "getMediaInfo",param, null);
}
- public JSONObject getRtpInfo(String stream_id){
+ public JSONObject getRtpInfo(IMediaServerItem mediaServerItem,String stream_id){
Map param = new HashMap<>();
param.put("stream_id",stream_id);
- return sendPost("getRtpInfo",param, null);
+ return sendPost(mediaServerItem, "getRtpInfo",param, null);
}
- public JSONObject addFFmpegSource(String src_url, String dst_url, String timeout_ms,
+ public JSONObject addFFmpegSource(IMediaServerItem mediaServerItem,String src_url, String dst_url, String timeout_ms,
boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){
logger.info(src_url);
logger.info(dst_url);
@@ -185,44 +182,44 @@ public class ZLMRESTfulUtils {
param.put("enable_hls", enable_hls);
param.put("enable_mp4", enable_mp4);
param.put("ffmpeg_cmd_key", ffmpeg_cmd_key);
- return sendPost("addFFmpegSource",param, null);
+ return sendPost(mediaServerItem, "addFFmpegSource",param, null);
}
- public JSONObject delFFmpegSource(String key){
+ public JSONObject delFFmpegSource(IMediaServerItem mediaServerItem,String key){
Map param = new HashMap<>();
param.put("key", key);
- return sendPost("delFFmpegSource",param, null);
+ return sendPost(mediaServerItem, "delFFmpegSource",param, null);
}
- public JSONObject getMediaServerConfig(){
- return sendPost("getServerConfig",null, null);
+ public JSONObject getMediaServerConfig(IMediaServerItem mediaServerItem){
+ return sendPost(mediaServerItem, "getServerConfig",null, null);
}
- public JSONObject setServerConfig(Map param){
- return sendPost("setServerConfig",param, null);
+ public JSONObject setServerConfig(IMediaServerItem mediaServerItem, Map param){
+ return sendPost(mediaServerItem,"setServerConfig",param, null);
}
- public JSONObject openRtpServer(Map param){
- return sendPost("openRtpServer",param, null);
+ public JSONObject openRtpServer(IMediaServerItem mediaServerItem,Map param){
+ return sendPost(mediaServerItem, "openRtpServer",param, null);
}
- public JSONObject closeRtpServer(Map param) {
- return sendPost("closeRtpServer",param, null);
+ public JSONObject closeRtpServer(IMediaServerItem mediaServerItem,Map param) {
+ return sendPost(mediaServerItem, "closeRtpServer",param, null);
}
- public JSONObject listRtpServer() {
- return sendPost("listRtpServer",null, null);
+ public JSONObject listRtpServer(IMediaServerItem mediaServerItem) {
+ return sendPost(mediaServerItem, "listRtpServer",null, null);
}
- public JSONObject startSendRtp(Map param) {
- return sendPost("startSendRtp",param, null);
+ public JSONObject startSendRtp(IMediaServerItem mediaServerItem,Map param) {
+ return sendPost(mediaServerItem, "startSendRtp",param, null);
}
- public JSONObject stopSendRtp(Map param) {
- return sendPost("stopSendRtp",param, null);
+ public JSONObject stopSendRtp(IMediaServerItem mediaServerItem,Map param) {
+ return sendPost(mediaServerItem, "stopSendRtp",param, null);
}
- public JSONObject addStreamProxy(String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) {
+ public JSONObject addStreamProxy(IMediaServerItem mediaServerItem,String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) {
Map param = new HashMap<>();
param.put("vhost", "__defaultVhost__");
param.put("app", app);
@@ -231,33 +228,33 @@ public class ZLMRESTfulUtils {
param.put("enable_hls", enable_hls?1:0);
param.put("enable_mp4", enable_mp4?1:0);
param.put("rtp_type", rtp_type);
- return sendPost("addStreamProxy",param, null);
+ return sendPost(mediaServerItem, "addStreamProxy",param, null);
}
- public JSONObject closeStreams(String app, String stream) {
+ public JSONObject closeStreams(IMediaServerItem 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("close_streams",param, null);
+ return sendPost(mediaServerItem, "close_streams",param, null);
}
- public JSONObject getAllSession() {
- return sendPost("getAllSession",null, null);
+ public JSONObject getAllSession(IMediaServerItem mediaServerItem) {
+ return sendPost(mediaServerItem, "getAllSession",null, null);
}
- public void kickSessions(String localPortSStr) {
+ public void kickSessions(IMediaServerItem mediaServerItem, String localPortSStr) {
Map param = new HashMap<>();
param.put("local_port", localPortSStr);
- sendPost("kick_sessions",param, null);
+ sendPost(mediaServerItem, "kick_sessions",param, null);
}
- public void getSnap(String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) {
+ public void getSnap(IMediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) {
Map param = new HashMap<>();
param.put("url", flvUrl);
param.put("timeout_sec", timeout_sec);
param.put("expire_sec", expire_sec);
- sendPostForImg("getSnap",param, targetPath, fileName);
+ sendPostForImg(mediaServerItem, "getSnap",param, targetPath, fileName);
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
index ed069f88..5919c9f7 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.session.SsrcUtil;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,10 +32,10 @@ public class ZLMRTPServerFactory {
private Map currentStreams = null;
- public int createRTPServer(String streamId) {
+ public int createRTPServer(IMediaServerItem mediaServerItem, String streamId) {
if (currentStreams == null) {
currentStreams = new HashMap<>();
- JSONObject jsonObject = zlmresTfulUtils.listRtpServer();
+ JSONObject jsonObject = zlmresTfulUtils.listRtpServer(mediaServerItem);
if (jsonObject != null) {
JSONArray data = jsonObject.getJSONArray("data");
if (data != null) {
@@ -48,7 +50,7 @@ public class ZLMRTPServerFactory {
if (currentStreams.get(streamId) != null) {
Map closeRtpServerParam = new HashMap<>();
closeRtpServerParam.put("stream_id", streamId);
- zlmresTfulUtils.closeRtpServer(closeRtpServerParam);
+ zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam);
currentStreams.remove(streamId);
}
@@ -58,7 +60,7 @@ public class ZLMRTPServerFactory {
param.put("port", newPort);
param.put("enable_tcp", 1);
param.put("stream_id", streamId);
- JSONObject jsonObject = zlmresTfulUtils.openRtpServer(param);
+ JSONObject jsonObject = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
if (jsonObject != null) {
switch (jsonObject.getInteger("code")){
@@ -68,11 +70,11 @@ public class ZLMRTPServerFactory {
case -300: // id已经存在, 可能已经在其他端口推流
Map closeRtpServerParam = new HashMap<>();
closeRtpServerParam.put("stream_id", streamId);
- zlmresTfulUtils.closeRtpServer(closeRtpServerParam);
+ zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam);
result = newPort;
break;
case -400: // 端口占用
- result= createRTPServer(streamId);
+ result= createRTPServer(mediaServerItem, streamId);
break;
default:
logger.error("创建RTP Server 失败 {}: " + jsonObject.getString("msg"), newPort);
@@ -85,20 +87,22 @@ public class ZLMRTPServerFactory {
return result;
}
- public boolean closeRTPServer(String streamId) {
+ public boolean closeRTPServer(IMediaServerItem serverItem, String streamId) {
boolean result = false;
- Map param = new HashMap<>();
- param.put("stream_id", streamId);
- JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(param);
- if (jsonObject != null ) {
- if (jsonObject.getInteger("code") == 0) {
- result = jsonObject.getInteger("hit") == 1;
+ if (serverItem !=null){
+ Map param = new HashMap<>();
+ param.put("stream_id", streamId);
+ JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(serverItem, param);
+ if (jsonObject != null ) {
+ if (jsonObject.getInteger("code") == 0) {
+ result = jsonObject.getInteger("hit") == 1;
+ }else {
+ logger.error("关闭RTP Server 失败: " + jsonObject.getString("msg"));
+ }
}else {
- logger.error("关闭RTP Server 失败: " + jsonObject.getString("msg"));
+ // 检查ZLM状态
+ logger.error("关闭RTP Server 失败: 请检查ZLM服务");
}
- }else {
- // 检查ZLM状态
- logger.error("关闭RTP Server 失败: 请检查ZLM服务");
}
return result;
}
@@ -131,11 +135,11 @@ public class ZLMRTPServerFactory {
* @param tcp 是否为tcp
* @return SendRtpItem
*/
- public SendRtpItem createSendRtpItem(String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){
+ public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){
String playSsrc = SsrcUtil.getPlaySsrc();
- int localPort = createRTPServer(SsrcUtil.getPlaySsrc());
+ int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc());
if (localPort != -1) {
- closeRTPServer(playSsrc);
+ closeRTPServer(serverItem, playSsrc);
}else {
logger.error("没有可用的端口");
return null;
@@ -150,6 +154,7 @@ public class ZLMRTPServerFactory {
sendRtpItem.setTcp(tcp);
sendRtpItem.setApp("rtp");
sendRtpItem.setLocalPort(localPort);
+ sendRtpItem.setMediaServerId(serverItem.getId());
return sendRtpItem;
}
@@ -163,11 +168,11 @@ public class ZLMRTPServerFactory {
* @param tcp 是否为tcp
* @return SendRtpItem
*/
- public SendRtpItem createSendRtpItem(String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
+ public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
String playSsrc = SsrcUtil.getPlaySsrc();
- int localPort = createRTPServer(SsrcUtil.getPlaySsrc());
+ int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc());
if (localPort != -1) {
- closeRTPServer(playSsrc);
+ closeRTPServer(serverItem, playSsrc);
}else {
logger.error("没有可用的端口");
return null;
@@ -182,21 +187,21 @@ public class ZLMRTPServerFactory {
sendRtpItem.setChannelId(channelId);
sendRtpItem.setTcp(tcp);
sendRtpItem.setLocalPort(localPort);
+ sendRtpItem.setMediaServerId(serverItem.getId());
return sendRtpItem;
}
/**
* 调用zlm RESTful API —— startSendRtp
*/
- public Boolean startSendRtpStream(Mapparam) {
+ public Boolean startSendRtpStream(IMediaServerItem mediaServerItem, Mapparam) {
Boolean result = false;
- JSONObject jsonObject = zlmresTfulUtils.startSendRtp(param);
- logger.info(jsonObject.toJSONString());
+ JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param);
if (jsonObject == null) {
logger.error("RTP推流失败: 请检查ZLM服务");
} else if (jsonObject.getInteger("code") == 0) {
result= true;
- logger.info("RTP推流请求成功,本地推流端口:" + jsonObject.getString("local_port"));
+ logger.info("RTP推流[ {}/{} ]请求成功,本地推流端口:{}" ,param.get("app"), param.get("stream"), jsonObject.getString("local_port"));
} else {
logger.error("RTP推流失败: " + jsonObject.getString("msg"));
}
@@ -206,16 +211,16 @@ public class ZLMRTPServerFactory {
/**
* 查询待转推的流是否就绪
*/
- public Boolean isRtpReady(String streamId) {
- JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId);
+ public Boolean isRtpReady(MediaServerItem mediaServerItem, String streamId) {
+ JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtmp", streamId);
return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
}
/**
* 查询待转推的流是否就绪
*/
- public Boolean isStreamReady(String app, String streamId) {
- JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(app, "rtmp", streamId);
+ public Boolean isStreamReady(IMediaServerItem mediaServerItem, String app, String streamId) {
+ JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
}
@@ -224,18 +229,17 @@ public class ZLMRTPServerFactory {
* @param streamId
* @return
*/
- public int totalReaderCount(String app, String streamId) {
- JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(app, "rtmp", streamId);
+ public int totalReaderCount(IMediaServerItem mediaServerItem, String app, String streamId) {
+ JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
return mediaInfo.getInteger("totalReaderCount");
}
/**
* 调用zlm RESTful API —— stopSendRtp
*/
- public Boolean stopSendRtpStream(Mapparam) {
+ public Boolean stopSendRtpStream(IMediaServerItem mediaServerItem,Mapparam) {
Boolean result = false;
- JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(param);
- logger.info(jsonObject.toJSONString());
+ JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param);
if (jsonObject == null) {
logger.error("停止RTP推流失败: 请检查ZLM服务");
} else if (jsonObject.getInteger("code") == 0) {
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 956db144..d06c6c32 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -4,7 +4,10 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.conf.MediaConfig;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+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.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.service.IStreamProxyService;
import org.slf4j.Logger;
@@ -14,10 +17,10 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import javax.print.attribute.standard.Media;
+import java.util.*;
@Component
@Order(value=1)
@@ -25,140 +28,131 @@ public class ZLMRunner implements CommandLineRunner {
private final static Logger logger = LoggerFactory.getLogger(ZLMRunner.class);
- @Autowired
- private IVideoManagerStorager storager;
-
- @Autowired
- private MediaConfig mediaConfig;
-
- @Value("${server.port}")
- private String serverPort;
-
- @Value("${server.ssl.enabled:false}")
- private boolean sslEnabled;
-
- private boolean startGetMedia = false;
+ private Map startGetMedia;
@Autowired
private ZLMRESTfulUtils zlmresTfulUtils;
- @Autowired
- private ZLMMediaListManager zlmMediaListManager;
-
@Autowired
private ZLMHttpHookSubscribe hookSubscribe;
- @Autowired
- private ZLMServerManger zlmServerManger;
-
@Autowired
private IStreamProxyService streamProxyService;
+ @Autowired
+ private IMediaServerService mediaServerService;
+
+ @Autowired
+ private MediaConfig mediaConfig;
+
@Override
public void run(String... strings) throws Exception {
- // 订阅 zlm启动事件
- hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null,(response)->{
- ZLMServerConfig ZLMServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class);
- zLmRunning(ZLMServerConfig);
+ IMediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort(
+ mediaConfig.getIp(), mediaConfig.getHttpPort());
+ if (presetMediaServer != null) {
+ mediaConfig.setId(presetMediaServer.getId());
+ mediaServerService.update(mediaConfig);
+ }
+
+ // 订阅 zlm启动事件, 新的zlm也会从这里进入系统
+ hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null,
+ (IMediaServerItem mediaServerItem, JSONObject response)->{
+ ZLMServerConfig zlmServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class);
+ if (zlmServerConfig !=null ) {
+ startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId());
+ mediaServerService.handLeZLMServerConfig(zlmServerConfig);
+// zLmRunning(zlmServerConfig);
+ }
});
// 获取zlm信息
- logger.info("等待zlm接入...");
- startGetMedia = true;
- ZLMServerConfig ZLMServerConfig = getMediaServerConfig();
+ logger.info("等待默认zlm接入...");
- if (ZLMServerConfig != null) {
- zLmRunning(ZLMServerConfig);
+ // 获取所有的zlm, 并开启主动连接
+ List all = mediaServerService.getAll();
+ if (presetMediaServer == null) {
+ all.add(mediaConfig.getMediaSerItem());
}
+ for (IMediaServerItem mediaServerItem : all) {
+ if (startGetMedia == null) startGetMedia = new HashMap<>();
+ startGetMedia.put(mediaServerItem.getId(), true);
+ new Thread(() -> {
+ ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem);
+ if (zlmServerConfig != null) {
+ startGetMedia.remove(mediaServerItem.getId());
+ mediaServerService.handLeZLMServerConfig(zlmServerConfig);
+ }
+ }).start();
+ }
+ Timer timer = new Timer();
+ // 1分钟后未连接到则不再去主动连接
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ if (startGetMedia != null) {
+ Set allZlmId = startGetMedia.keySet();
+ for (String id : allZlmId) {
+ logger.error("[ {} ]]主动连接失败,不再主动连接", id);
+ startGetMedia.put(id, false);
+ }
+ }
+ }
+ }, 60 * 1000 * 2);
}
- public ZLMServerConfig getMediaServerConfig() {
- if (!startGetMedia) return null;
- JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig();
+ public ZLMServerConfig getMediaServerConfig(IMediaServerItem mediaServerItem) {
+ 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);
-
+ ZLMServerConfig.setIp(mediaServerItem.getIp());
}
} else {
- logger.error("getMediaServerConfig失败, 1s后重试");
+ logger.error("[ {} ]-[ {}:{} ]主动连接失败失败, 2s后重试",
+ mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
try {
- Thread.sleep(1000);
+ Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
- ZLMServerConfig = getMediaServerConfig();
+ ZLMServerConfig = getMediaServerConfig(mediaServerItem);
}
return ZLMServerConfig;
- }
- private void saveZLMConfig() {
- logger.info("设置zlm...");
- String protocol = sslEnabled ? "https" : "http";
- String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaConfig.getHookIp(), serverPort);
- String recordHookPrex = null;
- if (mediaConfig.getRecordAssistPort() != 0) {
- recordHookPrex = String.format("http://127.0.0.1:%s/api/record", mediaConfig.getRecordAssistPort());
- }
- Map param = new HashMap<>();
- param.put("api.secret",mediaConfig.getSecret()); // -profile:v Baseline
- param.put("ffmpeg.cmd","%s -fflags nobuffer -rtsp_transport tcp -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s");
- param.put("hook.enable","1");
- param.put("hook.on_flow_report","");
- param.put("hook.on_play",String.format("%s/on_play", hookPrex));
- param.put("hook.on_http_access","");
- param.put("hook.on_publish", String.format("%s/on_publish", hookPrex));
- param.put("hook.on_record_mp4",recordHookPrex != null? String.format("%s/on_record_mp4", recordHookPrex): "");
- 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", hookPrex));
- param.put("hook.on_shell_login",String.format("%s/on_shell_login", hookPrex));
- param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrex));
- param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex));
- param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
- param.put("hook.timeoutSec","20");
- param.put("general.streamNoneReaderDelayMS",mediaConfig.getStreamNoneReaderDelayMS());
-
- JSONObject responseJSON = zlmresTfulUtils.setServerConfig(param);
-
- if (responseJSON != null && responseJSON.getInteger("code") == 0) {
- logger.info("设置zlm成功");
- }else {
- logger.info("设置zlm失败");
- }
}
/**
* zlm 连接成功或者zlm重启后
*/
- private void zLmRunning(ZLMServerConfig zlmServerConfig){
- logger.info( "[ id: " + zlmServerConfig.getGeneralMediaServerId() + "] zlm接入成功...");
- // 关闭循环获取zlm配置
- startGetMedia = false;
- if (mediaConfig.isAutoConfig()) saveZLMConfig();
- zlmServerManger.updateServerCatch(zlmServerConfig);
-
- // 清空所有session
-// zlmMediaListManager.clearAllSessions();
-
- // 更新流列表
- zlmMediaListManager.updateMediaList();
- // 恢复流代理
- List streamProxyListForEnable = storager.getStreamProxyListForEnable(true);
- for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {
- logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
- JSONObject jsonObject = streamProxyService.addStreamProxyToZlm(streamProxyDto);
- if (jsonObject == null) {
- // 设置为未启用
- logger.info("恢复流代理失败,请检查流地址后重新启用" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
- streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());
- }else if (jsonObject.getInteger("code") != 0){ // TODO 将错误信息存入数据库, 前端展示
- logger.info("恢复流代理失败:" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream() + "[ " + JSONObject.toJSONString(jsonObject) + " ]");
- streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());
- }
- }
- }
+// private void zLmRunning(ZLMServerConfig zlmServerConfig){
+// logger.info( "[ id: " + zlmServerConfig.getGeneralMediaServerId() + "] zlm接入成功...");
+// // 关闭循环获取zlm配置
+// startGetMedia = false;
+// MediaServerItem mediaServerItem = new MediaServerItem(zlmServerConfig, sipIp);
+// storager.updateMediaServer(mediaServerItem);
+//
+// if (mediaServerItem.isAutoConfig()) setZLMConfig(mediaServerItem);
+// zlmServerManger.updateServerCatchFromHook(zlmServerConfig);
+//
+// // 清空所有session
+//// zlmMediaListManager.clearAllSessions();
+//
+// // 更新流列表
+// zlmMediaListManager.updateMediaList(mediaServerItem);
+// // 恢复流代理, 只查找这个这个流媒体
+// List streamProxyListForEnable = storager.getStreamProxyListForEnableInMediaServer(
+// mediaServerItem.getId(), true);
+// for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {
+// logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
+// JSONObject jsonObject = streamProxyService.addStreamProxyToZlm(streamProxyDto);
+// if (jsonObject == null) {
+// // 设置为未启用
+// logger.info("恢复流代理失败,请检查流地址后重新启用" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
+// streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());
+// }
+// }
+// }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java
index 21fcebf1..c1a9bd20 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java
@@ -34,12 +34,15 @@ public class ZLMServerConfig {
@JSONField(name = "general.streamNoneReaderDelayMS")
private String generalStreamNoneReaderDelayMS;
+ @JSONField(name = "ip")
private String ip;
private String sdpIp;
private String streamIp;
+ private String hookIp;
+
private String updateTime;
private String createTime;
@@ -66,7 +69,7 @@ public class ZLMServerConfig {
private String hookEnable;
@JSONField(name = "hook.on_flow_report")
- private Integer hookOnFlowReport;
+ private String hookOnFlowReport;
@JSONField(name = "hook.on_http_access")
private String hookOnHttpAccess;
@@ -117,7 +120,7 @@ public class ZLMServerConfig {
private String httpNotFound;
@JSONField(name = "http.port")
- private Integer httpPort;
+ private int httpPort;
@JSONField(name = "http.rootPath")
private String httpRootPath;
@@ -126,7 +129,7 @@ public class ZLMServerConfig {
private String httpSendBufSize;
@JSONField(name = "http.sslport")
- private Integer httpSSLport;
+ private int httpSSLport;
@JSONField(name = "multicast.addrMax")
private String multicastAddrMax;
@@ -159,10 +162,10 @@ public class ZLMServerConfig {
private String rtmpModifyStamp;
@JSONField(name = "rtmp.port")
- private Integer rtmpPort;
+ private int rtmpPort;
@JSONField(name = "rtmp.sslport")
- private Integer rtmpSslPort;
+ private int rtmpSslPort;
@JSONField(name = "rtp.audioMtuSize")
private String rtpAudioMtuSize;
@@ -186,7 +189,7 @@ public class ZLMServerConfig {
private String rtpProxyDumpDir;
@JSONField(name = "rtp_proxy.port")
- private Integer rtpProxyPort;
+ private int rtpProxyPort;
@JSONField(name = "rtp_proxy.timeoutSec")
private String rtpProxyTimeoutSec;
@@ -201,10 +204,10 @@ public class ZLMServerConfig {
private String rtspKeepAliveSecond;
@JSONField(name = "rtsp.port")
- private Integer rtspPort;
+ private int rtspPort;
@JSONField(name = "rtsp.sslport")
- private Integer rtspSSlport;
+ private int rtspSSlport;
@JSONField(name = "shell.maxReqSize")
private String shellMaxReqSize;
@@ -212,6 +215,15 @@ public class ZLMServerConfig {
@JSONField(name = "shell.shell")
private String shellPhell;
+
+ public String getHookIp() {
+ return hookIp;
+ }
+
+ public void setHookIp(String hookIp) {
+ this.hookIp = hookIp;
+ }
+
public String getApiDebug() {
return apiDebug;
}
@@ -388,11 +400,11 @@ public class ZLMServerConfig {
this.hookEnable = hookEnable;
}
- public Integer getHookOnFlowReport() {
+ public String getHookOnFlowReport() {
return hookOnFlowReport;
}
- public void setHookOnFlowReport(Integer hookOnFlowReport) {
+ public void setHookOnFlowReport(String hookOnFlowReport) {
this.hookOnFlowReport = hookOnFlowReport;
}
@@ -524,11 +536,11 @@ public class ZLMServerConfig {
this.httpNotFound = httpNotFound;
}
- public Integer getHttpPort() {
+ public int getHttpPort() {
return httpPort;
}
- public void setHttpPort(Integer httpPort) {
+ public void setHttpPort(int httpPort) {
this.httpPort = httpPort;
}
@@ -548,11 +560,11 @@ public class ZLMServerConfig {
this.httpSendBufSize = httpSendBufSize;
}
- public Integer getHttpSSLport() {
+ public int getHttpSSLport() {
return httpSSLport;
}
- public void setHttpSSLport(Integer httpSSLport) {
+ public void setHttpSSLport(int httpSSLport) {
this.httpSSLport = httpSSLport;
}
@@ -636,19 +648,19 @@ public class ZLMServerConfig {
this.rtmpModifyStamp = rtmpModifyStamp;
}
- public Integer getRtmpPort() {
+ public int getRtmpPort() {
return rtmpPort;
}
- public void setRtmpPort(Integer rtmpPort) {
+ public void setRtmpPort(int rtmpPort) {
this.rtmpPort = rtmpPort;
}
- public Integer getRtmpSslPort() {
+ public int getRtmpSslPort() {
return rtmpSslPort;
}
- public void setRtmpSslPort(Integer rtmpSslPort) {
+ public void setRtmpSslPort(int rtmpSslPort) {
this.rtmpSslPort = rtmpSslPort;
}
@@ -708,11 +720,11 @@ public class ZLMServerConfig {
this.rtpProxyDumpDir = rtpProxyDumpDir;
}
- public Integer getRtpProxyPort() {
+ public int getRtpProxyPort() {
return rtpProxyPort;
}
- public void setRtpProxyPort(Integer rtpProxyPort) {
+ public void setRtpProxyPort(int rtpProxyPort) {
this.rtpProxyPort = rtpProxyPort;
}
@@ -748,19 +760,19 @@ public class ZLMServerConfig {
this.rtspKeepAliveSecond = rtspKeepAliveSecond;
}
- public Integer getRtspPort() {
+ public int getRtspPort() {
return rtspPort;
}
- public void setRtspPort(Integer rtspPort) {
+ public void setRtspPort(int rtspPort) {
this.rtspPort = rtspPort;
}
- public Integer getRtspSSlport() {
+ public int getRtspSSlport() {
return rtspSSlport;
}
- public void setRtspSSlport(Integer rtspSSlport) {
+ public void setRtspSSlport(int rtspSSlport) {
this.rtspSSlport = rtspSSlport;
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerManger.java
deleted file mode 100644
index fde3b447..00000000
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerManger.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.genersoft.iot.vmp.media.zlm;
-
-import com.genersoft.iot.vmp.conf.MediaConfig;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
-
-@Component
-public class ZLMServerManger {
-
- @Autowired
- private IRedisCatchStorage redisCatchStorage;
-
- @Autowired
- private MediaConfig mediaConfig;
-
- public void updateServerCatch(ZLMServerConfig zlmServerConfig) {
-
- zlmServerConfig.setIp(mediaConfig.getIp());
- zlmServerConfig.setStreamIp(mediaConfig.getStreamIp());
- zlmServerConfig.setSdpIp(mediaConfig.getSdpIp());
- zlmServerConfig.setHttpPort(mediaConfig.getHttpPort());
-
- if(!StringUtils.isEmpty(mediaConfig.getHttpSSlPort()))
- zlmServerConfig.setHttpSSLport(mediaConfig.getHttpSSlPort());
-
- if(!StringUtils.isEmpty(mediaConfig.getRtspPort()))
- zlmServerConfig.setRtspPort(mediaConfig.getRtspPort());
-
- if(!StringUtils.isEmpty(mediaConfig.getRtspSSLPort()))
- zlmServerConfig.setRtspSSlport(mediaConfig.getRtspSSLPort());
-
- if(!StringUtils.isEmpty(mediaConfig.getRtmpPort()))
- zlmServerConfig.setRtmpPort(mediaConfig.getRtmpPort());
-
- if(!StringUtils.isEmpty(mediaConfig.getRtmpSSlPort()))
- zlmServerConfig.setRtmpSslPort(mediaConfig.getRtmpSSlPort());
-
- if(!StringUtils.isEmpty(mediaConfig.getRtpProxyPort()))
- zlmServerConfig.setRtpProxyPort(mediaConfig.getRtpProxyPort());
-
- redisCatchStorage.updateMediaInfo(zlmServerConfig);
- }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java
new file mode 100644
index 00000000..64971628
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java
@@ -0,0 +1,92 @@
+package com.genersoft.iot.vmp.media.zlm.dto;
+
+public interface IMediaServerItem {
+
+ String getId();
+
+ void setId(String id);
+
+ String getIp();
+
+ void setIp(String ip);
+
+ String getHookIp();
+
+ void setHookIp(String hookIp);
+
+ String getSdpIp();
+
+ void setSdpIp(String sdpIp);
+
+ String getStreamIp();
+
+ void setStreamIp(String streamIp);
+
+ int getHttpPort();
+
+ void setHttpPort(int httpPort);
+
+ int getHttpSSlPort();
+
+ void setHttpSSlPort(int httpSSlPort);
+
+ int getRtmpPort();
+
+ void setRtmpPort(int rtmpPort);
+
+ int getRtmpSSlPort();
+
+ void setRtmpSSlPort(int rtmpSSlPort);
+
+ int getRtpProxyPort();
+
+ void setRtpProxyPort(int rtpProxyPort);
+
+ int getRtspPort();
+
+ void setRtspPort(int rtspPort);
+
+ int getRtspSSLPort();
+
+ void setRtspSSLPort(int rtspSSLPort);
+
+ boolean isAutoConfig();
+
+ void setAutoConfig(boolean autoConfig);
+
+ String getSecret();
+
+ void setSecret(String secret);
+
+ String getStreamNoneReaderDelayMS();
+
+ void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS);
+
+ boolean isRtpEnable();
+
+ void setRtpEnable(boolean rtpEnable);
+
+ String getRtpPortRange();
+
+ void setRtpPortRange(String rtpPortRange);
+
+ int getRecordAssistPort();
+
+ void setRecordAssistPort(int recordAssistPort);
+
+ boolean isDocker();
+
+ void setDocker(boolean docker);
+
+ String getUpdateTime();
+
+ void setUpdateTime(String updateTime);
+
+ String getCreateTime();
+
+ void setCreateTime(String createTime);
+
+ int getCount();
+
+ void setCount(int count);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java
index 24bfcc17..6d9ceee9 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java
@@ -78,6 +78,10 @@ public class MediaItem {
*/
private String vhost;
+ /**
+ * 是否是docker部署, docker部署不会自动更新zlm使用的端口,需要自己手动修改
+ */
+ private boolean docker;
public static class MediaTrack {
/**
@@ -364,4 +368,12 @@ public class MediaItem {
public OriginSock getOriginSock() {
return originSock;
}
+
+ public boolean isDocker() {
+ return docker;
+ }
+
+ public void setDocker(boolean docker) {
+ this.docker = docker;
+ }
}
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
new file mode 100644
index 00000000..b56881f7
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
@@ -0,0 +1,254 @@
+package com.genersoft.iot.vmp.media.zlm.dto;
+
+
+import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
+import org.springframework.util.StringUtils;
+
+public class MediaServerItem implements IMediaServerItem{
+
+ 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 boolean autoConfig;
+
+ private String secret;
+
+ private String streamNoneReaderDelayMS;
+
+ private boolean rtpEnable;
+
+ private String rtpPortRange;
+
+ private int recordAssistPort;
+
+ private String createTime;
+
+ private String updateTime;
+
+ private boolean docker;
+
+ private int count;
+
+ public MediaServerItem() {
+ }
+
+ public MediaServerItem(ZLMServerConfig zlmServerConfig, String sipIp) {
+ id = zlmServerConfig.getGeneralMediaServerId();
+ ip = zlmServerConfig.getIp();
+ hookIp = StringUtils.isEmpty(zlmServerConfig.getHookIp())? sipIp: zlmServerConfig.getHookIp();
+ sdpIp = StringUtils.isEmpty(zlmServerConfig.getSdpIp())? zlmServerConfig.getIp(): zlmServerConfig.getSdpIp();
+ streamIp = StringUtils.isEmpty(zlmServerConfig.getStreamIp())? zlmServerConfig.getIp(): zlmServerConfig.getStreamIp();
+ httpPort = zlmServerConfig.getHttpPort();
+ httpSSlPort = zlmServerConfig.getHttpSSLport();
+ rtmpPort = zlmServerConfig.getRtmpPort();
+ rtmpSSlPort = zlmServerConfig.getRtmpSslPort();
+ rtpProxyPort = zlmServerConfig.getRtpProxyPort();
+ rtspPort = zlmServerConfig.getRtspPort();
+ rtspSSLPort = zlmServerConfig.getRtspSSlport();
+ autoConfig = true; // 默认值true;
+ secret = zlmServerConfig.getApiSecret();
+ streamNoneReaderDelayMS = zlmServerConfig.getGeneralStreamNoneReaderDelayMS();
+ rtpEnable = false; // 默认使用单端口;直到用户自己设置开启多端口
+ recordAssistPort = 0; // 默认关闭
+
+ }
+
+ 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 boolean isAutoConfig() {
+ return autoConfig;
+ }
+
+ public void setAutoConfig(boolean autoConfig) {
+ this.autoConfig = autoConfig;
+ }
+
+ public String getSecret() {
+ return secret;
+ }
+
+ public void setSecret(String secret) {
+ this.secret = secret;
+ }
+
+ public String getStreamNoneReaderDelayMS() {
+ return streamNoneReaderDelayMS;
+ }
+
+ public void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS) {
+ this.streamNoneReaderDelayMS = streamNoneReaderDelayMS;
+ }
+
+ public boolean isRtpEnable() {
+ return rtpEnable;
+ }
+
+ public void setRtpEnable(boolean rtpEnable) {
+ this.rtpEnable = rtpEnable;
+ }
+
+ public String getRtpPortRange() {
+ return rtpPortRange;
+ }
+
+ public void setRtpPortRange(String rtpPortRange) {
+ this.rtpPortRange = rtpPortRange;
+ }
+
+ public int getRecordAssistPort() {
+ return recordAssistPort;
+ }
+
+ public void setRecordAssistPort(int recordAssistPort) {
+ this.recordAssistPort = recordAssistPort;
+ }
+
+ @Override
+ public boolean isDocker() {
+ return docker;
+ }
+
+ @Override
+ public void setDocker(boolean docker) {
+ this.docker = docker;
+ }
+
+ public String getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(String createTime) {
+ this.createTime = createTime;
+ }
+
+ public String getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(String updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
index 3f997a66..40ba215f 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
@@ -7,6 +7,7 @@ public class StreamProxyItem extends GbStream {
private String type;
private String app;
private String stream;
+ private String mediaServerId;
private String url;
private String src_url;
private String dst_url;
@@ -17,6 +18,7 @@ public class StreamProxyItem extends GbStream {
private boolean enable_hls;
private boolean enable_mp4;
private String platformGbId;
+ private String createTime;
public String getType() {
return type;
@@ -42,6 +44,16 @@ public class StreamProxyItem extends GbStream {
this.stream = stream;
}
+ @Override
+ public String getMediaServerId() {
+ return mediaServerId;
+ }
+
+ @Override
+ public void setMediaServerId(String mediaServerId) {
+ this.mediaServerId = mediaServerId;
+ }
+
public String getUrl() {
return url;
}
@@ -122,4 +134,12 @@ public class StreamProxyItem extends GbStream {
public void setPlatformGbId(String platformGbId) {
this.platformGbId = platformGbId;
}
+
+ public String getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(String createTime) {
+ this.createTime = createTime;
+ }
}
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 7a1c49ba..73e162af 100644
--- 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
@@ -76,6 +76,11 @@ public class StreamPushItem extends GbStream implements Comparable getAll();
+
+ IMediaServerItem getOne(String generalMediaServerId);
+
+ IMediaServerItem getOneByHostAndPort(String host, int port);
+
+ /**
+ * 新的节点加入
+ * @param zlmServerConfig
+ * @return
+ */
+ void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig);
+
+ void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean b);
+
+ IMediaServerItem getMediaServerForMinimumLoad();
+
+ void setZLMConfig(IMediaServerItem mediaServerItem);
+
+ void init();
+
+ void closeRTPServer(Device device, String channelId);
+
+ void update(MediaConfig mediaConfig);
+
+ void addCount(String mediaServerId);
+
+ void removeCount(String mediaServerId);
+}
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 010870a7..868a8310 100644
--- 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,8 @@ package com.genersoft.iot.vmp.service;
import com.alibaba.fastjson.JSONArray;
import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
/**
* 媒体信息业务
@@ -14,23 +16,8 @@ public interface IMediaService {
* @param stream
* @return
*/
- StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream);
+ StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr);
- /**
- * 根据应用名和流ID获取播放地址, 只是地址拼接
- * @param app
- * @param stream
- * @return
- */
- StreamInfo getStreamInfoByAppAndStream(String app, String stream, JSONArray tracks);
-
- /**
- * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况
- * @param app
- * @param stream
- * @return
- */
- StreamInfo getStreamInfoByAppAndStream(String app, String stream, JSONArray tracks, String addr);
/**
* 根据应用名和流ID获取播放地址, 通过zlm接口检查是否存在, 返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况
@@ -38,5 +25,21 @@ public interface IMediaService {
* @param stream
* @return
*/
- StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String addr);
+ StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId);
+
+ /**
+ * 根据应用名和流ID获取播放地址, 只是地址拼接
+ * @param app
+ * @param stream
+ * @return
+ */
+ StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaServerItem, String app, String stream, JSONArray tracks);
+
+ /**
+ * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况
+ * @param app
+ * @param stream
+ * @return
+ */
+ StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr);
}
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 a6492677..fdc86d6e 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -1,8 +1,11 @@
package com.genersoft.iot.vmp.service;
import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
/**
@@ -10,8 +13,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
*/
public interface IPlayService {
- void onPublishHandlerForPlayBack(JSONObject resonse, String deviceId, String channelId, String uuid);
- void onPublishHandlerForPlay(JSONObject resonse, String deviceId, String channelId, String uuid);
+ void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem,JSONObject resonse, String deviceId, String channelId, String uuid);
+ void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
- PlayResult play(String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
+ PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
+
+ IMediaServerItem getNewMediaServerItem(Device device);
}
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 2f7388a9..fa79d696 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
@@ -1,6 +1,8 @@
package com.genersoft.iot.vmp.service;
import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import com.github.pagehelper.PageInfo;
@@ -61,5 +63,5 @@ public interface IStreamProxyService {
* 获取ffmpeg.cmd模板
* @return
*/
- JSONObject getFFmpegCMDs();
+ JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem);
}
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 e66480a0..eaf24904 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
@@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.service;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
import com.github.pagehelper.PageInfo;
@@ -8,7 +9,7 @@ import java.util.List;
public interface IStreamPushService {
- List handleJSON(String json);
+ List handleJSON(String json, IMediaServerItem mediaServerItem);
/**
* 将应用名和流ID加入国标关联
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
new file mode 100644
index 00000000..a90225a8
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -0,0 +1,340 @@
+package com.genersoft.iot.vmp.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.conf.MediaConfig;
+import com.genersoft.iot.vmp.conf.ProxyServletConfig;
+import com.genersoft.iot.vmp.gb28181.bean.Device;
+import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
+import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
+import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
+import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.ZLMRunInfo;
+import com.genersoft.iot.vmp.service.IMediaServerService;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.storager.dao.MediaServerMapper;
+import org.mitre.dsmiley.httpproxy.ProxyServlet;
+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 java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 媒体服务器节点管理
+ */
+@Service
+public class MediaServerServiceImpl implements IMediaServerService {
+
+ private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class);
+
+ private Map zlmServers = new HashMap<>(); // 所有数据库的zlm的缓存
+ private Map zlmServerStatus = new LinkedHashMap<>(); // 所有上线的zlm的缓存以及负载
+
+ @Value("${sip.ip}")
+ private String sipIp;
+
+ @Value("${server.ssl.enabled:false}")
+ private boolean sslEnabled;
+
+ @Value("${server.port}")
+ private String serverPort;
+
+ @Autowired
+ private MediaConfig mediaConfig;
+
+ @Autowired
+ private ZLMRESTfulUtils zlmresTfulUtils;
+
+ @Autowired
+ private MediaServerMapper mediaServerMapper;
+
+
+ @Autowired
+ private IRedisCatchStorage redisCatchStorage;
+
+ @Autowired
+ private VideoStreamSessionManager streamSession;
+
+ @Autowired
+ private ZLMRTPServerFactory zlmrtpServerFactory;
+
+ private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ /**
+ * 初始化
+ */
+ @Override
+ public void init() {
+ zlmServers.clear();
+ zlmServerStatus.clear();
+ List mediaServerItemList = mediaServerMapper.queryAll();
+ for (IMediaServerItem mediaServerItem : mediaServerItemList) {
+ zlmServers.put(mediaServerItem.getId(), mediaServerItem);
+ }
+ }
+
+ @Override
+ public void closeRTPServer(Device device, String channelId) {
+ StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
+ IMediaServerItem mediaServerItem = null;
+ if (streamInfo != null) {
+ mediaServerItem = this.getOne (streamInfo.getMediaServerId());
+ }
+ String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
+ zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
+ streamSession.remove(device.getDeviceId(), channelId);
+ }
+
+ @Override
+ public void update(MediaConfig mediaConfig) {
+
+ }
+
+ @Override
+ public List getAll() {
+ if (zlmServers.size() == 0) {
+ init();
+ }
+ List result = new ArrayList<>();
+ for (String id : zlmServers.keySet()) {
+ IMediaServerItem mediaServerItem = zlmServers.get(id);
+ mediaServerItem.setCount(zlmServerStatus.get(id) == null ? 0 : zlmServerStatus.get(id));
+ result.add(mediaServerItem);
+ }
+ return result;
+
+
+// return mediaServerMapper.queryAll();
+ }
+
+ /**
+ * 获取单个zlm服务器
+ * @param mediaServerId 服务id
+ * @return MediaServerItem
+ */
+ @Override
+ public IMediaServerItem getOne(String mediaServerId) {
+ if (mediaServerId ==null) return null;
+ IMediaServerItem mediaServerItem = zlmServers.get(mediaServerId);
+ if (mediaServerItem != null) {
+ mediaServerItem.setCount(zlmServerStatus.get(mediaServerId) == null ? 0 : zlmServerStatus.get(mediaServerId));
+ return mediaServerItem;
+ }else {
+ IMediaServerItem item = mediaServerMapper.queryOne(mediaServerId);
+ if (item != null) {
+ zlmServers.put(item.getId(), item);
+ }
+ return item;
+ }
+ }
+
+ @Override
+ public IMediaServerItem getOneByHostAndPort(String host, int port) {
+ return mediaServerMapper.queryOneByHostAndPort(host, port);
+ }
+
+ /**
+ * 处理zlm上线
+ * @param zlmServerConfig zlm上线携带的参数
+ */
+ @Override
+ public void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig) {
+ logger.info("[ {} ]-[ {}:{} ]已连接",
+ zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort());
+
+ IMediaServerItem serverItem = getOne(zlmServerConfig.getGeneralMediaServerId());
+ String now = this.format.format(new Date(System.currentTimeMillis()));
+ if (serverItem != null) {
+ serverItem.setSecret(zlmServerConfig.getApiSecret());
+ serverItem.setIp(zlmServerConfig.getIp());
+ // 如果是配置文件中的zlm。 也就是默认zlm。 一切以配置文件内容为准
+ // docker部署不会使用zlm配置的端口号;
+ // 直接编译部署的使用配置文件的端口号,如果zlm修改配改了配置,wvp自动修改
+
+ if (serverItem.getId().equals(mediaConfig.getId())
+ || (serverItem.getIp().equals(mediaConfig.getIp()) && serverItem.getHttpPort() == mediaConfig.getHttpPort())) {
+ // 配置文件的zlm
+ mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId());
+ mediaConfig.setUpdateTime(now);
+ if (mediaConfig.getHttpPort() == 0) mediaConfig.setHttpPort(zlmServerConfig.getHttpPort());
+ if (mediaConfig.getHttpSSlPort() == 0) mediaConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport());
+ if (mediaConfig.getRtmpPort() == 0) mediaConfig.setRtmpPort(zlmServerConfig.getRtmpPort());
+ if (mediaConfig.getRtmpSSlPort() == 0) mediaConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
+ if (mediaConfig.getRtspPort() == 0) mediaConfig.setRtspPort(zlmServerConfig.getRtspPort());
+ if (mediaConfig.getRtspSSLPort() == 0) mediaConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport());
+ if (mediaConfig.getRtpProxyPort() == 0) mediaConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
+ mediaServerMapper.update(mediaConfig);
+ serverItem = mediaConfig.getMediaSerItem();
+ setZLMConfig(mediaConfig);
+ }else {
+ if (!serverItem.isDocker()) {
+ serverItem.setHttpPort(zlmServerConfig.getHttpPort());
+ serverItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport());
+ serverItem.setRtmpPort(zlmServerConfig.getRtmpPort());
+ serverItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
+ serverItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
+ serverItem.setRtspPort(zlmServerConfig.getRtspPort());
+
+ }
+ serverItem.setUpdateTime(now);
+ mediaServerMapper.update(serverItem);
+ setZLMConfig(serverItem);
+ }
+ }else {
+ if (zlmServerConfig.getGeneralMediaServerId().equals(mediaConfig.getId())
+ || (zlmServerConfig.getIp().equals(mediaConfig.getIp()) && zlmServerConfig.getHttpPort() == mediaConfig.getHttpPort())) {
+ mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId());
+ mediaConfig.setCreateTime(now);
+ mediaConfig.setUpdateTime(now);
+ serverItem = mediaConfig;
+ mediaServerMapper.add(mediaConfig);
+ }else {
+ // 一个新的zlm接入wvp
+ serverItem = new MediaServerItem(zlmServerConfig, sipIp);
+ serverItem.setCreateTime(now);
+ serverItem.setUpdateTime(now);
+ mediaServerMapper.add(serverItem);
+ }
+ }
+ // 更新缓存
+ if (zlmServerStatus.get(serverItem.getId()) == null) {
+ zlmServers.put(serverItem.getId(), serverItem);
+ zlmServerStatus.put(serverItem.getId(),0);
+ }
+ // 查询服务流数量
+ IMediaServerItem finalServerItem = serverItem;
+ zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{
+ Integer code = mediaList.getInteger("code");
+ if (code == 0) {
+ JSONArray data = mediaList.getJSONArray("data");
+ if (data != null) {
+ zlmServerStatus.put(finalServerItem.getId(),data.size());
+ }else {
+ zlmServerStatus.put(finalServerItem.getId(),0);
+ }
+
+ }
+ }));
+
+ }
+
+ /**
+ * 更新缓存
+ * @param mediaServerItem zlm服务
+ * @param count 在线数
+ * @param online 在线状态
+ */
+ @Override
+ public void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean online) {
+ if (mediaServerItem != null) {
+ zlmServers.put(mediaServerItem.getId(), mediaServerItem);
+ Collection values = zlmServerStatus.values();
+ if (online != null && count != null) {
+ zlmServerStatus.put(mediaServerItem.getId(), count);
+ }
+ }
+ }
+
+ @Override
+ public void addCount(String mediaServerId) {
+ if (zlmServerStatus.get(mediaServerId) != null) {
+ zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) + 1);
+ }
+ }
+
+ @Override
+ public void removeCount(String mediaServerId) {
+ if (zlmServerStatus.get(mediaServerId) != null) {
+ zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) - 1);
+ }
+ }
+
+ /**
+ * 获取负载最低的节点
+ * @return MediaServerItem
+ */
+ @Override
+ public IMediaServerItem getMediaServerForMinimumLoad() {
+ int mediaCount = -1;
+ String key = null;
+ System.out.println(JSON.toJSONString(zlmServerStatus));
+ if (zlmServerStatus.size() == 1) {
+ Map.Entry entry = zlmServerStatus.entrySet().iterator().next();
+ key= (String) entry.getKey();
+ }else {
+ for (String id : zlmServerStatus.keySet()) {
+ if (key == null) {
+ key = id;
+ mediaCount = zlmServerStatus.get(id);
+ }
+ if (zlmServerStatus.get(id) == 0) {
+ key = id;
+ break;
+ }else if (mediaCount >= zlmServerStatus.get(id)){
+ mediaCount = zlmServerStatus.get(id);
+ key = id;
+ }
+ }
+ }
+
+ if (key == null) {
+ logger.info("获取负载最低的节点时无在线节点");
+ return null;
+ }else{
+ return zlmServers.get(key);
+ }
+ }
+
+ /**
+ * 对zlm服务器进行基础配置
+ * @param mediaServerItem 服务ID
+ */
+ @Override
+ public void setZLMConfig(IMediaServerItem mediaServerItem) {
+ logger.info("[ {} ]-[ {}:{} ]设置zlm",
+ mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
+ String protocol = sslEnabled ? "https" : "http";
+ String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort);
+ String recordHookPrex = null;
+ if (mediaServerItem.getRecordAssistPort() != 0) {
+ recordHookPrex = String.format("http://127.0.0.1:%s/api/record", mediaServerItem.getRecordAssistPort());
+ }
+ Map param = new HashMap<>();
+ param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline
+ param.put("ffmpeg.cmd","%s -fflags nobuffer -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s");
+ param.put("hook.enable","1");
+ param.put("hook.on_flow_report","");
+ param.put("hook.on_play",String.format("%s/on_play", hookPrex));
+ param.put("hook.on_http_access","");
+ param.put("hook.on_publish", String.format("%s/on_publish", hookPrex));
+ param.put("hook.on_record_mp4",recordHookPrex != null? String.format("%s/on_record_mp4", recordHookPrex): "");
+ 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", hookPrex));
+ param.put("hook.on_shell_login",String.format("%s/on_shell_login", hookPrex));
+ param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrex));
+ param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex));
+ param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
+ param.put("hook.timeoutSec","20");
+ param.put("general.streamNoneReaderDelayMS",mediaServerItem.getStreamNoneReaderDelayMS());
+
+ JSONObject responseJSON = zlmresTfulUtils.setServerConfig(mediaServerItem, param);
+
+ if (responseJSON != null && responseJSON.getInteger("code") == 0) {
+ logger.info("[ {} ]-[ {}:{} ]设置zlm成功",
+ mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
+ }else {
+ logger.info("[ {} ]-[ {}:{} ]设置zlm失败" + responseJSON.getString("msg"),
+ mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
+ }
+ }
+}
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 e40f4b17..465ca88a 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
@@ -6,6 +6,9 @@ import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.service.IMediaService;
@@ -21,30 +24,53 @@ public class MediaServiceImpl implements IMediaService {
@Autowired
private IVideoManagerStorager storager;
+ @Autowired
+ private IMediaServerService mediaServerService;
+
@Autowired
private ZLMRESTfulUtils zlmresTfulUtils;
@Override
- public StreamInfo getStreamInfoByAppAndStream(String app, String stream, JSONArray tracks) {
- return getStreamInfoByAppAndStream(app, stream, tracks, null);
+ public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks) {
+ return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null);
}
@Override
- public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream) {
- return getStreamInfoByAppAndStreamWithCheck(app, stream, null);
+ public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) {
+ StreamInfo streamInfo = null;
+ IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
+ if (mediaInfo == null) {
+ return streamInfo;
+ }
+ 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 = JSON.parseObject(JSON.toJSONString(data.get(0)), JSONObject.class);
+ JSONArray tracks = mediaJSON.getJSONArray("tracks");
+ streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks);
+ }
+ }
+ return streamInfo;
}
@Override
- public StreamInfo getStreamInfoByAppAndStream(String app, String stream, JSONArray tracks, String addr) {
- ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
+ public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId) {
+ return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null);
+ }
+
+ @Override
+ public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr) {
StreamInfo streamInfoResult = new StreamInfo();
streamInfoResult.setStreamId(stream);
streamInfoResult.setApp(app);
if (addr == null) {
addr = mediaInfo.getStreamIp();
}
+ streamInfoResult.setMediaServerId(mediaInfo.getId());
streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s", addr, mediaInfo.getRtmpPort(), app, stream));
streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s", addr, mediaInfo.getRtspPort(), app, stream));
streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.flv", addr, mediaInfo.getHttpPort(), app, stream));
@@ -60,19 +86,4 @@ public class MediaServiceImpl implements IMediaService {
return streamInfoResult;
}
- @Override
- public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String addr) {
- StreamInfo streamInfo = null;
- JSONObject mediaList = zlmresTfulUtils.getMediaList(app, stream);
- if (mediaList != null) {
- if (mediaList.getInteger("code") == 0) {
- JSONArray data = mediaList.getJSONArray("data");
- if (data == null) return null;
- JSONObject mediaJSON = JSON.parseObject(JSON.toJSONString(data.get(0)), JSONObject.class);
- JSONArray tracks = mediaJSON.getJSONArray("tracks");
- streamInfo = getStreamInfoByAppAndStream(app, stream, tracks, addr);
- }
- }
- return streamInfo;
- }
}
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 172d9803..85a4f48c 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -14,6 +14,9 @@ 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.ZLMHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
@@ -59,6 +62,9 @@ public class PlayServiceImpl implements IPlayService {
@Autowired
private IMediaService mediaService;
+ @Autowired
+ private IMediaServerService mediaServerService;
+
@Autowired
private VideoStreamSessionManager streamSession;
@@ -67,8 +73,18 @@ public class PlayServiceImpl implements IPlayService {
@Override
- public PlayResult play(String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) {
+ public PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) {
PlayResult playResult = new PlayResult();
+ if (mediaServerItem == null) {
+ RequestMessage msg = new RequestMessage();
+ msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid());
+ WVPResult wvpResult = new WVPResult();
+ wvpResult.setCode(-1);
+ wvpResult.setMsg("未找到可用的zlm");
+ msg.setData(wvpResult);
+ resultHolder.invokeResult(msg);
+ return playResult;
+ }
Device device = storager.queryVideoDevice(deviceId);
StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
playResult.setDevice(device);
@@ -82,7 +98,7 @@ public class PlayServiceImpl implements IPlayService {
result.onTimeout(()->{
logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
// 释放rtpserver
- cmder.closeRTPServer(playResult.getDevice(), channelId);
+ mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid());
WVPResult wvpResult = new WVPResult();
@@ -115,9 +131,10 @@ public class PlayServiceImpl implements IPlayService {
WVPResult wvpResult = (WVPResult)responseEntity.getBody();
if (wvpResult.getCode() == 0) {
StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
+ IMediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
String streamUrl = streamInfoForSuccess.getFmp4();
// 请求截图
- zlmresTfulUtils.getSnap(streamUrl, 15, 1, path, fileName);
+ zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
}
}
} catch (FileNotFoundException e) {
@@ -126,17 +143,17 @@ public class PlayServiceImpl implements IPlayService {
});
if (streamInfo == null) {
// 发送点播消息
- cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
+ cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInUse, JSONObject response) -> {
logger.info("收到订阅消息: " + response.toJSONString());
- onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
+ onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid.toString());
if (hookEvent != null) {
- hookEvent.response(response);
+ hookEvent.response(mediaServerItem, response);
}
- }, event -> {
+ }, (event) -> {
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
Response response = event.getResponse();
- cmder.closeRTPServer(playResult.getDevice(), channelId);
+ mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
WVPResult wvpResult = new WVPResult();
wvpResult.setCode(-1);
wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
@@ -158,7 +175,10 @@ public class PlayServiceImpl implements IPlayService {
resultHolder.invokeResult(msg);
return playResult;
}
- JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
+ String mediaServerId = streamInfo.getMediaServerId();
+ IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
+
+ JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId);
if (rtpInfo != null && rtpInfo.getBoolean("exist")) {
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
@@ -171,16 +191,16 @@ public class PlayServiceImpl implements IPlayService {
resultHolder.invokeResult(msg);
if (hookEvent != null) {
- hookEvent.response(JSONObject.parseObject(JSON.toJSONString(streamInfo)));
+ hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo)));
}
} else {
redisCatchStorage.stopPlay(streamInfo);
storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
- cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
+ cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> {
logger.info("收到订阅消息: " + response.toJSONString());
- onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
- }, event -> {
- cmder.closeRTPServer(playResult.getDevice(), channelId);
+ onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());
+ }, (event) -> {
+ mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
Response response = event.getResponse();
@@ -198,10 +218,10 @@ public class PlayServiceImpl implements IPlayService {
}
@Override
- public void onPublishHandlerForPlay(JSONObject resonse, String deviceId, String channelId, String uuid) {
+ public void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
- StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid);
+ StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);
if (streamInfo != null) {
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
if (deviceChannel != null) {
@@ -234,10 +254,26 @@ public class PlayServiceImpl implements IPlayService {
}
@Override
- public void onPublishHandlerForPlayBack(JSONObject resonse, String deviceId, String channelId, String uuid) {
+ public IMediaServerItem getNewMediaServerItem(Device device) {
+ if (device == null) return null;
+ String mediaServerId = device.getMediaServerId();
+ IMediaServerItem mediaServerItem = null;
+ if (mediaServerId == null) {
+ mediaServerItem = mediaServerService.getMediaServerForMinimumLoad();
+ }else {
+ mediaServerItem = mediaServerService.getOne(mediaServerId);
+ }
+ if (mediaServerItem == null) {
+ logger.warn("点播时未找到可使用的ZLM...");
+ }
+ return mediaServerItem;
+ }
+
+ @Override
+ public void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
RequestMessage msg = new RequestMessage();
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
- StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid);
+ StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);
if (streamInfo != null) {
redisCatchStorage.startPlayback(streamInfo);
msg.setData(JSON.toJSONString(streamInfo));
@@ -249,10 +285,10 @@ public class PlayServiceImpl implements IPlayService {
}
}
- public StreamInfo onPublishHandler(JSONObject resonse, String deviceId, String channelId, String uuid) {
+ public StreamInfo onPublishHandler(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
String streamId = resonse.getString("stream");
JSONArray tracks = resonse.getJSONArray("tracks");
- StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream("rtp", streamId, tracks);
+ StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks);
streamInfo.setDeviceID(deviceId);
streamInfo.setChannelId(channelId);
return streamInfo;
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 2eb99b82..fe49c3b9 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -2,10 +2,12 @@ package com.genersoft.iot.vmp.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
-import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import com.genersoft.iot.vmp.service.IGbStreamService;
+import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
@@ -13,6 +15,8 @@ import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper;
import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper;
import com.genersoft.iot.vmp.service.IStreamProxyService;
import com.github.pagehelper.PageInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -25,6 +29,8 @@ import java.util.List;
@Service
public class StreamProxyServiceImpl implements IStreamProxyService {
+ private final static Logger logger = LoggerFactory.getLogger(StreamProxyServiceImpl.class);
+
@Autowired
private IVideoManagerStorager videoManagerStorager;
@@ -32,7 +38,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
private IRedisCatchStorage redisCatchStorage;
@Autowired
- private ZLMRESTfulUtils zlmresTfulUtils;
+ private ZLMRESTfulUtils zlmresTfulUtils;;
@Autowired
private StreamProxyMapper streamProxyMapper;
@@ -46,15 +52,28 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
@Autowired
private IGbStreamService gbStreamService;
+ @Autowired
+ private IMediaServerService mediaServerService;
+
@Override
public String save(StreamProxyItem param) {
- ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
+ IMediaServerItem mediaInfo;
+ if ("auto".equals(param.getMediaServerId())){
+ mediaInfo = mediaServerService.getMediaServerForMinimumLoad();
+ }else {
+ mediaInfo = mediaServerService.getOne(param.getMediaServerId());
+ }
+ if (mediaInfo == null) {
+ logger.warn("保存代理未找到在线的ZLM...");
+ return "保存失败";
+ }
String dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(),
param.getStream() );
param.setDst_url(dstUrl);
StringBuffer result = new StringBuffer();
boolean streamLive = false;
+ param.setMediaServerId(mediaInfo.getId());
// 更新
if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) {
if (videoManagerStorager.updateStreamProxy(param)) {
@@ -81,6 +100,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
videoManagerStorager.updateStreamProxy(param);
}
}
+ }else {
+ result.append("保存失败");
}
}
@@ -99,11 +120,18 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
@Override
public JSONObject addStreamProxyToZlm(StreamProxyItem param) {
JSONObject result = null;
+ IMediaServerItem mediaServerItem = null;
+ if (param.getMediaServerId() == null) {
+ logger.warn("添加代理时MediaServerId 为null");
+ return null;
+ }else {
+ mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+ }
if ("default".equals(param.getType())){
- result = zlmresTfulUtils.addStreamProxy(param.getApp(), param.getStream(), param.getUrl(),
+ result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl(),
param.isEnable_hls(), param.isEnable_mp4(), param.getRtp_type());
}else if ("ffmpeg".equals(param.getType())) {
- result = zlmresTfulUtils.addFFmpegSource(param.getSrc_url(), param.getDst_url(),
+ result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrc_url(), param.getDst_url(),
param.getTimeout_ms() + "", param.isEnable_hls(), param.isEnable_mp4(),
param.getFfmpeg_cmd_key());
}
@@ -112,8 +140,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
@Override
public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) {
- JSONObject result = zlmresTfulUtils.closeStreams(param.getApp(), param.getStream());
-
+ if (param ==null) return null;
+ IMediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+ JSONObject result = zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream());
return result;
}
@@ -124,17 +153,18 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
@Override
public void del(String app, String stream) {
- StreamProxyItem streamProxyItem = new StreamProxyItem();
- streamProxyItem.setApp(app);
- streamProxyItem.setStream(stream);
- JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyItem);
- if (jsonObject.getInteger("code") == 0) {
+ StreamProxyItem streamProxyItem = videoManagerStorager.queryStreamProxy(app, stream);
+ if (streamProxyItem != null) {
videoManagerStorager.deleteStreamProxy(app, stream);
- // 如果关联了国标那么移除关联
- gbStreamMapper.del(app, stream);
- platformGbStreamMapper.delByAppAndStream(app, stream);
- // TODO 如果关联的推流, 那么状态设置为离线
+ JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyItem);
+ if (jsonObject != null && jsonObject.getInteger("code") == 0) {
+ // 如果关联了国标那么移除关联
+ gbStreamMapper.del(app, stream);
+ platformGbStreamMapper.delByAppAndStream(app, stream);
+ // TODO 如果关联的推流, 那么状态设置为离线
+ }
}
+
}
@Override
@@ -168,9 +198,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
}
@Override
- public JSONObject getFFmpegCMDs() {
+ public JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem) {
JSONObject result = new JSONObject();
- JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig();
+ JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0
&& mediaServerConfigResuly.getJSONArray("data").size() > 0){
JSONObject mediaServerConfig = mediaServerConfigResuly.getJSONArray("data").getJSONObject(0);
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 7ebfb54a..3692e549 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -5,9 +5,13 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
+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.service.IStreamPushService;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
import com.genersoft.iot.vmp.storager.dao.StreamPushMapper;
import com.github.pagehelper.PageHelper;
@@ -32,8 +36,14 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Autowired
private ZLMRESTfulUtils zlmresTfulUtils;
+ @Autowired
+ private IRedisCatchStorage redisCatchStorage;
+
+ @Autowired
+ private IMediaServerService mediaServerService;
+
@Override
- public List handleJSON(String jsonData) {
+ public List handleJSON(String jsonData, IMediaServerItem mediaServerItem) {
if (jsonData == null) return null;
Map result = new HashMap<>();
@@ -50,6 +60,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
if (streamPushItem == null) {
streamPushItem = new StreamPushItem();
streamPushItem.setApp(item.getApp());
+ streamPushItem.setMediaServerId(mediaServerItem.getId());
streamPushItem.setStream(item.getStream());
streamPushItem.setAliveSecond(item.getAliveSecond());
streamPushItem.setCreateStamp(item.getCreateStamp());
@@ -87,7 +98,8 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Override
public boolean removeFromGB(GbStream stream) {
int del = gbStreamMapper.del(stream.getApp(), stream.getStream());
- JSONObject mediaList = zlmresTfulUtils.getMediaList(stream.getApp(), stream.getStream());
+ IMediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId());
+ JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream());
if (mediaList == null) {
streamPushMapper.del(stream.getApp(), stream.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 56c31c18..a4edb088 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -2,10 +2,11 @@ package com.genersoft.iot.vmp.storager;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
-import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import java.util.List;
import java.util.Map;
@@ -40,19 +41,6 @@ public interface IRedisCatchStorage {
StreamInfo queryPlayByDevice(String deviceId, String channelId);
- /**
- * 更新流媒体信息
- * @param ZLMServerConfig
- * @return
- */
- boolean updateMediaInfo(ZLMServerConfig ZLMServerConfig);
-
- /**
- * 获取流媒体信息
- * @return
- */
- ZLMServerConfig getMediaInfo();
-
Map queryPlayByDeviceId(String deviceId);
boolean startPlayback(StreamInfo stream);
@@ -114,6 +102,13 @@ public interface IRedisCatchStorage {
*/
void clearCatchByDeviceId(String deviceId);
+ /**
+ * 获取mediaServer节点
+ * @param mediaServerId
+ * @return
+ */
+// MediaServerItem getMediaInfo(String mediaServerId);
+
/**
* 设置所有设备离线
*/
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
index 5d838c5d..97c37944 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.storager;
import java.util.List;
import com.genersoft.iot.vmp.gb28181.bean.*;
+import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
+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.StreamPushItem;
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
@@ -365,4 +367,12 @@ public interface IVideoManagerStorager {
* @param online
*/
void updateParentPlatformStatus(String platformGbID, boolean online);
+
+ /**
+ * 更新媒体节点
+ * @param mediaServerItem
+ */
+ void updateMediaServer(MediaServerItem mediaServerItem);
+
+ List getStreamProxyListForEnableInMediaServer(String id, boolean b);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
index 80397d2c..230afbc9 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
@@ -12,9 +12,10 @@ import java.util.List;
public interface GbStreamMapper {
@Insert("INSERT INTO gb_stream (app, stream, gbId, name, " +
- "longitude, latitude, streamType, status) VALUES" +
+ "longitude, latitude, streamType, mediaServerId, status) VALUES" +
"('${app}', '${stream}', '${gbId}', '${name}', " +
- "'${longitude}', '${latitude}', '${streamType}', ${status})")
+ "'${longitude}', '${latitude}', '${streamType}', " +
+ "'${mediaServerId}', ${status})")
int add(GbStream gbStream);
@Update("UPDATE gb_stream " +
@@ -25,6 +26,7 @@ public interface GbStreamMapper {
"streamType=#{streamType}," +
"longitude=#{longitude}, " +
"latitude=#{latitude}," +
+ "mediaServerId=#{mediaServerId}," +
"status=${status} " +
"WHERE app=#{app} AND stream=#{stream} AND gbId=#{gbId}")
int update(GbStream gbStream);
@@ -52,4 +54,7 @@ public interface GbStreamMapper {
"SET status=${status} " +
"WHERE app=#{app} AND stream=#{stream}")
void setStatus(String app, String stream, boolean status);
+
+ @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream WHERE mediaServerId=#{mediaServerId} ")
+ List selectAllByMediaServerId(String mediaServerId);
}
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
new file mode 100644
index 00000000..475ec6d2
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
@@ -0,0 +1,99 @@
+package com.genersoft.iot.vmp.storager.dao;
+
+import com.genersoft.iot.vmp.conf.MediaConfig;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+
+@Mapper
+@Repository
+public interface MediaServerMapper {
+
+ @Insert("INSERT INTO media_server (" +
+ "id, " +
+ "ip, " +
+ "hookIp, " +
+ "sdpIp, " +
+ "streamIp, " +
+ "httpPort, " +
+ "httpSSlPort, " +
+ "rtmpPort, " +
+ "rtmpSSlPort, " +
+ "rtpProxyPort, " +
+ "rtspPort, " +
+ "rtspSSLPort, " +
+ "autoConfig, " +
+ "secret, " +
+ "streamNoneReaderDelayMS, " +
+ "rtpEnable, " +
+ "rtpPortRange, " +
+ "recordAssistPort, " +
+ "createTime, " +
+ "updateTime" +
+ ") VALUES " +
+ "(" +
+ "'${id}', " +
+ "'${ip}', " +
+ "'${hookIp}', " +
+ "'${sdpIp}', " +
+ "'${streamIp}', " +
+ "${httpPort}, " +
+ "${httpSSlPort}, " +
+ "${rtmpPort}, " +
+ "${rtmpSSlPort}, " +
+ "${rtpProxyPort}, " +
+ "${rtspPort}, " +
+ "${rtspSSLPort}, " +
+ "${autoConfig}, " +
+ "'${secret}', " +
+ "${streamNoneReaderDelayMS}, " +
+ "${rtpEnable}, " +
+ "'${rtpPortRange}', " +
+ "${recordAssistPort}, " +
+ "'${createTime}', " +
+ "'${updateTime}')")
+ int add(IMediaServerItem mediaServerItem);
+
+ @Update(value = {" "})
+ int update(IMediaServerItem mediaServerItem);
+
+ @Select("SELECT * FROM media_server WHERE id='${id}'")
+ MediaServerItem queryOne(String id);
+
+ @Select("SELECT * FROM media_server")
+ List queryAll();
+
+ @Select("DELETE FROM media_server WHERE id='${id}'")
+ int delOne(String secret);
+
+ @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}")
+ MediaServerItem queryOneByHostAndPort(String host, int port);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
index 3f53c362..7346da5c 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
@@ -10,10 +10,10 @@ import java.util.List;
@Repository
public interface StreamProxyMapper {
- @Insert("INSERT INTO stream_proxy (type, app, stream, url, src_url, dst_url, " +
- "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable) VALUES" +
- "('${type}','${app}', '${stream}', '${url}', '${src_url}', '${dst_url}', " +
- "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable} )")
+ @Insert("INSERT INTO stream_proxy (type, app, stream,mediaServerId, url, src_url, dst_url, " +
+ "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable, createTime) VALUES" +
+ "('${type}','${app}', '${stream}', '${mediaServerId}','${url}', '${src_url}', '${dst_url}', " +
+ "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable}, '${createTime}' )")
int add(StreamProxyItem streamProxyDto);
@Update("UPDATE stream_proxy " +
@@ -21,6 +21,7 @@ public interface StreamProxyMapper {
"app=#{app}," +
"stream=#{stream}," +
"url=#{url}, " +
+ "mediaServerId=#{mediaServerId}, " +
"src_url=#{src_url}," +
"dst_url=#{dst_url}, " +
"timeout_ms=#{timeout_ms}, " +
@@ -35,12 +36,17 @@ public interface StreamProxyMapper {
@Delete("DELETE FROM stream_proxy WHERE app=#{app} AND stream=#{stream}")
int del(String app, String stream);
- @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream")
+ @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream order by st.createTime desc")
List selectAll();
- @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.enable=${enable}")
+ @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.enable=${enable} order by st.createTime desc")
List selectForEnable(boolean enable);
- @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.app=#{app} AND st.stream=#{stream}")
+ @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.app=#{app} AND st.stream=#{stream} order by st.createTime desc")
StreamProxyItem selectOne(String app, String stream);
+
+ @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " +
+ "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " +
+ "WHERE st.enable=${enable} and st.mediaServerId = '${id}' order by st.createTime desc")
+ List selectForEnableInMediaServer(String id, boolean enable);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
index 455aa2cf..41e4c44e 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
@@ -11,14 +11,15 @@ import java.util.List;
public interface StreamPushMapper {
@Insert("INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
- "createStamp, aliveSecond) VALUES" +
+ "createStamp, aliveSecond, mediaServerId) VALUES" +
"('${app}', '${stream}', '${totalReaderCount}', '${originType}', '${originTypeStr}', " +
- "'${createStamp}', '${aliveSecond}' )")
+ "'${createStamp}', '${aliveSecond}', '${mediaServerId}' )")
int add(StreamPushItem streamPushItem);
@Update("UPDATE stream_push " +
"SET app=#{app}," +
"stream=#{stream}," +
+ "mediaServerId=#{mediaServerId}," +
"totalReaderCount=#{totalReaderCount}, " +
"originType=#{originType}," +
"originTypeStr=#{originTypeStr}, " +
@@ -41,10 +42,10 @@ public interface StreamPushMapper {
@Insert("")
void addAll(List streamPushItems);
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 86909c76..eafb8a0b 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -5,6 +5,8 @@ import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import com.genersoft.iot.vmp.gb28181.bean.*;
+import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
@@ -87,26 +89,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
return (StreamInfo)redis.get(playLeys.get(0).toString());
}
- /**
- * 更新流媒体信息
- * @param ZLMServerConfig
- * @return
- */
- @Override
- public boolean updateMediaInfo(ZLMServerConfig ZLMServerConfig) {
- ZLMServerConfig.setUpdateTime(format.format(new Date(System.currentTimeMillis())));
- return redis.set(VideoManagerConstants.MEDIA_SERVER_PREFIX, ZLMServerConfig);
- }
-
- /**
- * 获取流媒体信息
- * @return
- */
- @Override
- public ZLMServerConfig getMediaInfo() {
- return (ZLMServerConfig)redis.get(VideoManagerConstants.MEDIA_SERVER_PREFIX);
- }
-
@Override
public Map queryPlayByDeviceId(String deviceId) {
Map streamInfos = new HashMap<>();
@@ -297,7 +279,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
@Override
public void outlineForAll() {
- List