Commit 89a9ab4534f10a224f70e546db838423e84a1965

Authored by 64850858
1 parent 06d78575

添加zlm集群支持

Showing 54 changed files with 2084 additions and 739 deletions

Too many changes to show.

To preserve performance only 54 of 75 files are displayed.

@@ -196,6 +196,16 @@ @@ -196,6 +196,16 @@
196 <version>1.12</version> 196 <version>1.12</version>
197 </dependency> 197 </dependency>
198 198
  199 +<!-- &lt;!&ndash; 检测文件编码 &ndash;&gt;-->
  200 +<!-- &lt;!&ndash; https://mvnrepository.com/artifact/cpdetector/cpdetector &ndash;&gt;-->
  201 +<!-- <dependency>-->
  202 +<!-- <groupId>cpdetector</groupId>-->
  203 +<!-- <artifactId>cpdetector</artifactId>-->
  204 +<!-- <version>1.0.8</version>-->
  205 +<!-- </dependency>-->
  206 +
  207 +
  208 +
199 <!-- onvif协议栈 --> 209 <!-- onvif协议栈 -->
200 <dependency> 210 <dependency>
201 <groupId>be.teletask</groupId> 211 <groupId>be.teletask</groupId>
sql/mysql.sql
@@ -138,6 +138,7 @@ create table stream_proxy @@ -138,6 +138,7 @@ create table stream_proxy
138 timeout_ms int null, 138 timeout_ms int null,
139 ffmpeg_cmd_key varchar(255) null, 139 ffmpeg_cmd_key varchar(255) null,
140 rtp_type varchar(50) null, 140 rtp_type varchar(50) null,
  141 + mediaServerId varchar(50) null,
141 enable_hls bit(1) null, 142 enable_hls bit(1) null,
142 enable_mp4 bit(1) null, 143 enable_mp4 bit(1) null,
143 enable bit(1) not null, 144 enable bit(1) not null,
@@ -166,4 +167,28 @@ create table user @@ -166,4 +167,28 @@ create table user
166 create_time varchar(50) not null 167 create_time varchar(50) not null
167 ); 168 );
168 169
169 -insert into user (username, password, roleId, create_time) values ('admin', '21232f297a57a5a743894a0e4a801fc3', '0', '2021-04-13 14:14:57');  
170 \ No newline at end of file 170 \ No newline at end of file
  171 +insert into user (username, password, roleId, create_time) values ('admin', '21232f297a57a5a743894a0e4a801fc3', '0', '2021-04-13 14:14:57');
  172 +
  173 +create table media_server (
  174 + id varchar(255)
  175 + primary key,
  176 + ip varchar(50) NOT NULL,
  177 + hookIp varchar(50) NOT NULL,
  178 + sdpIp varchar(50) NOT NULL,
  179 + streamIp varchar(50) NOT NULL,
  180 + httpPort int NOT NULL,
  181 + httpSSlPort int NOT NULL,
  182 + rtmpPort int NOT NULL,
  183 + rtmpSSlPort int NOT NULL,
  184 + rtpProxyPort int NOT NULL,
  185 + rtspPort int NOT NULL,
  186 + rtspSSLPort int NOT NULL,
  187 + autoConfig int NOT NULL,
  188 + secret varchar(50) NOT NULL,
  189 + streamNoneReaderDelayMS int NOT NULL,
  190 + rtpEnable int NOT NULL,
  191 + rtpPortRange varchar(50) NOT NULL,
  192 + recordAssistPort int NOT NULL,
  193 + createTime varchar(50) not null,
  194 + updateTime varchar(50) not null
  195 +);
171 \ No newline at end of file 196 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
@@ -19,6 +19,7 @@ public class StreamInfo { @@ -19,6 +19,7 @@ public class StreamInfo {
19 private String rtmp; 19 private String rtmp;
20 private String rtsp; 20 private String rtsp;
21 private String rtc; 21 private String rtc;
  22 + private String mediaServerId;
22 private JSONArray tracks; 23 private JSONArray tracks;
23 24
24 public static class TransactionInfo{ 25 public static class TransactionInfo{
@@ -165,4 +166,12 @@ public class StreamInfo { @@ -165,4 +166,12 @@ public class StreamInfo {
165 public void setTransactionInfo(TransactionInfo transactionInfo) { 166 public void setTransactionInfo(TransactionInfo transactionInfo) {
166 this.transactionInfo = transactionInfo; 167 this.transactionInfo = transactionInfo;
167 } 168 }
  169 +
  170 + public String getMediaServerId() {
  171 + return mediaServerId;
  172 + }
  173 +
  174 + public void setMediaServerId(String mediaServerId) {
  175 + this.mediaServerId = mediaServerId;
  176 + }
168 } 177 }
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -10,33 +10,31 @@ public class VideoManagerConstants { @@ -10,33 +10,31 @@ public class VideoManagerConstants {
10 10
11 public static final String WVP_SERVER_PREFIX = "VMP_wvp_server"; 11 public static final String WVP_SERVER_PREFIX = "VMP_wvp_server";
12 12
13 - public static final String MEDIA_SERVER_PREFIX = "VMP_media_server"; 13 + public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_";
14 14
15 - public static final String MEDIA_STREAM_PREFIX = "VMP_media_stream"; 15 + public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM";
16 16
17 - public static final String DEVICE_PREFIX = "VMP_device_"; 17 + public static final String DEVICE_PREFIX = "VMP_DEVICE_";
18 18
19 - public static final String CACHEKEY_PREFIX = "VMP_channel_"; 19 + public static final String CACHEKEY_PREFIX = "VMP_CHANNEL_";
20 20
21 public static final String KEEPLIVEKEY_PREFIX = "VMP_keeplive_"; 21 public static final String KEEPLIVEKEY_PREFIX = "VMP_keeplive_";
22 22
23 - public static final String PLAYER_PREFIX = "VMP_player_"; 23 + public static final String PLAYER_PREFIX = "VMP_PLAYER_";
24 24
25 - public static final String PLAY_BLACK_PREFIX = "VMP_playback_"; 25 + public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_";
26 26
27 - public static final String PLATFORM_PREFIX = "VMP_platform"; 27 + public static final String PLATFORM_KEEPLIVEKEY_PREFIX = "VMP_PLATFORM_KEEPLIVE_";
28 28
29 - public static final String PLATFORM_KEEPLIVEKEY_PREFIX = "VMP_platform_keeplive_"; 29 + public static final String PLATFORM_CATCH_PREFIX = "VMP_PLATFORM_CATCH_";
30 30
31 - public static final String PLATFORM_CATCH_PREFIX = "VMP_platform_catch_"; 31 + public static final String PLATFORM_REGISTER_PREFIX = "VMP_PLATFORM_REGISTER_";
32 32
33 - public static final String PLATFORM_REGISTER_PREFIX = "VMP_platform_register_"; 33 + public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_PLATFORM_REGISTER_INFO_";
34 34
35 - public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_platform_register_info_"; 35 + public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_PLATFORM_SEND_RTP_INFO_";
36 36
37 - public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_platform_send_rtp_info_";  
38 -  
39 - public static final String Pattern_Topic = "VMP_keeplive_platform_"; 37 + public static final String Pattern_Topic = "VMP_KEEPLIVE_PLATFORM_";
40 38
41 public static final String EVENT_ONLINE_REGISTER = "1"; 39 public static final String EVENT_ONLINE_REGISTER = "1";
42 40
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
  3 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
3 import org.springframework.beans.factory.annotation.Value; 5 import org.springframework.beans.factory.annotation.Value;
4 import org.springframework.context.annotation.Configuration; 6 import org.springframework.context.annotation.Configuration;
5 import org.springframework.util.StringUtils; 7 import org.springframework.util.StringUtils;
6 8
7 @Configuration("mediaConfig") 9 @Configuration("mediaConfig")
8 -public class MediaConfig { 10 +public class MediaConfig implements IMediaServerItem {
  11 +
  12 + @Value("${media.id:}")
  13 + private String id;
9 14
10 @Value("${media.ip}") 15 @Value("${media.ip}")
11 private String ip; 16 private String ip;
@@ -25,22 +30,22 @@ public class MediaConfig { @@ -25,22 +30,22 @@ public class MediaConfig {
25 @Value("${media.http-port}") 30 @Value("${media.http-port}")
26 private Integer httpPort; 31 private Integer httpPort;
27 32
28 - @Value("${media.http-ssl-port:}") 33 + @Value("${media.http-ssl-port:0}")
29 private Integer httpSSlPort; 34 private Integer httpSSlPort;
30 35
31 - @Value("${media.rtmp-port:}") 36 + @Value("${media.rtmp-port:0}")
32 private Integer rtmpPort; 37 private Integer rtmpPort;
33 38
34 - @Value("${media.rtmp-ssl-port:}") 39 + @Value("${media.rtmp-ssl-port:0}")
35 private Integer rtmpSSlPort; 40 private Integer rtmpSSlPort;
36 41
37 - @Value("${media.rtp-proxy-port:}") 42 + @Value("${media.rtp-proxy-port:0}")
38 private Integer rtpProxyPort; 43 private Integer rtpProxyPort;
39 44
40 - @Value("${media.rtsp-port:}") 45 + @Value("${media.rtsp-port:0}")
41 private Integer rtspPort; 46 private Integer rtspPort;
42 47
43 - @Value("${media.rtsp-ssl-port:}") 48 + @Value("${media.rtsp-ssl-port:0}")
44 private Integer rtspSSLPort; 49 private Integer rtspSSLPort;
45 50
46 @Value("${media.auto-config:true}") 51 @Value("${media.auto-config:true}")
@@ -61,6 +66,23 @@ public class MediaConfig { @@ -61,6 +66,23 @@ public class MediaConfig {
61 @Value("${media.record-assist-port:0}") 66 @Value("${media.record-assist-port:0}")
62 private Integer recordAssistPort; 67 private Integer recordAssistPort;
63 68
  69 + private String updateTime;
  70 +
  71 + private String createTime;
  72 +
  73 + private boolean docker = false;
  74 +
  75 + private int count;
  76 +
  77 +
  78 + public String getId() {
  79 + return id;
  80 + }
  81 +
  82 + public void setId(String id) {
  83 + this.id = id;
  84 + }
  85 +
64 public String getIp() { 86 public String getIp() {
65 return ip; 87 return ip;
66 } 88 }
@@ -82,82 +104,114 @@ public class MediaConfig { @@ -82,82 +104,114 @@ public class MediaConfig {
82 this.hookIp = hookIp; 104 this.hookIp = hookIp;
83 } 105 }
84 106
85 - public String getSdpIp() {  
86 - if (StringUtils.isEmpty(sdpIp)){  
87 - return ip;  
88 - }else {  
89 - return sdpIp;  
90 - } 107 + public String getSipIp() {
  108 + return sipIp;
91 } 109 }
92 110
93 - public void setSdpIp(String sdpIp) {  
94 - this.sdpIp = sdpIp; 111 + public void setSipIp(String sipIp) {
  112 + this.sipIp = sipIp;
95 } 113 }
96 114
97 - public String getStreamIp() {  
98 - if (StringUtils.isEmpty(streamIp)){  
99 - return ip;  
100 - }else {  
101 - return streamIp;  
102 - } 115 + public void setSdpIp(String sdpIp) {
  116 + this.sdpIp = sdpIp;
103 } 117 }
104 118
105 public void setStreamIp(String streamIp) { 119 public void setStreamIp(String streamIp) {
106 this.streamIp = streamIp; 120 this.streamIp = streamIp;
107 } 121 }
108 122
109 - public Integer getHttpPort() { 123 + public int getHttpPort() {
110 return httpPort; 124 return httpPort;
111 } 125 }
112 126
  127 + @Override
  128 + public void setHttpPort(int httpPort) {
  129 +
  130 + }
  131 +
113 public void setHttpPort(Integer httpPort) { 132 public void setHttpPort(Integer httpPort) {
114 this.httpPort = httpPort; 133 this.httpPort = httpPort;
115 } 134 }
116 135
117 - public Integer getHttpSSlPort() { 136 + public int getHttpSSlPort() {
118 return httpSSlPort; 137 return httpSSlPort;
119 } 138 }
120 139
  140 + @Override
  141 + public void setHttpSSlPort(int httpSSlPort) {
  142 +
  143 + }
  144 +
121 public void setHttpSSlPort(Integer httpSSlPort) { 145 public void setHttpSSlPort(Integer httpSSlPort) {
122 this.httpSSlPort = httpSSlPort; 146 this.httpSSlPort = httpSSlPort;
123 } 147 }
124 148
125 - public Integer getRtmpPort() { 149 + public int getRtmpPort() {
126 return rtmpPort; 150 return rtmpPort;
127 } 151 }
128 152
  153 + @Override
  154 + public void setRtmpPort(int rtmpPort) {
  155 +
  156 + }
  157 +
129 public void setRtmpPort(Integer rtmpPort) { 158 public void setRtmpPort(Integer rtmpPort) {
130 this.rtmpPort = rtmpPort; 159 this.rtmpPort = rtmpPort;
131 } 160 }
132 161
133 - public Integer getRtmpSSlPort() { 162 + public int getRtmpSSlPort() {
134 return rtmpSSlPort; 163 return rtmpSSlPort;
135 } 164 }
136 165
  166 + @Override
  167 + public void setRtmpSSlPort(int rtmpSSlPort) {
  168 +
  169 + }
  170 +
137 public void setRtmpSSlPort(Integer rtmpSSlPort) { 171 public void setRtmpSSlPort(Integer rtmpSSlPort) {
138 this.rtmpSSlPort = rtmpSSlPort; 172 this.rtmpSSlPort = rtmpSSlPort;
139 } 173 }
140 174
141 - public Integer getRtpProxyPort() {  
142 - return rtpProxyPort; 175 + public int getRtpProxyPort() {
  176 + if (rtpProxyPort == null) {
  177 + return 0;
  178 + }else {
  179 + return rtpProxyPort;
  180 + }
  181 +
  182 + }
  183 +
  184 + @Override
  185 + public void setRtpProxyPort(int rtpProxyPort) {
  186 +
143 } 187 }
144 188
145 public void setRtpProxyPort(Integer rtpProxyPort) { 189 public void setRtpProxyPort(Integer rtpProxyPort) {
146 this.rtpProxyPort = rtpProxyPort; 190 this.rtpProxyPort = rtpProxyPort;
147 } 191 }
148 192
149 - public Integer getRtspPort() { 193 + public int getRtspPort() {
150 return rtspPort; 194 return rtspPort;
151 } 195 }
152 196
  197 + @Override
  198 + public void setRtspPort(int rtspPort) {
  199 +
  200 + }
  201 +
153 public void setRtspPort(Integer rtspPort) { 202 public void setRtspPort(Integer rtspPort) {
154 this.rtspPort = rtspPort; 203 this.rtspPort = rtspPort;
155 } 204 }
156 205
157 - public Integer getRtspSSLPort() { 206 + public int getRtspSSLPort() {
158 return rtspSSLPort; 207 return rtspSSLPort;
159 } 208 }
160 209
  210 + @Override
  211 + public void setRtspSSLPort(int rtspSSLPort) {
  212 +
  213 + }
  214 +
161 public void setRtspSSLPort(Integer rtspSSLPort) { 215 public void setRtspSSLPort(Integer rtspSSLPort) {
162 this.rtspSSLPort = rtspSSLPort; 216 this.rtspSSLPort = rtspSSLPort;
163 } 217 }
@@ -202,11 +256,101 @@ public class MediaConfig { @@ -202,11 +256,101 @@ public class MediaConfig {
202 this.rtpPortRange = rtpPortRange; 256 this.rtpPortRange = rtpPortRange;
203 } 257 }
204 258
205 - public Integer getRecordAssistPort() { 259 + public int getRecordAssistPort() {
206 return recordAssistPort; 260 return recordAssistPort;
207 } 261 }
208 262
  263 + @Override
  264 + public void setRecordAssistPort(int recordAssistPort) {
  265 +
  266 + }
  267 +
209 public void setRecordAssistPort(Integer recordAssistPort) { 268 public void setRecordAssistPort(Integer recordAssistPort) {
210 this.recordAssistPort = recordAssistPort; 269 this.recordAssistPort = recordAssistPort;
211 } 270 }
  271 +
  272 + @Override
  273 + public boolean isDocker() {
  274 + return docker;
  275 + }
  276 +
  277 + @Override
  278 + public void setDocker(boolean docker) {
  279 + this.docker = docker;
  280 + }
  281 +
  282 + public String getSdpIp() {
  283 + if (StringUtils.isEmpty(sdpIp)){
  284 + return ip;
  285 + }else {
  286 + return sdpIp;
  287 + }
  288 + }
  289 +
  290 + public String getStreamIp() {
  291 + if (StringUtils.isEmpty(streamIp)){
  292 + return ip;
  293 + }else {
  294 + return streamIp;
  295 + }
  296 + }
  297 +
  298 +
  299 +
  300 + public MediaServerItem getMediaSerItem(){
  301 + MediaServerItem mediaServerItem = new MediaServerItem();
  302 + mediaServerItem.setId(id);
  303 + mediaServerItem.setIp(ip);
  304 + mediaServerItem.setDocker(true);
  305 + mediaServerItem.setHookIp(hookIp);
  306 + mediaServerItem.setSdpIp(sdpIp);
  307 + mediaServerItem.setStreamIp(streamIp);
  308 + mediaServerItem.setHttpPort(httpPort);
  309 + mediaServerItem.setHttpSSlPort(httpSSlPort);
  310 + mediaServerItem.setRtmpPort(rtmpPort);
  311 + mediaServerItem.setRtmpSSlPort(rtmpSSlPort);
  312 + mediaServerItem.setRtpProxyPort(rtpProxyPort);
  313 + mediaServerItem.setRtspPort(rtspPort);
  314 + mediaServerItem.setRtspSSLPort(rtspSSLPort);
  315 + mediaServerItem.setAutoConfig(autoConfig);
  316 + mediaServerItem.setSecret(secret);
  317 + mediaServerItem.setStreamNoneReaderDelayMS(streamNoneReaderDelayMS);
  318 + mediaServerItem.setRtpEnable(rtpEnable);
  319 + mediaServerItem.setRtpPortRange(rtpPortRange);
  320 + mediaServerItem.setRecordAssistPort(recordAssistPort);
  321 + mediaServerItem.setCreateTime(createTime);
  322 + mediaServerItem.setUpdateTime(updateTime);
  323 + mediaServerItem.setCount(count);
  324 + return mediaServerItem;
  325 + }
  326 +
  327 + @Override
  328 + public String getUpdateTime() {
  329 + return updateTime;
  330 + }
  331 +
  332 + @Override
  333 + public void setUpdateTime(String updateTime) {
  334 + this.updateTime = updateTime;
  335 + }
  336 +
  337 + @Override
  338 + public String getCreateTime() {
  339 + return createTime;
  340 + }
  341 +
  342 + @Override
  343 + public void setCreateTime(String createTime) {
  344 + this.createTime = createTime;
  345 + }
  346 +
  347 + @Override
  348 + public int getCount() {
  349 + return count;
  350 + }
  351 +
  352 + @Override
  353 + public void setCount(int count) {
  354 + this.count = count;
  355 + }
212 } 356 }
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
  3 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  4 +import com.genersoft.iot.vmp.service.IMediaServerService;
  5 +import org.apache.catalina.connector.ClientAbortException;
  6 +import org.apache.http.HttpHost;
3 import org.apache.http.HttpRequest; 7 import org.apache.http.HttpRequest;
4 import org.apache.http.HttpResponse; 8 import org.apache.http.HttpResponse;
5 -import org.apache.catalina.connector.ClientAbortException;  
6 import org.mitre.dsmiley.httpproxy.ProxyServlet; 9 import org.mitre.dsmiley.httpproxy.ProxyServlet;
7 import org.slf4j.Logger; 10 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
9 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.beans.factory.annotation.Value;
10 import org.springframework.boot.web.servlet.ServletRegistrationBean; 14 import org.springframework.boot.web.servlet.ServletRegistrationBean;
11 import org.springframework.context.annotation.Bean; 15 import org.springframework.context.annotation.Bean;
12 import org.springframework.context.annotation.Configuration; 16 import org.springframework.context.annotation.Configuration;
@@ -24,13 +28,16 @@ public class ProxyServletConfig { @@ -24,13 +28,16 @@ public class ProxyServletConfig {
24 private final static Logger logger = LoggerFactory.getLogger(ProxyServletConfig.class); 28 private final static Logger logger = LoggerFactory.getLogger(ProxyServletConfig.class);
25 29
26 @Autowired 30 @Autowired
27 - private MediaConfig mediaConfig; 31 + private IMediaServerService mediaServerService;
  32 +
  33 + @Value("${server.port}")
  34 + private int serverPort;
28 35
29 @Bean 36 @Bean
30 public ServletRegistrationBean zlmServletRegistrationBean(){ 37 public ServletRegistrationBean zlmServletRegistrationBean(){
31 ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ZLMProxySerlet(),"/zlm/*"); 38 ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ZLMProxySerlet(),"/zlm/*");
32 servletRegistrationBean.setName("zlm_Proxy"); 39 servletRegistrationBean.setName("zlm_Proxy");
33 - servletRegistrationBean.addInitParameter("targetUri", String.format("http://%s:%s", mediaConfig.getIp(), mediaConfig.getHttpPort())); 40 + servletRegistrationBean.addInitParameter("targetUri", "http://127.0.0.1:6080");
34 servletRegistrationBean.addUrlMappings(); 41 servletRegistrationBean.addUrlMappings();
35 if (logger.isDebugEnabled()) { 42 if (logger.isDebugEnabled()) {
36 servletRegistrationBean.addInitParameter("log", "true"); 43 servletRegistrationBean.addInitParameter("log", "true");
@@ -38,24 +45,26 @@ public class ProxyServletConfig { @@ -38,24 +45,26 @@ public class ProxyServletConfig {
38 return servletRegistrationBean; 45 return servletRegistrationBean;
39 } 46 }
40 47
41 - class ZLMProxySerlet extends ProxyServlet{  
42 -  
43 -  
44 - 48 + class ZLMProxySerlet extends ProxyServlet{
45 @Override 49 @Override
46 protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { 50 protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
47 String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); 51 String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
48 - if (!StringUtils.isEmpty(queryStr)) {  
49 - queryStr += "&secret=" + mediaConfig.getSecret();  
50 - }else {  
51 - queryStr = "secret=" + mediaConfig.getSecret(); 52 + IMediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
  53 + if (mediaInfo != null) {
  54 + if (!StringUtils.isEmpty(queryStr)) {
  55 + queryStr += "&secret=" + mediaInfo.getSecret();
  56 + }else {
  57 + queryStr = "secret=" + mediaInfo.getSecret();
  58 + }
52 } 59 }
53 return queryStr; 60 return queryStr;
54 } 61 }
55 62
  63 + /**
  64 + * 异常处理
  65 + */
56 @Override 66 @Override
57 protected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResonse, Exception e){ 67 protected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResonse, Exception e){
58 - //System.out.println(e.getMessage());  
59 try { 68 try {
60 super.handleRequestException(proxyRequest, proxyResonse, e); 69 super.handleRequestException(proxyRequest, proxyResonse, e);
61 } catch (ServletException servletException) { 70 } catch (ServletException servletException) {
@@ -72,6 +81,64 @@ public class ProxyServletConfig { @@ -72,6 +81,64 @@ public class ProxyServletConfig {
72 logger.error("zlm 代理失败: ", e); 81 logger.error("zlm 代理失败: ", e);
73 } 82 }
74 } 83 }
  84 +
  85 + /**
  86 + * 对于为按照格式请求的可以直接返回404
  87 + */
  88 + @Override
  89 + protected String getTargetUri(HttpServletRequest servletRequest) {
  90 + String requestURI = servletRequest.getRequestURI();
  91 + IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
  92 +
  93 + String uri = null;
  94 + if (mediaInfo != null) {
  95 +// String realRequestURI = requestURI.substring(requestURI.indexOf(mediaInfo.getId())+ mediaInfo.getId().length());
  96 + uri = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getHttpPort());
  97 + }else {
  98 + uri = "http://127.0.0.1:" + serverPort +"/index/hook/null"; // 只是一个能返回404的请求而已, 其他的也可以
  99 + }
  100 + return uri;
  101 + }
  102 +
  103 + /**
  104 + * 动态替换请求目标
  105 + */
  106 + @Override
  107 + protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
  108 + String requestURI = servletRequest.getRequestURI();
  109 + IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
  110 + HttpHost host;
  111 + if (mediaInfo != null) {
  112 + host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort());
  113 + }else {
  114 + host = new HttpHost("127.0.0.1", serverPort);
  115 + }
  116 + return host;
  117 +
  118 + }
  119 +
  120 + /**
  121 + * 根据uri获取流媒体信息
  122 + */
  123 + IMediaServerItem getMediaInfoByUri(String uri){
  124 + String[] split = uri.split("/");
  125 + String mediaServerId = split[2];
  126 + return mediaServerService.getOne(mediaServerId);
  127 + }
  128 +
  129 + /**
  130 + * 去掉url中的标志信息
  131 + */
  132 + @Override
  133 + protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
  134 + String requestURI = servletRequest.getRequestURI();
  135 + IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
  136 + String url = super.rewriteUrlFromRequest(servletRequest);
  137 + if (mediaInfo == null) {
  138 + return url;
  139 + }
  140 + return url.replace(mediaInfo.getId() + "/", "");
  141 + }
75 } 142 }
76 143
77 } 144 }
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -95,20 +95,43 @@ public class SipLayer implements SipListener { @@ -95,20 +95,43 @@ public class SipLayer implements SipListener {
95 tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "TCP"); 95 tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "TCP");
96 tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); 96 tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
97 tcpSipProvider.addSipListener(this); 97 tcpSipProvider.addSipListener(this);
98 - logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getSipPort() + "}");  
99 - } catch (TransportNotSupportedException | InvalidArgumentException | TooManyListenersException | ObjectInUseException e) {  
100 - logger.error(String.format("创建SIP服务失败: %s", e.getMessage())); 98 + logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getSipPort() + "}");
  99 +// } catch (TransportNotSupportedException | InvalidArgumentException | TooManyListenersException | ObjectInUseException e) {
  100 +// logger.error(String.format("创建SIP服务失败: %s", e.getMessage()));
  101 +// }
  102 + } catch (TransportNotSupportedException e) {
  103 + e.printStackTrace();
  104 + } catch (InvalidArgumentException e) {
  105 + logger.error("无法使用 [ {}:{} ]作为SIP[ TCP ]服务,可排查: 1. sip.monitor-ip 是否为本机网卡IP; 2. sip.port 是否已被占用"
  106 + , sipConfig.getMonitorIp(), sipConfig.getSipPort());
  107 + } catch (TooManyListenersException e) {
  108 + e.printStackTrace();
  109 + } catch (ObjectInUseException e) {
  110 + e.printStackTrace();
101 } 111 }
102 return tcpSipProvider; 112 return tcpSipProvider;
103 } 113 }
104 114
105 @Bean("udpSipProvider") 115 @Bean("udpSipProvider")
106 @DependsOn("sipStack") 116 @DependsOn("sipStack")
107 - private SipProvider startUdpListener() throws Exception {  
108 - ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP");  
109 - SipProvider udpSipProvider = sipStack.createSipProvider(udpListeningPoint);  
110 - udpSipProvider.addSipListener(this);  
111 - logger.info("Sip Server UDP 启动成功 port {" + sipConfig.getSipPort() + "}"); 117 + private SipProvider startUdpListener() {
  118 + ListeningPoint udpListeningPoint = null;
  119 + SipProvider udpSipProvider = null;
  120 + try {
  121 + udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP");
  122 + udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
  123 + udpSipProvider.addSipListener(this);
  124 + } catch (TransportNotSupportedException e) {
  125 + e.printStackTrace();
  126 + } catch (InvalidArgumentException e) {
  127 + logger.error("无法使用 [ {}:{} ]作为SIP[ UDP ]服务,可排查: 1. sip.monitor-ip 是否为本机网卡IP; 2. sip.port 是否已被占用"
  128 + , sipConfig.getMonitorIp(), sipConfig.getSipPort());
  129 + } catch (TooManyListenersException e) {
  130 + e.printStackTrace();
  131 + } catch (ObjectInUseException e) {
  132 + e.printStackTrace();
  133 + }
  134 + logger.info("Sip Server UDP 启动成功 port [" + sipConfig.getMonitorIp() + ":" + sipConfig.getSipPort() + "]");
112 return udpSipProvider; 135 return udpSipProvider;
113 } 136 }
114 137
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -94,6 +94,11 @@ public class Device { @@ -94,6 +94,11 @@ public class Device {
94 */ 94 */
95 private String updateTime; 95 private String updateTime;
96 96
  97 + /**
  98 + * 设备使用的媒体id, 默认为null
  99 + */
  100 + private String mediaServerId;
  101 +
97 public String getDeviceId() { 102 public String getDeviceId() {
98 return deviceId; 103 return deviceId;
99 } 104 }
@@ -229,4 +234,12 @@ public class Device { @@ -229,4 +234,12 @@ public class Device {
229 public void setUpdateTime(String updateTime) { 234 public void setUpdateTime(String updateTime) {
230 this.updateTime = updateTime; 235 this.updateTime = updateTime;
231 } 236 }
  237 +
  238 + public String getMediaServerId() {
  239 + return mediaServerId;
  240 + }
  241 +
  242 + public void setMediaServerId(String mediaServerId) {
  243 + this.mediaServerId = mediaServerId;
  244 + }
232 } 245 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java
@@ -9,6 +9,7 @@ public class GbStream extends PlatformGbStream{ @@ -9,6 +9,7 @@ public class GbStream extends PlatformGbStream{
9 private String stream; 9 private String stream;
10 private String gbId; 10 private String gbId;
11 private String name; 11 private String name;
  12 + private String mediaServerId;
12 private double longitude; 13 private double longitude;
13 private double latitude; 14 private double latitude;
14 private String streamType; 15 private String streamType;
@@ -77,4 +78,12 @@ public class GbStream extends PlatformGbStream{ @@ -77,4 +78,12 @@ public class GbStream extends PlatformGbStream{
77 public void setStatus(boolean status) { 78 public void setStatus(boolean status) {
78 this.status = status; 79 this.status = status;
79 } 80 }
  81 +
  82 + public String getMediaServerId() {
  83 + return mediaServerId;
  84 + }
  85 +
  86 + public void setMediaServerId(String mediaServerId) {
  87 + this.mediaServerId = mediaServerId;
  88 + }
80 } 89 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
@@ -66,6 +66,11 @@ public class SendRtpItem { @@ -66,6 +66,11 @@ public class SendRtpItem {
66 */ 66 */
67 private int localPort; 67 private int localPort;
68 68
  69 + /**
  70 + * 使用的流媒体
  71 + */
  72 + private String mediaServerId;
  73 +
69 public String getIp() { 74 public String getIp() {
70 return ip; 75 return ip;
71 } 76 }
@@ -161,4 +166,12 @@ public class SendRtpItem { @@ -161,4 +166,12 @@ public class SendRtpItem {
161 public void setTcpActive(boolean tcpActive) { 166 public void setTcpActive(boolean tcpActive) {
162 this.tcpActive = tcpActive; 167 this.tcpActive = tcpActive;
163 } 168 }
  169 +
  170 + public String getMediaServerId() {
  171 + return mediaServerId;
  172 + }
  173 +
  174 + public void setMediaServerId(String mediaServerId) {
  175 + this.mediaServerId = mediaServerId;
  176 + }
164 } 177 }
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
@@ -6,6 +6,9 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; @@ -6,6 +6,9 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
6 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 6 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
8 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 8 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  9 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  10 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  11 +import com.genersoft.iot.vmp.service.IMediaServerService;
9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
10 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
11 import org.slf4j.Logger; 14 import org.slf4j.Logger;
@@ -32,6 +35,8 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf @@ -32,6 +35,8 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf
32 private IVideoManagerStorager storager; 35 private IVideoManagerStorager storager;
33 @Autowired 36 @Autowired
34 private IRedisCatchStorage redisCatchStorage; 37 private IRedisCatchStorage redisCatchStorage;
  38 + @Autowired
  39 + private IMediaServerService mediaServerService;
35 40
36 @Autowired 41 @Autowired
37 private SIPCommanderFroPlatform sipCommanderFroPlatform; 42 private SIPCommanderFroPlatform sipCommanderFroPlatform;
@@ -62,22 +67,24 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf @@ -62,22 +67,24 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf
62 logger.info("停止[ {} ]的所有推流", event.getPlatformGbID()); 67 logger.info("停止[ {} ]的所有推流", event.getPlatformGbID());
63 StringBuilder app = new StringBuilder(); 68 StringBuilder app = new StringBuilder();
64 StringBuilder stream = new StringBuilder(); 69 StringBuilder stream = new StringBuilder();
65 - for (int i = 0; i < sendRtpItems.size(); i++) { 70 + for (SendRtpItem sendRtpItem : sendRtpItems) {
66 if (app.length() != 0) { 71 if (app.length() != 0) {
67 app.append(","); 72 app.append(",");
68 } 73 }
69 - app.append(sendRtpItems.get(i).getApp()); 74 + app.append(sendRtpItem.getApp());
70 if (stream.length() != 0) { 75 if (stream.length() != 0) {
71 stream.append(","); 76 stream.append(",");
72 } 77 }
73 - stream.append(sendRtpItems.get(i).getStreamId());  
74 - redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItems.get(i).getChannelId()); 78 + stream.append(sendRtpItem.getStreamId());
  79 + redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId());
  80 + IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
  81 + Map<String, Object> param = new HashMap<>();
  82 + param.put("vhost", "__defaultVhost__");
  83 + param.put("app", app.toString());
  84 + param.put("stream", stream.toString());
  85 + zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
75 } 86 }
76 - Map<String, Object> param = new HashMap<>();  
77 - param.put("vhost","__defaultVhost__");  
78 - param.put("app", app.toString());  
79 - param.put("stream", stream.toString());  
80 - zlmrtpServerFactory.stopSendRtpStream(param); 87 +
81 88
82 } 89 }
83 90
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -9,6 +9,7 @@ import javax.sip.message.Response; @@ -9,6 +9,7 @@ import javax.sip.message.Response;
9 9
10 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 10 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
11 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 11 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  12 +import com.genersoft.iot.vmp.service.IMediaServerService;
12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; 14 import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
14 import com.genersoft.iot.vmp.service.IPlayService; 15 import com.genersoft.iot.vmp.service.IPlayService;
@@ -104,6 +105,9 @@ public class SIPProcessorFactory { @@ -104,6 +105,9 @@ public class SIPProcessorFactory {
104 @Autowired 105 @Autowired
105 private ZLMRTPServerFactory zlmrtpServerFactory; 106 private ZLMRTPServerFactory zlmrtpServerFactory;
106 107
  108 + @Autowired
  109 + private IMediaServerService mediaServerService;
  110 +
107 111
108 // 注:这里使用注解会导致循环依赖注入,暂用springBean 112 // 注:这里使用注解会导致循环依赖注入,暂用springBean
109 private SipProvider tcpSipProvider; 113 private SipProvider tcpSipProvider;
@@ -128,6 +132,7 @@ public class SIPProcessorFactory { @@ -128,6 +132,7 @@ public class SIPProcessorFactory {
128 processor.setStorager(storager); 132 processor.setStorager(storager);
129 processor.setRedisCatchStorage(redisCatchStorage); 133 processor.setRedisCatchStorage(redisCatchStorage);
130 processor.setZlmrtpServerFactory(zlmrtpServerFactory); 134 processor.setZlmrtpServerFactory(zlmrtpServerFactory);
  135 + processor.setMediaServerService(mediaServerService);
131 return processor; 136 return processor;
132 } else if (Request.REGISTER.equals(method)) { 137 } else if (Request.REGISTER.equals(method)) {
133 RegisterRequestProcessor processor = new RegisterRequestProcessor(); 138 RegisterRequestProcessor processor = new RegisterRequestProcessor();
@@ -148,6 +153,7 @@ public class SIPProcessorFactory { @@ -148,6 +153,7 @@ public class SIPProcessorFactory {
148 processor.setRequestEvent(evt); 153 processor.setRequestEvent(evt);
149 processor.setRedisCatchStorage(redisCatchStorage); 154 processor.setRedisCatchStorage(redisCatchStorage);
150 processor.setZlmrtpServerFactory(zlmrtpServerFactory); 155 processor.setZlmrtpServerFactory(zlmrtpServerFactory);
  156 + processor.setMediaServerService(mediaServerService);
151 return processor; 157 return processor;
152 } else if (Request.BYE.equals(method)) { 158 } else if (Request.BYE.equals(method)) {
153 ByeRequestProcessor processor = new ByeRequestProcessor(); 159 ByeRequestProcessor processor = new ByeRequestProcessor();
@@ -155,6 +161,7 @@ public class SIPProcessorFactory { @@ -155,6 +161,7 @@ public class SIPProcessorFactory {
155 processor.setRedisCatchStorage(redisCatchStorage); 161 processor.setRedisCatchStorage(redisCatchStorage);
156 processor.setZlmrtpServerFactory(zlmrtpServerFactory); 162 processor.setZlmrtpServerFactory(zlmrtpServerFactory);
157 processor.setSIPCommander(cmder); 163 processor.setSIPCommander(cmder);
  164 + processor.setMediaServerService(mediaServerService);
158 return processor; 165 return processor;
159 } else if (Request.CANCEL.equals(method)) { 166 } else if (Request.CANCEL.equals(method)) {
160 CancelRequestProcessor processor = new CancelRequestProcessor(); 167 CancelRequestProcessor processor = new CancelRequestProcessor();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; @@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd;
3 import com.genersoft.iot.vmp.gb28181.bean.Device; 3 import com.genersoft.iot.vmp.gb28181.bean.Device;
4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 5 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 8
7 /** 9 /**
8 * @Description:设备能力接口,用于定义设备的控制、查询能力 10 * @Description:设备能力接口,用于定义设备的控制、查询能力
@@ -90,7 +92,7 @@ public interface ISIPCommander { @@ -90,7 +92,7 @@ public interface ISIPCommander {
90 * @param device 视频设备 92 * @param device 视频设备
91 * @param channelId 预览通道 93 * @param channelId 预览通道
92 */ 94 */
93 - void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 95 + void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
94 96
95 /** 97 /**
96 * 请求回放视频流 98 * 请求回放视频流
@@ -100,7 +102,7 @@ public interface ISIPCommander { @@ -100,7 +102,7 @@ public interface ISIPCommander {
100 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss 102 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss
101 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss 103 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
102 */ 104 */
103 - void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 105 + void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
104 106
105 /** 107 /**
106 * 视频流停止 108 * 视频流停止
@@ -288,12 +290,4 @@ public interface ISIPCommander { @@ -288,12 +290,4 @@ public interface ISIPCommander {
288 * @return true = 命令发送成功 290 * @return true = 命令发送成功
289 */ 291 */
290 boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime); 292 boolean alarmSubscribe(Device device, int expires, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime);
291 -  
292 -  
293 - /**  
294 - * 释放rtpserver  
295 - * @param device  
296 - * @param channelId  
297 - */  
298 - void closeRTPServer(Device device, String channelId);  
299 } 293 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -13,11 +13,10 @@ import com.alibaba.fastjson.JSONObject; @@ -13,11 +13,10 @@ import com.alibaba.fastjson.JSONObject;
13 import com.genersoft.iot.vmp.common.StreamInfo; 13 import com.genersoft.iot.vmp.common.StreamInfo;
14 import com.genersoft.iot.vmp.conf.MediaConfig; 14 import com.genersoft.iot.vmp.conf.MediaConfig;
15 import com.genersoft.iot.vmp.conf.UserSetup; 15 import com.genersoft.iot.vmp.conf.UserSetup;
16 -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 16 +import com.genersoft.iot.vmp.media.zlm.*;
17 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 17 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
18 -import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;  
19 -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;  
20 -import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 18 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  19 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
21 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
22 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 21 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
23 import gov.nist.javax.sip.message.SIPRequest; 22 import gov.nist.javax.sip.message.SIPRequest;
@@ -37,6 +36,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; @@ -37,6 +36,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
37 import com.genersoft.iot.vmp.gb28181.utils.DateUtil; 36 import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
38 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; 37 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
39 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; 38 import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
  39 +import org.springframework.util.StringUtils;
40 40
41 /** 41 /**
42 * @Description:设备能力接口,用于定义设备的控制、查询能力 42 * @Description:设备能力接口,用于定义设备的控制、查询能力
@@ -78,12 +78,6 @@ public class SIPCommander implements ISIPCommander { @@ -78,12 +78,6 @@ public class SIPCommander implements ISIPCommander {
78 private ZLMRTPServerFactory zlmrtpServerFactory; 78 private ZLMRTPServerFactory zlmrtpServerFactory;
79 79
80 @Autowired 80 @Autowired
81 - private ZLMRESTfulUtils zlmresTfulUtils;  
82 -  
83 - @Autowired  
84 - private MediaConfig mediaConfig;  
85 -  
86 - @Autowired  
87 private UserSetup userSetup; 81 private UserSetup userSetup;
88 82
89 @Autowired 83 @Autowired
@@ -340,48 +334,45 @@ public class SIPCommander implements ISIPCommander { @@ -340,48 +334,45 @@ public class SIPCommander implements ISIPCommander {
340 * @param errorEvent sip错误订阅 334 * @param errorEvent sip错误订阅
341 */ 335 */
342 @Override 336 @Override
343 - public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { 337 + public void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
344 String streamId = null; 338 String streamId = null;
345 try { 339 try {
346 if (device == null) return; 340 if (device == null) return;
  341 + String streamMode = device.getStreamMode().toUpperCase();
  342 +
347 String ssrc = streamSession.createPlaySsrc(); 343 String ssrc = streamSession.createPlaySsrc();
348 - if (mediaConfig.isRtpEnable()) { 344 + if (mediaServerItem.isRtpEnable()) {
349 streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); 345 streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
350 }else { 346 }else {
351 streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); 347 streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
352 } 348 }
353 - String streamMode = device.getStreamMode().toUpperCase();  
354 - ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();  
355 - if (mediaInfo == null) {  
356 - logger.warn("点播时发现ZLM尚未连接...");  
357 - return;  
358 - }  
359 Integer mediaPort = null; 349 Integer mediaPort = null;
360 // 使用动态udp端口 350 // 使用动态udp端口
361 - if (mediaConfig.isRtpEnable()) {  
362 - mediaPort = zlmrtpServerFactory.createRTPServer(streamId); 351 + if (mediaServerItem.isRtpEnable()) {
  352 + mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId);
363 }else { 353 }else {
364 - mediaPort = mediaInfo.getRtpProxyPort(); 354 + mediaPort = mediaServerItem.getRtpProxyPort();
365 } 355 }
366 - 356 + logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort);
367 // 添加订阅 357 // 添加订阅
368 JSONObject subscribeKey = new JSONObject(); 358 JSONObject subscribeKey = new JSONObject();
369 subscribeKey.put("app", "rtp"); 359 subscribeKey.put("app", "rtp");
370 subscribeKey.put("stream", streamId); 360 subscribeKey.put("stream", streamId);
371 subscribeKey.put("regist", true); 361 subscribeKey.put("regist", true);
372 -  
373 - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, json->{ 362 + subscribeKey.put("mediaServerId", mediaServerItem.getId());
  363 + subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
  364 + (IMediaServerItem mediaServerItemInUse, JSONObject json)->{
374 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; 365 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;
375 - event.response(json); 366 + event.response(mediaServerItemInUse, json);
376 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); 367 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
377 }); 368 });
378 // 369 //
379 StringBuffer content = new StringBuffer(200); 370 StringBuffer content = new StringBuffer(200);
380 content.append("v=0\r\n"); 371 content.append("v=0\r\n");
381 // content.append("o=" + sipConfig.getSipId() + " 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); 372 // content.append("o=" + sipConfig.getSipId() + " 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
382 - content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getSdpIp()+"\r\n"); 373 + content.append("o="+"00000"+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
383 content.append("s=Play\r\n"); 374 content.append("s=Play\r\n");
384 - content.append("c=IN IP4 "+mediaInfo.getSdpIp()+"\r\n"); 375 + content.append("c=IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
385 content.append("t=0 0\r\n"); 376 content.append("t=0 0\r\n");
386 377
387 if (userSetup.isSeniorSdp()) { 378 if (userSetup.isSeniorSdp()) {
@@ -459,21 +450,32 @@ public class SIPCommander implements ISIPCommander { @@ -459,21 +450,32 @@ public class SIPCommander implements ISIPCommander {
459 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss 450 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
460 */ 451 */
461 @Override 452 @Override
462 - public void playbackStreamCmd(Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event 453 + public void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event
463 , SipSubscribe.Event errorEvent) { 454 , SipSubscribe.Event errorEvent) {
464 try { 455 try {
465 - ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();  
466 String ssrc = streamSession.createPlayBackSsrc(); 456 String ssrc = streamSession.createPlayBackSsrc();
467 String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); 457 String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
  458 +
  459 + Integer mediaPort = null;
  460 + // 使用动态udp端口
  461 + if (mediaServerItem.isRtpEnable()) {
  462 + mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId);
  463 + }else {
  464 + mediaPort = mediaServerItem.getRtpProxyPort();
  465 + }
  466 + logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort);
  467 +
468 // 添加订阅 468 // 添加订阅
469 JSONObject subscribeKey = new JSONObject(); 469 JSONObject subscribeKey = new JSONObject();
470 subscribeKey.put("app", "rtp"); 470 subscribeKey.put("app", "rtp");
471 subscribeKey.put("stream", streamId); 471 subscribeKey.put("stream", streamId);
472 subscribeKey.put("regist", true); 472 subscribeKey.put("regist", true);
  473 + subscribeKey.put("mediaServerId", mediaServerItem.getId());
473 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 474 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
474 - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, json->{ 475 + subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
  476 + (IMediaServerItem mediaServerItemInUse, JSONObject json)->{
475 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; 477 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;
476 - event.response(json); 478 + event.response(mediaServerItemInUse, json);
477 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); 479 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
478 }); 480 });
479 481
@@ -482,16 +484,12 @@ public class SIPCommander implements ISIPCommander { @@ -482,16 +484,12 @@ public class SIPCommander implements ISIPCommander {
482 content.append("o="+sipConfig.getSipId()+" 0 0 IN IP4 "+sipConfig.getSipIp()+"\r\n"); 484 content.append("o="+sipConfig.getSipId()+" 0 0 IN IP4 "+sipConfig.getSipIp()+"\r\n");
483 content.append("s=Playback\r\n"); 485 content.append("s=Playback\r\n");
484 content.append("u="+channelId+":0\r\n"); 486 content.append("u="+channelId+":0\r\n");
485 - content.append("c=IN IP4 "+mediaInfo.getSdpIp()+"\r\n"); 487 + content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
486 content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" " 488 content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" "
487 +DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n"); 489 +DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n");
488 - Integer mediaPort = null;  
489 - // 使用动态udp端口  
490 - if (mediaConfig.isRtpEnable()) {  
491 - mediaPort = zlmrtpServerFactory.createRTPServer(streamId);  
492 - }else {  
493 - mediaPort = mediaInfo.getRtpProxyPort();  
494 - } 490 +
  491 +
  492 +
495 String streamMode = device.getStreamMode().toUpperCase(); 493 String streamMode = device.getStreamMode().toUpperCase();
496 494
497 if (userSetup.isSeniorSdp()) { 495 if (userSetup.isSeniorSdp()) {
@@ -560,56 +558,63 @@ public class SIPCommander implements ISIPCommander { @@ -560,56 +558,63 @@ public class SIPCommander implements ISIPCommander {
560 558
561 559
562 /** 560 /**
563 - * 视频流停止  
564 - * 561 + * 视频流停止, 不使用回调
565 */ 562 */
566 @Override 563 @Override
567 public void streamByeCmd(String deviceId, String channelId) { 564 public void streamByeCmd(String deviceId, String channelId) {
568 streamByeCmd(deviceId, channelId, null); 565 streamByeCmd(deviceId, channelId, null);
569 } 566 }
  567 +
  568 + /**
  569 + * 视频流停止
  570 + */
570 @Override 571 @Override
571 public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) { 572 public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) {
572 - 573 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
573 try { 574 try {
574 ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); 575 ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId);
575 // 服务重启后, 无法直接发送bye, 通过手动构建发送 576 // 服务重启后, 无法直接发送bye, 通过手动构建发送
  577 +// if (transaction == null) {
  578 +//
  579 +// if (streamInfo != null) {
  580 +// MediaServerItem mediaServerItem = redisCatchStorage.getMediaInfo(streamInfo.getMediaServerId());
  581 +// JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem,streamInfo.getApp(), streamInfo.getStreamId());
  582 +// if (mediaList != null) { // 仍在推流才发送
  583 +// if (mediaList.getInteger("code") == 0) {
  584 +// JSONArray data = mediaList.getJSONArray("data");
  585 +// if (data != null && data.size() > 0) {
  586 +// Device device = storager.queryVideoDevice(deviceId);
  587 +// if (device != null) {
  588 +// StreamInfo.TransactionInfo transactionInfo = streamInfo.getTransactionInfo();
  589 +// try {
  590 +// Request byteRequest = headerProvider.createByteRequest(device, channelId,
  591 +// transactionInfo.branch,
  592 +// transactionInfo.localTag,
  593 +// transactionInfo.remoteTag,
  594 +// transactionInfo.callId);
  595 +// transmitRequest(device, byteRequest);
  596 +// } catch (InvalidArgumentException e) {
  597 +// e.printStackTrace();
  598 +// }
  599 +// }
  600 +// }
  601 +// }
  602 +// }
  603 +// redisCatchStorage.stopPlay(streamInfo);
  604 +// }
  605 +//
  606 +// if (okEvent != null) {
  607 +// okEvent.response(null);
  608 +// }
  609 +// return;
  610 +// }
576 if (transaction == null) { 611 if (transaction == null) {
577 -  
578 - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);  
579 - if (streamInfo != null) {  
580 - JSONObject mediaList = zlmresTfulUtils.getMediaList(streamInfo.getApp(), streamInfo.getStreamId());  
581 - if (mediaList != null) { // 仍在推流才发送  
582 - if (mediaList.getInteger("code") == 0) {  
583 - JSONArray data = mediaList.getJSONArray("data");  
584 - if (data != null && data.size() > 0) {  
585 - Device device = storager.queryVideoDevice(deviceId);  
586 - if (device != null) {  
587 - StreamInfo.TransactionInfo transactionInfo = streamInfo.getTransactionInfo();  
588 - try {  
589 - Request byteRequest = headerProvider.createByteRequest(device, channelId,  
590 - transactionInfo.branch,  
591 - transactionInfo.localTag,  
592 - transactionInfo.remoteTag,  
593 - transactionInfo.callId);  
594 - transmitRequest(device, byteRequest);  
595 - } catch (InvalidArgumentException e) {  
596 - e.printStackTrace();  
597 - }  
598 - }  
599 - }  
600 - }  
601 - }  
602 - redisCatchStorage.stopPlay(streamInfo);  
603 - }  
604 -  
605 - if (okEvent != null) {  
606 - okEvent.response(null);  
607 - } 612 + logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId);
608 return; 613 return;
609 } 614 }
610 -  
611 Dialog dialog = transaction.getDialog(); 615 Dialog dialog = transaction.getDialog();
612 if (dialog == null) { 616 if (dialog == null) {
  617 + logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId);
613 return; 618 return;
614 } 619 }
615 Request byeRequest = dialog.createRequest(Request.BYE); 620 Request byeRequest = dialog.createRequest(Request.BYE);
@@ -632,7 +637,7 @@ public class SIPCommander implements ISIPCommander { @@ -632,7 +637,7 @@ public class SIPCommander implements ISIPCommander {
632 } 637 }
633 638
634 dialog.sendRequest(clientTransaction); 639 dialog.sendRequest(clientTransaction);
635 - zlmrtpServerFactory.closeRTPServer(streamSession.getStreamId(deviceId, channelId)); 640 +
636 streamSession.remove(deviceId, channelId); 641 streamSession.remove(deviceId, channelId);
637 } catch (SipException | ParseException e) { 642 } catch (SipException | ParseException e) {
638 e.printStackTrace(); 643 e.printStackTrace();
@@ -721,7 +726,7 @@ public class SIPCommander implements ISIPCommander { @@ -721,7 +726,7 @@ public class SIPCommander implements ISIPCommander {
721 cmdXml.append("<Control>\r\n"); 726 cmdXml.append("<Control>\r\n");
722 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); 727 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
723 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 728 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
724 - if (XmlUtil.isEmpty(channelId)) { 729 + if (StringUtils.isEmpty(channelId)) {
725 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 730 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
726 } else { 731 } else {
727 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); 732 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
@@ -821,16 +826,16 @@ public class SIPCommander implements ISIPCommander { @@ -821,16 +826,16 @@ public class SIPCommander implements ISIPCommander {
821 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 826 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
822 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 827 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
823 cmdXml.append("<AlarmCmd>ResetAlarm</AlarmCmd>\r\n"); 828 cmdXml.append("<AlarmCmd>ResetAlarm</AlarmCmd>\r\n");
824 - if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) { 829 + if (!StringUtils.isEmpty(alarmMethod) || !StringUtils.isEmpty(alarmType)) {
825 cmdXml.append("<Info>\r\n"); 830 cmdXml.append("<Info>\r\n");
826 } 831 }
827 - if (!XmlUtil.isEmpty(alarmMethod)) { 832 + if (!StringUtils.isEmpty(alarmMethod)) {
828 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n"); 833 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
829 } 834 }
830 - if (!XmlUtil.isEmpty(alarmType)) { 835 + if (!StringUtils.isEmpty(alarmType)) {
831 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n"); 836 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
832 } 837 }
833 - if (!XmlUtil.isEmpty(alarmMethod) || !XmlUtil.isEmpty(alarmType)) { 838 + if (!StringUtils.isEmpty(alarmMethod) || !StringUtils.isEmpty(alarmType)) {
834 cmdXml.append("</Info>\r\n"); 839 cmdXml.append("</Info>\r\n");
835 } 840 }
836 cmdXml.append("</Control>\r\n"); 841 cmdXml.append("</Control>\r\n");
@@ -863,7 +868,7 @@ public class SIPCommander implements ISIPCommander { @@ -863,7 +868,7 @@ public class SIPCommander implements ISIPCommander {
863 cmdXml.append("<Control>\r\n"); 868 cmdXml.append("<Control>\r\n");
864 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); 869 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
865 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 870 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
866 - if (XmlUtil.isEmpty(channelId)) { 871 + if (StringUtils.isEmpty(channelId)) {
867 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 872 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
868 } else { 873 } else {
869 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); 874 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
@@ -901,7 +906,7 @@ public class SIPCommander implements ISIPCommander { @@ -901,7 +906,7 @@ public class SIPCommander implements ISIPCommander {
901 cmdXml.append("<Control>\r\n"); 906 cmdXml.append("<Control>\r\n");
902 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n"); 907 cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
903 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 908 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
904 - if (XmlUtil.isEmpty(channelId)) { 909 + if (StringUtils.isEmpty(channelId)) {
905 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 910 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
906 } else { 911 } else {
907 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); 912 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
@@ -969,13 +974,13 @@ public class SIPCommander implements ISIPCommander { @@ -969,13 +974,13 @@ public class SIPCommander implements ISIPCommander {
969 cmdXml.append("<Control>\r\n"); 974 cmdXml.append("<Control>\r\n");
970 cmdXml.append("<CmdType>DeviceConfig</CmdType>\r\n"); 975 cmdXml.append("<CmdType>DeviceConfig</CmdType>\r\n");
971 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 976 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
972 - if (XmlUtil.isEmpty(channelId)) { 977 + if (StringUtils.isEmpty(channelId)) {
973 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 978 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
974 } else { 979 } else {
975 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); 980 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
976 } 981 }
977 cmdXml.append("<BasicParam>\r\n"); 982 cmdXml.append("<BasicParam>\r\n");
978 - if (!XmlUtil.isEmpty(name)) { 983 + if (!StringUtils.isEmpty(name)) {
979 cmdXml.append("<Name>" + name + "</Name>\r\n"); 984 cmdXml.append("<Name>" + name + "</Name>\r\n");
980 } 985 }
981 if (NumericUtil.isInteger(expiration)) { 986 if (NumericUtil.isInteger(expiration)) {
@@ -1169,22 +1174,22 @@ public class SIPCommander implements ISIPCommander { @@ -1169,22 +1174,22 @@ public class SIPCommander implements ISIPCommander {
1169 cmdXml.append("<CmdType>Alarm</CmdType>\r\n"); 1174 cmdXml.append("<CmdType>Alarm</CmdType>\r\n");
1170 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 1175 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1171 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 1176 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1172 - if (!XmlUtil.isEmpty(startPriority)) { 1177 + if (!StringUtils.isEmpty(startPriority)) {
1173 cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n"); 1178 cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n");
1174 } 1179 }
1175 - if (!XmlUtil.isEmpty(endPriority)) { 1180 + if (!StringUtils.isEmpty(endPriority)) {
1176 cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n"); 1181 cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n");
1177 } 1182 }
1178 - if (!XmlUtil.isEmpty(alarmMethod)) { 1183 + if (!StringUtils.isEmpty(alarmMethod)) {
1179 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n"); 1184 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
1180 } 1185 }
1181 - if (!XmlUtil.isEmpty(alarmType)) { 1186 + if (!StringUtils.isEmpty(alarmType)) {
1182 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n"); 1187 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
1183 } 1188 }
1184 - if (!XmlUtil.isEmpty(startTime)) { 1189 + if (!StringUtils.isEmpty(startTime)) {
1185 cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n"); 1190 cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n");
1186 } 1191 }
1187 - if (!XmlUtil.isEmpty(endTime)) { 1192 + if (!StringUtils.isEmpty(endTime)) {
1188 cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n"); 1193 cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n");
1189 } 1194 }
1190 cmdXml.append("</Query>\r\n"); 1195 cmdXml.append("</Query>\r\n");
@@ -1218,7 +1223,7 @@ public class SIPCommander implements ISIPCommander { @@ -1218,7 +1223,7 @@ public class SIPCommander implements ISIPCommander {
1218 cmdXml.append("<Query>\r\n"); 1223 cmdXml.append("<Query>\r\n");
1219 cmdXml.append("<CmdType>ConfigDownload</CmdType>\r\n"); 1224 cmdXml.append("<CmdType>ConfigDownload</CmdType>\r\n");
1220 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 1225 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1221 - if (XmlUtil.isEmpty(channelId)) { 1226 + if (StringUtils.isEmpty(channelId)) {
1222 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 1227 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1223 } else { 1228 } else {
1224 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); 1229 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
@@ -1253,7 +1258,7 @@ public class SIPCommander implements ISIPCommander { @@ -1253,7 +1258,7 @@ public class SIPCommander implements ISIPCommander {
1253 cmdXml.append("<Query>\r\n"); 1258 cmdXml.append("<Query>\r\n");
1254 cmdXml.append("<CmdType>PresetQuery</CmdType>\r\n"); 1259 cmdXml.append("<CmdType>PresetQuery</CmdType>\r\n");
1255 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 1260 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1256 - if (XmlUtil.isEmpty(channelId)) { 1261 + if (StringUtils.isEmpty(channelId)) {
1257 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 1262 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1258 } else { 1263 } else {
1259 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); 1264 cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
@@ -1365,22 +1370,22 @@ public class SIPCommander implements ISIPCommander { @@ -1365,22 +1370,22 @@ public class SIPCommander implements ISIPCommander {
1365 cmdXml.append("<CmdType>Alarm</CmdType>\r\n"); 1370 cmdXml.append("<CmdType>Alarm</CmdType>\r\n");
1366 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); 1371 cmdXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
1367 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n"); 1372 cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
1368 - if (!XmlUtil.isEmpty(startPriority)) { 1373 + if (!StringUtils.isEmpty(startPriority)) {
1369 cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n"); 1374 cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n");
1370 } 1375 }
1371 - if (!XmlUtil.isEmpty(endPriority)) { 1376 + if (!StringUtils.isEmpty(endPriority)) {
1372 cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n"); 1377 cmdXml.append("<EndAlarmPriority>" + endPriority + "</EndAlarmPriority>\r\n");
1373 } 1378 }
1374 - if (!XmlUtil.isEmpty(alarmMethod)) { 1379 + if (!StringUtils.isEmpty(alarmMethod)) {
1375 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n"); 1380 cmdXml.append("<AlarmMethod>" + alarmMethod + "</AlarmMethod>\r\n");
1376 } 1381 }
1377 - if (!XmlUtil.isEmpty(alarmType)) { 1382 + if (!StringUtils.isEmpty(alarmType)) {
1378 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n"); 1383 cmdXml.append("<AlarmType>" + alarmType + "</AlarmType>\r\n");
1379 } 1384 }
1380 - if (!XmlUtil.isEmpty(startTime)) { 1385 + if (!StringUtils.isEmpty(startTime)) {
1381 cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n"); 1386 cmdXml.append("<StartAlarmTime>" + startTime + "</StartAlarmTime>\r\n");
1382 } 1387 }
1383 - if (!XmlUtil.isEmpty(endTime)) { 1388 + if (!StringUtils.isEmpty(endTime)) {
1384 cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n"); 1389 cmdXml.append("<EndAlarmTime>" + endTime + "</EndAlarmTime>\r\n");
1385 } 1390 }
1386 cmdXml.append("</Query>\r\n"); 1391 cmdXml.append("</Query>\r\n");
@@ -1431,16 +1436,4 @@ public class SIPCommander implements ISIPCommander { @@ -1431,16 +1436,4 @@ public class SIPCommander implements ISIPCommander {
1431 clientTransaction.sendRequest(); 1436 clientTransaction.sendRequest();
1432 return clientTransaction; 1437 return clientTransaction;
1433 } 1438 }
1434 -  
1435 -  
1436 -  
1437 -  
1438 - @Override  
1439 - public void closeRTPServer(Device device, String channelId) {  
1440 - if (mediaConfig.isRtpEnable()) {  
1441 - String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);  
1442 - zlmrtpServerFactory.closeRTPServer(streamId);  
1443 - }  
1444 - streamSession.remove(device.getDeviceId(), channelId);  
1445 - }  
1446 } 1439 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/SIPRequestAbstractProcessor.java
@@ -16,6 +16,8 @@ import javax.sip.message.Request; @@ -16,6 +16,8 @@ import javax.sip.message.Request;
16 import gov.nist.javax.sip.SipStackImpl; 16 import gov.nist.javax.sip.SipStackImpl;
17 import gov.nist.javax.sip.message.SIPRequest; 17 import gov.nist.javax.sip.message.SIPRequest;
18 import gov.nist.javax.sip.stack.SIPServerTransaction; 18 import gov.nist.javax.sip.stack.SIPServerTransaction;
  19 +import org.slf4j.Logger;
  20 +import org.slf4j.LoggerFactory;
19 21
20 /** 22 /**
21 * @Description:处理接收IPCamera发来的SIP协议请求消息 23 * @Description:处理接收IPCamera发来的SIP协议请求消息
@@ -24,6 +26,8 @@ import gov.nist.javax.sip.stack.SIPServerTransaction; @@ -24,6 +26,8 @@ import gov.nist.javax.sip.stack.SIPServerTransaction;
24 */ 26 */
25 public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcessor { 27 public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcessor {
26 28
  29 + private final static Logger logger = LoggerFactory.getLogger(SIPRequestAbstractProcessor.class);
  30 +
27 protected RequestEvent evt; 31 protected RequestEvent evt;
28 32
29 private SipProvider tcpSipProvider; 33 private SipProvider tcpSipProvider;
@@ -64,9 +68,9 @@ public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcesso @@ -64,9 +68,9 @@ public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcesso
64 } 68 }
65 } 69 }
66 } catch (TransactionAlreadyExistsException e) { 70 } catch (TransactionAlreadyExistsException e) {
67 - e.printStackTrace(); 71 + logger.error(e.getMessage());
68 } catch (TransactionUnavailableException e) { 72 } catch (TransactionUnavailableException e) {
69 - e.printStackTrace(); 73 + logger.error(e.getMessage());
70 } 74 }
71 } 75 }
72 return serverTransaction; 76 return serverTransaction;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
@@ -13,6 +13,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -13,6 +13,9 @@ import com.genersoft.iot.vmp.common.StreamInfo;
13 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 13 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
14 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; 14 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
15 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 15 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  16 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  17 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  18 +import com.genersoft.iot.vmp.service.IMediaServerService;
16 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 19 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
17 import org.slf4j.Logger; 20 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory; 21 import org.slf4j.LoggerFactory;
@@ -30,6 +33,8 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { @@ -30,6 +33,8 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
30 33
31 private ZLMRTPServerFactory zlmrtpServerFactory; 34 private ZLMRTPServerFactory zlmrtpServerFactory;
32 35
  36 + private IMediaServerService mediaServerService;
  37 +
33 /** 38 /**
34 * 处理 ACK请求 39 * 处理 ACK请求
35 * 40 *
@@ -76,18 +81,22 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { @@ -76,18 +81,22 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
76 while (!rtpPushed) { 81 while (!rtpPushed) {
77 try { 82 try {
78 if (System.currentTimeMillis() - startTime < 30 * 1000) { 83 if (System.currentTimeMillis() - startTime < 30 * 1000) {
79 - if (zlmrtpServerFactory.isStreamReady(streamInfo.getApp(), streamInfo.getStreamId())) { 84 + IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
  85 + if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) {
80 rtpPushed = true; 86 rtpPushed = true;
81 - logger.info("已获取设备推流,开始向上级推流");  
82 - zlmrtpServerFactory.startSendRtpStream(param); 87 + logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",
  88 + streamInfo.getApp() ,streamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort());
  89 + zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
83 } else { 90 } else {
84 - logger.info("等待设备推流......."); 91 + logger.info("等待设备推流[{}/{}].......",
  92 + streamInfo.getApp() ,streamInfo.getStreamId());
85 Thread.sleep(1000); 93 Thread.sleep(1000);
86 continue; 94 continue;
87 } 95 }
88 } else { 96 } else {
89 rtpPushed = true; 97 rtpPushed = true;
90 - logger.info("设备推流超时,终止向上级推流"); 98 + logger.info("设备推流[{}/{}]超时,终止向上级推流",
  99 + streamInfo.getApp() ,streamInfo.getStreamId());
91 } 100 }
92 } catch (InterruptedException e) { 101 } catch (InterruptedException e) {
93 e.printStackTrace(); 102 e.printStackTrace();
@@ -123,4 +132,12 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { @@ -123,4 +132,12 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
123 public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) { 132 public void setZlmrtpServerFactory(ZLMRTPServerFactory zlmrtpServerFactory) {
124 this.zlmrtpServerFactory = zlmrtpServerFactory; 133 this.zlmrtpServerFactory = zlmrtpServerFactory;
125 } 134 }
  135 +
  136 + public IMediaServerService getMediaServerService() {
  137 + return mediaServerService;
  138 + }
  139 +
  140 + public void setMediaServerService(IMediaServerService mediaServerService) {
  141 + this.mediaServerService = mediaServerService;
  142 + }
126 } 143 }
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; @@ -15,6 +15,9 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; 15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
16 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; 16 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
17 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 17 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  18 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  19 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  20 +import com.genersoft.iot.vmp.service.IMediaServerService;
18 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 21 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
19 import org.slf4j.Logger; 22 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory; 23 import org.slf4j.LoggerFactory;
@@ -38,6 +41,8 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { @@ -38,6 +41,8 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
38 41
39 private ZLMRTPServerFactory zlmrtpServerFactory; 42 private ZLMRTPServerFactory zlmrtpServerFactory;
40 43
  44 + private IMediaServerService mediaServerService;
  45 +
41 /** 46 /**
42 * 处理BYE请求 47 * 处理BYE请求
43 * @param evt 48 * @param evt
@@ -60,9 +65,10 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { @@ -60,9 +65,10 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
60 param.put("stream",streamId); 65 param.put("stream",streamId);
61 param.put("ssrc",sendRtpItem.getSsrc()); 66 param.put("ssrc",sendRtpItem.getSsrc());
62 logger.info("停止向上级推流:" + streamId); 67 logger.info("停止向上级推流:" + streamId);
63 - zlmrtpServerFactory.stopSendRtpStream(param); 68 + IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
  69 + zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
64 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); 70 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
65 - if (zlmrtpServerFactory.totalReaderCount(sendRtpItem.getApp(), streamId) == 0) { 71 + if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) {
66 logger.info(streamId + "无其它观看者,通知设备停止推流"); 72 logger.info(streamId + "无其它观看者,通知设备停止推流");
67 cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId); 73 cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId);
68 } 74 }
@@ -112,4 +118,11 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { @@ -112,4 +118,11 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
112 this.cmder = cmder; 118 this.cmder = cmder;
113 } 119 }
114 120
  121 + public IMediaServerService getMediaServerService() {
  122 + return mediaServerService;
  123 + }
  124 +
  125 + public void setMediaServerService(IMediaServerService mediaServerService) {
  126 + this.mediaServerService = mediaServerService;
  127 + }
115 } 128 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
@@ -11,12 +11,16 @@ import javax.sip.header.*; @@ -11,12 +11,16 @@ import javax.sip.header.*;
11 import javax.sip.message.Request; 11 import javax.sip.message.Request;
12 import javax.sip.message.Response; 12 import javax.sip.message.Response;
13 13
  14 +import com.genersoft.iot.vmp.common.StreamInfo;
14 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 15 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
15 import com.genersoft.iot.vmp.gb28181.bean.*; 16 import com.genersoft.iot.vmp.gb28181.bean.*;
16 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 17 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
17 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 18 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
18 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; 19 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
19 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 20 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  21 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  22 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  23 +import com.genersoft.iot.vmp.service.IMediaServerService;
20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 24 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 25 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
22 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 26 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
@@ -51,6 +55,8 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -51,6 +55,8 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
51 55
52 private ZLMRTPServerFactory zlmrtpServerFactory; 56 private ZLMRTPServerFactory zlmrtpServerFactory;
53 57
  58 + private IMediaServerService mediaServerService;
  59 +
54 public ZLMRTPServerFactory getZlmrtpServerFactory() { 60 public ZLMRTPServerFactory getZlmrtpServerFactory() {
55 return zlmrtpServerFactory; 61 return zlmrtpServerFactory;
56 } 62 }
@@ -91,6 +97,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -91,6 +97,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
91 // 查询平台下是否有该通道 97 // 查询平台下是否有该通道
92 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); 98 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
93 GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); 99 GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
  100 + IMediaServerItem mediaServerItem = null;
94 // 不是通道可能是直播流 101 // 不是通道可能是直播流
95 if (channel != null && gbStream == null ) { 102 if (channel != null && gbStream == null ) {
96 if (channel.getStatus() == 0) { 103 if (channel.getStatus() == 0) {
@@ -100,8 +107,15 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -100,8 +107,15 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
100 } 107 }
101 responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中 108 responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
102 }else if(channel == null && gbStream != null){ 109 }else if(channel == null && gbStream != null){
103 - Boolean streamReady = zlmrtpServerFactory.isStreamReady(gbStream.getApp(), gbStream.getStream());  
104 - if (!streamReady) { 110 + String mediaServerId = gbStream.getMediaServerId();
  111 + mediaServerItem = mediaServerService.getOne(mediaServerId);
  112 + if (mediaServerItem == null) {
  113 + logger.info("[ app={}, stream={} ]zlm找不到,返回410",gbStream.getApp(), gbStream.getStream());
  114 + responseAck(evt, Response.GONE, "media server not found");
  115 + return;
  116 + }
  117 + Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
  118 + if (!streamReady ) {
105 logger.info("[ app={}, stream={} ]通道离线,返回400",gbStream.getApp(), gbStream.getStream()); 119 logger.info("[ app={}, stream={} ]通道离线,返回400",gbStream.getApp(), gbStream.getStream());
106 responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline"); 120 responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
107 return; 121 return;
@@ -130,8 +144,8 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -130,8 +144,8 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
130 //boolean recvonly = false; 144 //boolean recvonly = false;
131 boolean mediaTransmissionTCP = false; 145 boolean mediaTransmissionTCP = false;
132 Boolean tcpActive = null; 146 Boolean tcpActive = null;
133 - for (int i = 0; i < mediaDescriptions.size(); i++) {  
134 - MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i); 147 + for (Object description : mediaDescriptions) {
  148 + MediaDescription mediaDescription = (MediaDescription) description;
135 Media media = mediaDescription.getMedia(); 149 Media media = mediaDescription.getMedia();
136 150
137 Vector mediaFormats = media.getMediaFormats(false); 151 Vector mediaFormats = media.getMediaFormats(false);
@@ -147,7 +161,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -147,7 +161,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
147 mediaTransmissionTCP = true; 161 mediaTransmissionTCP = true;
148 if ("active".equals(setup)) { 162 if ("active".equals(setup)) {
149 tcpActive = true; 163 tcpActive = true;
150 - }else if ("passive".equals(setup)) { 164 + } else if ("passive".equals(setup)) {
151 tcpActive = false; 165 tcpActive = false;
152 } 166 }
153 } 167 }
@@ -174,7 +188,13 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -174,7 +188,13 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
174 responseAck(evt, Response.SERVER_INTERNAL_ERROR); 188 responseAck(evt, Response.SERVER_INTERNAL_ERROR);
175 return; 189 return;
176 } 190 }
177 - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId, 191 + mediaServerItem = playService.getNewMediaServerItem(device);
  192 + if (mediaServerItem == null) {
  193 + logger.warn("未找到可用的zlm");
  194 + responseAck(evt, Response.BUSY_HERE);
  195 + return;
  196 + }
  197 + SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
178 device.getDeviceId(), channelId, 198 device.getDeviceId(), channelId,
179 mediaTransmissionTCP); 199 mediaTransmissionTCP);
180 if (tcpActive != null) { 200 if (tcpActive != null) {
@@ -189,18 +209,18 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -189,18 +209,18 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
189 // 写入redis, 超时时回复 209 // 写入redis, 超时时回复
190 redisCatchStorage.updateSendRTPSever(sendRtpItem); 210 redisCatchStorage.updateSendRTPSever(sendRtpItem);
191 // 通知下级推流, 211 // 通知下级推流,
192 - PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{ 212 + PlayResult playResult = playService.play(mediaServerItem,device.getDeviceId(), channelId, (mediaServerItemInUSe, responseJSON)->{
193 // 收到推流, 回复200OK, 等待ack 213 // 收到推流, 回复200OK, 等待ack
194 // if (sendRtpItem == null) return; 214 // if (sendRtpItem == null) return;
195 sendRtpItem.setStatus(1); 215 sendRtpItem.setStatus(1);
196 redisCatchStorage.updateSendRTPSever(sendRtpItem); 216 redisCatchStorage.updateSendRTPSever(sendRtpItem);
197 // TODO 添加对tcp的支持 217 // TODO 添加对tcp的支持
198 - ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); 218 +
199 StringBuffer content = new StringBuffer(200); 219 StringBuffer content = new StringBuffer(200);
200 content.append("v=0\r\n"); 220 content.append("v=0\r\n");
201 - content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getSdpIp()+"\r\n"); 221 + content.append("o="+"00000"+" 0 0 IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n");
202 content.append("s=Play\r\n"); 222 content.append("s=Play\r\n");
203 - content.append("c=IN IP4 "+mediaInfo.getSdpIp()+"\r\n"); 223 + content.append("c=IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n");
204 content.append("t=0 0\r\n"); 224 content.append("t=0 0\r\n");
205 content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n"); 225 content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
206 content.append("a=sendonly\r\n"); 226 content.append("a=sendonly\r\n");
@@ -217,7 +237,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -217,7 +237,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
217 } catch (ParseException e) { 237 } catch (ParseException e) {
218 e.printStackTrace(); 238 e.printStackTrace();
219 } 239 }
220 - } ,(event -> { 240 + } ,((event) -> {
221 // 未知错误。直接转发设备点播的错误 241 // 未知错误。直接转发设备点播的错误
222 Response response = null; 242 Response response = null;
223 try { 243 try {
@@ -232,7 +252,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -232,7 +252,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
232 } 252 }
233 253
234 }else if (gbStream != null) { 254 }else if (gbStream != null) {
235 - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId, 255 + SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
236 gbStream.getApp(), gbStream.getStream(), channelId, 256 gbStream.getApp(), gbStream.getStream(), channelId,
237 mediaTransmissionTCP); 257 mediaTransmissionTCP);
238 258
@@ -251,12 +271,11 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -251,12 +271,11 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
251 sendRtpItem.setStatus(1); 271 sendRtpItem.setStatus(1);
252 redisCatchStorage.updateSendRTPSever(sendRtpItem); 272 redisCatchStorage.updateSendRTPSever(sendRtpItem);
253 // TODO 添加对tcp的支持 273 // TODO 添加对tcp的支持
254 - ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();  
255 StringBuffer content = new StringBuffer(200); 274 StringBuffer content = new StringBuffer(200);
256 content.append("v=0\r\n"); 275 content.append("v=0\r\n");
257 - content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getSdpIp()+"\r\n"); 276 + content.append("o="+"00000"+" 0 0 IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
258 content.append("s=Play\r\n"); 277 content.append("s=Play\r\n");
259 - content.append("c=IN IP4 "+mediaInfo.getSdpIp()+"\r\n"); 278 + content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
260 content.append("t=0 0\r\n"); 279 content.append("t=0 0\r\n");
261 content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n"); 280 content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
262 content.append("a=sendonly\r\n"); 281 content.append("a=sendonly\r\n");
@@ -444,4 +463,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -444,4 +463,12 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
444 public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { 463 public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
445 this.redisCatchStorage = redisCatchStorage; 464 this.redisCatchStorage = redisCatchStorage;
446 } 465 }
  466 +
  467 + public IMediaServerService getMediaServerService() {
  468 + return mediaServerService;
  469 + }
  470 +
  471 + public void setMediaServerService(IMediaServerService mediaServerService) {
  472 + this.mediaServerService = mediaServerService;
  473 + }
447 } 474 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -282,7 +282,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -282,7 +282,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
282 //String result = XmlUtil.getText(rootElement, "Result"); 282 //String result = XmlUtil.getText(rootElement, "Result");
283 // 回复200 OK 283 // 回复200 OK
284 responseAck(evt); 284 responseAck(evt);
285 - if (rootElement.getName().equals("Response")) {//} !XmlUtil.isEmpty(result)) { 285 + if (rootElement.getName().equals("Response")) {//} !StringUtils.isEmpty(result)) {
286 // 此处是对本平台发出DeviceControl指令的应答 286 // 此处是对本平台发出DeviceControl指令的应答
287 JSONObject json = new JSONObject(); 287 JSONObject json = new JSONObject();
288 XmlUtil.node2Json(rootElement, json); 288 XmlUtil.node2Json(rootElement, json);
@@ -299,7 +299,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -299,7 +299,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
299 String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); 299 String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser();
300 String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); 300 String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
301 // 远程启动功能 301 // 远程启动功能
302 - if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) { 302 + if (!StringUtils.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) {
303 if (deviceId.equals(targetGBId)) { 303 if (deviceId.equals(targetGBId)) {
304 // 远程启动本平台:需要在重新启动程序后先对SipStack解绑 304 // 远程启动本平台:需要在重新启动程序后先对SipStack解绑
305 logger.info("执行远程启动本平台命令"); 305 logger.info("执行远程启动本平台命令");
@@ -337,7 +337,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -337,7 +337,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
337 } 337 }
338 } 338 }
339 // 云台/前端控制命令 339 // 云台/前端控制命令
340 - if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) { 340 + if (!StringUtils.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) {
341 String cmdString = XmlUtil.getText(rootElement,"PTZCmd"); 341 String cmdString = XmlUtil.getText(rootElement,"PTZCmd");
342 Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId); 342 Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId);
343 cmder.fronEndCmd(device, deviceId, cmdString); 343 cmder.fronEndCmd(device, deviceId, cmdString);
@@ -421,7 +421,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -421,7 +421,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
421 String deviceId = XmlUtil.getText(rootElement, "DeviceID"); 421 String deviceId = XmlUtil.getText(rootElement, "DeviceID");
422 // 回复200 OK 422 // 回复200 OK
423 responseAck(evt); 423 responseAck(evt);
424 - if (rootElement.getName().equals("Response")) {// !XmlUtil.isEmpty(result)) { 424 + if (rootElement.getName().equals("Response")) {// !StringUtils.isEmpty(result)) {
425 // 此处是对本平台发出DeviceControl指令的应答 425 // 此处是对本平台发出DeviceControl指令的应答
426 JSONObject json = new JSONObject(); 426 JSONObject json = new JSONObject();
427 XmlUtil.node2Json(rootElement, json); 427 XmlUtil.node2Json(rootElement, json);
@@ -718,7 +718,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -718,7 +718,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
718 deviceAlarm.setLatitude(0.00); 718 deviceAlarm.setLatitude(0.00);
719 } 719 }
720 720
721 - if (!XmlUtil.isEmpty(deviceAlarm.getAlarmMethod())) { 721 + if (!StringUtils.isEmpty(deviceAlarm.getAlarmMethod())) {
722 if ( deviceAlarm.getAlarmMethod().equals("4")) { 722 if ( deviceAlarm.getAlarmMethod().equals("4")) {
723 MobilePosition mobilePosition = new MobilePosition(); 723 MobilePosition mobilePosition = new MobilePosition();
724 mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); 724 mobilePosition.setDeviceId(deviceAlarm.getDeviceId());
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
@@ -17,6 +17,7 @@ import org.dom4j.Element; @@ -17,6 +17,7 @@ import org.dom4j.Element;
17 import org.dom4j.io.SAXReader; 17 import org.dom4j.io.SAXReader;
18 import org.slf4j.Logger; 18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory; 19 import org.slf4j.LoggerFactory;
  20 +import org.springframework.util.StringUtils;
20 21
21 /** 22 /**
22 * 基于dom4j的工具包 23 * 基于dom4j的工具包
@@ -114,12 +115,12 @@ public class XmlUtil { @@ -114,12 +115,12 @@ public class XmlUtil {
114 // 如果是属性 115 // 如果是属性
115 for (Object o : element.attributes()) { 116 for (Object o : element.attributes()) {
116 Attribute attr = (Attribute) o; 117 Attribute attr = (Attribute) o;
117 - if (!isEmpty(attr.getValue())) { 118 + if (!StringUtils.isEmpty(attr.getValue())) {
118 json.put("@" + attr.getName(), attr.getValue()); 119 json.put("@" + attr.getName(), attr.getValue());
119 } 120 }
120 } 121 }
121 List<Element> chdEl = element.elements(); 122 List<Element> chdEl = element.elements();
122 - if (chdEl.isEmpty() && !isEmpty(element.getText())) {// 如果没有子元素,只有一个值 123 + if (chdEl.isEmpty() && !StringUtils.isEmpty(element.getText())) {// 如果没有子元素,只有一个值
123 json.put(element.getName(), element.getText()); 124 json.put(element.getName(), element.getText());
124 } 125 }
125 126
@@ -150,7 +151,7 @@ public class XmlUtil { @@ -150,7 +151,7 @@ public class XmlUtil {
150 } else { // 子元素没有子元素 151 } else { // 子元素没有子元素
151 for (Object o : element.attributes()) { 152 for (Object o : element.attributes()) {
152 Attribute attr = (Attribute) o; 153 Attribute attr = (Attribute) o;
153 - if (!isEmpty(attr.getValue())) { 154 + if (!StringUtils.isEmpty(attr.getValue())) {
154 json.put("@" + attr.getName(), attr.getValue()); 155 json.put("@" + attr.getName(), attr.getValue());
155 } 156 }
156 } 157 }
@@ -160,11 +161,4 @@ public class XmlUtil { @@ -160,11 +161,4 @@ public class XmlUtil {
160 } 161 }
161 } 162 }
162 } 163 }
163 -  
164 - public static boolean isEmpty(String str) {  
165 - if (str == null || str.trim().isEmpty() || "null".equals(str)) {  
166 - return true;  
167 - }  
168 - return false;  
169 - }  
170 } 164 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java deleted 100644 → 0
1 -//package com.genersoft.iot.vmp.media.zlm;  
2 -//  
3 -//import com.genersoft.iot.vmp.conf.MediaConfig;  
4 -//import com.genersoft.iot.vmp.storager.IRedisCatchStorage;  
5 -//import org.springframework.beans.factory.annotation.Autowired;  
6 -//import org.springframework.beans.factory.annotation.Value;  
7 -//import org.springframework.web.bind.annotation.*;  
8 -//import org.springframework.web.client.HttpClientErrorException;  
9 -//import org.springframework.web.client.RestTemplate;  
10 -//  
11 -//import javax.servlet.http.HttpServletRequest;  
12 -//import javax.servlet.http.HttpServletResponse;  
13 -//  
14 -//@RestController  
15 -//@RequestMapping("/zlm")  
16 -//public class ZLMHTTPProxyController {  
17 -//  
18 -//  
19 -// // private final static Logger logger = LoggerFactory.getLogger(ZLMHTTPProxyController.class);  
20 -//  
21 -// @Autowired  
22 -// private IRedisCatchStorage redisCatchStorage;  
23 -//  
24 -// @Autowired  
25 -// private MediaConfig mediaConfig;  
26 -//  
27 -// @ResponseBody  
28 -// @RequestMapping(value = "/**/**/**", produces = "application/json;charset=UTF-8")  
29 -// public Object proxy(HttpServletRequest request, HttpServletResponse response){  
30 -//  
31 -// if (redisCatchStorage.getMediaInfo() == null) {  
32 -// return "未接入流媒体";  
33 -// }  
34 -// ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();  
35 -// String requestURI = String.format("http://%s:%s%s?%s&%s",  
36 -// mediaInfo.getLocalIP(),  
37 -// mediaConfig.getHttpPort(),  
38 -// request.getRequestURI().replace("/zlm",""),  
39 -// mediaInfo.getHookAdminParams(),  
40 -// request.getQueryString()  
41 -// );  
42 -// // 发送请求  
43 -// RestTemplate restTemplate = new RestTemplate();  
44 -// //将指定的url返回的参数自动封装到自定义好的对应类对象中  
45 -// Object result = null;  
46 -// try {  
47 -// result = restTemplate.getForObject(requestURI,Object.class);  
48 -//  
49 -// }catch (HttpClientErrorException httpClientErrorException) {  
50 -// response.setStatus(httpClientErrorException.getStatusCode().value());  
51 -// }  
52 -// return result;  
53 -// }  
54 -//}  
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -9,6 +9,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -9,6 +9,9 @@ import com.genersoft.iot.vmp.common.StreamInfo;
9 import com.genersoft.iot.vmp.conf.MediaConfig; 9 import com.genersoft.iot.vmp.conf.MediaConfig;
10 import com.genersoft.iot.vmp.conf.UserSetup; 10 import com.genersoft.iot.vmp.conf.UserSetup;
11 import com.genersoft.iot.vmp.gb28181.bean.Device; 11 import com.genersoft.iot.vmp.gb28181.bean.Device;
  12 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  13 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  14 +import com.genersoft.iot.vmp.service.IMediaServerService;
12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 16 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
14 import com.genersoft.iot.vmp.service.IPlayService; 17 import com.genersoft.iot.vmp.service.IPlayService;
@@ -53,10 +56,10 @@ public class ZLMHttpHookListener { @@ -53,10 +56,10 @@ public class ZLMHttpHookListener {
53 private IRedisCatchStorage redisCatchStorage; 56 private IRedisCatchStorage redisCatchStorage;
54 57
55 @Autowired 58 @Autowired
56 - private ZLMRESTfulUtils zlmresTfulUtils; 59 + private IMediaServerService mediaServerService;
57 60
58 @Autowired 61 @Autowired
59 - private ZLMServerManger zlmServerManger; 62 + private ZLMRESTfulUtils zlmresTfulUtils;
60 63
61 @Autowired 64 @Autowired
62 private ZLMMediaListManager zlmMediaListManager; 65 private ZLMMediaListManager zlmMediaListManager;
@@ -81,6 +84,7 @@ public class ZLMHttpHookListener { @@ -81,6 +84,7 @@ public class ZLMHttpHookListener {
81 if (logger.isDebugEnabled()) { 84 if (logger.isDebugEnabled()) {
82 logger.debug("ZLM HOOK on_flow_report API调用,参数:" + json.toString()); 85 logger.debug("ZLM HOOK on_flow_report API调用,参数:" + json.toString());
83 } 86 }
  87 + String mediaServerId = json.getString("mediaServerId");
84 JSONObject ret = new JSONObject(); 88 JSONObject ret = new JSONObject();
85 ret.put("code", 0); 89 ret.put("code", 0);
86 ret.put("msg", "success"); 90 ret.put("msg", "success");
@@ -98,6 +102,7 @@ public class ZLMHttpHookListener { @@ -98,6 +102,7 @@ public class ZLMHttpHookListener {
98 if (logger.isDebugEnabled()) { 102 if (logger.isDebugEnabled()) {
99 logger.debug("ZLM HOOK on_http_access API 调用,参数:" + json.toString()); 103 logger.debug("ZLM HOOK on_http_access API 调用,参数:" + json.toString());
100 } 104 }
  105 + String mediaServerId = json.getString("mediaServerId");
101 JSONObject ret = new JSONObject(); 106 JSONObject ret = new JSONObject();
102 ret.put("code", 0); 107 ret.put("code", 0);
103 ret.put("err", ""); 108 ret.put("err", "");
@@ -117,9 +122,14 @@ public class ZLMHttpHookListener { @@ -117,9 +122,14 @@ public class ZLMHttpHookListener {
117 if (logger.isDebugEnabled()) { 122 if (logger.isDebugEnabled()) {
118 logger.debug("ZLM HOOK on_play API调用,参数:" + json.toString()); 123 logger.debug("ZLM HOOK on_play API调用,参数:" + json.toString());
119 } 124 }
  125 + String mediaServerId = json.getString("mediaServerId");
120 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json); 126 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json);
121 if (subscribe != null ) { 127 if (subscribe != null ) {
122 - subscribe.response(json); 128 + IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
  129 + if (mediaInfo != null) {
  130 + subscribe.response(mediaInfo, json);
  131 + }
  132 +
123 } 133 }
124 JSONObject ret = new JSONObject(); 134 JSONObject ret = new JSONObject();
125 ret.put("code", 0); 135 ret.put("code", 0);
@@ -133,20 +143,25 @@ public class ZLMHttpHookListener { @@ -133,20 +143,25 @@ public class ZLMHttpHookListener {
133 */ 143 */
134 @ResponseBody 144 @ResponseBody
135 @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8") 145 @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8")
136 - public ResponseEntity<String> onPublish(@RequestBody JSONObject json){ 146 + public ResponseEntity<String> onPublish(@RequestBody JSONObject json) {
137 147
138 logger.debug("ZLM HOOK on_publish API调用,参数:" + json.toString()); 148 logger.debug("ZLM HOOK on_publish API调用,参数:" + json.toString());
139 149
  150 + String mediaServerId = json.getString("mediaServerId");
140 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); 151 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json);
141 - if (subscribe != null) subscribe.response(json);  
142 - 152 + if (subscribe != null) {
  153 + IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
  154 + if (mediaInfo != null) {
  155 + subscribe.response(mediaInfo, json);
  156 + }
  157 + }
143 JSONObject ret = new JSONObject(); 158 JSONObject ret = new JSONObject();
144 ret.put("code", 0); 159 ret.put("code", 0);
145 ret.put("msg", "success"); 160 ret.put("msg", "success");
146 ret.put("enableHls", true); 161 ret.put("enableHls", true);
147 ret.put("enableMP4", userSetup.isRecordPushLive()); 162 ret.put("enableMP4", userSetup.isRecordPushLive());
148 ret.put("enableRtxp", true); 163 ret.put("enableRtxp", true);
149 - return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); 164 + return new ResponseEntity<String>(ret.toString(), HttpStatus.OK);
150 } 165 }
151 166
152 /** 167 /**
@@ -160,6 +175,7 @@ public class ZLMHttpHookListener { @@ -160,6 +175,7 @@ public class ZLMHttpHookListener {
160 if (logger.isDebugEnabled()) { 175 if (logger.isDebugEnabled()) {
161 logger.debug("ZLM HOOK on_record_mp4 API调用,参数:" + json.toString()); 176 logger.debug("ZLM HOOK on_record_mp4 API调用,参数:" + json.toString());
162 } 177 }
  178 + String mediaServerId = json.getString("mediaServerId");
163 JSONObject ret = new JSONObject(); 179 JSONObject ret = new JSONObject();
164 ret.put("code", 0); 180 ret.put("code", 0);
165 ret.put("msg", "success"); 181 ret.put("msg", "success");
@@ -177,6 +193,7 @@ public class ZLMHttpHookListener { @@ -177,6 +193,7 @@ public class ZLMHttpHookListener {
177 if (logger.isDebugEnabled()) { 193 if (logger.isDebugEnabled()) {
178 logger.debug("ZLM HOOK on_rtsp_realm API调用,参数:" + json.toString()); 194 logger.debug("ZLM HOOK on_rtsp_realm API调用,参数:" + json.toString());
179 } 195 }
  196 + String mediaServerId = json.getString("mediaServerId");
180 JSONObject ret = new JSONObject(); 197 JSONObject ret = new JSONObject();
181 ret.put("code", 0); 198 ret.put("code", 0);
182 ret.put("realm", ""); 199 ret.put("realm", "");
@@ -195,6 +212,7 @@ public class ZLMHttpHookListener { @@ -195,6 +212,7 @@ public class ZLMHttpHookListener {
195 if (logger.isDebugEnabled()) { 212 if (logger.isDebugEnabled()) {
196 logger.debug("ZLM HOOK on_rtsp_auth API调用,参数:" + json.toString()); 213 logger.debug("ZLM HOOK on_rtsp_auth API调用,参数:" + json.toString());
197 } 214 }
  215 + String mediaServerId = json.getString("mediaServerId");
198 JSONObject ret = new JSONObject(); 216 JSONObject ret = new JSONObject();
199 ret.put("code", 0); 217 ret.put("code", 0);
200 ret.put("encrypted", false); 218 ret.put("encrypted", false);
@@ -216,9 +234,15 @@ public class ZLMHttpHookListener { @@ -216,9 +234,15 @@ public class ZLMHttpHookListener {
216 // TODO 如果是带有rtpstream则开启按需拉流 234 // TODO 如果是带有rtpstream则开启按需拉流
217 // String app = json.getString("app"); 235 // String app = json.getString("app");
218 // String stream = json.getString("stream"); 236 // String stream = json.getString("stream");
219 - 237 + String mediaServerId = json.getString("mediaServerId");
220 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json); 238 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json);
221 - if (subscribe != null) subscribe.response(json); 239 + if (subscribe != null ) {
  240 + IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
  241 + if (mediaInfo != null) {
  242 + subscribe.response(mediaInfo, json);
  243 + }
  244 +
  245 + }
222 246
223 JSONObject ret = new JSONObject(); 247 JSONObject ret = new JSONObject();
224 ret.put("code", 0); 248 ret.put("code", 0);
@@ -237,9 +261,15 @@ public class ZLMHttpHookListener { @@ -237,9 +261,15 @@ public class ZLMHttpHookListener {
237 if (logger.isDebugEnabled()) { 261 if (logger.isDebugEnabled()) {
238 logger.debug("ZLM HOOK on_stream_changed API调用,参数:" + json.toString()); 262 logger.debug("ZLM HOOK on_stream_changed API调用,参数:" + json.toString());
239 } 263 }
240 - 264 + String mediaServerId = json.getString("mediaServerId");
241 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json); 265 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json);
242 - if (subscribe != null) subscribe.response(json); 266 + if (subscribe != null ) {
  267 + IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
  268 + if (mediaInfo != null) {
  269 + subscribe.response(mediaInfo, json);
  270 + }
  271 +
  272 + }
243 273
244 // 流消失移除redis play 274 // 流消失移除redis play
245 String app = json.getString("app"); 275 String app = json.getString("app");
@@ -251,6 +281,11 @@ public class ZLMHttpHookListener { @@ -251,6 +281,11 @@ public class ZLMHttpHookListener {
251 logger.info("[stream: " + streamId + "] on_stream_changed->>" + schema); 281 logger.info("[stream: " + streamId + "] on_stream_changed->>" + schema);
252 } 282 }
253 if ("rtmp".equals(schema)){ 283 if ("rtmp".equals(schema)){
  284 + if (regist) {
  285 + mediaServerService.addCount(mediaServerId);
  286 + }else {
  287 + mediaServerService.removeCount(mediaServerId);
  288 + }
254 if ("rtp".equals(app) && !regist ) { 289 if ("rtp".equals(app) && !regist ) {
255 StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); 290 StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
256 if (streamInfo!=null){ 291 if (streamInfo!=null){
@@ -262,10 +297,11 @@ public class ZLMHttpHookListener { @@ -262,10 +297,11 @@ public class ZLMHttpHookListener {
262 } 297 }
263 }else { 298 }else {
264 if (!"rtp".equals(app) ){ 299 if (!"rtp".equals(app) ){
  300 + IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
265 if (regist) { 301 if (regist) {
266 - zlmMediaListManager.addMedia(app, streamId); 302 + zlmMediaListManager.addMedia(mediaServerItem, app, streamId);
267 }else { 303 }else {
268 - zlmMediaListManager.removeMedia(app, streamId); 304 + zlmMediaListManager.removeMedia( app, streamId);
269 } 305 }
270 } 306 }
271 } 307 }
@@ -288,7 +324,7 @@ public class ZLMHttpHookListener { @@ -288,7 +324,7 @@ public class ZLMHttpHookListener {
288 if (logger.isDebugEnabled()) { 324 if (logger.isDebugEnabled()) {
289 logger.debug("ZLM HOOK on_stream_none_reader API调用,参数:" + json.toString()); 325 logger.debug("ZLM HOOK on_stream_none_reader API调用,参数:" + json.toString());
290 } 326 }
291 - 327 + String mediaServerId = json.getString("mediaServerId");
292 String streamId = json.getString("stream"); 328 String streamId = json.getString("stream");
293 String app = json.getString("app"); 329 String app = json.getString("app");
294 330
@@ -329,11 +365,12 @@ public class ZLMHttpHookListener { @@ -329,11 +365,12 @@ public class ZLMHttpHookListener {
329 @ResponseBody 365 @ResponseBody
330 @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") 366 @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8")
331 public ResponseEntity<String> onStreamNotFound(@RequestBody JSONObject json){ 367 public ResponseEntity<String> onStreamNotFound(@RequestBody JSONObject json){
332 -  
333 if (logger.isDebugEnabled()) { 368 if (logger.isDebugEnabled()) {
334 logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString()); 369 logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString());
335 } 370 }
336 - if (userSetup.isAutoApplyPlay()) { 371 + String mediaServerId = json.getString("mediaServerId");
  372 + IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
  373 + if (userSetup.isAutoApplyPlay() && mediaInfo != null) {
337 String app = json.getString("app"); 374 String app = json.getString("app");
338 String streamId = json.getString("stream"); 375 String streamId = json.getString("stream");
339 if ("rtp".equals(app) && streamId.contains("gb_play") ) { 376 if ("rtp".equals(app) && streamId.contains("gb_play") ) {
@@ -344,9 +381,9 @@ public class ZLMHttpHookListener { @@ -344,9 +381,9 @@ public class ZLMHttpHookListener {
344 Device device = storager.queryVideoDevice(deviceId); 381 Device device = storager.queryVideoDevice(deviceId);
345 if (device != null) { 382 if (device != null) {
346 UUID uuid = UUID.randomUUID(); 383 UUID uuid = UUID.randomUUID();
347 - cmder.playStreamCmd(device, channelId, (JSONObject response) -> { 384 + cmder.playStreamCmd(mediaInfo, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> {
348 logger.info("收到订阅消息: " + response.toJSONString()); 385 logger.info("收到订阅消息: " + response.toJSONString());
349 - playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); 386 + playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());
350 }, null); 387 }, null);
351 } 388 }
352 389
@@ -367,26 +404,19 @@ public class ZLMHttpHookListener { @@ -367,26 +404,19 @@ public class ZLMHttpHookListener {
367 */ 404 */
368 @ResponseBody 405 @ResponseBody
369 @PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8") 406 @PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8")
370 - public ResponseEntity<String> onServerStarted(HttpServletRequest request, @RequestBody JSONObject json){ 407 + public ResponseEntity<String> onServerStarted(HttpServletRequest request, @RequestBody JSONObject jsonObject){
371 408
372 if (logger.isDebugEnabled()) { 409 if (logger.isDebugEnabled()) {
373 - logger.debug("ZLM HOOK on_server_started API调用,参数:" + json.toString()); 410 + logger.debug("ZLM HOOK on_server_started API调用,参数:" + jsonObject.toString());
374 } 411 }
375 -  
376 -// String data = json.getString("data");  
377 -// List<MediaServerConfig> mediaServerConfigs = JSON.parseArray(JSON.toJSONString(json), MediaServerConfig.class);  
378 -// MediaServerConfig mediaServerConfig = mediaServerConfigs.get(0);  
379 - 412 + String remoteAddr = request.getRemoteAddr();
  413 + jsonObject.put("ip", remoteAddr);
380 List<ZLMHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(ZLMHttpHookSubscribe.HookType.on_server_started); 414 List<ZLMHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(ZLMHttpHookSubscribe.HookType.on_server_started);
381 - if (subscribes != null && subscribes.size() > 0) { 415 + if (subscribes != null && subscribes.size() > 0) {
382 for (ZLMHttpHookSubscribe.Event subscribe : subscribes) { 416 for (ZLMHttpHookSubscribe.Event subscribe : subscribes) {
383 - subscribe.response(json); 417 + subscribe.response(null, jsonObject);
384 } 418 }
385 } 419 }
386 - ZLMServerConfig ZLMServerConfig = JSON.toJavaObject(json, ZLMServerConfig.class);  
387 - zlmServerManger.updateServerCatch(ZLMServerConfig);  
388 - // 重新发起代理  
389 -  
390 JSONObject ret = new JSONObject(); 420 JSONObject ret = new JSONObject();
391 ret.put("code", 0); 421 ret.put("code", 0);
392 ret.put("msg", "success"); 422 ret.put("msg", "success");
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
1 package com.genersoft.iot.vmp.media.zlm; 1 package com.genersoft.iot.vmp.media.zlm;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
4 import org.springframework.stereotype.Component; 6 import org.springframework.stereotype.Component;
5 7
6 import java.util.*; 8 import java.util.*;
@@ -30,7 +32,7 @@ public class ZLMHttpHookSubscribe { @@ -30,7 +32,7 @@ public class ZLMHttpHookSubscribe {
30 } 32 }
31 33
32 public interface Event{ 34 public interface Event{
33 - void response(JSONObject response); 35 + void response(IMediaServerItem mediaServerItem, JSONObject response);
34 } 36 }
35 37
36 private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); 38 private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>();
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
@@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.media.zlm; @@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.media.zlm;
2 2
3 import com.alibaba.fastjson.JSONArray; 3 import com.alibaba.fastjson.JSONArray;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
5 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
6 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 8 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
7 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 9 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
@@ -45,11 +47,11 @@ public class ZLMMediaListManager { @@ -45,11 +47,11 @@ public class ZLMMediaListManager {
45 private ZLMHttpHookSubscribe subscribe; 47 private ZLMHttpHookSubscribe subscribe;
46 48
47 49
48 - public void updateMediaList() { 50 + public void updateMediaList(MediaServerItem mediaServerItem) {
49 storager.clearMediaList(); 51 storager.clearMediaList();
50 52
51 // 使用异步的当时更新媒体流列表 53 // 使用异步的当时更新媒体流列表
52 - zlmresTfulUtils.getMediaList((mediaList ->{ 54 + zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{
53 if (mediaList == null) return; 55 if (mediaList == null) return;
54 String dataStr = mediaList.getString("data"); 56 String dataStr = mediaList.getString("data");
55 57
@@ -57,10 +59,10 @@ public class ZLMMediaListManager { @@ -57,10 +59,10 @@ public class ZLMMediaListManager {
57 Map<String, StreamPushItem> result = new HashMap<>(); 59 Map<String, StreamPushItem> result = new HashMap<>();
58 List<StreamPushItem> streamPushItems = null; 60 List<StreamPushItem> streamPushItems = null;
59 // 获取所有的国标关联 61 // 获取所有的国标关联
60 - List<GbStream> gbStreams = gbStreamMapper.selectAll(); 62 +// List<GbStream> gbStreams = gbStreamMapper.selectAllByMediaServerId(mediaServerItem.getId());
61 if (code == 0 ) { 63 if (code == 0 ) {
62 if (dataStr != null) { 64 if (dataStr != null) {
63 - streamPushItems = streamPushService.handleJSON(dataStr); 65 + streamPushItems = streamPushService.handleJSON(dataStr, mediaServerItem);
64 } 66 }
65 }else { 67 }else {
66 logger.warn("更新视频流失败,错误code: " + code); 68 logger.warn("更新视频流失败,错误code: " + code);
@@ -72,24 +74,27 @@ public class ZLMMediaListManager { @@ -72,24 +74,27 @@ public class ZLMMediaListManager {
72 JSONObject jsonObject = new JSONObject(); 74 JSONObject jsonObject = new JSONObject();
73 jsonObject.put("app", streamPushItem.getApp()); 75 jsonObject.put("app", streamPushItem.getApp());
74 jsonObject.put("stream", streamPushItem.getStream()); 76 jsonObject.put("stream", streamPushItem.getStream());
75 - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject,(response)->{  
76 - updateMedia(response.getString("app"), response.getString("stream"));  
77 - }); 77 + jsonObject.put("mediaServerId", mediaServerItem.getId());
  78 + subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject,
  79 + (IMediaServerItem mediaServerItemInuse, JSONObject response)->{
  80 + updateMedia(mediaServerItem, response.getString("app"), response.getString("stream"));
  81 + }
  82 + );
78 } 83 }
79 } 84 }
80 })); 85 }));
81 86
82 } 87 }
83 88
84 - public void addMedia(String app, String streamId) { 89 + public void addMedia(IMediaServerItem mediaServerItem, String app, String streamId) {
85 //使用异步更新推流 90 //使用异步更新推流
86 - updateMedia(app, streamId); 91 + updateMedia(mediaServerItem, app, streamId);
87 } 92 }
88 93
89 94
90 - public void updateMedia(String app, String streamId) { 95 + public void updateMedia(IMediaServerItem mediaServerItem, String app, String streamId) {
91 //使用异步更新推流 96 //使用异步更新推流
92 - zlmresTfulUtils.getMediaList(app, streamId, "rtmp", json->{ 97 + zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{
93 98
94 if (json == null) return; 99 if (json == null) return;
95 String dataStr = json.getString("data"); 100 String dataStr = json.getString("data");
@@ -99,7 +104,7 @@ public class ZLMMediaListManager { @@ -99,7 +104,7 @@ public class ZLMMediaListManager {
99 List<StreamPushItem> streamPushItems = null; 104 List<StreamPushItem> streamPushItems = null;
100 if (code == 0 ) { 105 if (code == 0 ) {
101 if (dataStr != null) { 106 if (dataStr != null) {
102 - streamPushItems = streamPushService.handleJSON(dataStr); 107 + streamPushItems = streamPushService.handleJSON(dataStr, mediaServerItem);
103 } 108 }
104 }else { 109 }else {
105 logger.warn("更新视频流失败,错误code: " + code); 110 logger.warn("更新视频流失败,错误code: " + code);
@@ -122,32 +127,32 @@ public class ZLMMediaListManager { @@ -122,32 +127,32 @@ public class ZLMMediaListManager {
122 } 127 }
123 } 128 }
124 129
125 - public void clearAllSessions() {  
126 - logger.info("清空所有国标相关的session");  
127 - JSONObject allSessionJSON = zlmresTfulUtils.getAllSession();  
128 - ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();  
129 - HashSet<String> allLocalPorts = new HashSet();  
130 - if (allSessionJSON.getInteger("code") == 0) {  
131 - JSONArray data = allSessionJSON.getJSONArray("data");  
132 - if (data.size() > 0) {  
133 - for (int i = 0; i < data.size(); i++) {  
134 - JSONObject sessionJOSN = data.getJSONObject(i);  
135 - Integer local_port = sessionJOSN.getInteger("local_port");  
136 - if (!local_port.equals(Integer.valueOf(mediaInfo.getHttpPort())) &&  
137 - !local_port.equals(Integer.valueOf(mediaInfo.getHttpSSLport())) &&  
138 - !local_port.equals(Integer.valueOf(mediaInfo.getRtmpPort())) &&  
139 - !local_port.equals(Integer.valueOf(mediaInfo.getRtspPort())) &&  
140 - !local_port.equals(Integer.valueOf(mediaInfo.getRtspSSlport())) &&  
141 - !local_port.equals(Integer.valueOf(mediaInfo.getHookOnFlowReport()))){  
142 - allLocalPorts.add(sessionJOSN.getInteger("local_port") + "");  
143 - }  
144 - }  
145 - }  
146 - }  
147 - if (allLocalPorts.size() > 0) {  
148 - List<String> result = new ArrayList<>(allLocalPorts);  
149 - String localPortSStr = String.join(",", result);  
150 - zlmresTfulUtils.kickSessions(localPortSStr);  
151 - }  
152 - } 130 +// public void clearAllSessions() {
  131 +// logger.info("清空所有国标相关的session");
  132 +// JSONObject allSessionJSON = zlmresTfulUtils.getAllSession();
  133 +// ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
  134 +// HashSet<String> allLocalPorts = new HashSet();
  135 +// if (allSessionJSON.getInteger("code") == 0) {
  136 +// JSONArray data = allSessionJSON.getJSONArray("data");
  137 +// if (data.size() > 0) {
  138 +// for (int i = 0; i < data.size(); i++) {
  139 +// JSONObject sessionJOSN = data.getJSONObject(i);
  140 +// Integer local_port = sessionJOSN.getInteger("local_port");
  141 +// if (!local_port.equals(Integer.valueOf(mediaInfo.getHttpPort())) &&
  142 +// !local_port.equals(Integer.valueOf(mediaInfo.getHttpSSLport())) &&
  143 +// !local_port.equals(Integer.valueOf(mediaInfo.getRtmpPort())) &&
  144 +// !local_port.equals(Integer.valueOf(mediaInfo.getRtspPort())) &&
  145 +// !local_port.equals(Integer.valueOf(mediaInfo.getRtspSSlport())) &&
  146 +// !local_port.equals(Integer.valueOf(mediaInfo.getHookOnFlowReport()))){
  147 +// allLocalPorts.add(sessionJOSN.getInteger("local_port") + "");
  148 +// }
  149 +// }
  150 +// }
  151 +// }
  152 +// if (allLocalPorts.size() > 0) {
  153 +// List<String> result = new ArrayList<>(allLocalPorts);
  154 +// String localPortSStr = String.join(",", result);
  155 +// zlmresTfulUtils.kickSessions(localPortSStr);
  156 +// }
  157 +// }
153 } 158 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.media.zlm; @@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.media.zlm;
3 import com.alibaba.fastjson.JSON; 3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
5 import com.genersoft.iot.vmp.conf.MediaConfig; 5 import com.genersoft.iot.vmp.conf.MediaConfig;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import okhttp3.*; 8 import okhttp3.*;
7 import org.jetbrains.annotations.NotNull; 9 import org.jetbrains.annotations.NotNull;
8 import org.slf4j.Logger; 10 import org.slf4j.Logger;
@@ -21,23 +23,18 @@ public class ZLMRESTfulUtils { @@ -21,23 +23,18 @@ public class ZLMRESTfulUtils {
21 23
22 private final static Logger logger = LoggerFactory.getLogger(ZLMRESTfulUtils.class); 24 private final static Logger logger = LoggerFactory.getLogger(ZLMRESTfulUtils.class);
23 25
24 - @Autowired  
25 - private MediaConfig mediaConfig;  
26 -  
27 -  
28 -  
29 public interface RequestCallback{ 26 public interface RequestCallback{
30 void run(JSONObject response); 27 void run(JSONObject response);
31 } 28 }
32 29
33 - public JSONObject sendPost(String api, Map<String, Object> param, RequestCallback callback) { 30 + public JSONObject sendPost(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) {
34 OkHttpClient client = new OkHttpClient(); 31 OkHttpClient client = new OkHttpClient();
35 - String url = String.format("http://%s:%s/index/api/%s", mediaConfig.getIp(), mediaConfig.getHttpPort(), api); 32 + String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
36 JSONObject responseJSON = null; 33 JSONObject responseJSON = null;
37 logger.debug(url); 34 logger.debug(url);
38 35
39 FormBody.Builder builder = new FormBody.Builder(); 36 FormBody.Builder builder = new FormBody.Builder();
40 - builder.add("secret",mediaConfig.getSecret()); 37 + builder.add("secret",mediaServerItem.getSecret());
41 if (param != null && param.keySet().size() > 0) { 38 if (param != null && param.keySet().size() > 0) {
42 for (String key : param.keySet()){ 39 for (String key : param.keySet()){
43 if (param.get(key) != null) { 40 if (param.get(key) != null) {
@@ -96,14 +93,14 @@ public class ZLMRESTfulUtils { @@ -96,14 +93,14 @@ public class ZLMRESTfulUtils {
96 } 93 }
97 94
98 95
99 - public void sendPostForImg(String api, Map<String, Object> param, String targetPath, String fileName) { 96 + public void sendPostForImg(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) {
100 OkHttpClient client = new OkHttpClient(); 97 OkHttpClient client = new OkHttpClient();
101 - String url = String.format("http://%s:%s/index/api/%s", mediaConfig.getIp(), mediaConfig.getHttpPort(), api); 98 + String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
102 JSONObject responseJSON = null; 99 JSONObject responseJSON = null;
103 logger.debug(url); 100 logger.debug(url);
104 101
105 FormBody.Builder builder = new FormBody.Builder(); 102 FormBody.Builder builder = new FormBody.Builder();
106 - builder.add("secret",mediaConfig.getSecret()); 103 + builder.add("secret",mediaServerItem.getSecret());
107 if (param != null && param.keySet().size() > 0) { 104 if (param != null && param.keySet().size() > 0) {
108 for (String key : param.keySet()){ 105 for (String key : param.keySet()){
109 if (param.get(key) != null) { 106 if (param.get(key) != null) {
@@ -142,39 +139,39 @@ public class ZLMRESTfulUtils { @@ -142,39 +139,39 @@ public class ZLMRESTfulUtils {
142 } 139 }
143 140
144 141
145 - public JSONObject getMediaList(String app, String stream, String schema, RequestCallback callback){ 142 + public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream, String schema, RequestCallback callback){
146 Map<String, Object> param = new HashMap<>(); 143 Map<String, Object> param = new HashMap<>();
147 if (app != null) param.put("app",app); 144 if (app != null) param.put("app",app);
148 if (stream != null) param.put("stream",stream); 145 if (stream != null) param.put("stream",stream);
149 if (schema != null) param.put("schema",schema); 146 if (schema != null) param.put("schema",schema);
150 param.put("vhost","__defaultVhost__"); 147 param.put("vhost","__defaultVhost__");
151 - return sendPost("getMediaList",param, callback); 148 + return sendPost(mediaServerItem, "getMediaList",param, callback);
152 } 149 }
153 150
154 - public JSONObject getMediaList(String app, String stream){  
155 - return getMediaList(app, stream,null, null); 151 + public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream){
  152 + return getMediaList(mediaServerItem, app, stream,null, null);
156 } 153 }
157 154
158 - public JSONObject getMediaList(RequestCallback callback){  
159 - return sendPost("getMediaList",null, callback); 155 + public JSONObject getMediaList(IMediaServerItem mediaServerItem,RequestCallback callback){
  156 + return sendPost(mediaServerItem, "getMediaList",null, callback);
160 } 157 }
161 158
162 - public JSONObject getMediaInfo(String app, String schema, String stream){ 159 + public JSONObject getMediaInfo(IMediaServerItem mediaServerItem,String app, String schema, String stream){
163 Map<String, Object> param = new HashMap<>(); 160 Map<String, Object> param = new HashMap<>();
164 param.put("app",app); 161 param.put("app",app);
165 param.put("schema",schema); 162 param.put("schema",schema);
166 param.put("stream",stream); 163 param.put("stream",stream);
167 param.put("vhost","__defaultVhost__"); 164 param.put("vhost","__defaultVhost__");
168 - return sendPost("getMediaInfo",param, null); 165 + return sendPost(mediaServerItem, "getMediaInfo",param, null);
169 } 166 }
170 167
171 - public JSONObject getRtpInfo(String stream_id){ 168 + public JSONObject getRtpInfo(IMediaServerItem mediaServerItem,String stream_id){
172 Map<String, Object> param = new HashMap<>(); 169 Map<String, Object> param = new HashMap<>();
173 param.put("stream_id",stream_id); 170 param.put("stream_id",stream_id);
174 - return sendPost("getRtpInfo",param, null); 171 + return sendPost(mediaServerItem, "getRtpInfo",param, null);
175 } 172 }
176 173
177 - public JSONObject addFFmpegSource(String src_url, String dst_url, String timeout_ms, 174 + public JSONObject addFFmpegSource(IMediaServerItem mediaServerItem,String src_url, String dst_url, String timeout_ms,
178 boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){ 175 boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){
179 logger.info(src_url); 176 logger.info(src_url);
180 logger.info(dst_url); 177 logger.info(dst_url);
@@ -185,44 +182,44 @@ public class ZLMRESTfulUtils { @@ -185,44 +182,44 @@ public class ZLMRESTfulUtils {
185 param.put("enable_hls", enable_hls); 182 param.put("enable_hls", enable_hls);
186 param.put("enable_mp4", enable_mp4); 183 param.put("enable_mp4", enable_mp4);
187 param.put("ffmpeg_cmd_key", ffmpeg_cmd_key); 184 param.put("ffmpeg_cmd_key", ffmpeg_cmd_key);
188 - return sendPost("addFFmpegSource",param, null); 185 + return sendPost(mediaServerItem, "addFFmpegSource",param, null);
189 } 186 }
190 187
191 - public JSONObject delFFmpegSource(String key){ 188 + public JSONObject delFFmpegSource(IMediaServerItem mediaServerItem,String key){
192 Map<String, Object> param = new HashMap<>(); 189 Map<String, Object> param = new HashMap<>();
193 param.put("key", key); 190 param.put("key", key);
194 - return sendPost("delFFmpegSource",param, null); 191 + return sendPost(mediaServerItem, "delFFmpegSource",param, null);
195 } 192 }
196 193
197 - public JSONObject getMediaServerConfig(){  
198 - return sendPost("getServerConfig",null, null); 194 + public JSONObject getMediaServerConfig(IMediaServerItem mediaServerItem){
  195 + return sendPost(mediaServerItem, "getServerConfig",null, null);
199 } 196 }
200 197
201 - public JSONObject setServerConfig(Map<String, Object> param){  
202 - return sendPost("setServerConfig",param, null); 198 + public JSONObject setServerConfig(IMediaServerItem mediaServerItem, Map<String, Object> param){
  199 + return sendPost(mediaServerItem,"setServerConfig",param, null);
203 } 200 }
204 201
205 - public JSONObject openRtpServer(Map<String, Object> param){  
206 - return sendPost("openRtpServer",param, null); 202 + public JSONObject openRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param){
  203 + return sendPost(mediaServerItem, "openRtpServer",param, null);
207 } 204 }
208 205
209 - public JSONObject closeRtpServer(Map<String, Object> param) {  
210 - return sendPost("closeRtpServer",param, null); 206 + public JSONObject closeRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param) {
  207 + return sendPost(mediaServerItem, "closeRtpServer",param, null);
211 } 208 }
212 209
213 - public JSONObject listRtpServer() {  
214 - return sendPost("listRtpServer",null, null); 210 + public JSONObject listRtpServer(IMediaServerItem mediaServerItem) {
  211 + return sendPost(mediaServerItem, "listRtpServer",null, null);
215 } 212 }
216 213
217 - public JSONObject startSendRtp(Map<String, Object> param) {  
218 - return sendPost("startSendRtp",param, null); 214 + public JSONObject startSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) {
  215 + return sendPost(mediaServerItem, "startSendRtp",param, null);
219 } 216 }
220 217
221 - public JSONObject stopSendRtp(Map<String, Object> param) {  
222 - return sendPost("stopSendRtp",param, null); 218 + public JSONObject stopSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) {
  219 + return sendPost(mediaServerItem, "stopSendRtp",param, null);
223 } 220 }
224 221
225 - public JSONObject addStreamProxy(String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) { 222 + public JSONObject addStreamProxy(IMediaServerItem mediaServerItem,String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) {
226 Map<String, Object> param = new HashMap<>(); 223 Map<String, Object> param = new HashMap<>();
227 param.put("vhost", "__defaultVhost__"); 224 param.put("vhost", "__defaultVhost__");
228 param.put("app", app); 225 param.put("app", app);
@@ -231,33 +228,33 @@ public class ZLMRESTfulUtils { @@ -231,33 +228,33 @@ public class ZLMRESTfulUtils {
231 param.put("enable_hls", enable_hls?1:0); 228 param.put("enable_hls", enable_hls?1:0);
232 param.put("enable_mp4", enable_mp4?1:0); 229 param.put("enable_mp4", enable_mp4?1:0);
233 param.put("rtp_type", rtp_type); 230 param.put("rtp_type", rtp_type);
234 - return sendPost("addStreamProxy",param, null); 231 + return sendPost(mediaServerItem, "addStreamProxy",param, null);
235 } 232 }
236 233
237 - public JSONObject closeStreams(String app, String stream) { 234 + public JSONObject closeStreams(IMediaServerItem mediaServerItem,String app, String stream) {
238 Map<String, Object> param = new HashMap<>(); 235 Map<String, Object> param = new HashMap<>();
239 param.put("vhost", "__defaultVhost__"); 236 param.put("vhost", "__defaultVhost__");
240 param.put("app", app); 237 param.put("app", app);
241 param.put("stream", stream); 238 param.put("stream", stream);
242 param.put("force", 1); 239 param.put("force", 1);
243 - return sendPost("close_streams",param, null); 240 + return sendPost(mediaServerItem, "close_streams",param, null);
244 } 241 }
245 242
246 - public JSONObject getAllSession() {  
247 - return sendPost("getAllSession",null, null); 243 + public JSONObject getAllSession(IMediaServerItem mediaServerItem) {
  244 + return sendPost(mediaServerItem, "getAllSession",null, null);
248 } 245 }
249 246
250 - public void kickSessions(String localPortSStr) { 247 + public void kickSessions(IMediaServerItem mediaServerItem, String localPortSStr) {
251 Map<String, Object> param = new HashMap<>(); 248 Map<String, Object> param = new HashMap<>();
252 param.put("local_port", localPortSStr); 249 param.put("local_port", localPortSStr);
253 - sendPost("kick_sessions",param, null); 250 + sendPost(mediaServerItem, "kick_sessions",param, null);
254 } 251 }
255 252
256 - public void getSnap(String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { 253 + public void getSnap(IMediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) {
257 Map<String, Object> param = new HashMap<>(); 254 Map<String, Object> param = new HashMap<>();
258 param.put("url", flvUrl); 255 param.put("url", flvUrl);
259 param.put("timeout_sec", timeout_sec); 256 param.put("timeout_sec", timeout_sec);
260 param.put("expire_sec", expire_sec); 257 param.put("expire_sec", expire_sec);
261 - sendPostForImg("getSnap",param, targetPath, fileName); 258 + sendPostForImg(mediaServerItem, "getSnap",param, targetPath, fileName);
262 } 259 }
263 } 260 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject; @@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject;
5 import com.genersoft.iot.vmp.conf.MediaConfig; 5 import com.genersoft.iot.vmp.conf.MediaConfig;
6 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 6 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
7 import com.genersoft.iot.vmp.gb28181.session.SsrcUtil; 7 import com.genersoft.iot.vmp.gb28181.session.SsrcUtil;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  9 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import org.slf4j.Logger; 10 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
10 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,10 +32,10 @@ public class ZLMRTPServerFactory { @@ -30,10 +32,10 @@ public class ZLMRTPServerFactory {
30 32
31 private Map<String, Integer> currentStreams = null; 33 private Map<String, Integer> currentStreams = null;
32 34
33 - public int createRTPServer(String streamId) { 35 + public int createRTPServer(IMediaServerItem mediaServerItem, String streamId) {
34 if (currentStreams == null) { 36 if (currentStreams == null) {
35 currentStreams = new HashMap<>(); 37 currentStreams = new HashMap<>();
36 - JSONObject jsonObject = zlmresTfulUtils.listRtpServer(); 38 + JSONObject jsonObject = zlmresTfulUtils.listRtpServer(mediaServerItem);
37 if (jsonObject != null) { 39 if (jsonObject != null) {
38 JSONArray data = jsonObject.getJSONArray("data"); 40 JSONArray data = jsonObject.getJSONArray("data");
39 if (data != null) { 41 if (data != null) {
@@ -48,7 +50,7 @@ public class ZLMRTPServerFactory { @@ -48,7 +50,7 @@ public class ZLMRTPServerFactory {
48 if (currentStreams.get(streamId) != null) { 50 if (currentStreams.get(streamId) != null) {
49 Map<String, Object> closeRtpServerParam = new HashMap<>(); 51 Map<String, Object> closeRtpServerParam = new HashMap<>();
50 closeRtpServerParam.put("stream_id", streamId); 52 closeRtpServerParam.put("stream_id", streamId);
51 - zlmresTfulUtils.closeRtpServer(closeRtpServerParam); 53 + zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam);
52 currentStreams.remove(streamId); 54 currentStreams.remove(streamId);
53 } 55 }
54 56
@@ -58,7 +60,7 @@ public class ZLMRTPServerFactory { @@ -58,7 +60,7 @@ public class ZLMRTPServerFactory {
58 param.put("port", newPort); 60 param.put("port", newPort);
59 param.put("enable_tcp", 1); 61 param.put("enable_tcp", 1);
60 param.put("stream_id", streamId); 62 param.put("stream_id", streamId);
61 - JSONObject jsonObject = zlmresTfulUtils.openRtpServer(param); 63 + JSONObject jsonObject = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
62 64
63 if (jsonObject != null) { 65 if (jsonObject != null) {
64 switch (jsonObject.getInteger("code")){ 66 switch (jsonObject.getInteger("code")){
@@ -68,11 +70,11 @@ public class ZLMRTPServerFactory { @@ -68,11 +70,11 @@ public class ZLMRTPServerFactory {
68 case -300: // id已经存在, 可能已经在其他端口推流 70 case -300: // id已经存在, 可能已经在其他端口推流
69 Map<String, Object> closeRtpServerParam = new HashMap<>(); 71 Map<String, Object> closeRtpServerParam = new HashMap<>();
70 closeRtpServerParam.put("stream_id", streamId); 72 closeRtpServerParam.put("stream_id", streamId);
71 - zlmresTfulUtils.closeRtpServer(closeRtpServerParam); 73 + zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam);
72 result = newPort; 74 result = newPort;
73 break; 75 break;
74 case -400: // 端口占用 76 case -400: // 端口占用
75 - result= createRTPServer(streamId); 77 + result= createRTPServer(mediaServerItem, streamId);
76 break; 78 break;
77 default: 79 default:
78 logger.error("创建RTP Server 失败 {}: " + jsonObject.getString("msg"), newPort); 80 logger.error("创建RTP Server 失败 {}: " + jsonObject.getString("msg"), newPort);
@@ -85,20 +87,22 @@ public class ZLMRTPServerFactory { @@ -85,20 +87,22 @@ public class ZLMRTPServerFactory {
85 return result; 87 return result;
86 } 88 }
87 89
88 - public boolean closeRTPServer(String streamId) { 90 + public boolean closeRTPServer(IMediaServerItem serverItem, String streamId) {
89 boolean result = false; 91 boolean result = false;
90 - Map<String, Object> param = new HashMap<>();  
91 - param.put("stream_id", streamId);  
92 - JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(param);  
93 - if (jsonObject != null ) {  
94 - if (jsonObject.getInteger("code") == 0) {  
95 - result = jsonObject.getInteger("hit") == 1; 92 + if (serverItem !=null){
  93 + Map<String, Object> param = new HashMap<>();
  94 + param.put("stream_id", streamId);
  95 + JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(serverItem, param);
  96 + if (jsonObject != null ) {
  97 + if (jsonObject.getInteger("code") == 0) {
  98 + result = jsonObject.getInteger("hit") == 1;
  99 + }else {
  100 + logger.error("关闭RTP Server 失败: " + jsonObject.getString("msg"));
  101 + }
96 }else { 102 }else {
97 - logger.error("关闭RTP Server 失败: " + jsonObject.getString("msg")); 103 + // 检查ZLM状态
  104 + logger.error("关闭RTP Server 失败: 请检查ZLM服务");
98 } 105 }
99 - }else {  
100 - // 检查ZLM状态  
101 - logger.error("关闭RTP Server 失败: 请检查ZLM服务");  
102 } 106 }
103 return result; 107 return result;
104 } 108 }
@@ -131,11 +135,11 @@ public class ZLMRTPServerFactory { @@ -131,11 +135,11 @@ public class ZLMRTPServerFactory {
131 * @param tcp 是否为tcp 135 * @param tcp 是否为tcp
132 * @return SendRtpItem 136 * @return SendRtpItem
133 */ 137 */
134 - public SendRtpItem createSendRtpItem(String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){ 138 + public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){
135 String playSsrc = SsrcUtil.getPlaySsrc(); 139 String playSsrc = SsrcUtil.getPlaySsrc();
136 - int localPort = createRTPServer(SsrcUtil.getPlaySsrc()); 140 + int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc());
137 if (localPort != -1) { 141 if (localPort != -1) {
138 - closeRTPServer(playSsrc); 142 + closeRTPServer(serverItem, playSsrc);
139 }else { 143 }else {
140 logger.error("没有可用的端口"); 144 logger.error("没有可用的端口");
141 return null; 145 return null;
@@ -150,6 +154,7 @@ public class ZLMRTPServerFactory { @@ -150,6 +154,7 @@ public class ZLMRTPServerFactory {
150 sendRtpItem.setTcp(tcp); 154 sendRtpItem.setTcp(tcp);
151 sendRtpItem.setApp("rtp"); 155 sendRtpItem.setApp("rtp");
152 sendRtpItem.setLocalPort(localPort); 156 sendRtpItem.setLocalPort(localPort);
  157 + sendRtpItem.setMediaServerId(serverItem.getId());
153 return sendRtpItem; 158 return sendRtpItem;
154 } 159 }
155 160
@@ -163,11 +168,11 @@ public class ZLMRTPServerFactory { @@ -163,11 +168,11 @@ public class ZLMRTPServerFactory {
163 * @param tcp 是否为tcp 168 * @param tcp 是否为tcp
164 * @return SendRtpItem 169 * @return SendRtpItem
165 */ 170 */
166 - public SendRtpItem createSendRtpItem(String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){ 171 + public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
167 String playSsrc = SsrcUtil.getPlaySsrc(); 172 String playSsrc = SsrcUtil.getPlaySsrc();
168 - int localPort = createRTPServer(SsrcUtil.getPlaySsrc()); 173 + int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc());
169 if (localPort != -1) { 174 if (localPort != -1) {
170 - closeRTPServer(playSsrc); 175 + closeRTPServer(serverItem, playSsrc);
171 }else { 176 }else {
172 logger.error("没有可用的端口"); 177 logger.error("没有可用的端口");
173 return null; 178 return null;
@@ -182,21 +187,21 @@ public class ZLMRTPServerFactory { @@ -182,21 +187,21 @@ public class ZLMRTPServerFactory {
182 sendRtpItem.setChannelId(channelId); 187 sendRtpItem.setChannelId(channelId);
183 sendRtpItem.setTcp(tcp); 188 sendRtpItem.setTcp(tcp);
184 sendRtpItem.setLocalPort(localPort); 189 sendRtpItem.setLocalPort(localPort);
  190 + sendRtpItem.setMediaServerId(serverItem.getId());
185 return sendRtpItem; 191 return sendRtpItem;
186 } 192 }
187 193
188 /** 194 /**
189 * 调用zlm RESTful API —— startSendRtp 195 * 调用zlm RESTful API —— startSendRtp
190 */ 196 */
191 - public Boolean startSendRtpStream(Map<String, Object>param) { 197 + public Boolean startSendRtpStream(IMediaServerItem mediaServerItem, Map<String, Object>param) {
192 Boolean result = false; 198 Boolean result = false;
193 - JSONObject jsonObject = zlmresTfulUtils.startSendRtp(param);  
194 - logger.info(jsonObject.toJSONString()); 199 + JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param);
195 if (jsonObject == null) { 200 if (jsonObject == null) {
196 logger.error("RTP推流失败: 请检查ZLM服务"); 201 logger.error("RTP推流失败: 请检查ZLM服务");
197 } else if (jsonObject.getInteger("code") == 0) { 202 } else if (jsonObject.getInteger("code") == 0) {
198 result= true; 203 result= true;
199 - logger.info("RTP推流请求成功,本地推流端口:" + jsonObject.getString("local_port")); 204 + logger.info("RTP推流[ {}/{} ]请求成功,本地推流端口:{}" ,param.get("app"), param.get("stream"), jsonObject.getString("local_port"));
200 } else { 205 } else {
201 logger.error("RTP推流失败: " + jsonObject.getString("msg")); 206 logger.error("RTP推流失败: " + jsonObject.getString("msg"));
202 } 207 }
@@ -206,16 +211,16 @@ public class ZLMRTPServerFactory { @@ -206,16 +211,16 @@ public class ZLMRTPServerFactory {
206 /** 211 /**
207 * 查询待转推的流是否就绪 212 * 查询待转推的流是否就绪
208 */ 213 */
209 - public Boolean isRtpReady(String streamId) {  
210 - JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId); 214 + public Boolean isRtpReady(MediaServerItem mediaServerItem, String streamId) {
  215 + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtmp", streamId);
211 return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")); 216 return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
212 } 217 }
213 218
214 /** 219 /**
215 * 查询待转推的流是否就绪 220 * 查询待转推的流是否就绪
216 */ 221 */
217 - public Boolean isStreamReady(String app, String streamId) {  
218 - JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(app, "rtmp", streamId); 222 + public Boolean isStreamReady(IMediaServerItem mediaServerItem, String app, String streamId) {
  223 + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
219 return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")); 224 return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
220 } 225 }
221 226
@@ -224,18 +229,17 @@ public class ZLMRTPServerFactory { @@ -224,18 +229,17 @@ public class ZLMRTPServerFactory {
224 * @param streamId 229 * @param streamId
225 * @return 230 * @return
226 */ 231 */
227 - public int totalReaderCount(String app, String streamId) {  
228 - JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(app, "rtmp", streamId); 232 + public int totalReaderCount(IMediaServerItem mediaServerItem, String app, String streamId) {
  233 + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
229 return mediaInfo.getInteger("totalReaderCount"); 234 return mediaInfo.getInteger("totalReaderCount");
230 } 235 }
231 236
232 /** 237 /**
233 * 调用zlm RESTful API —— stopSendRtp 238 * 调用zlm RESTful API —— stopSendRtp
234 */ 239 */
235 - public Boolean stopSendRtpStream(Map<String, Object>param) { 240 + public Boolean stopSendRtpStream(IMediaServerItem mediaServerItem,Map<String, Object>param) {
236 Boolean result = false; 241 Boolean result = false;
237 - JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(param);  
238 - logger.info(jsonObject.toJSONString()); 242 + JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param);
239 if (jsonObject == null) { 243 if (jsonObject == null) {
240 logger.error("停止RTP推流失败: 请检查ZLM服务"); 244 logger.error("停止RTP推流失败: 请检查ZLM服务");
241 } else if (jsonObject.getInteger("code") == 0) { 245 } else if (jsonObject.getInteger("code") == 0) {
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -4,7 +4,10 @@ import com.alibaba.fastjson.JSON; @@ -4,7 +4,10 @@ import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONArray; 4 import com.alibaba.fastjson.JSONArray;
5 import com.alibaba.fastjson.JSONObject; 5 import com.alibaba.fastjson.JSONObject;
6 import com.genersoft.iot.vmp.conf.MediaConfig; 6 import com.genersoft.iot.vmp.conf.MediaConfig;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 9 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
  10 +import com.genersoft.iot.vmp.service.IMediaServerService;
8 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 11 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
9 import com.genersoft.iot.vmp.service.IStreamProxyService; 12 import com.genersoft.iot.vmp.service.IStreamProxyService;
10 import org.slf4j.Logger; 13 import org.slf4j.Logger;
@@ -14,10 +17,10 @@ import org.springframework.beans.factory.annotation.Value; @@ -14,10 +17,10 @@ import org.springframework.beans.factory.annotation.Value;
14 import org.springframework.boot.CommandLineRunner; 17 import org.springframework.boot.CommandLineRunner;
15 import org.springframework.core.annotation.Order; 18 import org.springframework.core.annotation.Order;
16 import org.springframework.stereotype.Component; 19 import org.springframework.stereotype.Component;
  20 +import org.springframework.util.StringUtils;
17 21
18 -import java.util.HashMap;  
19 -import java.util.List;  
20 -import java.util.Map; 22 +import javax.print.attribute.standard.Media;
  23 +import java.util.*;
21 24
22 @Component 25 @Component
23 @Order(value=1) 26 @Order(value=1)
@@ -25,140 +28,131 @@ public class ZLMRunner implements CommandLineRunner { @@ -25,140 +28,131 @@ public class ZLMRunner implements CommandLineRunner {
25 28
26 private final static Logger logger = LoggerFactory.getLogger(ZLMRunner.class); 29 private final static Logger logger = LoggerFactory.getLogger(ZLMRunner.class);
27 30
28 - @Autowired  
29 - private IVideoManagerStorager storager;  
30 -  
31 - @Autowired  
32 - private MediaConfig mediaConfig;  
33 -  
34 - @Value("${server.port}")  
35 - private String serverPort;  
36 -  
37 - @Value("${server.ssl.enabled:false}")  
38 - private boolean sslEnabled;  
39 -  
40 - private boolean startGetMedia = false; 31 + private Map<String, Boolean> startGetMedia;
41 32
42 @Autowired 33 @Autowired
43 private ZLMRESTfulUtils zlmresTfulUtils; 34 private ZLMRESTfulUtils zlmresTfulUtils;
44 35
45 @Autowired 36 @Autowired
46 - private ZLMMediaListManager zlmMediaListManager; 37 + private ZLMHttpHookSubscribe hookSubscribe;
47 38
48 @Autowired 39 @Autowired
49 - private ZLMHttpHookSubscribe hookSubscribe; 40 + private IStreamProxyService streamProxyService;
50 41
51 @Autowired 42 @Autowired
52 - private ZLMServerManger zlmServerManger; 43 + private IMediaServerService mediaServerService;
53 44
54 @Autowired 45 @Autowired
55 - private IStreamProxyService streamProxyService; 46 + private MediaConfig mediaConfig;
56 47
57 @Override 48 @Override
58 public void run(String... strings) throws Exception { 49 public void run(String... strings) throws Exception {
59 - // 订阅 zlm启动事件  
60 - hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null,(response)->{  
61 - ZLMServerConfig ZLMServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class);  
62 - zLmRunning(ZLMServerConfig); 50 + IMediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort(
  51 + mediaConfig.getIp(), mediaConfig.getHttpPort());
  52 + if (presetMediaServer != null) {
  53 + mediaConfig.setId(presetMediaServer.getId());
  54 + mediaServerService.update(mediaConfig);
  55 + }
  56 +
  57 + // 订阅 zlm启动事件, 新的zlm也会从这里进入系统
  58 + hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null,
  59 + (IMediaServerItem mediaServerItem, JSONObject response)->{
  60 + ZLMServerConfig zlmServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class);
  61 + if (zlmServerConfig !=null ) {
  62 + startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId());
  63 + mediaServerService.handLeZLMServerConfig(zlmServerConfig);
  64 +// zLmRunning(zlmServerConfig);
  65 + }
63 }); 66 });
64 67
65 // 获取zlm信息 68 // 获取zlm信息
66 - logger.info("等待zlm接入...");  
67 - startGetMedia = true;  
68 - ZLMServerConfig ZLMServerConfig = getMediaServerConfig(); 69 + logger.info("等待默认zlm接入...");
69 70
70 - if (ZLMServerConfig != null) {  
71 - zLmRunning(ZLMServerConfig); 71 + // 获取所有的zlm, 并开启主动连接
  72 + List<IMediaServerItem> all = mediaServerService.getAll();
  73 + if (presetMediaServer == null) {
  74 + all.add(mediaConfig.getMediaSerItem());
  75 + }
  76 + for (IMediaServerItem mediaServerItem : all) {
  77 + if (startGetMedia == null) startGetMedia = new HashMap<>();
  78 + startGetMedia.put(mediaServerItem.getId(), true);
  79 + new Thread(() -> {
  80 + ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem);
  81 + if (zlmServerConfig != null) {
  82 + startGetMedia.remove(mediaServerItem.getId());
  83 + mediaServerService.handLeZLMServerConfig(zlmServerConfig);
  84 + }
  85 + }).start();
72 } 86 }
  87 + Timer timer = new Timer();
  88 + // 1分钟后未连接到则不再去主动连接
  89 + timer.schedule(new TimerTask() {
  90 + @Override
  91 + public void run() {
  92 + if (startGetMedia != null) {
  93 + Set<String> allZlmId = startGetMedia.keySet();
  94 + for (String id : allZlmId) {
  95 + logger.error("[ {} ]]主动连接失败,不再主动连接", id);
  96 + startGetMedia.put(id, false);
  97 + }
  98 + }
  99 + }
  100 + }, 60 * 1000 * 2);
73 } 101 }
74 102
75 - public ZLMServerConfig getMediaServerConfig() {  
76 - if (!startGetMedia) return null;  
77 - JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(); 103 + public ZLMServerConfig getMediaServerConfig(IMediaServerItem mediaServerItem) {
  104 + if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) return null;
  105 + JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
78 ZLMServerConfig ZLMServerConfig = null; 106 ZLMServerConfig ZLMServerConfig = null;
79 if (responseJSON != null) { 107 if (responseJSON != null) {
80 JSONArray data = responseJSON.getJSONArray("data"); 108 JSONArray data = responseJSON.getJSONArray("data");
81 if (data != null && data.size() > 0) { 109 if (data != null && data.size() > 0) {
82 ZLMServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); 110 ZLMServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
83 - 111 + ZLMServerConfig.setIp(mediaServerItem.getIp());
84 } 112 }
85 } else { 113 } else {
86 - logger.error("getMediaServerConfig失败, 1s后重试"); 114 + logger.error("[ {} ]-[ {}:{} ]主动连接失败失败, 2s后重试",
  115 + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
87 try { 116 try {
88 - Thread.sleep(1000); 117 + Thread.sleep(2000);
89 } catch (InterruptedException e) { 118 } catch (InterruptedException e) {
90 e.printStackTrace(); 119 e.printStackTrace();
91 } 120 }
92 - ZLMServerConfig = getMediaServerConfig(); 121 + ZLMServerConfig = getMediaServerConfig(mediaServerItem);
93 } 122 }
94 return ZLMServerConfig; 123 return ZLMServerConfig;
95 - }  
96 124
97 - private void saveZLMConfig() {  
98 - logger.info("设置zlm...");  
99 - String protocol = sslEnabled ? "https" : "http";  
100 - String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaConfig.getHookIp(), serverPort);  
101 - String recordHookPrex = null;  
102 - if (mediaConfig.getRecordAssistPort() != 0) {  
103 - recordHookPrex = String.format("http://127.0.0.1:%s/api/record", mediaConfig.getRecordAssistPort());  
104 - }  
105 - Map<String, Object> param = new HashMap<>();  
106 - param.put("api.secret",mediaConfig.getSecret()); // -profile:v Baseline  
107 - 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");  
108 - param.put("hook.enable","1");  
109 - param.put("hook.on_flow_report","");  
110 - param.put("hook.on_play",String.format("%s/on_play", hookPrex));  
111 - param.put("hook.on_http_access","");  
112 - param.put("hook.on_publish", String.format("%s/on_publish", hookPrex));  
113 - param.put("hook.on_record_mp4",recordHookPrex != null? String.format("%s/on_record_mp4", recordHookPrex): "");  
114 - param.put("hook.on_record_ts","");  
115 - param.put("hook.on_rtsp_auth","");  
116 - param.put("hook.on_rtsp_realm","");  
117 - param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrex));  
118 - param.put("hook.on_shell_login",String.format("%s/on_shell_login", hookPrex));  
119 - param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrex));  
120 - param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex));  
121 - param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));  
122 - param.put("hook.timeoutSec","20");  
123 - param.put("general.streamNoneReaderDelayMS",mediaConfig.getStreamNoneReaderDelayMS());  
124 -  
125 - JSONObject responseJSON = zlmresTfulUtils.setServerConfig(param);  
126 -  
127 - if (responseJSON != null && responseJSON.getInteger("code") == 0) {  
128 - logger.info("设置zlm成功");  
129 - }else {  
130 - logger.info("设置zlm失败");  
131 - }  
132 } 125 }
133 126
134 /** 127 /**
135 * zlm 连接成功或者zlm重启后 128 * zlm 连接成功或者zlm重启后
136 */ 129 */
137 - private void zLmRunning(ZLMServerConfig zlmServerConfig){  
138 - logger.info( "[ id: " + zlmServerConfig.getGeneralMediaServerId() + "] zlm接入成功...");  
139 - // 关闭循环获取zlm配置  
140 - startGetMedia = false;  
141 - if (mediaConfig.isAutoConfig()) saveZLMConfig();  
142 - zlmServerManger.updateServerCatch(zlmServerConfig);  
143 -  
144 - // 清空所有session  
145 -// zlmMediaListManager.clearAllSessions();  
146 -  
147 - // 更新流列表  
148 - zlmMediaListManager.updateMediaList();  
149 - // 恢复流代理  
150 - List<StreamProxyItem> streamProxyListForEnable = storager.getStreamProxyListForEnable(true);  
151 - for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {  
152 - logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());  
153 - JSONObject jsonObject = streamProxyService.addStreamProxyToZlm(streamProxyDto);  
154 - if (jsonObject == null) {  
155 - // 设置为未启用  
156 - logger.info("恢复流代理失败,请检查流地址后重新启用" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());  
157 - streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());  
158 - }else if (jsonObject.getInteger("code") != 0){ // TODO 将错误信息存入数据库, 前端展示  
159 - logger.info("恢复流代理失败:" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream() + "[ " + JSONObject.toJSONString(jsonObject) + " ]");  
160 - streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());  
161 - }  
162 - }  
163 - } 130 +// private void zLmRunning(ZLMServerConfig zlmServerConfig){
  131 +// logger.info( "[ id: " + zlmServerConfig.getGeneralMediaServerId() + "] zlm接入成功...");
  132 +// // 关闭循环获取zlm配置
  133 +// startGetMedia = false;
  134 +// MediaServerItem mediaServerItem = new MediaServerItem(zlmServerConfig, sipIp);
  135 +// storager.updateMediaServer(mediaServerItem);
  136 +//
  137 +// if (mediaServerItem.isAutoConfig()) setZLMConfig(mediaServerItem);
  138 +// zlmServerManger.updateServerCatchFromHook(zlmServerConfig);
  139 +//
  140 +// // 清空所有session
  141 +//// zlmMediaListManager.clearAllSessions();
  142 +//
  143 +// // 更新流列表
  144 +// zlmMediaListManager.updateMediaList(mediaServerItem);
  145 +// // 恢复流代理, 只查找这个这个流媒体
  146 +// List<StreamProxyItem> streamProxyListForEnable = storager.getStreamProxyListForEnableInMediaServer(
  147 +// mediaServerItem.getId(), true);
  148 +// for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {
  149 +// logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
  150 +// JSONObject jsonObject = streamProxyService.addStreamProxyToZlm(streamProxyDto);
  151 +// if (jsonObject == null) {
  152 +// // 设置为未启用
  153 +// logger.info("恢复流代理失败,请检查流地址后重新启用" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
  154 +// streamProxyService.stop(streamProxyDto.getApp(), streamProxyDto.getStream());
  155 +// }
  156 +// }
  157 +// }
164 } 158 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java
@@ -34,12 +34,15 @@ public class ZLMServerConfig { @@ -34,12 +34,15 @@ public class ZLMServerConfig {
34 @JSONField(name = "general.streamNoneReaderDelayMS") 34 @JSONField(name = "general.streamNoneReaderDelayMS")
35 private String generalStreamNoneReaderDelayMS; 35 private String generalStreamNoneReaderDelayMS;
36 36
  37 + @JSONField(name = "ip")
37 private String ip; 38 private String ip;
38 39
39 private String sdpIp; 40 private String sdpIp;
40 41
41 private String streamIp; 42 private String streamIp;
42 43
  44 + private String hookIp;
  45 +
43 private String updateTime; 46 private String updateTime;
44 47
45 private String createTime; 48 private String createTime;
@@ -66,7 +69,7 @@ public class ZLMServerConfig { @@ -66,7 +69,7 @@ public class ZLMServerConfig {
66 private String hookEnable; 69 private String hookEnable;
67 70
68 @JSONField(name = "hook.on_flow_report") 71 @JSONField(name = "hook.on_flow_report")
69 - private Integer hookOnFlowReport; 72 + private String hookOnFlowReport;
70 73
71 @JSONField(name = "hook.on_http_access") 74 @JSONField(name = "hook.on_http_access")
72 private String hookOnHttpAccess; 75 private String hookOnHttpAccess;
@@ -117,7 +120,7 @@ public class ZLMServerConfig { @@ -117,7 +120,7 @@ public class ZLMServerConfig {
117 private String httpNotFound; 120 private String httpNotFound;
118 121
119 @JSONField(name = "http.port") 122 @JSONField(name = "http.port")
120 - private Integer httpPort; 123 + private int httpPort;
121 124
122 @JSONField(name = "http.rootPath") 125 @JSONField(name = "http.rootPath")
123 private String httpRootPath; 126 private String httpRootPath;
@@ -126,7 +129,7 @@ public class ZLMServerConfig { @@ -126,7 +129,7 @@ public class ZLMServerConfig {
126 private String httpSendBufSize; 129 private String httpSendBufSize;
127 130
128 @JSONField(name = "http.sslport") 131 @JSONField(name = "http.sslport")
129 - private Integer httpSSLport; 132 + private int httpSSLport;
130 133
131 @JSONField(name = "multicast.addrMax") 134 @JSONField(name = "multicast.addrMax")
132 private String multicastAddrMax; 135 private String multicastAddrMax;
@@ -159,10 +162,10 @@ public class ZLMServerConfig { @@ -159,10 +162,10 @@ public class ZLMServerConfig {
159 private String rtmpModifyStamp; 162 private String rtmpModifyStamp;
160 163
161 @JSONField(name = "rtmp.port") 164 @JSONField(name = "rtmp.port")
162 - private Integer rtmpPort; 165 + private int rtmpPort;
163 166
164 @JSONField(name = "rtmp.sslport") 167 @JSONField(name = "rtmp.sslport")
165 - private Integer rtmpSslPort; 168 + private int rtmpSslPort;
166 169
167 @JSONField(name = "rtp.audioMtuSize") 170 @JSONField(name = "rtp.audioMtuSize")
168 private String rtpAudioMtuSize; 171 private String rtpAudioMtuSize;
@@ -186,7 +189,7 @@ public class ZLMServerConfig { @@ -186,7 +189,7 @@ public class ZLMServerConfig {
186 private String rtpProxyDumpDir; 189 private String rtpProxyDumpDir;
187 190
188 @JSONField(name = "rtp_proxy.port") 191 @JSONField(name = "rtp_proxy.port")
189 - private Integer rtpProxyPort; 192 + private int rtpProxyPort;
190 193
191 @JSONField(name = "rtp_proxy.timeoutSec") 194 @JSONField(name = "rtp_proxy.timeoutSec")
192 private String rtpProxyTimeoutSec; 195 private String rtpProxyTimeoutSec;
@@ -201,10 +204,10 @@ public class ZLMServerConfig { @@ -201,10 +204,10 @@ public class ZLMServerConfig {
201 private String rtspKeepAliveSecond; 204 private String rtspKeepAliveSecond;
202 205
203 @JSONField(name = "rtsp.port") 206 @JSONField(name = "rtsp.port")
204 - private Integer rtspPort; 207 + private int rtspPort;
205 208
206 @JSONField(name = "rtsp.sslport") 209 @JSONField(name = "rtsp.sslport")
207 - private Integer rtspSSlport; 210 + private int rtspSSlport;
208 211
209 @JSONField(name = "shell.maxReqSize") 212 @JSONField(name = "shell.maxReqSize")
210 private String shellMaxReqSize; 213 private String shellMaxReqSize;
@@ -212,6 +215,15 @@ public class ZLMServerConfig { @@ -212,6 +215,15 @@ public class ZLMServerConfig {
212 @JSONField(name = "shell.shell") 215 @JSONField(name = "shell.shell")
213 private String shellPhell; 216 private String shellPhell;
214 217
  218 +
  219 + public String getHookIp() {
  220 + return hookIp;
  221 + }
  222 +
  223 + public void setHookIp(String hookIp) {
  224 + this.hookIp = hookIp;
  225 + }
  226 +
215 public String getApiDebug() { 227 public String getApiDebug() {
216 return apiDebug; 228 return apiDebug;
217 } 229 }
@@ -388,11 +400,11 @@ public class ZLMServerConfig { @@ -388,11 +400,11 @@ public class ZLMServerConfig {
388 this.hookEnable = hookEnable; 400 this.hookEnable = hookEnable;
389 } 401 }
390 402
391 - public Integer getHookOnFlowReport() { 403 + public String getHookOnFlowReport() {
392 return hookOnFlowReport; 404 return hookOnFlowReport;
393 } 405 }
394 406
395 - public void setHookOnFlowReport(Integer hookOnFlowReport) { 407 + public void setHookOnFlowReport(String hookOnFlowReport) {
396 this.hookOnFlowReport = hookOnFlowReport; 408 this.hookOnFlowReport = hookOnFlowReport;
397 } 409 }
398 410
@@ -524,11 +536,11 @@ public class ZLMServerConfig { @@ -524,11 +536,11 @@ public class ZLMServerConfig {
524 this.httpNotFound = httpNotFound; 536 this.httpNotFound = httpNotFound;
525 } 537 }
526 538
527 - public Integer getHttpPort() { 539 + public int getHttpPort() {
528 return httpPort; 540 return httpPort;
529 } 541 }
530 542
531 - public void setHttpPort(Integer httpPort) { 543 + public void setHttpPort(int httpPort) {
532 this.httpPort = httpPort; 544 this.httpPort = httpPort;
533 } 545 }
534 546
@@ -548,11 +560,11 @@ public class ZLMServerConfig { @@ -548,11 +560,11 @@ public class ZLMServerConfig {
548 this.httpSendBufSize = httpSendBufSize; 560 this.httpSendBufSize = httpSendBufSize;
549 } 561 }
550 562
551 - public Integer getHttpSSLport() { 563 + public int getHttpSSLport() {
552 return httpSSLport; 564 return httpSSLport;
553 } 565 }
554 566
555 - public void setHttpSSLport(Integer httpSSLport) { 567 + public void setHttpSSLport(int httpSSLport) {
556 this.httpSSLport = httpSSLport; 568 this.httpSSLport = httpSSLport;
557 } 569 }
558 570
@@ -636,19 +648,19 @@ public class ZLMServerConfig { @@ -636,19 +648,19 @@ public class ZLMServerConfig {
636 this.rtmpModifyStamp = rtmpModifyStamp; 648 this.rtmpModifyStamp = rtmpModifyStamp;
637 } 649 }
638 650
639 - public Integer getRtmpPort() { 651 + public int getRtmpPort() {
640 return rtmpPort; 652 return rtmpPort;
641 } 653 }
642 654
643 - public void setRtmpPort(Integer rtmpPort) { 655 + public void setRtmpPort(int rtmpPort) {
644 this.rtmpPort = rtmpPort; 656 this.rtmpPort = rtmpPort;
645 } 657 }
646 658
647 - public Integer getRtmpSslPort() { 659 + public int getRtmpSslPort() {
648 return rtmpSslPort; 660 return rtmpSslPort;
649 } 661 }
650 662
651 - public void setRtmpSslPort(Integer rtmpSslPort) { 663 + public void setRtmpSslPort(int rtmpSslPort) {
652 this.rtmpSslPort = rtmpSslPort; 664 this.rtmpSslPort = rtmpSslPort;
653 } 665 }
654 666
@@ -708,11 +720,11 @@ public class ZLMServerConfig { @@ -708,11 +720,11 @@ public class ZLMServerConfig {
708 this.rtpProxyDumpDir = rtpProxyDumpDir; 720 this.rtpProxyDumpDir = rtpProxyDumpDir;
709 } 721 }
710 722
711 - public Integer getRtpProxyPort() { 723 + public int getRtpProxyPort() {
712 return rtpProxyPort; 724 return rtpProxyPort;
713 } 725 }
714 726
715 - public void setRtpProxyPort(Integer rtpProxyPort) { 727 + public void setRtpProxyPort(int rtpProxyPort) {
716 this.rtpProxyPort = rtpProxyPort; 728 this.rtpProxyPort = rtpProxyPort;
717 } 729 }
718 730
@@ -748,19 +760,19 @@ public class ZLMServerConfig { @@ -748,19 +760,19 @@ public class ZLMServerConfig {
748 this.rtspKeepAliveSecond = rtspKeepAliveSecond; 760 this.rtspKeepAliveSecond = rtspKeepAliveSecond;
749 } 761 }
750 762
751 - public Integer getRtspPort() { 763 + public int getRtspPort() {
752 return rtspPort; 764 return rtspPort;
753 } 765 }
754 766
755 - public void setRtspPort(Integer rtspPort) { 767 + public void setRtspPort(int rtspPort) {
756 this.rtspPort = rtspPort; 768 this.rtspPort = rtspPort;
757 } 769 }
758 770
759 - public Integer getRtspSSlport() { 771 + public int getRtspSSlport() {
760 return rtspSSlport; 772 return rtspSSlport;
761 } 773 }
762 774
763 - public void setRtspSSlport(Integer rtspSSlport) { 775 + public void setRtspSSlport(int rtspSSlport) {
764 this.rtspSSlport = rtspSSlport; 776 this.rtspSSlport = rtspSSlport;
765 } 777 }
766 778
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerManger.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.media.zlm;  
2 -  
3 -import com.genersoft.iot.vmp.conf.MediaConfig;  
4 -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;  
5 -import org.springframework.beans.factory.annotation.Autowired;  
6 -import org.springframework.stereotype.Component;  
7 -import org.springframework.util.StringUtils;  
8 -  
9 -@Component  
10 -public class ZLMServerManger {  
11 -  
12 - @Autowired  
13 - private IRedisCatchStorage redisCatchStorage;  
14 -  
15 - @Autowired  
16 - private MediaConfig mediaConfig;  
17 -  
18 - public void updateServerCatch(ZLMServerConfig zlmServerConfig) {  
19 -  
20 - zlmServerConfig.setIp(mediaConfig.getIp());  
21 - zlmServerConfig.setStreamIp(mediaConfig.getStreamIp());  
22 - zlmServerConfig.setSdpIp(mediaConfig.getSdpIp());  
23 - zlmServerConfig.setHttpPort(mediaConfig.getHttpPort());  
24 -  
25 - if(!StringUtils.isEmpty(mediaConfig.getHttpSSlPort()))  
26 - zlmServerConfig.setHttpSSLport(mediaConfig.getHttpSSlPort());  
27 -  
28 - if(!StringUtils.isEmpty(mediaConfig.getRtspPort()))  
29 - zlmServerConfig.setRtspPort(mediaConfig.getRtspPort());  
30 -  
31 - if(!StringUtils.isEmpty(mediaConfig.getRtspSSLPort()))  
32 - zlmServerConfig.setRtspSSlport(mediaConfig.getRtspSSLPort());  
33 -  
34 - if(!StringUtils.isEmpty(mediaConfig.getRtmpPort()))  
35 - zlmServerConfig.setRtmpPort(mediaConfig.getRtmpPort());  
36 -  
37 - if(!StringUtils.isEmpty(mediaConfig.getRtmpSSlPort()))  
38 - zlmServerConfig.setRtmpSslPort(mediaConfig.getRtmpSSlPort());  
39 -  
40 - if(!StringUtils.isEmpty(mediaConfig.getRtpProxyPort()))  
41 - zlmServerConfig.setRtpProxyPort(mediaConfig.getRtpProxyPort());  
42 -  
43 - redisCatchStorage.updateMediaInfo(zlmServerConfig);  
44 - }  
45 -}  
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto;
  2 +
  3 +public interface IMediaServerItem {
  4 +
  5 + String getId();
  6 +
  7 + void setId(String id);
  8 +
  9 + String getIp();
  10 +
  11 + void setIp(String ip);
  12 +
  13 + String getHookIp();
  14 +
  15 + void setHookIp(String hookIp);
  16 +
  17 + String getSdpIp();
  18 +
  19 + void setSdpIp(String sdpIp);
  20 +
  21 + String getStreamIp();
  22 +
  23 + void setStreamIp(String streamIp);
  24 +
  25 + int getHttpPort();
  26 +
  27 + void setHttpPort(int httpPort);
  28 +
  29 + int getHttpSSlPort();
  30 +
  31 + void setHttpSSlPort(int httpSSlPort);
  32 +
  33 + int getRtmpPort();
  34 +
  35 + void setRtmpPort(int rtmpPort);
  36 +
  37 + int getRtmpSSlPort();
  38 +
  39 + void setRtmpSSlPort(int rtmpSSlPort);
  40 +
  41 + int getRtpProxyPort();
  42 +
  43 + void setRtpProxyPort(int rtpProxyPort);
  44 +
  45 + int getRtspPort();
  46 +
  47 + void setRtspPort(int rtspPort);
  48 +
  49 + int getRtspSSLPort();
  50 +
  51 + void setRtspSSLPort(int rtspSSLPort);
  52 +
  53 + boolean isAutoConfig();
  54 +
  55 + void setAutoConfig(boolean autoConfig);
  56 +
  57 + String getSecret();
  58 +
  59 + void setSecret(String secret);
  60 +
  61 + String getStreamNoneReaderDelayMS();
  62 +
  63 + void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS);
  64 +
  65 + boolean isRtpEnable();
  66 +
  67 + void setRtpEnable(boolean rtpEnable);
  68 +
  69 + String getRtpPortRange();
  70 +
  71 + void setRtpPortRange(String rtpPortRange);
  72 +
  73 + int getRecordAssistPort();
  74 +
  75 + void setRecordAssistPort(int recordAssistPort);
  76 +
  77 + boolean isDocker();
  78 +
  79 + void setDocker(boolean docker);
  80 +
  81 + String getUpdateTime();
  82 +
  83 + void setUpdateTime(String updateTime);
  84 +
  85 + String getCreateTime();
  86 +
  87 + void setCreateTime(String createTime);
  88 +
  89 + int getCount();
  90 +
  91 + void setCount(int count);
  92 +}
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java
@@ -78,6 +78,10 @@ public class MediaItem { @@ -78,6 +78,10 @@ public class MediaItem {
78 */ 78 */
79 private String vhost; 79 private String vhost;
80 80
  81 + /**
  82 + * 是否是docker部署, docker部署不会自动更新zlm使用的端口,需要自己手动修改
  83 + */
  84 + private boolean docker;
81 85
82 public static class MediaTrack { 86 public static class MediaTrack {
83 /** 87 /**
@@ -364,4 +368,12 @@ public class MediaItem { @@ -364,4 +368,12 @@ public class MediaItem {
364 public OriginSock getOriginSock() { 368 public OriginSock getOriginSock() {
365 return originSock; 369 return originSock;
366 } 370 }
  371 +
  372 + public boolean isDocker() {
  373 + return docker;
  374 + }
  375 +
  376 + public void setDocker(boolean docker) {
  377 + this.docker = docker;
  378 + }
367 } 379 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto;
  2 +
  3 +
  4 +import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
  5 +import org.springframework.util.StringUtils;
  6 +
  7 +public class MediaServerItem implements IMediaServerItem{
  8 +
  9 + private String id;
  10 +
  11 + private String ip;
  12 +
  13 + private String hookIp;
  14 +
  15 + private String sdpIp;
  16 +
  17 + private String streamIp;
  18 +
  19 + private int httpPort;
  20 +
  21 + private int httpSSlPort;
  22 +
  23 + private int rtmpPort;
  24 +
  25 + private int rtmpSSlPort;
  26 +
  27 + private int rtpProxyPort;
  28 +
  29 + private int rtspPort;
  30 +
  31 + private int rtspSSLPort;
  32 +
  33 + private boolean autoConfig;
  34 +
  35 + private String secret;
  36 +
  37 + private String streamNoneReaderDelayMS;
  38 +
  39 + private boolean rtpEnable;
  40 +
  41 + private String rtpPortRange;
  42 +
  43 + private int recordAssistPort;
  44 +
  45 + private String createTime;
  46 +
  47 + private String updateTime;
  48 +
  49 + private boolean docker;
  50 +
  51 + private int count;
  52 +
  53 + public MediaServerItem() {
  54 + }
  55 +
  56 + public MediaServerItem(ZLMServerConfig zlmServerConfig, String sipIp) {
  57 + id = zlmServerConfig.getGeneralMediaServerId();
  58 + ip = zlmServerConfig.getIp();
  59 + hookIp = StringUtils.isEmpty(zlmServerConfig.getHookIp())? sipIp: zlmServerConfig.getHookIp();
  60 + sdpIp = StringUtils.isEmpty(zlmServerConfig.getSdpIp())? zlmServerConfig.getIp(): zlmServerConfig.getSdpIp();
  61 + streamIp = StringUtils.isEmpty(zlmServerConfig.getStreamIp())? zlmServerConfig.getIp(): zlmServerConfig.getStreamIp();
  62 + httpPort = zlmServerConfig.getHttpPort();
  63 + httpSSlPort = zlmServerConfig.getHttpSSLport();
  64 + rtmpPort = zlmServerConfig.getRtmpPort();
  65 + rtmpSSlPort = zlmServerConfig.getRtmpSslPort();
  66 + rtpProxyPort = zlmServerConfig.getRtpProxyPort();
  67 + rtspPort = zlmServerConfig.getRtspPort();
  68 + rtspSSLPort = zlmServerConfig.getRtspSSlport();
  69 + autoConfig = true; // 默认值true;
  70 + secret = zlmServerConfig.getApiSecret();
  71 + streamNoneReaderDelayMS = zlmServerConfig.getGeneralStreamNoneReaderDelayMS();
  72 + rtpEnable = false; // 默认使用单端口;直到用户自己设置开启多端口
  73 + recordAssistPort = 0; // 默认关闭
  74 +
  75 + }
  76 +
  77 + public String getId() {
  78 + return id;
  79 + }
  80 +
  81 + public void setId(String id) {
  82 + this.id = id;
  83 + }
  84 +
  85 + public String getIp() {
  86 + return ip;
  87 + }
  88 +
  89 + public void setIp(String ip) {
  90 + this.ip = ip;
  91 + }
  92 +
  93 + public String getHookIp() {
  94 + return hookIp;
  95 + }
  96 +
  97 + public void setHookIp(String hookIp) {
  98 + this.hookIp = hookIp;
  99 + }
  100 +
  101 + public String getSdpIp() {
  102 + return sdpIp;
  103 + }
  104 +
  105 + public void setSdpIp(String sdpIp) {
  106 + this.sdpIp = sdpIp;
  107 + }
  108 +
  109 + public String getStreamIp() {
  110 + return streamIp;
  111 + }
  112 +
  113 + public void setStreamIp(String streamIp) {
  114 + this.streamIp = streamIp;
  115 + }
  116 +
  117 + public int getHttpPort() {
  118 + return httpPort;
  119 + }
  120 +
  121 + public void setHttpPort(int httpPort) {
  122 + this.httpPort = httpPort;
  123 + }
  124 +
  125 + public int getHttpSSlPort() {
  126 + return httpSSlPort;
  127 + }
  128 +
  129 + public void setHttpSSlPort(int httpSSlPort) {
  130 + this.httpSSlPort = httpSSlPort;
  131 + }
  132 +
  133 + public int getRtmpPort() {
  134 + return rtmpPort;
  135 + }
  136 +
  137 + public void setRtmpPort(int rtmpPort) {
  138 + this.rtmpPort = rtmpPort;
  139 + }
  140 +
  141 + public int getRtmpSSlPort() {
  142 + return rtmpSSlPort;
  143 + }
  144 +
  145 + public void setRtmpSSlPort(int rtmpSSlPort) {
  146 + this.rtmpSSlPort = rtmpSSlPort;
  147 + }
  148 +
  149 + public int getRtpProxyPort() {
  150 + return rtpProxyPort;
  151 + }
  152 +
  153 + public void setRtpProxyPort(int rtpProxyPort) {
  154 + this.rtpProxyPort = rtpProxyPort;
  155 + }
  156 +
  157 + public int getRtspPort() {
  158 + return rtspPort;
  159 + }
  160 +
  161 + public void setRtspPort(int rtspPort) {
  162 + this.rtspPort = rtspPort;
  163 + }
  164 +
  165 + public int getRtspSSLPort() {
  166 + return rtspSSLPort;
  167 + }
  168 +
  169 + public void setRtspSSLPort(int rtspSSLPort) {
  170 + this.rtspSSLPort = rtspSSLPort;
  171 + }
  172 +
  173 + public boolean isAutoConfig() {
  174 + return autoConfig;
  175 + }
  176 +
  177 + public void setAutoConfig(boolean autoConfig) {
  178 + this.autoConfig = autoConfig;
  179 + }
  180 +
  181 + public String getSecret() {
  182 + return secret;
  183 + }
  184 +
  185 + public void setSecret(String secret) {
  186 + this.secret = secret;
  187 + }
  188 +
  189 + public String getStreamNoneReaderDelayMS() {
  190 + return streamNoneReaderDelayMS;
  191 + }
  192 +
  193 + public void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS) {
  194 + this.streamNoneReaderDelayMS = streamNoneReaderDelayMS;
  195 + }
  196 +
  197 + public boolean isRtpEnable() {
  198 + return rtpEnable;
  199 + }
  200 +
  201 + public void setRtpEnable(boolean rtpEnable) {
  202 + this.rtpEnable = rtpEnable;
  203 + }
  204 +
  205 + public String getRtpPortRange() {
  206 + return rtpPortRange;
  207 + }
  208 +
  209 + public void setRtpPortRange(String rtpPortRange) {
  210 + this.rtpPortRange = rtpPortRange;
  211 + }
  212 +
  213 + public int getRecordAssistPort() {
  214 + return recordAssistPort;
  215 + }
  216 +
  217 + public void setRecordAssistPort(int recordAssistPort) {
  218 + this.recordAssistPort = recordAssistPort;
  219 + }
  220 +
  221 + @Override
  222 + public boolean isDocker() {
  223 + return docker;
  224 + }
  225 +
  226 + @Override
  227 + public void setDocker(boolean docker) {
  228 + this.docker = docker;
  229 + }
  230 +
  231 + public String getCreateTime() {
  232 + return createTime;
  233 + }
  234 +
  235 + public void setCreateTime(String createTime) {
  236 + this.createTime = createTime;
  237 + }
  238 +
  239 + public String getUpdateTime() {
  240 + return updateTime;
  241 + }
  242 +
  243 + public void setUpdateTime(String updateTime) {
  244 + this.updateTime = updateTime;
  245 + }
  246 +
  247 + public int getCount() {
  248 + return count;
  249 + }
  250 +
  251 + public void setCount(int count) {
  252 + this.count = count;
  253 + }
  254 +}
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
@@ -7,6 +7,7 @@ public class StreamProxyItem extends GbStream { @@ -7,6 +7,7 @@ public class StreamProxyItem extends GbStream {
7 private String type; 7 private String type;
8 private String app; 8 private String app;
9 private String stream; 9 private String stream;
  10 + private String mediaServerId;
10 private String url; 11 private String url;
11 private String src_url; 12 private String src_url;
12 private String dst_url; 13 private String dst_url;
@@ -17,6 +18,7 @@ public class StreamProxyItem extends GbStream { @@ -17,6 +18,7 @@ public class StreamProxyItem extends GbStream {
17 private boolean enable_hls; 18 private boolean enable_hls;
18 private boolean enable_mp4; 19 private boolean enable_mp4;
19 private String platformGbId; 20 private String platformGbId;
  21 + private String createTime;
20 22
21 public String getType() { 23 public String getType() {
22 return type; 24 return type;
@@ -42,6 +44,16 @@ public class StreamProxyItem extends GbStream { @@ -42,6 +44,16 @@ public class StreamProxyItem extends GbStream {
42 this.stream = stream; 44 this.stream = stream;
43 } 45 }
44 46
  47 + @Override
  48 + public String getMediaServerId() {
  49 + return mediaServerId;
  50 + }
  51 +
  52 + @Override
  53 + public void setMediaServerId(String mediaServerId) {
  54 + this.mediaServerId = mediaServerId;
  55 + }
  56 +
45 public String getUrl() { 57 public String getUrl() {
46 return url; 58 return url;
47 } 59 }
@@ -122,4 +134,12 @@ public class StreamProxyItem extends GbStream { @@ -122,4 +134,12 @@ public class StreamProxyItem extends GbStream {
122 public void setPlatformGbId(String platformGbId) { 134 public void setPlatformGbId(String platformGbId) {
123 this.platformGbId = platformGbId; 135 this.platformGbId = platformGbId;
124 } 136 }
  137 +
  138 + public String getCreateTime() {
  139 + return createTime;
  140 + }
  141 +
  142 + public void setCreateTime(String createTime) {
  143 + this.createTime = createTime;
  144 + }
125 } 145 }
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java
@@ -76,6 +76,11 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte @@ -76,6 +76,11 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte
76 */ 76 */
77 private String vhost; 77 private String vhost;
78 78
  79 + /**
  80 + * 使用的流媒体ID
  81 + */
  82 + private String mediaServerId;
  83 +
79 public String getVhost() { 84 public String getVhost() {
80 return vhost; 85 return vhost;
81 } 86 }
@@ -202,5 +207,14 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte @@ -202,5 +207,14 @@ public class StreamPushItem extends GbStream implements Comparable&lt;StreamPushIte
202 } 207 }
203 208
204 209
  210 + @Override
  211 + public String getMediaServerId() {
  212 + return mediaServerId;
  213 + }
  214 +
  215 + @Override
  216 + public void setMediaServerId(String mediaServerId) {
  217 + this.mediaServerId = mediaServerId;
  218 + }
205 } 219 }
206 220
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ZLMRunInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto;
  2 +
  3 +/**
  4 + * 记录zlm运行中一些参数
  5 + */
  6 +public class ZLMRunInfo {
  7 +
  8 + /**
  9 + * zlm当前流数量
  10 + */
  11 + private int mediaCount;
  12 +
  13 + /**
  14 + * 在线状态
  15 + */
  16 + private boolean online;
  17 +
  18 + public int getMediaCount() {
  19 + return mediaCount;
  20 + }
  21 +
  22 + public void setMediaCount(int mediaCount) {
  23 + this.mediaCount = mediaCount;
  24 + }
  25 +
  26 + public boolean isOnline() {
  27 + return online;
  28 + }
  29 +
  30 + public void setOnline(boolean online) {
  31 + this.online = online;
  32 + }
  33 +}
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service;
  2 +
  3 +import com.genersoft.iot.vmp.conf.MediaConfig;
  4 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  5 +import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  8 +
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * 媒体服务节点
  13 + */
  14 +public interface IMediaServerService {
  15 +
  16 + List<IMediaServerItem> getAll();
  17 +
  18 + IMediaServerItem getOne(String generalMediaServerId);
  19 +
  20 + IMediaServerItem getOneByHostAndPort(String host, int port);
  21 +
  22 + /**
  23 + * 新的节点加入
  24 + * @param zlmServerConfig
  25 + * @return
  26 + */
  27 + void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig);
  28 +
  29 + void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean b);
  30 +
  31 + IMediaServerItem getMediaServerForMinimumLoad();
  32 +
  33 + void setZLMConfig(IMediaServerItem mediaServerItem);
  34 +
  35 + void init();
  36 +
  37 + void closeRTPServer(Device device, String channelId);
  38 +
  39 + void update(MediaConfig mediaConfig);
  40 +
  41 + void addCount(String mediaServerId);
  42 +
  43 + void removeCount(String mediaServerId);
  44 +}
src/main/java/com/genersoft/iot/vmp/service/IMediaService.java
@@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.service; @@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.service;
2 2
3 import com.alibaba.fastjson.JSONArray; 3 import com.alibaba.fastjson.JSONArray;
4 import com.genersoft.iot.vmp.common.StreamInfo; 4 import com.genersoft.iot.vmp.common.StreamInfo;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
5 7
6 /** 8 /**
7 * 媒体信息业务 9 * 媒体信息业务
@@ -14,29 +16,30 @@ public interface IMediaService { @@ -14,29 +16,30 @@ public interface IMediaService {
14 * @param stream 16 * @param stream
15 * @return 17 * @return
16 */ 18 */
17 - StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream); 19 + StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr);
  20 +
18 21
19 /** 22 /**
20 - * 根据应用名和流ID获取播放地址, 只是地址拼接 23 + * 根据应用名和流ID获取播放地址, 通过zlm接口检查是否存在, 返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况
21 * @param app 24 * @param app
22 * @param stream 25 * @param stream
23 * @return 26 * @return
24 */ 27 */
25 - StreamInfo getStreamInfoByAppAndStream(String app, String stream, JSONArray tracks); 28 + StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId);
26 29
27 /** 30 /**
28 - * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 31 + * 根据应用名和流ID获取播放地址, 只是地址拼接
29 * @param app 32 * @param app
30 * @param stream 33 * @param stream
31 * @return 34 * @return
32 */ 35 */
33 - StreamInfo getStreamInfoByAppAndStream(String app, String stream, JSONArray tracks, String addr); 36 + StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaServerItem, String app, String stream, JSONArray tracks);
34 37
35 /** 38 /**
36 - * 根据应用名和流ID获取播放地址, 通过zlm接口检查是否存在, 返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 39 + * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况
37 * @param app 40 * @param app
38 * @param stream 41 * @param stream
39 * @return 42 * @return
40 */ 43 */
41 - StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String addr); 44 + StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr);
42 } 45 }
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
1 package com.genersoft.iot.vmp.service; 1 package com.genersoft.iot.vmp.service;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
  4 +import com.genersoft.iot.vmp.gb28181.bean.Device;
4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 6 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 9 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
7 10
8 /** 11 /**
@@ -10,8 +13,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; @@ -10,8 +13,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
10 */ 13 */
11 public interface IPlayService { 14 public interface IPlayService {
12 15
13 - void onPublishHandlerForPlayBack(JSONObject resonse, String deviceId, String channelId, String uuid);  
14 - void onPublishHandlerForPlay(JSONObject resonse, String deviceId, String channelId, String uuid); 16 + void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem,JSONObject resonse, String deviceId, String channelId, String uuid);
  17 + void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
15 18
16 - PlayResult play(String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 19 + PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
  20 +
  21 + IMediaServerItem getNewMediaServerItem(Device device);
17 } 22 }
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
1 package com.genersoft.iot.vmp.service; 1 package com.genersoft.iot.vmp.service;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
4 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
5 import com.github.pagehelper.PageInfo; 7 import com.github.pagehelper.PageInfo;
6 8
@@ -61,5 +63,5 @@ public interface IStreamProxyService { @@ -61,5 +63,5 @@ public interface IStreamProxyService {
61 * 获取ffmpeg.cmd模板 63 * 获取ffmpeg.cmd模板
62 * @return 64 * @return
63 */ 65 */
64 - JSONObject getFFmpegCMDs(); 66 + JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem);
65 } 67 }
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
1 package com.genersoft.iot.vmp.service; 1 package com.genersoft.iot.vmp.service;
2 2
3 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 3 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
4 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
5 import com.github.pagehelper.PageInfo; 6 import com.github.pagehelper.PageInfo;
6 7
@@ -8,7 +9,7 @@ import java.util.List; @@ -8,7 +9,7 @@ import java.util.List;
8 9
9 public interface IStreamPushService { 10 public interface IStreamPushService {
10 11
11 - List<StreamPushItem> handleJSON(String json); 12 + List<StreamPushItem> handleJSON(String json, IMediaServerItem mediaServerItem);
12 13
13 /** 14 /**
14 * 将应用名和流ID加入国标关联 15 * 将应用名和流ID加入国标关联
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.impl;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONArray;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.genersoft.iot.vmp.common.StreamInfo;
  7 +import com.genersoft.iot.vmp.conf.MediaConfig;
  8 +import com.genersoft.iot.vmp.conf.ProxyServletConfig;
  9 +import com.genersoft.iot.vmp.gb28181.bean.Device;
  10 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
  11 +import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  12 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  13 +import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
  14 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  15 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  16 +import com.genersoft.iot.vmp.media.zlm.dto.ZLMRunInfo;
  17 +import com.genersoft.iot.vmp.service.IMediaServerService;
  18 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  19 +import com.genersoft.iot.vmp.storager.dao.MediaServerMapper;
  20 +import org.mitre.dsmiley.httpproxy.ProxyServlet;
  21 +import org.slf4j.Logger;
  22 +import org.slf4j.LoggerFactory;
  23 +import org.springframework.beans.factory.annotation.Autowired;
  24 +import org.springframework.beans.factory.annotation.Value;
  25 +import org.springframework.stereotype.Service;
  26 +
  27 +import java.text.SimpleDateFormat;
  28 +import java.util.*;
  29 +
  30 +/**
  31 + * 媒体服务器节点管理
  32 + */
  33 +@Service
  34 +public class MediaServerServiceImpl implements IMediaServerService {
  35 +
  36 + private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class);
  37 +
  38 + private Map<String, IMediaServerItem> zlmServers = new HashMap<>(); // 所有数据库的zlm的缓存
  39 + private Map<String, Integer> zlmServerStatus = new LinkedHashMap<>(); // 所有上线的zlm的缓存以及负载
  40 +
  41 + @Value("${sip.ip}")
  42 + private String sipIp;
  43 +
  44 + @Value("${server.ssl.enabled:false}")
  45 + private boolean sslEnabled;
  46 +
  47 + @Value("${server.port}")
  48 + private String serverPort;
  49 +
  50 + @Autowired
  51 + private MediaConfig mediaConfig;
  52 +
  53 + @Autowired
  54 + private ZLMRESTfulUtils zlmresTfulUtils;
  55 +
  56 + @Autowired
  57 + private MediaServerMapper mediaServerMapper;
  58 +
  59 +
  60 + @Autowired
  61 + private IRedisCatchStorage redisCatchStorage;
  62 +
  63 + @Autowired
  64 + private VideoStreamSessionManager streamSession;
  65 +
  66 + @Autowired
  67 + private ZLMRTPServerFactory zlmrtpServerFactory;
  68 +
  69 + private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  70 +
  71 + /**
  72 + * 初始化
  73 + */
  74 + @Override
  75 + public void init() {
  76 + zlmServers.clear();
  77 + zlmServerStatus.clear();
  78 + List<MediaServerItem> mediaServerItemList = mediaServerMapper.queryAll();
  79 + for (IMediaServerItem mediaServerItem : mediaServerItemList) {
  80 + zlmServers.put(mediaServerItem.getId(), mediaServerItem);
  81 + }
  82 + }
  83 +
  84 + @Override
  85 + public void closeRTPServer(Device device, String channelId) {
  86 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
  87 + IMediaServerItem mediaServerItem = null;
  88 + if (streamInfo != null) {
  89 + mediaServerItem = this.getOne (streamInfo.getMediaServerId());
  90 + }
  91 + String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
  92 + zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
  93 + streamSession.remove(device.getDeviceId(), channelId);
  94 + }
  95 +
  96 + @Override
  97 + public void update(MediaConfig mediaConfig) {
  98 +
  99 + }
  100 +
  101 + @Override
  102 + public List<IMediaServerItem> getAll() {
  103 + if (zlmServers.size() == 0) {
  104 + init();
  105 + }
  106 + List<IMediaServerItem> result = new ArrayList<>();
  107 + for (String id : zlmServers.keySet()) {
  108 + IMediaServerItem mediaServerItem = zlmServers.get(id);
  109 + mediaServerItem.setCount(zlmServerStatus.get(id) == null ? 0 : zlmServerStatus.get(id));
  110 + result.add(mediaServerItem);
  111 + }
  112 + return result;
  113 +
  114 +
  115 +// return mediaServerMapper.queryAll();
  116 + }
  117 +
  118 + /**
  119 + * 获取单个zlm服务器
  120 + * @param mediaServerId 服务id
  121 + * @return MediaServerItem
  122 + */
  123 + @Override
  124 + public IMediaServerItem getOne(String mediaServerId) {
  125 + if (mediaServerId ==null) return null;
  126 + IMediaServerItem mediaServerItem = zlmServers.get(mediaServerId);
  127 + if (mediaServerItem != null) {
  128 + mediaServerItem.setCount(zlmServerStatus.get(mediaServerId) == null ? 0 : zlmServerStatus.get(mediaServerId));
  129 + return mediaServerItem;
  130 + }else {
  131 + IMediaServerItem item = mediaServerMapper.queryOne(mediaServerId);
  132 + if (item != null) {
  133 + zlmServers.put(item.getId(), item);
  134 + }
  135 + return item;
  136 + }
  137 + }
  138 +
  139 + @Override
  140 + public IMediaServerItem getOneByHostAndPort(String host, int port) {
  141 + return mediaServerMapper.queryOneByHostAndPort(host, port);
  142 + }
  143 +
  144 + /**
  145 + * 处理zlm上线
  146 + * @param zlmServerConfig zlm上线携带的参数
  147 + */
  148 + @Override
  149 + public void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig) {
  150 + logger.info("[ {} ]-[ {}:{} ]已连接",
  151 + zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort());
  152 +
  153 + IMediaServerItem serverItem = getOne(zlmServerConfig.getGeneralMediaServerId());
  154 + String now = this.format.format(new Date(System.currentTimeMillis()));
  155 + if (serverItem != null) {
  156 + serverItem.setSecret(zlmServerConfig.getApiSecret());
  157 + serverItem.setIp(zlmServerConfig.getIp());
  158 + // 如果是配置文件中的zlm。 也就是默认zlm。 一切以配置文件内容为准
  159 + // docker部署不会使用zlm配置的端口号;
  160 + // 直接编译部署的使用配置文件的端口号,如果zlm修改配改了配置,wvp自动修改
  161 +
  162 + if (serverItem.getId().equals(mediaConfig.getId())
  163 + || (serverItem.getIp().equals(mediaConfig.getIp()) && serverItem.getHttpPort() == mediaConfig.getHttpPort())) {
  164 + // 配置文件的zlm
  165 + mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId());
  166 + mediaConfig.setUpdateTime(now);
  167 + if (mediaConfig.getHttpPort() == 0) mediaConfig.setHttpPort(zlmServerConfig.getHttpPort());
  168 + if (mediaConfig.getHttpSSlPort() == 0) mediaConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport());
  169 + if (mediaConfig.getRtmpPort() == 0) mediaConfig.setRtmpPort(zlmServerConfig.getRtmpPort());
  170 + if (mediaConfig.getRtmpSSlPort() == 0) mediaConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
  171 + if (mediaConfig.getRtspPort() == 0) mediaConfig.setRtspPort(zlmServerConfig.getRtspPort());
  172 + if (mediaConfig.getRtspSSLPort() == 0) mediaConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport());
  173 + if (mediaConfig.getRtpProxyPort() == 0) mediaConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
  174 + mediaServerMapper.update(mediaConfig);
  175 + serverItem = mediaConfig.getMediaSerItem();
  176 + setZLMConfig(mediaConfig);
  177 + }else {
  178 + if (!serverItem.isDocker()) {
  179 + serverItem.setHttpPort(zlmServerConfig.getHttpPort());
  180 + serverItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport());
  181 + serverItem.setRtmpPort(zlmServerConfig.getRtmpPort());
  182 + serverItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
  183 + serverItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
  184 + serverItem.setRtspPort(zlmServerConfig.getRtspPort());
  185 +
  186 + }
  187 + serverItem.setUpdateTime(now);
  188 + mediaServerMapper.update(serverItem);
  189 + setZLMConfig(serverItem);
  190 + }
  191 + }else {
  192 + if (zlmServerConfig.getGeneralMediaServerId().equals(mediaConfig.getId())
  193 + || (zlmServerConfig.getIp().equals(mediaConfig.getIp()) && zlmServerConfig.getHttpPort() == mediaConfig.getHttpPort())) {
  194 + mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId());
  195 + mediaConfig.setCreateTime(now);
  196 + mediaConfig.setUpdateTime(now);
  197 + serverItem = mediaConfig;
  198 + mediaServerMapper.add(mediaConfig);
  199 + }else {
  200 + // 一个新的zlm接入wvp
  201 + serverItem = new MediaServerItem(zlmServerConfig, sipIp);
  202 + serverItem.setCreateTime(now);
  203 + serverItem.setUpdateTime(now);
  204 + mediaServerMapper.add(serverItem);
  205 + }
  206 + }
  207 + // 更新缓存
  208 + if (zlmServerStatus.get(serverItem.getId()) == null) {
  209 + zlmServers.put(serverItem.getId(), serverItem);
  210 + zlmServerStatus.put(serverItem.getId(),0);
  211 + }
  212 + // 查询服务流数量
  213 + IMediaServerItem finalServerItem = serverItem;
  214 + zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{
  215 + Integer code = mediaList.getInteger("code");
  216 + if (code == 0) {
  217 + JSONArray data = mediaList.getJSONArray("data");
  218 + if (data != null) {
  219 + zlmServerStatus.put(finalServerItem.getId(),data.size());
  220 + }else {
  221 + zlmServerStatus.put(finalServerItem.getId(),0);
  222 + }
  223 +
  224 + }
  225 + }));
  226 +
  227 + }
  228 +
  229 + /**
  230 + * 更新缓存
  231 + * @param mediaServerItem zlm服务
  232 + * @param count 在线数
  233 + * @param online 在线状态
  234 + */
  235 + @Override
  236 + public void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean online) {
  237 + if (mediaServerItem != null) {
  238 + zlmServers.put(mediaServerItem.getId(), mediaServerItem);
  239 + Collection<Integer> values = zlmServerStatus.values();
  240 + if (online != null && count != null) {
  241 + zlmServerStatus.put(mediaServerItem.getId(), count);
  242 + }
  243 + }
  244 + }
  245 +
  246 + @Override
  247 + public void addCount(String mediaServerId) {
  248 + if (zlmServerStatus.get(mediaServerId) != null) {
  249 + zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) + 1);
  250 + }
  251 + }
  252 +
  253 + @Override
  254 + public void removeCount(String mediaServerId) {
  255 + if (zlmServerStatus.get(mediaServerId) != null) {
  256 + zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) - 1);
  257 + }
  258 + }
  259 +
  260 + /**
  261 + * 获取负载最低的节点
  262 + * @return MediaServerItem
  263 + */
  264 + @Override
  265 + public IMediaServerItem getMediaServerForMinimumLoad() {
  266 + int mediaCount = -1;
  267 + String key = null;
  268 + System.out.println(JSON.toJSONString(zlmServerStatus));
  269 + if (zlmServerStatus.size() == 1) {
  270 + Map.Entry entry = zlmServerStatus.entrySet().iterator().next();
  271 + key= (String) entry.getKey();
  272 + }else {
  273 + for (String id : zlmServerStatus.keySet()) {
  274 + if (key == null) {
  275 + key = id;
  276 + mediaCount = zlmServerStatus.get(id);
  277 + }
  278 + if (zlmServerStatus.get(id) == 0) {
  279 + key = id;
  280 + break;
  281 + }else if (mediaCount >= zlmServerStatus.get(id)){
  282 + mediaCount = zlmServerStatus.get(id);
  283 + key = id;
  284 + }
  285 + }
  286 + }
  287 +
  288 + if (key == null) {
  289 + logger.info("获取负载最低的节点时无在线节点");
  290 + return null;
  291 + }else{
  292 + return zlmServers.get(key);
  293 + }
  294 + }
  295 +
  296 + /**
  297 + * 对zlm服务器进行基础配置
  298 + * @param mediaServerItem 服务ID
  299 + */
  300 + @Override
  301 + public void setZLMConfig(IMediaServerItem mediaServerItem) {
  302 + logger.info("[ {} ]-[ {}:{} ]设置zlm",
  303 + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
  304 + String protocol = sslEnabled ? "https" : "http";
  305 + String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort);
  306 + String recordHookPrex = null;
  307 + if (mediaServerItem.getRecordAssistPort() != 0) {
  308 + recordHookPrex = String.format("http://127.0.0.1:%s/api/record", mediaServerItem.getRecordAssistPort());
  309 + }
  310 + Map<String, Object> param = new HashMap<>();
  311 + param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline
  312 + param.put("ffmpeg.cmd","%s -fflags nobuffer -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s");
  313 + param.put("hook.enable","1");
  314 + param.put("hook.on_flow_report","");
  315 + param.put("hook.on_play",String.format("%s/on_play", hookPrex));
  316 + param.put("hook.on_http_access","");
  317 + param.put("hook.on_publish", String.format("%s/on_publish", hookPrex));
  318 + param.put("hook.on_record_mp4",recordHookPrex != null? String.format("%s/on_record_mp4", recordHookPrex): "");
  319 + param.put("hook.on_record_ts","");
  320 + param.put("hook.on_rtsp_auth","");
  321 + param.put("hook.on_rtsp_realm","");
  322 + param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrex));
  323 + param.put("hook.on_shell_login",String.format("%s/on_shell_login", hookPrex));
  324 + param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrex));
  325 + param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex));
  326 + param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
  327 + param.put("hook.timeoutSec","20");
  328 + param.put("general.streamNoneReaderDelayMS",mediaServerItem.getStreamNoneReaderDelayMS());
  329 +
  330 + JSONObject responseJSON = zlmresTfulUtils.setServerConfig(mediaServerItem, param);
  331 +
  332 + if (responseJSON != null && responseJSON.getInteger("code") == 0) {
  333 + logger.info("[ {} ]-[ {}:{} ]设置zlm成功",
  334 + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
  335 + }else {
  336 + logger.info("[ {} ]-[ {}:{} ]设置zlm失败" + responseJSON.getString("msg"),
  337 + mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
  338 + }
  339 + }
  340 +}
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
@@ -6,6 +6,9 @@ import com.alibaba.fastjson.JSONObject; @@ -6,6 +6,9 @@ import com.alibaba.fastjson.JSONObject;
6 import com.genersoft.iot.vmp.common.StreamInfo; 6 import com.genersoft.iot.vmp.common.StreamInfo;
7 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 7 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
8 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 8 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  9 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  10 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  11 +import com.genersoft.iot.vmp.service.IMediaServerService;
9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
10 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
11 import com.genersoft.iot.vmp.service.IMediaService; 14 import com.genersoft.iot.vmp.service.IMediaService;
@@ -22,29 +25,52 @@ public class MediaServiceImpl implements IMediaService { @@ -22,29 +25,52 @@ public class MediaServiceImpl implements IMediaService {
22 private IVideoManagerStorager storager; 25 private IVideoManagerStorager storager;
23 26
24 @Autowired 27 @Autowired
  28 + private IMediaServerService mediaServerService;
  29 +
  30 + @Autowired
25 private ZLMRESTfulUtils zlmresTfulUtils; 31 private ZLMRESTfulUtils zlmresTfulUtils;
26 32
27 33
28 34
29 @Override 35 @Override
30 - public StreamInfo getStreamInfoByAppAndStream(String app, String stream, JSONArray tracks) {  
31 - return getStreamInfoByAppAndStream(app, stream, tracks, null); 36 + public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks) {
  37 + return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null);
  38 + }
  39 +
  40 + @Override
  41 + public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) {
  42 + StreamInfo streamInfo = null;
  43 + IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
  44 + if (mediaInfo == null) {
  45 + return streamInfo;
  46 + }
  47 + JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, app, stream);
  48 + if (mediaList != null) {
  49 + if (mediaList.getInteger("code") == 0) {
  50 + JSONArray data = mediaList.getJSONArray("data");
  51 + if (data == null) return null;
  52 + JSONObject mediaJSON = JSON.parseObject(JSON.toJSONString(data.get(0)), JSONObject.class);
  53 + JSONArray tracks = mediaJSON.getJSONArray("tracks");
  54 + streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks);
  55 + }
  56 + }
  57 + return streamInfo;
32 } 58 }
33 59
34 @Override 60 @Override
35 - public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream) {  
36 - return getStreamInfoByAppAndStreamWithCheck(app, stream, null); 61 + public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId) {
  62 + return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null);
37 } 63 }
38 64
39 @Override 65 @Override
40 - public StreamInfo getStreamInfoByAppAndStream(String app, String stream, JSONArray tracks, String addr) {  
41 - ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); 66 + public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr) {
42 StreamInfo streamInfoResult = new StreamInfo(); 67 StreamInfo streamInfoResult = new StreamInfo();
43 streamInfoResult.setStreamId(stream); 68 streamInfoResult.setStreamId(stream);
44 streamInfoResult.setApp(app); 69 streamInfoResult.setApp(app);
45 if (addr == null) { 70 if (addr == null) {
46 addr = mediaInfo.getStreamIp(); 71 addr = mediaInfo.getStreamIp();
47 } 72 }
  73 + streamInfoResult.setMediaServerId(mediaInfo.getId());
48 streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s", addr, mediaInfo.getRtmpPort(), app, stream)); 74 streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s", addr, mediaInfo.getRtmpPort(), app, stream));
49 streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s", addr, mediaInfo.getRtspPort(), app, stream)); 75 streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s", addr, mediaInfo.getRtspPort(), app, stream));
50 streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.flv", addr, mediaInfo.getHttpPort(), app, stream)); 76 streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.flv", addr, mediaInfo.getHttpPort(), app, stream));
@@ -60,19 +86,4 @@ public class MediaServiceImpl implements IMediaService { @@ -60,19 +86,4 @@ public class MediaServiceImpl implements IMediaService {
60 return streamInfoResult; 86 return streamInfoResult;
61 } 87 }
62 88
63 - @Override  
64 - public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String addr) {  
65 - StreamInfo streamInfo = null;  
66 - JSONObject mediaList = zlmresTfulUtils.getMediaList(app, stream);  
67 - if (mediaList != null) {  
68 - if (mediaList.getInteger("code") == 0) {  
69 - JSONArray data = mediaList.getJSONArray("data");  
70 - if (data == null) return null;  
71 - JSONObject mediaJSON = JSON.parseObject(JSON.toJSONString(data.get(0)), JSONObject.class);  
72 - JSONArray tracks = mediaJSON.getJSONArray("tracks");  
73 - streamInfo = getStreamInfoByAppAndStream(app, stream, tracks, addr);  
74 - }  
75 - }  
76 - return streamInfo;  
77 - }  
78 } 89 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -14,6 +14,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; @@ -14,6 +14,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
14 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 14 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
15 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 15 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  17 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  18 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  19 +import com.genersoft.iot.vmp.service.IMediaServerService;
17 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
18 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 21 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
19 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 22 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
@@ -60,6 +63,9 @@ public class PlayServiceImpl implements IPlayService { @@ -60,6 +63,9 @@ public class PlayServiceImpl implements IPlayService {
60 private IMediaService mediaService; 63 private IMediaService mediaService;
61 64
62 @Autowired 65 @Autowired
  66 + private IMediaServerService mediaServerService;
  67 +
  68 + @Autowired
63 private VideoStreamSessionManager streamSession; 69 private VideoStreamSessionManager streamSession;
64 70
65 @Autowired 71 @Autowired
@@ -67,8 +73,18 @@ public class PlayServiceImpl implements IPlayService { @@ -67,8 +73,18 @@ public class PlayServiceImpl implements IPlayService {
67 73
68 74
69 @Override 75 @Override
70 - public PlayResult play(String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { 76 + public PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) {
71 PlayResult playResult = new PlayResult(); 77 PlayResult playResult = new PlayResult();
  78 + if (mediaServerItem == null) {
  79 + RequestMessage msg = new RequestMessage();
  80 + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid());
  81 + WVPResult wvpResult = new WVPResult();
  82 + wvpResult.setCode(-1);
  83 + wvpResult.setMsg("未找到可用的zlm");
  84 + msg.setData(wvpResult);
  85 + resultHolder.invokeResult(msg);
  86 + return playResult;
  87 + }
72 Device device = storager.queryVideoDevice(deviceId); 88 Device device = storager.queryVideoDevice(deviceId);
73 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); 89 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
74 playResult.setDevice(device); 90 playResult.setDevice(device);
@@ -82,7 +98,7 @@ public class PlayServiceImpl implements IPlayService { @@ -82,7 +98,7 @@ public class PlayServiceImpl implements IPlayService {
82 result.onTimeout(()->{ 98 result.onTimeout(()->{
83 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 99 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
84 // 释放rtpserver 100 // 释放rtpserver
85 - cmder.closeRTPServer(playResult.getDevice(), channelId); 101 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
86 RequestMessage msg = new RequestMessage(); 102 RequestMessage msg = new RequestMessage();
87 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid()); 103 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid());
88 WVPResult wvpResult = new WVPResult(); 104 WVPResult wvpResult = new WVPResult();
@@ -115,9 +131,10 @@ public class PlayServiceImpl implements IPlayService { @@ -115,9 +131,10 @@ public class PlayServiceImpl implements IPlayService {
115 WVPResult wvpResult = (WVPResult)responseEntity.getBody(); 131 WVPResult wvpResult = (WVPResult)responseEntity.getBody();
116 if (wvpResult.getCode() == 0) { 132 if (wvpResult.getCode() == 0) {
117 StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData(); 133 StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
  134 + IMediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
118 String streamUrl = streamInfoForSuccess.getFmp4(); 135 String streamUrl = streamInfoForSuccess.getFmp4();
119 // 请求截图 136 // 请求截图
120 - zlmresTfulUtils.getSnap(streamUrl, 15, 1, path, fileName); 137 + zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
121 } 138 }
122 } 139 }
123 } catch (FileNotFoundException e) { 140 } catch (FileNotFoundException e) {
@@ -126,17 +143,17 @@ public class PlayServiceImpl implements IPlayService { @@ -126,17 +143,17 @@ public class PlayServiceImpl implements IPlayService {
126 }); 143 });
127 if (streamInfo == null) { 144 if (streamInfo == null) {
128 // 发送点播消息 145 // 发送点播消息
129 - cmder.playStreamCmd(device, channelId, (JSONObject response) -> { 146 + cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInUse, JSONObject response) -> {
130 logger.info("收到订阅消息: " + response.toJSONString()); 147 logger.info("收到订阅消息: " + response.toJSONString());
131 - onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); 148 + onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid.toString());
132 if (hookEvent != null) { 149 if (hookEvent != null) {
133 - hookEvent.response(response); 150 + hookEvent.response(mediaServerItem, response);
134 } 151 }
135 - }, event -> { 152 + }, (event) -> {
136 RequestMessage msg = new RequestMessage(); 153 RequestMessage msg = new RequestMessage();
137 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); 154 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
138 Response response = event.getResponse(); 155 Response response = event.getResponse();
139 - cmder.closeRTPServer(playResult.getDevice(), channelId); 156 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
140 WVPResult wvpResult = new WVPResult(); 157 WVPResult wvpResult = new WVPResult();
141 wvpResult.setCode(-1); 158 wvpResult.setCode(-1);
142 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); 159 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
@@ -158,7 +175,10 @@ public class PlayServiceImpl implements IPlayService { @@ -158,7 +175,10 @@ public class PlayServiceImpl implements IPlayService {
158 resultHolder.invokeResult(msg); 175 resultHolder.invokeResult(msg);
159 return playResult; 176 return playResult;
160 } 177 }
161 - JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); 178 + String mediaServerId = streamInfo.getMediaServerId();
  179 + IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
  180 +
  181 + JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId);
162 if (rtpInfo != null && rtpInfo.getBoolean("exist")) { 182 if (rtpInfo != null && rtpInfo.getBoolean("exist")) {
163 RequestMessage msg = new RequestMessage(); 183 RequestMessage msg = new RequestMessage();
164 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); 184 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
@@ -171,16 +191,16 @@ public class PlayServiceImpl implements IPlayService { @@ -171,16 +191,16 @@ public class PlayServiceImpl implements IPlayService {
171 191
172 resultHolder.invokeResult(msg); 192 resultHolder.invokeResult(msg);
173 if (hookEvent != null) { 193 if (hookEvent != null) {
174 - hookEvent.response(JSONObject.parseObject(JSON.toJSONString(streamInfo))); 194 + hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo)));
175 } 195 }
176 } else { 196 } else {
177 redisCatchStorage.stopPlay(streamInfo); 197 redisCatchStorage.stopPlay(streamInfo);
178 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 198 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
179 - cmder.playStreamCmd(device, channelId, (JSONObject response) -> { 199 + cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> {
180 logger.info("收到订阅消息: " + response.toJSONString()); 200 logger.info("收到订阅消息: " + response.toJSONString());
181 - onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());  
182 - }, event -> {  
183 - cmder.closeRTPServer(playResult.getDevice(), channelId); 201 + onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());
  202 + }, (event) -> {
  203 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
184 RequestMessage msg = new RequestMessage(); 204 RequestMessage msg = new RequestMessage();
185 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); 205 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
186 Response response = event.getResponse(); 206 Response response = event.getResponse();
@@ -198,10 +218,10 @@ public class PlayServiceImpl implements IPlayService { @@ -198,10 +218,10 @@ public class PlayServiceImpl implements IPlayService {
198 } 218 }
199 219
200 @Override 220 @Override
201 - public void onPublishHandlerForPlay(JSONObject resonse, String deviceId, String channelId, String uuid) { 221 + public void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
202 RequestMessage msg = new RequestMessage(); 222 RequestMessage msg = new RequestMessage();
203 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); 223 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
204 - StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid); 224 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);
205 if (streamInfo != null) { 225 if (streamInfo != null) {
206 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); 226 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
207 if (deviceChannel != null) { 227 if (deviceChannel != null) {
@@ -234,10 +254,26 @@ public class PlayServiceImpl implements IPlayService { @@ -234,10 +254,26 @@ public class PlayServiceImpl implements IPlayService {
234 } 254 }
235 255
236 @Override 256 @Override
237 - public void onPublishHandlerForPlayBack(JSONObject resonse, String deviceId, String channelId, String uuid) { 257 + public IMediaServerItem getNewMediaServerItem(Device device) {
  258 + if (device == null) return null;
  259 + String mediaServerId = device.getMediaServerId();
  260 + IMediaServerItem mediaServerItem = null;
  261 + if (mediaServerId == null) {
  262 + mediaServerItem = mediaServerService.getMediaServerForMinimumLoad();
  263 + }else {
  264 + mediaServerItem = mediaServerService.getOne(mediaServerId);
  265 + }
  266 + if (mediaServerItem == null) {
  267 + logger.warn("点播时未找到可使用的ZLM...");
  268 + }
  269 + return mediaServerItem;
  270 + }
  271 +
  272 + @Override
  273 + public void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
238 RequestMessage msg = new RequestMessage(); 274 RequestMessage msg = new RequestMessage();
239 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); 275 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
240 - StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid); 276 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);
241 if (streamInfo != null) { 277 if (streamInfo != null) {
242 redisCatchStorage.startPlayback(streamInfo); 278 redisCatchStorage.startPlayback(streamInfo);
243 msg.setData(JSON.toJSONString(streamInfo)); 279 msg.setData(JSON.toJSONString(streamInfo));
@@ -249,10 +285,10 @@ public class PlayServiceImpl implements IPlayService { @@ -249,10 +285,10 @@ public class PlayServiceImpl implements IPlayService {
249 } 285 }
250 } 286 }
251 287
252 - public StreamInfo onPublishHandler(JSONObject resonse, String deviceId, String channelId, String uuid) { 288 + public StreamInfo onPublishHandler(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
253 String streamId = resonse.getString("stream"); 289 String streamId = resonse.getString("stream");
254 JSONArray tracks = resonse.getJSONArray("tracks"); 290 JSONArray tracks = resonse.getJSONArray("tracks");
255 - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream("rtp", streamId, tracks); 291 + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks);
256 streamInfo.setDeviceID(deviceId); 292 streamInfo.setDeviceID(deviceId);
257 streamInfo.setChannelId(channelId); 293 streamInfo.setChannelId(channelId);
258 return streamInfo; 294 return streamInfo;
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -2,10 +2,12 @@ package com.genersoft.iot.vmp.service.impl; @@ -2,10 +2,12 @@ package com.genersoft.iot.vmp.service.impl;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
4 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 4 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
5 -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;  
6 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 5 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 8 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
8 import com.genersoft.iot.vmp.service.IGbStreamService; 9 import com.genersoft.iot.vmp.service.IGbStreamService;
  10 +import com.genersoft.iot.vmp.service.IMediaServerService;
9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
10 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 12 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
11 import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; 13 import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
@@ -13,6 +15,8 @@ import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; @@ -13,6 +15,8 @@ import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper;
13 import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper; 15 import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper;
14 import com.genersoft.iot.vmp.service.IStreamProxyService; 16 import com.genersoft.iot.vmp.service.IStreamProxyService;
15 import com.github.pagehelper.PageInfo; 17 import com.github.pagehelper.PageInfo;
  18 +import org.slf4j.Logger;
  19 +import org.slf4j.LoggerFactory;
16 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.stereotype.Service; 21 import org.springframework.stereotype.Service;
18 22
@@ -25,6 +29,8 @@ import java.util.List; @@ -25,6 +29,8 @@ import java.util.List;
25 @Service 29 @Service
26 public class StreamProxyServiceImpl implements IStreamProxyService { 30 public class StreamProxyServiceImpl implements IStreamProxyService {
27 31
  32 + private final static Logger logger = LoggerFactory.getLogger(StreamProxyServiceImpl.class);
  33 +
28 @Autowired 34 @Autowired
29 private IVideoManagerStorager videoManagerStorager; 35 private IVideoManagerStorager videoManagerStorager;
30 36
@@ -32,7 +38,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -32,7 +38,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
32 private IRedisCatchStorage redisCatchStorage; 38 private IRedisCatchStorage redisCatchStorage;
33 39
34 @Autowired 40 @Autowired
35 - private ZLMRESTfulUtils zlmresTfulUtils; 41 + private ZLMRESTfulUtils zlmresTfulUtils;;
36 42
37 @Autowired 43 @Autowired
38 private StreamProxyMapper streamProxyMapper; 44 private StreamProxyMapper streamProxyMapper;
@@ -46,15 +52,28 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -46,15 +52,28 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
46 @Autowired 52 @Autowired
47 private IGbStreamService gbStreamService; 53 private IGbStreamService gbStreamService;
48 54
  55 + @Autowired
  56 + private IMediaServerService mediaServerService;
  57 +
49 58
50 @Override 59 @Override
51 public String save(StreamProxyItem param) { 60 public String save(StreamProxyItem param) {
52 - ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); 61 + IMediaServerItem mediaInfo;
  62 + if ("auto".equals(param.getMediaServerId())){
  63 + mediaInfo = mediaServerService.getMediaServerForMinimumLoad();
  64 + }else {
  65 + mediaInfo = mediaServerService.getOne(param.getMediaServerId());
  66 + }
  67 + if (mediaInfo == null) {
  68 + logger.warn("保存代理未找到在线的ZLM...");
  69 + return "保存失败";
  70 + }
53 String dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(), 71 String dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(),
54 param.getStream() ); 72 param.getStream() );
55 param.setDst_url(dstUrl); 73 param.setDst_url(dstUrl);
56 StringBuffer result = new StringBuffer(); 74 StringBuffer result = new StringBuffer();
57 boolean streamLive = false; 75 boolean streamLive = false;
  76 + param.setMediaServerId(mediaInfo.getId());
58 // 更新 77 // 更新
59 if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) { 78 if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) {
60 if (videoManagerStorager.updateStreamProxy(param)) { 79 if (videoManagerStorager.updateStreamProxy(param)) {
@@ -81,6 +100,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -81,6 +100,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
81 videoManagerStorager.updateStreamProxy(param); 100 videoManagerStorager.updateStreamProxy(param);
82 } 101 }
83 } 102 }
  103 + }else {
  104 + result.append("保存失败");
84 } 105 }
85 106
86 } 107 }
@@ -99,11 +120,18 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -99,11 +120,18 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
99 @Override 120 @Override
100 public JSONObject addStreamProxyToZlm(StreamProxyItem param) { 121 public JSONObject addStreamProxyToZlm(StreamProxyItem param) {
101 JSONObject result = null; 122 JSONObject result = null;
  123 + IMediaServerItem mediaServerItem = null;
  124 + if (param.getMediaServerId() == null) {
  125 + logger.warn("添加代理时MediaServerId 为null");
  126 + return null;
  127 + }else {
  128 + mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
  129 + }
102 if ("default".equals(param.getType())){ 130 if ("default".equals(param.getType())){
103 - result = zlmresTfulUtils.addStreamProxy(param.getApp(), param.getStream(), param.getUrl(), 131 + result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl(),
104 param.isEnable_hls(), param.isEnable_mp4(), param.getRtp_type()); 132 param.isEnable_hls(), param.isEnable_mp4(), param.getRtp_type());
105 }else if ("ffmpeg".equals(param.getType())) { 133 }else if ("ffmpeg".equals(param.getType())) {
106 - result = zlmresTfulUtils.addFFmpegSource(param.getSrc_url(), param.getDst_url(), 134 + result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrc_url(), param.getDst_url(),
107 param.getTimeout_ms() + "", param.isEnable_hls(), param.isEnable_mp4(), 135 param.getTimeout_ms() + "", param.isEnable_hls(), param.isEnable_mp4(),
108 param.getFfmpeg_cmd_key()); 136 param.getFfmpeg_cmd_key());
109 } 137 }
@@ -112,8 +140,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -112,8 +140,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
112 140
113 @Override 141 @Override
114 public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) { 142 public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) {
115 - JSONObject result = zlmresTfulUtils.closeStreams(param.getApp(), param.getStream());  
116 - 143 + if (param ==null) return null;
  144 + IMediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
  145 + JSONObject result = zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream());
117 return result; 146 return result;
118 } 147 }
119 148
@@ -124,17 +153,18 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -124,17 +153,18 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
124 153
125 @Override 154 @Override
126 public void del(String app, String stream) { 155 public void del(String app, String stream) {
127 - StreamProxyItem streamProxyItem = new StreamProxyItem();  
128 - streamProxyItem.setApp(app);  
129 - streamProxyItem.setStream(stream);  
130 - JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyItem);  
131 - if (jsonObject.getInteger("code") == 0) { 156 + StreamProxyItem streamProxyItem = videoManagerStorager.queryStreamProxy(app, stream);
  157 + if (streamProxyItem != null) {
132 videoManagerStorager.deleteStreamProxy(app, stream); 158 videoManagerStorager.deleteStreamProxy(app, stream);
133 - // 如果关联了国标那么移除关联  
134 - gbStreamMapper.del(app, stream);  
135 - platformGbStreamMapper.delByAppAndStream(app, stream);  
136 - // TODO 如果关联的推流, 那么状态设置为离线 159 + JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyItem);
  160 + if (jsonObject != null && jsonObject.getInteger("code") == 0) {
  161 + // 如果关联了国标那么移除关联
  162 + gbStreamMapper.del(app, stream);
  163 + platformGbStreamMapper.delByAppAndStream(app, stream);
  164 + // TODO 如果关联的推流, 那么状态设置为离线
  165 + }
137 } 166 }
  167 +
138 } 168 }
139 169
140 @Override 170 @Override
@@ -168,9 +198,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -168,9 +198,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
168 } 198 }
169 199
170 @Override 200 @Override
171 - public JSONObject getFFmpegCMDs() { 201 + public JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem) {
172 JSONObject result = new JSONObject(); 202 JSONObject result = new JSONObject();
173 - JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(); 203 + JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
174 if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0 204 if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0
175 && mediaServerConfigResuly.getJSONArray("data").size() > 0){ 205 && mediaServerConfigResuly.getJSONArray("data").size() > 0){
176 JSONObject mediaServerConfig = mediaServerConfigResuly.getJSONArray("data").getJSONObject(0); 206 JSONObject mediaServerConfig = mediaServerConfigResuly.getJSONArray("data").getJSONObject(0);
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -5,9 +5,13 @@ import com.alibaba.fastjson.JSONObject; @@ -5,9 +5,13 @@ import com.alibaba.fastjson.JSONObject;
5 import com.alibaba.fastjson.TypeReference; 5 import com.alibaba.fastjson.TypeReference;
6 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 6 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
7 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 7 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
8 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
  10 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
9 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
  12 +import com.genersoft.iot.vmp.service.IMediaServerService;
10 import com.genersoft.iot.vmp.service.IStreamPushService; 13 import com.genersoft.iot.vmp.service.IStreamPushService;
  14 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; 15 import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
12 import com.genersoft.iot.vmp.storager.dao.StreamPushMapper; 16 import com.genersoft.iot.vmp.storager.dao.StreamPushMapper;
13 import com.github.pagehelper.PageHelper; 17 import com.github.pagehelper.PageHelper;
@@ -32,8 +36,14 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -32,8 +36,14 @@ public class StreamPushServiceImpl implements IStreamPushService {
32 @Autowired 36 @Autowired
33 private ZLMRESTfulUtils zlmresTfulUtils; 37 private ZLMRESTfulUtils zlmresTfulUtils;
34 38
  39 + @Autowired
  40 + private IRedisCatchStorage redisCatchStorage;
  41 +
  42 + @Autowired
  43 + private IMediaServerService mediaServerService;
  44 +
35 @Override 45 @Override
36 - public List<StreamPushItem> handleJSON(String jsonData) { 46 + public List<StreamPushItem> handleJSON(String jsonData, IMediaServerItem mediaServerItem) {
37 if (jsonData == null) return null; 47 if (jsonData == null) return null;
38 48
39 Map<String, StreamPushItem> result = new HashMap<>(); 49 Map<String, StreamPushItem> result = new HashMap<>();
@@ -50,6 +60,7 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -50,6 +60,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
50 if (streamPushItem == null) { 60 if (streamPushItem == null) {
51 streamPushItem = new StreamPushItem(); 61 streamPushItem = new StreamPushItem();
52 streamPushItem.setApp(item.getApp()); 62 streamPushItem.setApp(item.getApp());
  63 + streamPushItem.setMediaServerId(mediaServerItem.getId());
53 streamPushItem.setStream(item.getStream()); 64 streamPushItem.setStream(item.getStream());
54 streamPushItem.setAliveSecond(item.getAliveSecond()); 65 streamPushItem.setAliveSecond(item.getAliveSecond());
55 streamPushItem.setCreateStamp(item.getCreateStamp()); 66 streamPushItem.setCreateStamp(item.getCreateStamp());
@@ -87,7 +98,8 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -87,7 +98,8 @@ public class StreamPushServiceImpl implements IStreamPushService {
87 @Override 98 @Override
88 public boolean removeFromGB(GbStream stream) { 99 public boolean removeFromGB(GbStream stream) {
89 int del = gbStreamMapper.del(stream.getApp(), stream.getStream()); 100 int del = gbStreamMapper.del(stream.getApp(), stream.getStream());
90 - JSONObject mediaList = zlmresTfulUtils.getMediaList(stream.getApp(), stream.getStream()); 101 + IMediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId());
  102 + JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream());
91 if (mediaList == null) { 103 if (mediaList == null) {
92 streamPushMapper.del(stream.getApp(), stream.getStream()); 104 streamPushMapper.del(stream.getApp(), stream.getStream());
93 } 105 }
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -2,10 +2,11 @@ package com.genersoft.iot.vmp.storager; @@ -2,10 +2,11 @@ package com.genersoft.iot.vmp.storager;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
4 import com.genersoft.iot.vmp.common.StreamInfo; 4 import com.genersoft.iot.vmp.common.StreamInfo;
5 -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;  
6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
8 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 7 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  9 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
9 10
10 import java.util.List; 11 import java.util.List;
11 import java.util.Map; 12 import java.util.Map;
@@ -40,19 +41,6 @@ public interface IRedisCatchStorage { @@ -40,19 +41,6 @@ public interface IRedisCatchStorage {
40 41
41 StreamInfo queryPlayByDevice(String deviceId, String channelId); 42 StreamInfo queryPlayByDevice(String deviceId, String channelId);
42 43
43 - /**  
44 - * 更新流媒体信息  
45 - * @param ZLMServerConfig  
46 - * @return  
47 - */  
48 - boolean updateMediaInfo(ZLMServerConfig ZLMServerConfig);  
49 -  
50 - /**  
51 - * 获取流媒体信息  
52 - * @return  
53 - */  
54 - ZLMServerConfig getMediaInfo();  
55 -  
56 Map<String, StreamInfo> queryPlayByDeviceId(String deviceId); 44 Map<String, StreamInfo> queryPlayByDeviceId(String deviceId);
57 45
58 boolean startPlayback(StreamInfo stream); 46 boolean startPlayback(StreamInfo stream);
@@ -115,6 +103,13 @@ public interface IRedisCatchStorage { @@ -115,6 +103,13 @@ public interface IRedisCatchStorage {
115 void clearCatchByDeviceId(String deviceId); 103 void clearCatchByDeviceId(String deviceId);
116 104
117 /** 105 /**
  106 + * 获取mediaServer节点
  107 + * @param mediaServerId
  108 + * @return
  109 + */
  110 +// MediaServerItem getMediaInfo(String mediaServerId);
  111 +
  112 + /**
118 * 设置所有设备离线 113 * 设置所有设备离线
119 */ 114 */
120 void outlineForAll(); 115 void outlineForAll();
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.storager; @@ -3,6 +3,8 @@ package com.genersoft.iot.vmp.storager;
3 import java.util.List; 3 import java.util.List;
4 4
5 import com.genersoft.iot.vmp.gb28181.bean.*; 5 import com.genersoft.iot.vmp.gb28181.bean.*;
  6 +import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 8 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
7 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 9 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
8 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; 10 import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
@@ -365,4 +367,12 @@ public interface IVideoManagerStorager { @@ -365,4 +367,12 @@ public interface IVideoManagerStorager {
365 * @param online 367 * @param online
366 */ 368 */
367 void updateParentPlatformStatus(String platformGbID, boolean online); 369 void updateParentPlatformStatus(String platformGbID, boolean online);
  370 +
  371 + /**
  372 + * 更新媒体节点
  373 + * @param mediaServerItem
  374 + */
  375 + void updateMediaServer(MediaServerItem mediaServerItem);
  376 +
  377 + List<StreamProxyItem> getStreamProxyListForEnableInMediaServer(String id, boolean b);
368 } 378 }
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
@@ -12,9 +12,10 @@ import java.util.List; @@ -12,9 +12,10 @@ import java.util.List;
12 public interface GbStreamMapper { 12 public interface GbStreamMapper {
13 13
14 @Insert("INSERT INTO gb_stream (app, stream, gbId, name, " + 14 @Insert("INSERT INTO gb_stream (app, stream, gbId, name, " +
15 - "longitude, latitude, streamType, status) VALUES" + 15 + "longitude, latitude, streamType, mediaServerId, status) VALUES" +
16 "('${app}', '${stream}', '${gbId}', '${name}', " + 16 "('${app}', '${stream}', '${gbId}', '${name}', " +
17 - "'${longitude}', '${latitude}', '${streamType}', ${status})") 17 + "'${longitude}', '${latitude}', '${streamType}', " +
  18 + "'${mediaServerId}', ${status})")
18 int add(GbStream gbStream); 19 int add(GbStream gbStream);
19 20
20 @Update("UPDATE gb_stream " + 21 @Update("UPDATE gb_stream " +
@@ -25,6 +26,7 @@ public interface GbStreamMapper { @@ -25,6 +26,7 @@ public interface GbStreamMapper {
25 "streamType=#{streamType}," + 26 "streamType=#{streamType}," +
26 "longitude=#{longitude}, " + 27 "longitude=#{longitude}, " +
27 "latitude=#{latitude}," + 28 "latitude=#{latitude}," +
  29 + "mediaServerId=#{mediaServerId}," +
28 "status=${status} " + 30 "status=${status} " +
29 "WHERE app=#{app} AND stream=#{stream} AND gbId=#{gbId}") 31 "WHERE app=#{app} AND stream=#{stream} AND gbId=#{gbId}")
30 int update(GbStream gbStream); 32 int update(GbStream gbStream);
@@ -52,4 +54,7 @@ public interface GbStreamMapper { @@ -52,4 +54,7 @@ public interface GbStreamMapper {
52 "SET status=${status} " + 54 "SET status=${status} " +
53 "WHERE app=#{app} AND stream=#{stream}") 55 "WHERE app=#{app} AND stream=#{stream}")
54 void setStatus(String app, String stream, boolean status); 56 void setStatus(String app, String stream, boolean status);
  57 +
  58 + @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} ")
  59 + List<GbStream> selectAllByMediaServerId(String mediaServerId);
55 } 60 }
src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java 0 → 100644
  1 +package com.genersoft.iot.vmp.storager.dao;
  2 +
  3 +import com.genersoft.iot.vmp.conf.MediaConfig;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  6 +import org.apache.ibatis.annotations.Insert;
  7 +import org.apache.ibatis.annotations.Mapper;
  8 +import org.apache.ibatis.annotations.Select;
  9 +import org.apache.ibatis.annotations.Update;
  10 +import org.springframework.stereotype.Repository;
  11 +
  12 +import java.util.List;
  13 +
  14 +
  15 +@Mapper
  16 +@Repository
  17 +public interface MediaServerMapper {
  18 +
  19 + @Insert("INSERT INTO media_server (" +
  20 + "id, " +
  21 + "ip, " +
  22 + "hookIp, " +
  23 + "sdpIp, " +
  24 + "streamIp, " +
  25 + "httpPort, " +
  26 + "httpSSlPort, " +
  27 + "rtmpPort, " +
  28 + "rtmpSSlPort, " +
  29 + "rtpProxyPort, " +
  30 + "rtspPort, " +
  31 + "rtspSSLPort, " +
  32 + "autoConfig, " +
  33 + "secret, " +
  34 + "streamNoneReaderDelayMS, " +
  35 + "rtpEnable, " +
  36 + "rtpPortRange, " +
  37 + "recordAssistPort, " +
  38 + "createTime, " +
  39 + "updateTime" +
  40 + ") VALUES " +
  41 + "(" +
  42 + "'${id}', " +
  43 + "'${ip}', " +
  44 + "'${hookIp}', " +
  45 + "'${sdpIp}', " +
  46 + "'${streamIp}', " +
  47 + "${httpPort}, " +
  48 + "${httpSSlPort}, " +
  49 + "${rtmpPort}, " +
  50 + "${rtmpSSlPort}, " +
  51 + "${rtpProxyPort}, " +
  52 + "${rtspPort}, " +
  53 + "${rtspSSLPort}, " +
  54 + "${autoConfig}, " +
  55 + "'${secret}', " +
  56 + "${streamNoneReaderDelayMS}, " +
  57 + "${rtpEnable}, " +
  58 + "'${rtpPortRange}', " +
  59 + "${recordAssistPort}, " +
  60 + "'${createTime}', " +
  61 + "'${updateTime}')")
  62 + int add(IMediaServerItem mediaServerItem);
  63 +
  64 + @Update(value = {" <script>" +
  65 + "UPDATE media_server " +
  66 + "SET updateTime='${updateTime}'" +
  67 + "<if test=\"ip != null\">, ip='${ip}'</if>" +
  68 + "<if test=\"hookIp != null\">, hookIp='${hookIp}'</if>" +
  69 + "<if test=\"sdpIp != null\">, sdpIp='${sdpIp}'</if>" +
  70 + "<if test=\"streamIp != null\">, streamIp='${streamIp}'</if>" +
  71 + "<if test=\"httpPort != null\">, httpPort=${httpPort}</if>" +
  72 + "<if test=\"httpSSlPort != null\">, httpSSlPort=${httpSSlPort}</if>" +
  73 + "<if test=\"rtmpPort != null\">, rtmpPort=${rtmpPort}</if>" +
  74 + "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=${rtmpSSlPort}</if>" +
  75 + "<if test=\"rtpProxyPort != null\">, rtpProxyPort=${rtpProxyPort}</if>" +
  76 + "<if test=\"rtspPort != null\">, rtspPort=${rtspPort}</if>" +
  77 + "<if test=\"rtspSSLPort != null\">, rtspSSLPort=${rtspSSLPort}</if>" +
  78 + "<if test=\"autoConfig != null\">, autoConfig=${autoConfig}</if>" +
  79 + "<if test=\"streamNoneReaderDelayMS != null\">, streamNoneReaderDelayMS=${streamNoneReaderDelayMS}</if>" +
  80 + "<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" +
  81 + "<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" +
  82 + "<if test=\"secret != null\">, secret='${secret}'</if>" +
  83 + "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +
  84 + "WHERE id='${id}'"+
  85 + " </script>"})
  86 + int update(IMediaServerItem mediaServerItem);
  87 +
  88 + @Select("SELECT * FROM media_server WHERE id='${id}'")
  89 + MediaServerItem queryOne(String id);
  90 +
  91 + @Select("SELECT * FROM media_server")
  92 + List<MediaServerItem> queryAll();
  93 +
  94 + @Select("DELETE FROM media_server WHERE id='${id}'")
  95 + int delOne(String secret);
  96 +
  97 + @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}")
  98 + MediaServerItem queryOneByHostAndPort(String host, int port);
  99 +}
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
@@ -10,10 +10,10 @@ import java.util.List; @@ -10,10 +10,10 @@ import java.util.List;
10 @Repository 10 @Repository
11 public interface StreamProxyMapper { 11 public interface StreamProxyMapper {
12 12
13 - @Insert("INSERT INTO stream_proxy (type, app, stream, url, src_url, dst_url, " +  
14 - "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable) VALUES" +  
15 - "('${type}','${app}', '${stream}', '${url}', '${src_url}', '${dst_url}', " +  
16 - "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable} )") 13 + @Insert("INSERT INTO stream_proxy (type, app, stream,mediaServerId, url, src_url, dst_url, " +
  14 + "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable, createTime) VALUES" +
  15 + "('${type}','${app}', '${stream}', '${mediaServerId}','${url}', '${src_url}', '${dst_url}', " +
  16 + "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable}, '${createTime}' )")
17 int add(StreamProxyItem streamProxyDto); 17 int add(StreamProxyItem streamProxyDto);
18 18
19 @Update("UPDATE stream_proxy " + 19 @Update("UPDATE stream_proxy " +
@@ -21,6 +21,7 @@ public interface StreamProxyMapper { @@ -21,6 +21,7 @@ public interface StreamProxyMapper {
21 "app=#{app}," + 21 "app=#{app}," +
22 "stream=#{stream}," + 22 "stream=#{stream}," +
23 "url=#{url}, " + 23 "url=#{url}, " +
  24 + "mediaServerId=#{mediaServerId}, " +
24 "src_url=#{src_url}," + 25 "src_url=#{src_url}," +
25 "dst_url=#{dst_url}, " + 26 "dst_url=#{dst_url}, " +
26 "timeout_ms=#{timeout_ms}, " + 27 "timeout_ms=#{timeout_ms}, " +
@@ -35,12 +36,17 @@ public interface StreamProxyMapper { @@ -35,12 +36,17 @@ public interface StreamProxyMapper {
35 @Delete("DELETE FROM stream_proxy WHERE app=#{app} AND stream=#{stream}") 36 @Delete("DELETE FROM stream_proxy WHERE app=#{app} AND stream=#{stream}")
36 int del(String app, String stream); 37 int del(String app, String stream);
37 38
38 - @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") 39 + @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")
39 List<StreamProxyItem> selectAll(); 40 List<StreamProxyItem> selectAll();
40 41
41 - @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}") 42 + @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")
42 List<StreamProxyItem> selectForEnable(boolean enable); 43 List<StreamProxyItem> selectForEnable(boolean enable);
43 44
44 - @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}") 45 + @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")
45 StreamProxyItem selectOne(String app, String stream); 46 StreamProxyItem selectOne(String app, String stream);
  47 +
  48 + @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " +
  49 + "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " +
  50 + "WHERE st.enable=${enable} and st.mediaServerId = '${id}' order by st.createTime desc")
  51 + List<StreamProxyItem> selectForEnableInMediaServer(String id, boolean enable);
46 } 52 }
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
@@ -11,14 +11,15 @@ import java.util.List; @@ -11,14 +11,15 @@ import java.util.List;
11 public interface StreamPushMapper { 11 public interface StreamPushMapper {
12 12
13 @Insert("INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " + 13 @Insert("INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
14 - "createStamp, aliveSecond) VALUES" + 14 + "createStamp, aliveSecond, mediaServerId) VALUES" +
15 "('${app}', '${stream}', '${totalReaderCount}', '${originType}', '${originTypeStr}', " + 15 "('${app}', '${stream}', '${totalReaderCount}', '${originType}', '${originTypeStr}', " +
16 - "'${createStamp}', '${aliveSecond}' )") 16 + "'${createStamp}', '${aliveSecond}', '${mediaServerId}' )")
17 int add(StreamPushItem streamPushItem); 17 int add(StreamPushItem streamPushItem);
18 18
19 @Update("UPDATE stream_push " + 19 @Update("UPDATE stream_push " +
20 "SET app=#{app}," + 20 "SET app=#{app}," +
21 "stream=#{stream}," + 21 "stream=#{stream}," +
  22 + "mediaServerId=#{mediaServerId}," +
22 "totalReaderCount=#{totalReaderCount}, " + 23 "totalReaderCount=#{totalReaderCount}, " +
23 "originType=#{originType}," + 24 "originType=#{originType}," +
24 "originTypeStr=#{originTypeStr}, " + 25 "originTypeStr=#{originTypeStr}, " +
@@ -41,10 +42,10 @@ public interface StreamPushMapper { @@ -41,10 +42,10 @@ public interface StreamPushMapper {
41 42
42 @Insert("<script>" + 43 @Insert("<script>" +
43 "INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " + 44 "INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
44 - "createStamp, aliveSecond) " + 45 + "createStamp, aliveSecond, mediaServerId) " +
45 "VALUES <foreach collection='streamPushItems' item='item' index='index' >" + 46 "VALUES <foreach collection='streamPushItems' item='item' index='index' >" +
46 "( '${item.app}', '${item.stream}', '${item.totalReaderCount}', '${item.originType}', " + 47 "( '${item.app}', '${item.stream}', '${item.totalReaderCount}', '${item.originType}', " +
47 - "'${item.originTypeStr}','${item.createStamp}', '${item.aliveSecond}' )" + 48 + "'${item.originTypeStr}','${item.createStamp}', '${item.aliveSecond}', '${item.mediaServerId}' )" +
48 " </foreach>" + 49 " </foreach>" +
49 "</script>") 50 "</script>")
50 void addAll(List<StreamPushItem> streamPushItems); 51 void addAll(List<StreamPushItem> streamPushItems);
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -5,6 +5,8 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -5,6 +5,8 @@ import com.genersoft.iot.vmp.common.StreamInfo;
5 import com.genersoft.iot.vmp.common.VideoManagerConstants; 5 import com.genersoft.iot.vmp.common.VideoManagerConstants;
6 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 6 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
7 import com.genersoft.iot.vmp.gb28181.bean.*; 7 import com.genersoft.iot.vmp.gb28181.bean.*;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
  9 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
9 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; 11 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
10 import com.genersoft.iot.vmp.utils.redis.RedisUtil; 12 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
@@ -87,26 +89,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -87,26 +89,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
87 return (StreamInfo)redis.get(playLeys.get(0).toString()); 89 return (StreamInfo)redis.get(playLeys.get(0).toString());
88 } 90 }
89 91
90 - /**  
91 - * 更新流媒体信息  
92 - * @param ZLMServerConfig  
93 - * @return  
94 - */  
95 - @Override  
96 - public boolean updateMediaInfo(ZLMServerConfig ZLMServerConfig) {  
97 - ZLMServerConfig.setUpdateTime(format.format(new Date(System.currentTimeMillis())));  
98 - return redis.set(VideoManagerConstants.MEDIA_SERVER_PREFIX, ZLMServerConfig);  
99 - }  
100 -  
101 - /**  
102 - * 获取流媒体信息  
103 - * @return  
104 - */  
105 - @Override  
106 - public ZLMServerConfig getMediaInfo() {  
107 - return (ZLMServerConfig)redis.get(VideoManagerConstants.MEDIA_SERVER_PREFIX);  
108 - }  
109 -  
110 @Override 92 @Override
111 public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) { 93 public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) {
112 Map<String, StreamInfo> streamInfos = new HashMap<>(); 94 Map<String, StreamInfo> streamInfos = new HashMap<>();
@@ -297,7 +279,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -297,7 +279,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
297 279
298 @Override 280 @Override
299 public void outlineForAll() { 281 public void outlineForAll() {
300 - List<Object> onlineDevices = redis.scan(String.format("%S*", VideoManagerConstants.KEEPLIVEKEY_PREFIX)); 282 + List<Object> onlineDevices = redis.scan(VideoManagerConstants.KEEPLIVEKEY_PREFIX + "*" );
301 for (int i = 0; i < onlineDevices.size(); i++) { 283 for (int i = 0; i < onlineDevices.size(); i++) {
302 String key = (String) onlineDevices.get(i); 284 String key = (String) onlineDevices.get(i);
303 redis.del(key); 285 redis.del(key);
@@ -308,4 +290,5 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -308,4 +290,5 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
308 public void updateWVPInfo(JSONObject jsonObject) { 290 public void updateWVPInfo(JSONObject jsonObject) {
309 291
310 } 292 }
  293 +
311 } 294 }
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -5,6 +5,7 @@ import java.util.*; @@ -5,6 +5,7 @@ import java.util.*;
5 5
6 import com.genersoft.iot.vmp.gb28181.bean.*; 6 import com.genersoft.iot.vmp.gb28181.bean.*;
7 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 7 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 9 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
9 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 10 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -70,6 +71,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -70,6 +71,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
70 @Autowired 71 @Autowired
71 private VideoStreamSessionManager streamSession; 72 private VideoStreamSessionManager streamSession;
72 73
  74 + @Autowired
  75 + private MediaServerMapper mediaServerMapper;
  76 +
73 private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 77 private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
74 78
75 79
@@ -459,6 +463,8 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -459,6 +463,8 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
459 boolean result = false; 463 boolean result = false;
460 streamProxyItem.setStreamType("proxy"); 464 streamProxyItem.setStreamType("proxy");
461 streamProxyItem.setStatus(true); 465 streamProxyItem.setStatus(true);
  466 + String now = this.format.format(new Date(System.currentTimeMillis()));
  467 + streamProxyItem.setCreateTime(now);
462 try { 468 try {
463 if (gbStreamMapper.add(streamProxyItem)<0 || streamProxyMapper.add(streamProxyItem) < 0) { 469 if (gbStreamMapper.add(streamProxyItem)<0 || streamProxyMapper.add(streamProxyItem) < 0) {
464 //事务回滚 470 //事务回滚
@@ -467,6 +473,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -467,6 +473,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
467 result = true; 473 result = true;
468 dataSourceTransactionManager.commit(transactionStatus); //手动提交 474 dataSourceTransactionManager.commit(transactionStatus); //手动提交
469 }catch (Exception e) { 475 }catch (Exception e) {
  476 + logger.error("向数据库添加流代理失败:", e);
470 dataSourceTransactionManager.rollback(transactionStatus); 477 dataSourceTransactionManager.rollback(transactionStatus);
471 } 478 }
472 return result; 479 return result;
@@ -599,4 +606,21 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -599,4 +606,21 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
599 public void updateParentPlatformStatus(String platformGbID, boolean online) { 606 public void updateParentPlatformStatus(String platformGbID, boolean online) {
600 platformMapper.updateParentPlatformStatus(platformGbID, online); 607 platformMapper.updateParentPlatformStatus(platformGbID, online);
601 } 608 }
  609 +
  610 + @Override
  611 + public void updateMediaServer(MediaServerItem mediaServerItem) {
  612 + String now = this.format.format(new Date(System.currentTimeMillis()));
  613 + mediaServerItem.setUpdateTime(now);
  614 + if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) {
  615 + mediaServerMapper.update(mediaServerItem);
  616 + }else {
  617 + mediaServerItem.setCreateTime(now);
  618 + mediaServerMapper.add(mediaServerItem);
  619 + }
  620 + }
  621 +
  622 + @Override
  623 + public List<StreamProxyItem> getStreamProxyListForEnableInMediaServer(String id, boolean enable) {
  624 + return streamProxyMapper.selectForEnableInMediaServer(id, enable);
  625 + }
602 } 626 }
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceConfig.java
@@ -25,6 +25,7 @@ import org.slf4j.Logger; @@ -25,6 +25,7 @@ import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory; 25 import org.slf4j.LoggerFactory;
26 import org.springframework.beans.factory.annotation.Autowired; 26 import org.springframework.beans.factory.annotation.Autowired;
27 import org.springframework.http.ResponseEntity; 27 import org.springframework.http.ResponseEntity;
  28 +import org.springframework.util.StringUtils;
28 import org.springframework.web.bind.annotation.*; 29 import org.springframework.web.bind.annotation.*;
29 import org.springframework.web.context.request.async.DeferredResult; 30 import org.springframework.web.context.request.async.DeferredResult;
30 31
@@ -78,7 +79,7 @@ public class DeviceConfig { @@ -78,7 +79,7 @@ public class DeviceConfig {
78 cmder.deviceBasicConfigCmd(device, channelId, name, expiration, heartBeatInterval, heartBeatCount, event -> { 79 cmder.deviceBasicConfigCmd(device, channelId, name, expiration, heartBeatInterval, heartBeatCount, event -> {
79 Response response = event.getResponse(); 80 Response response = event.getResponse();
80 RequestMessage msg = new RequestMessage(); 81 RequestMessage msg = new RequestMessage();
81 - msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); 82 + msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (StringUtils.isEmpty(channelId) ? deviceId : channelId));
82 msg.setData(String.format("设备配置操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); 83 msg.setData(String.format("设备配置操作失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
83 resultHolder.invokeResult(msg); 84 resultHolder.invokeResult(msg);
84 }); 85 });
@@ -87,7 +88,7 @@ public class DeviceConfig { @@ -87,7 +88,7 @@ public class DeviceConfig {
87 logger.warn(String.format("设备配置操作超时, 设备未返回应答指令")); 88 logger.warn(String.format("设备配置操作超时, 设备未返回应答指令"));
88 // 释放rtpserver 89 // 释放rtpserver
89 RequestMessage msg = new RequestMessage(); 90 RequestMessage msg = new RequestMessage();
90 - msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); 91 + msg.setId(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (StringUtils.isEmpty(channelId) ? deviceId : channelId));
91 JSONObject json = new JSONObject(); 92 JSONObject json = new JSONObject();
92 json.put("DeviceID", deviceId); 93 json.put("DeviceID", deviceId);
93 json.put("Status", "Timeout"); 94 json.put("Status", "Timeout");
@@ -95,7 +96,7 @@ public class DeviceConfig { @@ -95,7 +96,7 @@ public class DeviceConfig {
95 msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令"); 96 msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令");
96 resultHolder.invokeResult(msg); 97 resultHolder.invokeResult(msg);
97 }); 98 });
98 - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (XmlUtil.isEmpty(channelId) ? deviceId : channelId), result); 99 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + (StringUtils.isEmpty(channelId) ? deviceId : channelId), result);
99 return result; 100 return result;
100 } 101 }
101 102
@@ -123,7 +124,7 @@ public class DeviceConfig { @@ -123,7 +124,7 @@ public class DeviceConfig {
123 cmder.deviceConfigQuery(device, channelId, configType, event -> { 124 cmder.deviceConfigQuery(device, channelId, configType, event -> {
124 Response response = event.getResponse(); 125 Response response = event.getResponse();
125 RequestMessage msg = new RequestMessage(); 126 RequestMessage msg = new RequestMessage();
126 - msg.setId(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); 127 + msg.setId(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (StringUtils.isEmpty(channelId) ? deviceId : channelId));
127 msg.setData(String.format("获取设备配置失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase())); 128 msg.setData(String.format("获取设备配置失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
128 resultHolder.invokeResult(msg); 129 resultHolder.invokeResult(msg);
129 }); 130 });
@@ -132,11 +133,11 @@ public class DeviceConfig { @@ -132,11 +133,11 @@ public class DeviceConfig {
132 logger.warn(String.format("获取设备配置超时")); 133 logger.warn(String.format("获取设备配置超时"));
133 // 释放rtpserver 134 // 释放rtpserver
134 RequestMessage msg = new RequestMessage(); 135 RequestMessage msg = new RequestMessage();
135 - msg.setId(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (XmlUtil.isEmpty(channelId) ? deviceId : channelId)); 136 + msg.setId(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (StringUtils.isEmpty(channelId) ? deviceId : channelId));
136 msg.setData("Timeout. Device did not response to this command."); 137 msg.setData("Timeout. Device did not response to this command.");
137 resultHolder.invokeResult(msg); 138 resultHolder.invokeResult(msg);
138 }); 139 });
139 - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (XmlUtil.isEmpty(channelId) ? deviceId : channelId), result); 140 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (StringUtils.isEmpty(channelId) ? deviceId : channelId), result);
140 return result; 141 return result;
141 } 142 }
142 143