Commit 3469271ec25c69e4528b085ba3be7d9d85ec519e

Authored by 64850858
1 parent 379830f7

优化集群方案, 每个zlm一套ssrc;

优化集群下的docker接入逻辑;
更正sql脚本;
支持重启不设置设备离线。重启SIP事务不丢失
Showing 56 changed files with 1312 additions and 1070 deletions
@@ -46,6 +46,7 @@ @@ -46,6 +46,7 @@
46 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 46 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
47 <maven.build.timestamp.format>MMddHHmm</maven.build.timestamp.format> 47 <maven.build.timestamp.format>MMddHHmm</maven.build.timestamp.format>
48 <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> 48 <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
  49 + <jedis-version>3.1.0</jedis-version>
49 50
50 <!-- 依赖版本 --> 51 <!-- 依赖版本 -->
51 <pagehelper.version>5.2.0</pagehelper.version> 52 <pagehelper.version>5.2.0</pagehelper.version>
@@ -80,6 +81,12 @@ @@ -80,6 +81,12 @@
80 <artifactId>spring-boot-starter-security</artifactId> 81 <artifactId>spring-boot-starter-security</artifactId>
81 </dependency> 82 </dependency>
82 83
  84 + <dependency>
  85 + <groupId>redis.clients</groupId>
  86 + <artifactId>jedis</artifactId>
  87 + <version>${jedis-version}</version>
  88 + </dependency>
  89 +
83 <!-- druid数据库连接池 --> 90 <!-- druid数据库连接池 -->
84 <dependency> 91 <dependency>
85 <groupId>com.alibaba</groupId> 92 <groupId>com.alibaba</groupId>
sql/mysql.sql
1 -- auto-generated definition 1 -- auto-generated definition
2 -create schema wvp collate utf8_bin; 2 +
  3 +
  4 +CREATE DATABASE `wvp` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_bin */;
  5 +
  6 +use wvp;
3 7
4 create table device 8 create table device
5 ( 9 (
6 - deviceId varchar(50) not null 10 + deviceId varchar(50) not null
7 primary key, 11 primary key,
8 - name varchar(255) null,  
9 - manufacturer varchar(255) null,  
10 - model varchar(255) null,  
11 - firmware varchar(255) null,  
12 - transport varchar(50) null,  
13 - streamMode varchar(50) null,  
14 - online varchar(50) null,  
15 - registerTime varchar(50) null,  
16 - keepaliveTime varchar(50) null,  
17 - ip varchar(50) not null,  
18 - createTime varchar(50) not null,  
19 - updateTime varchar(50) not null,  
20 - port int not null,  
21 - expires int not null,  
22 - hostAddress varchar(50) not null 12 + name varchar(255) null,
  13 + manufacturer varchar(255) null,
  14 + model varchar(255) null,
  15 + firmware varchar(255) null,
  16 + transport varchar(50) null,
  17 + streamMode varchar(50) null,
  18 + online varchar(50) null,
  19 + registerTime varchar(50) null,
  20 + keepaliveTime varchar(50) null,
  21 + ip varchar(50) not null,
  22 + createTime varchar(50) not null,
  23 + updateTime varchar(50) not null,
  24 + port int not null,
  25 + expires int not null,
  26 + hostAddress varchar(50) not null
23 ); 27 );
24 28
25 create table device_channel 29 create table device_channel
26 ( 30 (
27 - channelId varchar(50) not null, 31 + channelId varchar(50) not null,
28 name varchar(255) null, 32 name varchar(255) null,
29 - manufacture varchar(50) null,  
30 - model varchar(50) null,  
31 - owner varchar(50) null,  
32 - civilCode varchar(50) null,  
33 - block varchar(50) null,  
34 - address varchar(50) null,  
35 - parentId varchar(50) null, 33 + manufacture varchar(50) null,
  34 + model varchar(50) null,
  35 + owner varchar(50) null,
  36 + civilCode varchar(50) null,
  37 + block varchar(50) null,
  38 + address varchar(50) null,
  39 + parentId varchar(50) null,
36 safetyWay int null, 40 safetyWay int null,
37 registerWay int null, 41 registerWay int null,
38 - certNum varchar(50) null, 42 + certNum varchar(50) null,
39 certifiable int null, 43 certifiable int null,
40 errCode int null, 44 errCode int null,
41 - endTime varchar(50) null,  
42 - secrecy varchar(50) null,  
43 - ipAddress varchar(50) null, 45 + endTime varchar(50) null,
  46 + secrecy varchar(50) null,
  47 + ipAddress varchar(50) null,
44 port int null, 48 port int null,
45 password varchar(255) null, 49 password varchar(255) null,
46 PTZType int null, 50 PTZType int null,
47 status int null, 51 status int null,
48 longitude double null, 52 longitude double null,
49 latitude double null, 53 latitude double null,
50 - streamId varchar(50) null,  
51 - deviceId varchar(50) not null,  
52 - parental varchar(50) null,  
53 - hasAudio bit(1) null,  
54 - createTime varchar(50) not null,  
55 - updateTime varchar(50) not null, 54 + streamId varchar(50) null,
  55 + deviceId varchar(50) not null,
  56 + parental varchar(50) null,
  57 + hasAudio bit null,
  58 + createTime varchar(50) not null,
  59 + updateTime varchar(50) not null,
56 primary key (channelId, deviceId) 60 primary key (channelId, deviceId)
57 ); 61 );
58 62
59 create table device_mobile_position 63 create table device_mobile_position
60 ( 64 (
61 - deviceId varchar(50) not null, 65 + deviceId varchar(50) not null,
62 deviceName varchar(255) null, 66 deviceName varchar(255) null,
63 - time varchar(50) not null, 67 + time varchar(50) not null,
64 longitude double not null, 68 longitude double not null,
65 latitude double not null, 69 latitude double not null,
66 altitude double null, 70 altitude double null,
67 speed double null, 71 speed double null,
68 direction double null, 72 direction double null,
69 - reportSource varchar(50) null,  
70 - geodeticSystem varchar(50) null,  
71 - cnLng varchar(50) null,  
72 - cnLat varchar(50) null, 73 + reportSource varchar(50) null,
  74 + geodeticSystem varchar(50) null,
  75 + cnLng varchar(50) null,
  76 + cnLat varchar(50) null,
73 primary key (deviceId, time) 77 primary key (deviceId, time)
74 ); 78 );
75 79
76 create table gb_stream 80 create table gb_stream
77 ( 81 (
78 - app varchar(255) not null,  
79 - stream varchar(255) not null,  
80 - gbId varchar(50) not null,  
81 - name varchar(255) null,  
82 - longitude double null,  
83 - latitude double null,  
84 - streamType varchar(50) null,  
85 - status int null, 82 + app varchar(255) not null,
  83 + stream varchar(255) not null,
  84 + gbId varchar(50) not null,
  85 + name varchar(255) null,
  86 + longitude double null,
  87 + latitude double null,
  88 + streamType varchar(50) null,
  89 + mediaServerId varchar(50) null,
  90 + status int null,
86 primary key (app, stream, gbId) 91 primary key (app, stream, gbId)
87 ); 92 );
88 93
  94 +create table media_server
  95 +(
  96 + id varchar(255) not null
  97 + primary key,
  98 + ip varchar(50) not null,
  99 + hookIp varchar(50) not null,
  100 + sdpIp varchar(50) not null,
  101 + streamIp varchar(50) not null,
  102 + httpPort int not null,
  103 + httpSSlPort int not null,
  104 + rtmpPort int not null,
  105 + rtmpSSlPort int not null,
  106 + rtpProxyPort int not null,
  107 + rtspPort int not null,
  108 + rtspSSLPort int not null,
  109 + autoConfig int not null,
  110 + secret varchar(50) not null,
  111 + streamNoneReaderDelayMS int not null,
  112 + rtpEnable int not null,
  113 + rtpPortRange varchar(50) not null,
  114 + recordAssistPort int not null,
  115 + defaultServer int not null,
  116 + createTime varchar(50) not null,
  117 + updateTime varchar(50) not null,
  118 + constraint media_server_i
  119 + unique (ip, httpPort)
  120 +);
  121 +
89 create table parent_platform 122 create table parent_platform
90 ( 123 (
91 - id int auto_increment, 124 + id int auto_increment,
92 enable int null, 125 enable int null,
93 name varchar(255) null, 126 name varchar(255) null,
94 - serverGBId varchar(50) not null,  
95 - serverGBDomain varchar(50) null,  
96 - serverIP varchar(50) null, 127 + serverGBId varchar(50) not null,
  128 + serverGBDomain varchar(50) null,
  129 + serverIP varchar(50) null,
97 serverPort int null, 130 serverPort int null,
98 - deviceGBId varchar(50) not null,  
99 - deviceIp varchar(50) null,  
100 - devicePort varchar(50) null, 131 + deviceGBId varchar(50) not null,
  132 + deviceIp varchar(50) null,
  133 + devicePort varchar(50) null,
101 username varchar(255) null, 134 username varchar(255) null,
102 - password varchar(50) null,  
103 - expires varchar(50) null,  
104 - keepTimeout varchar(50) null,  
105 - transport varchar(50) null,  
106 - characterSet varchar(50) null, 135 + password varchar(50) null,
  136 + expires varchar(50) null,
  137 + keepTimeout varchar(50) null,
  138 + transport varchar(50) null,
  139 + characterSet varchar(50) null,
107 ptz int null, 140 ptz int null,
108 rtcp int null, 141 rtcp int null,
109 - status bit(1) null, 142 + status bit null,
110 primary key (id, serverGBId) 143 primary key (id, serverGBId)
111 ); 144 );
112 145
@@ -121,7 +154,7 @@ create table platform_gb_channel @@ -121,7 +154,7 @@ create table platform_gb_channel
121 154
122 create table platform_gb_stream 155 create table platform_gb_stream
123 ( 156 (
124 - platformId varchar(50) not null, 157 + platformId varchar(50) not null,
125 app varchar(255) not null, 158 app varchar(255) not null,
126 stream varchar(255) not null, 159 stream varchar(255) not null,
127 primary key (platformId, app, stream) 160 primary key (platformId, app, stream)
@@ -129,7 +162,7 @@ create table platform_gb_stream @@ -129,7 +162,7 @@ create table platform_gb_stream
129 162
130 create table stream_proxy 163 create table stream_proxy
131 ( 164 (
132 - type varchar(50) not null, 165 + type varchar(50) not null,
133 app varchar(255) not null, 166 app varchar(255) not null,
134 stream varchar(255) not null, 167 stream varchar(255) not null,
135 url varchar(255) null, 168 url varchar(255) null,
@@ -137,11 +170,12 @@ create table stream_proxy @@ -137,11 +170,12 @@ create table stream_proxy
137 dst_url varchar(255) null, 170 dst_url varchar(255) null,
138 timeout_ms int null, 171 timeout_ms int null,
139 ffmpeg_cmd_key varchar(255) null, 172 ffmpeg_cmd_key varchar(255) null,
140 - rtp_type varchar(50) null,  
141 - mediaServerId varchar(50) null,  
142 - enable_hls bit(1) null,  
143 - enable_mp4 bit(1) null,  
144 - enable bit(1) not null, 173 + rtp_type varchar(50) null,
  174 + mediaServerId varchar(50) null,
  175 + enable_hls bit null,
  176 + enable_mp4 bit null,
  177 + enable bit not null,
  178 + createTime varchar(50) not null,
145 primary key (app, stream) 179 primary key (app, stream)
146 ); 180 );
147 181
@@ -149,11 +183,12 @@ create table stream_push @@ -149,11 +183,12 @@ create table stream_push
149 ( 183 (
150 app varchar(255) not null, 184 app varchar(255) not null,
151 stream varchar(255) not null, 185 stream varchar(255) not null,
152 - totalReaderCount varchar(50) null, 186 + totalReaderCount varchar(50) null,
153 originType int null, 187 originType int null,
154 - originTypeStr varchar(50) null, 188 + originTypeStr varchar(50) null,
155 createStamp int null, 189 createStamp int null,
156 aliveSecond int null, 190 aliveSecond int null,
  191 + mediaServerId varchar(50) null,
157 primary key (app, stream) 192 primary key (app, stream)
158 ); 193 );
159 194
@@ -164,31 +199,6 @@ create table user @@ -164,31 +199,6 @@ create table user
164 username varchar(255) not null, 199 username varchar(255) not null,
165 password varchar(255) not null, 200 password varchar(255) not null,
166 roleId int not null, 201 roleId int not null,
167 - create_time varchar(50) not null 202 + create_time varchar(50) not null
168 ); 203 );
169 204
170 -insert into user (username, password, roleId, create_time) values ('admin', '21232f297a57a5a743894a0e4a801fc3', '0', '2021-04-13 14:14:57');  
171 -  
172 -create table media_server (  
173 - id varchar(255)  
174 - primary key,  
175 - ip varchar(50) NOT NULL,  
176 - hookIp varchar(50) NOT NULL,  
177 - sdpIp varchar(50) NOT NULL,  
178 - streamIp varchar(50) NOT NULL,  
179 - httpPort int NOT NULL,  
180 - httpSSlPort int NOT NULL,  
181 - rtmpPort int NOT NULL,  
182 - rtmpSSlPort int NOT NULL,  
183 - rtpProxyPort int NOT NULL,  
184 - rtspPort int NOT NULL,  
185 - rtspSSLPort int NOT NULL,  
186 - autoConfig int NOT NULL,  
187 - secret varchar(50) NOT NULL,  
188 - streamNoneReaderDelayMS int NOT NULL,  
189 - rtpEnable int NOT NULL,  
190 - rtpPortRange varchar(50) NOT NULL,  
191 - recordAssistPort int NOT NULL,  
192 - createTime varchar(50) not null,  
193 - updateTime varchar(50) not null  
194 -);  
195 \ No newline at end of file 205 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -12,6 +12,8 @@ public class VideoManagerConstants { @@ -12,6 +12,8 @@ public class VideoManagerConstants {
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_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS";
  16 +
15 public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM"; 17 public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM";
16 18
17 public static final String DEVICE_PREFIX = "VMP_DEVICE_"; 19 public static final String DEVICE_PREFIX = "VMP_DEVICE_";
@@ -45,4 +47,8 @@ public class VideoManagerConstants { @@ -45,4 +47,8 @@ public class VideoManagerConstants {
45 public static final String EVENT_OUTLINE_UNREGISTER = "1"; 47 public static final String EVENT_OUTLINE_UNREGISTER = "1";
46 48
47 public static final String EVENT_OUTLINE_TIMEOUT = "2"; 49 public static final String EVENT_OUTLINE_TIMEOUT = "2";
  50 +
  51 + public static final String MEDIA_SSRC_USED_PREFIX = "VMP_media_used_ssrc_";
  52 +
  53 + public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_media_transaction_";
48 } 54 }
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; 3 +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
4 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 4 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
5 import org.springframework.beans.factory.annotation.Value; 5 import org.springframework.beans.factory.annotation.Value;
6 import org.springframework.context.annotation.Configuration; 6 import org.springframework.context.annotation.Configuration;
7 import org.springframework.util.StringUtils; 7 import org.springframework.util.StringUtils;
8 8
  9 +import java.text.SimpleDateFormat;
  10 +import java.util.Date;
  11 +
9 @Configuration("mediaConfig") 12 @Configuration("mediaConfig")
10 -public class MediaConfig implements IMediaServerItem { 13 +public class MediaConfig{
11 14
12 @Value("${media.id:}") 15 @Value("${media.id:}")
13 private String id; 16 private String id;
@@ -21,6 +24,9 @@ public class MediaConfig implements IMediaServerItem { @@ -21,6 +24,9 @@ public class MediaConfig implements IMediaServerItem {
21 @Value("${sip.ip}") 24 @Value("${sip.ip}")
22 private String sipIp; 25 private String sipIp;
23 26
  27 + @Value("${sip.domain}")
  28 + private String sipDomain;
  29 +
24 @Value("${media.sdp-ip:${media.ip}}") 30 @Value("${media.sdp-ip:${media.ip}}")
25 private String sdpIp; 31 private String sdpIp;
26 32
@@ -66,31 +72,14 @@ public class MediaConfig implements IMediaServerItem { @@ -66,31 +72,14 @@ public class MediaConfig implements IMediaServerItem {
66 @Value("${media.record-assist-port:0}") 72 @Value("${media.record-assist-port:0}")
67 private Integer recordAssistPort = 0; 73 private Integer recordAssistPort = 0;
68 74
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() { 75 public String getId() {
79 return id; 76 return id;
80 } 77 }
81 78
82 - public void setId(String id) {  
83 - this.id = id;  
84 - }  
85 -  
86 public String getIp() { 79 public String getIp() {
87 return ip; 80 return ip;
88 } 81 }
89 82
90 - public void setIp(String ip) {  
91 - this.ip = ip;  
92 - }  
93 -  
94 public String getHookIp() { 83 public String getHookIp() {
95 if (StringUtils.isEmpty(hookIp)){ 84 if (StringUtils.isEmpty(hookIp)){
96 return sipIp; 85 return sipIp;
@@ -100,78 +89,26 @@ public class MediaConfig implements IMediaServerItem { @@ -100,78 +89,26 @@ public class MediaConfig implements IMediaServerItem {
100 89
101 } 90 }
102 91
103 - public void setHookIp(String hookIp) {  
104 - this.hookIp = hookIp;  
105 - }  
106 -  
107 public String getSipIp() { 92 public String getSipIp() {
108 return sipIp; 93 return sipIp;
109 } 94 }
110 95
111 - public void setSipIp(String sipIp) {  
112 - this.sipIp = sipIp;  
113 - }  
114 -  
115 - public void setSdpIp(String sdpIp) {  
116 - this.sdpIp = sdpIp;  
117 - }  
118 -  
119 - public void setStreamIp(String streamIp) {  
120 - this.streamIp = streamIp;  
121 - }  
122 -  
123 public int getHttpPort() { 96 public int getHttpPort() {
124 return httpPort; 97 return httpPort;
125 } 98 }
126 99
127 - @Override  
128 - public void setHttpPort(int httpPort) {  
129 -  
130 - }  
131 -  
132 - public void setHttpPort(Integer httpPort) {  
133 - this.httpPort = httpPort;  
134 - }  
135 -  
136 public int getHttpSSlPort() { 100 public int getHttpSSlPort() {
137 return httpSSlPort; 101 return httpSSlPort;
138 } 102 }
139 103
140 - @Override  
141 - public void setHttpSSlPort(int httpSSlPort) {  
142 -  
143 - }  
144 -  
145 - public void setHttpSSlPort(Integer httpSSlPort) {  
146 - this.httpSSlPort = httpSSlPort;  
147 - }  
148 -  
149 public int getRtmpPort() { 104 public int getRtmpPort() {
150 return rtmpPort; 105 return rtmpPort;
151 } 106 }
152 -  
153 - @Override  
154 - public void setRtmpPort(int rtmpPort) {  
155 -  
156 - }  
157 -  
158 - public void setRtmpPort(Integer rtmpPort) {  
159 - this.rtmpPort = rtmpPort;  
160 - }  
161 - 107 +
162 public int getRtmpSSlPort() { 108 public int getRtmpSSlPort() {
163 return rtmpSSlPort; 109 return rtmpSSlPort;
164 } 110 }
165 111
166 - @Override  
167 - public void setRtmpSSlPort(int rtmpSSlPort) {  
168 -  
169 - }  
170 -  
171 - public void setRtmpSSlPort(Integer rtmpSSlPort) {  
172 - this.rtmpSSlPort = rtmpSSlPort;  
173 - }  
174 -  
175 public int getRtpProxyPort() { 112 public int getRtpProxyPort() {
176 if (rtpProxyPort == null) { 113 if (rtpProxyPort == null) {
177 return 0; 114 return 0;
@@ -181,104 +118,38 @@ public class MediaConfig implements IMediaServerItem { @@ -181,104 +118,38 @@ public class MediaConfig implements IMediaServerItem {
181 118
182 } 119 }
183 120
184 - @Override  
185 - public void setRtpProxyPort(int rtpProxyPort) {  
186 -  
187 - }  
188 -  
189 - public void setRtpProxyPort(Integer rtpProxyPort) {  
190 - this.rtpProxyPort = rtpProxyPort;  
191 - }  
192 -  
193 public int getRtspPort() { 121 public int getRtspPort() {
194 return rtspPort; 122 return rtspPort;
195 } 123 }
196 124
197 - @Override  
198 - public void setRtspPort(int rtspPort) {  
199 -  
200 - }  
201 -  
202 - public void setRtspPort(Integer rtspPort) {  
203 - this.rtspPort = rtspPort;  
204 - }  
205 -  
206 public int getRtspSSLPort() { 125 public int getRtspSSLPort() {
207 return rtspSSLPort; 126 return rtspSSLPort;
208 } 127 }
209 128
210 - @Override  
211 - public void setRtspSSLPort(int rtspSSLPort) {  
212 -  
213 - }  
214 -  
215 - public void setRtspSSLPort(Integer rtspSSLPort) {  
216 - this.rtspSSLPort = rtspSSLPort;  
217 - }  
218 -  
219 public boolean isAutoConfig() { 129 public boolean isAutoConfig() {
220 return autoConfig; 130 return autoConfig;
221 } 131 }
222 132
223 - public void setAutoConfig(boolean autoConfig) {  
224 - this.autoConfig = autoConfig;  
225 - }  
226 -  
227 public String getSecret() { 133 public String getSecret() {
228 return secret; 134 return secret;
229 } 135 }
230 136
231 - public void setSecret(String secret) {  
232 - this.secret = secret;  
233 - }  
234 -  
235 public String getStreamNoneReaderDelayMS() { 137 public String getStreamNoneReaderDelayMS() {
236 return streamNoneReaderDelayMS; 138 return streamNoneReaderDelayMS;
237 } 139 }
238 140
239 - public void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS) {  
240 - this.streamNoneReaderDelayMS = streamNoneReaderDelayMS;  
241 - }  
242 -  
243 public boolean isRtpEnable() { 141 public boolean isRtpEnable() {
244 return rtpEnable; 142 return rtpEnable;
245 } 143 }
246 144
247 - public void setRtpEnable(boolean rtpEnable) {  
248 - this.rtpEnable = rtpEnable;  
249 - }  
250 -  
251 public String getRtpPortRange() { 145 public String getRtpPortRange() {
252 return rtpPortRange; 146 return rtpPortRange;
253 } 147 }
254 -  
255 - public void setRtpPortRange(String rtpPortRange) {  
256 - this.rtpPortRange = rtpPortRange;  
257 - }  
258 - 148 +
259 public int getRecordAssistPort() { 149 public int getRecordAssistPort() {
260 return recordAssistPort; 150 return recordAssistPort;
261 } 151 }
262 152
263 - @Override  
264 - public void setRecordAssistPort(int recordAssistPort) {  
265 -  
266 - }  
267 -  
268 - public void setRecordAssistPort(Integer recordAssistPort) {  
269 - this.recordAssistPort = recordAssistPort;  
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() { 153 public String getSdpIp() {
283 if (StringUtils.isEmpty(sdpIp)){ 154 if (StringUtils.isEmpty(sdpIp)){
284 return ip; 155 return ip;
@@ -295,13 +166,11 @@ public class MediaConfig implements IMediaServerItem { @@ -295,13 +166,11 @@ public class MediaConfig implements IMediaServerItem {
295 } 166 }
296 } 167 }
297 168
298 -  
299 -  
300 public MediaServerItem getMediaSerItem(){ 169 public MediaServerItem getMediaSerItem(){
301 MediaServerItem mediaServerItem = new MediaServerItem(); 170 MediaServerItem mediaServerItem = new MediaServerItem();
302 mediaServerItem.setId(id); 171 mediaServerItem.setId(id);
303 mediaServerItem.setIp(ip); 172 mediaServerItem.setIp(ip);
304 - mediaServerItem.setDocker(true); 173 + mediaServerItem.setDefaultServer(true);
305 mediaServerItem.setHookIp(hookIp); 174 mediaServerItem.setHookIp(hookIp);
306 mediaServerItem.setSdpIp(sdpIp); 175 mediaServerItem.setSdpIp(sdpIp);
307 mediaServerItem.setStreamIp(streamIp); 176 mediaServerItem.setStreamIp(streamIp);
@@ -318,39 +187,12 @@ public class MediaConfig implements IMediaServerItem { @@ -318,39 +187,12 @@ public class MediaConfig implements IMediaServerItem {
318 mediaServerItem.setRtpEnable(rtpEnable); 187 mediaServerItem.setRtpEnable(rtpEnable);
319 mediaServerItem.setRtpPortRange(rtpPortRange); 188 mediaServerItem.setRtpPortRange(rtpPortRange);
320 mediaServerItem.setRecordAssistPort(recordAssistPort); 189 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 190
332 - @Override  
333 - public void setUpdateTime(String updateTime) {  
334 - this.updateTime = updateTime;  
335 - } 191 + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  192 + mediaServerItem.setCreateTime(format.format(new Date(System.currentTimeMillis())));
  193 + mediaServerItem.setUpdateTime(format.format(new Date(System.currentTimeMillis())));
336 194
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; 195 + return mediaServerItem;
350 } 196 }
351 197
352 - @Override  
353 - public void setCount(int count) {  
354 - this.count = count;  
355 - }  
356 } 198 }
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; 3 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
4 import com.genersoft.iot.vmp.service.IMediaServerService; 4 import com.genersoft.iot.vmp.service.IMediaServerService;
5 import org.apache.catalina.connector.ClientAbortException; 5 import org.apache.catalina.connector.ClientAbortException;
6 import org.apache.http.HttpHost; 6 import org.apache.http.HttpHost;
@@ -49,7 +49,7 @@ public class ProxyServletConfig { @@ -49,7 +49,7 @@ public class ProxyServletConfig {
49 @Override 49 @Override
50 protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { 50 protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
51 String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); 51 String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
52 - IMediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); 52 + MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
53 if (mediaInfo != null) { 53 if (mediaInfo != null) {
54 if (!StringUtils.isEmpty(queryStr)) { 54 if (!StringUtils.isEmpty(queryStr)) {
55 queryStr += "&secret=" + mediaInfo.getSecret(); 55 queryStr += "&secret=" + mediaInfo.getSecret();
@@ -88,7 +88,7 @@ public class ProxyServletConfig { @@ -88,7 +88,7 @@ public class ProxyServletConfig {
88 @Override 88 @Override
89 protected String getTargetUri(HttpServletRequest servletRequest) { 89 protected String getTargetUri(HttpServletRequest servletRequest) {
90 String requestURI = servletRequest.getRequestURI(); 90 String requestURI = servletRequest.getRequestURI();
91 - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); 91 + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
92 92
93 String uri = null; 93 String uri = null;
94 if (mediaInfo != null) { 94 if (mediaInfo != null) {
@@ -106,7 +106,7 @@ public class ProxyServletConfig { @@ -106,7 +106,7 @@ public class ProxyServletConfig {
106 @Override 106 @Override
107 protected HttpHost getTargetHost(HttpServletRequest servletRequest) { 107 protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
108 String requestURI = servletRequest.getRequestURI(); 108 String requestURI = servletRequest.getRequestURI();
109 - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); 109 + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
110 HttpHost host; 110 HttpHost host;
111 if (mediaInfo != null) { 111 if (mediaInfo != null) {
112 host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort()); 112 host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort());
@@ -120,7 +120,7 @@ public class ProxyServletConfig { @@ -120,7 +120,7 @@ public class ProxyServletConfig {
120 /** 120 /**
121 * 根据uri获取流媒体信息 121 * 根据uri获取流媒体信息
122 */ 122 */
123 - IMediaServerItem getMediaInfoByUri(String uri){ 123 + MediaServerItem getMediaInfoByUri(String uri){
124 String[] split = uri.split("/"); 124 String[] split = uri.split("/");
125 String mediaServerId = split[2]; 125 String mediaServerId = split[2];
126 return mediaServerService.getOne(mediaServerId); 126 return mediaServerService.getOne(mediaServerId);
@@ -132,7 +132,7 @@ public class ProxyServletConfig { @@ -132,7 +132,7 @@ public class ProxyServletConfig {
132 @Override 132 @Override
133 protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { 133 protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
134 String requestURI = servletRequest.getRequestURI(); 134 String requestURI = servletRequest.getRequestURI();
135 - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); 135 + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
136 String url = super.rewriteUrlFromRequest(servletRequest); 136 String url = super.rewriteUrlFromRequest(servletRequest);
137 if (mediaInfo == null) { 137 if (mediaInfo == null) {
138 return url; 138 return url;
@@ -186,7 +186,7 @@ public class ProxyServletConfig { @@ -186,7 +186,7 @@ public class ProxyServletConfig {
186 @Override 186 @Override
187 protected String getTargetUri(HttpServletRequest servletRequest) { 187 protected String getTargetUri(HttpServletRequest servletRequest) {
188 String requestURI = servletRequest.getRequestURI(); 188 String requestURI = servletRequest.getRequestURI();
189 - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); 189 + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
190 190
191 String uri = null; 191 String uri = null;
192 if (mediaInfo != null) { 192 if (mediaInfo != null) {
@@ -204,7 +204,7 @@ public class ProxyServletConfig { @@ -204,7 +204,7 @@ public class ProxyServletConfig {
204 @Override 204 @Override
205 protected HttpHost getTargetHost(HttpServletRequest servletRequest) { 205 protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
206 String requestURI = servletRequest.getRequestURI(); 206 String requestURI = servletRequest.getRequestURI();
207 - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); 207 + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
208 HttpHost host; 208 HttpHost host;
209 if (mediaInfo != null) { 209 if (mediaInfo != null) {
210 host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort()); 210 host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort());
@@ -218,7 +218,7 @@ public class ProxyServletConfig { @@ -218,7 +218,7 @@ public class ProxyServletConfig {
218 /** 218 /**
219 * 根据uri获取流媒体信息 219 * 根据uri获取流媒体信息
220 */ 220 */
221 - IMediaServerItem getMediaInfoByUri(String uri){ 221 + MediaServerItem getMediaInfoByUri(String uri){
222 String[] split = uri.split("/"); 222 String[] split = uri.split("/");
223 String mediaServerId = split[2]; 223 String mediaServerId = split[2];
224 return mediaServerService.getOne(mediaServerId); 224 return mediaServerService.getOne(mediaServerId);
@@ -230,7 +230,7 @@ public class ProxyServletConfig { @@ -230,7 +230,7 @@ public class ProxyServletConfig {
230 @Override 230 @Override
231 protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { 231 protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
232 String requestURI = servletRequest.getRequestURI(); 232 String requestURI = servletRequest.getRequestURI();
233 - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); 233 + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
234 String url = super.rewriteUrlFromRequest(servletRequest); 234 String url = super.rewriteUrlFromRequest(servletRequest);
235 if (mediaInfo == null) { 235 if (mediaInfo == null) {
236 return url; 236 return url;
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
1 package com.genersoft.iot.vmp.conf; 1 package com.genersoft.iot.vmp.conf;
2 2
  3 +import org.apache.commons.lang3.StringUtils;
  4 +import org.springframework.beans.factory.annotation.Value;
3 import org.springframework.cache.annotation.CachingConfigurerSupport; 5 import org.springframework.cache.annotation.CachingConfigurerSupport;
4 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration; 7 import org.springframework.context.annotation.Configuration;
@@ -10,6 +12,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; @@ -10,6 +12,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
10 12
11 import com.alibaba.fastjson.parser.ParserConfig; 13 import com.alibaba.fastjson.parser.ParserConfig;
12 import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; 14 import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
  15 +import redis.clients.jedis.JedisPool;
  16 +import redis.clients.jedis.JedisPoolConfig;
13 17
14 /** 18 /**
15 * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置 19 * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
@@ -20,6 +24,37 @@ import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; @@ -20,6 +24,37 @@ import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
20 @Configuration 24 @Configuration
21 public class RedisConfig extends CachingConfigurerSupport { 25 public class RedisConfig extends CachingConfigurerSupport {
22 26
  27 + @Value("${spring.redis.host}")
  28 + private String host;
  29 + @Value("${spring.redis.port}")
  30 + private int port;
  31 + @Value("${spring.redis.database}")
  32 + private int database;
  33 + @Value("${spring.redis.password}")
  34 + private String password;
  35 + @Value("${spring.redis.timeout}")
  36 + private int timeout;
  37 + @Value("${spring.redis.poolMaxTotal:1000}")
  38 + private int poolMaxTotal;
  39 + @Value("${spring.redis.poolMaxIdle:500}")
  40 + private int poolMaxIdle;
  41 + @Value("${spring.redis.poolMaxWait:5}")
  42 + private int poolMaxWait;
  43 +
  44 + @Bean
  45 + public JedisPool jedisPool() {
  46 + if (StringUtils.isBlank(password)) {
  47 + password = null;
  48 + }
  49 + JedisPoolConfig poolConfig = new JedisPoolConfig();
  50 + poolConfig.setMaxIdle(poolMaxIdle);
  51 + poolConfig.setMaxTotal(poolMaxTotal);
  52 + // 秒转毫秒
  53 + poolConfig.setMaxWaitMillis(poolMaxWait * 1000L);
  54 + JedisPool jp = new JedisPool(poolConfig, host, port, timeout * 1000, password, database);
  55 + return jp;
  56 + }
  57 +
23 @Bean("redisTemplate") 58 @Bean("redisTemplate")
24 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { 59 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
25 RedisTemplate<Object, Object> template = new RedisTemplate<>(); 60 RedisTemplate<Object, Object> template = new RedisTemplate<>();
@@ -34,7 +69,7 @@ public class RedisConfig extends CachingConfigurerSupport { @@ -34,7 +69,7 @@ public class RedisConfig extends CachingConfigurerSupport {
34 template.setHashKeySerializer(new StringRedisSerializer()); 69 template.setHashKeySerializer(new StringRedisSerializer());
35 template.setConnectionFactory(redisConnectionFactory); 70 template.setConnectionFactory(redisConnectionFactory);
36 // 使用fastjson时需设置此项,否则会报异常not support type 71 // 使用fastjson时需设置此项,否则会报异常not support type
37 - ParserConfig.getGlobalInstance().setAutoTypeSupport(true); 72 + ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
38 return template; 73 return template;
39 } 74 }
40 75
src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.conf;  
2 -  
3 -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;  
4 -import com.genersoft.iot.vmp.storager.IVideoManagerStorager;  
5 -import org.springframework.beans.factory.annotation.Autowired;  
6 -import org.springframework.boot.CommandLineRunner;  
7 -import org.springframework.core.annotation.Order;  
8 -import org.springframework.stereotype.Component;  
9 -  
10 -  
11 -/**  
12 - * 系统启动时控制设备离线  
13 - */  
14 -@Component  
15 -@Order(value=4)  
16 -public class SipDeviceRunner implements CommandLineRunner {  
17 -  
18 - @Autowired  
19 - private IVideoManagerStorager storager;  
20 -  
21 - @Autowired  
22 - private IRedisCatchStorage redisCatchStorage;  
23 -  
24 - @Override  
25 - public void run(String... args) throws Exception {  
26 - // 设置所有设备离线  
27 - storager.outlineForAll();  
28 - // 设置所有设备离线  
29 - redisCatchStorage.outlineForAll();  
30 - }  
31 -}  
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -12,6 +12,7 @@ import javax.sip.header.CallIdHeader; @@ -12,6 +12,7 @@ import javax.sip.header.CallIdHeader;
12 import javax.sip.message.Response; 12 import javax.sip.message.Response;
13 13
14 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 14 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  15 +import gov.nist.javax.sip.SipProviderImpl;
15 import org.slf4j.Logger; 16 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory; 17 import org.slf4j.LoggerFactory;
17 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.beans.factory.annotation.Autowired;
@@ -39,7 +40,7 @@ public class SipLayer implements SipListener { @@ -39,7 +40,7 @@ public class SipLayer implements SipListener {
39 @Autowired 40 @Autowired
40 private SipSubscribe sipSubscribe; 41 private SipSubscribe sipSubscribe;
41 42
42 - private SipStack sipStack; 43 + private SipStackImpl sipStack;
43 44
44 private SipFactory sipFactory; 45 private SipFactory sipFactory;
45 46
@@ -52,7 +53,7 @@ public class SipLayer implements SipListener { @@ -52,7 +53,7 @@ public class SipLayer implements SipListener {
52 private ThreadPoolExecutor initSipServer() { 53 private ThreadPoolExecutor initSipServer() {
53 54
54 int processThreadNum = Runtime.getRuntime().availableProcessors() * 10; 55 int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
55 - LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<Runnable>(10000); 56 + LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000);
56 processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum, 57 processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
57 0L,TimeUnit.MILLISECONDS,processQueue, 58 0L,TimeUnit.MILLISECONDS,processQueue,
58 new ThreadPoolExecutor.CallerRunsPolicy()); 59 new ThreadPoolExecutor.CallerRunsPolicy());
@@ -88,17 +89,14 @@ public class SipLayer implements SipListener { @@ -88,17 +89,14 @@ public class SipLayer implements SipListener {
88 89
89 @Bean("tcpSipProvider") 90 @Bean("tcpSipProvider")
90 @DependsOn("sipStack") 91 @DependsOn("sipStack")
91 - private SipProvider startTcpListener() { 92 + private SipProviderImpl startTcpListener() {
92 ListeningPoint tcpListeningPoint = null; 93 ListeningPoint tcpListeningPoint = null;
93 - SipProvider tcpSipProvider = null; 94 + SipProviderImpl tcpSipProvider = null;
94 try { 95 try {
95 tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "TCP"); 96 tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "TCP");
96 - tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); 97 + tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint);
97 tcpSipProvider.addSipListener(this); 98 tcpSipProvider.addSipListener(this);
98 logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getSipPort() + "}"); 99 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) { 100 } catch (TransportNotSupportedException e) {
103 e.printStackTrace(); 101 e.printStackTrace();
104 } catch (InvalidArgumentException e) { 102 } catch (InvalidArgumentException e) {
@@ -114,13 +112,14 @@ public class SipLayer implements SipListener { @@ -114,13 +112,14 @@ public class SipLayer implements SipListener {
114 112
115 @Bean("udpSipProvider") 113 @Bean("udpSipProvider")
116 @DependsOn("sipStack") 114 @DependsOn("sipStack")
117 - private SipProvider startUdpListener() { 115 + private SipProviderImpl startUdpListener() {
118 ListeningPoint udpListeningPoint = null; 116 ListeningPoint udpListeningPoint = null;
119 - SipProvider udpSipProvider = null; 117 + SipProviderImpl udpSipProvider = null;
120 try { 118 try {
121 udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP"); 119 udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP");
122 - udpSipProvider = sipStack.createSipProvider(udpListeningPoint); 120 + udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint);
123 udpSipProvider.addSipListener(this); 121 udpSipProvider.addSipListener(this);
  122 +// udpSipProvider.setAutomaticDialogSupportEnabled(false);
124 } catch (TransportNotSupportedException e) { 123 } catch (TransportNotSupportedException e) {
125 e.printStackTrace(); 124 e.printStackTrace();
126 } catch (InvalidArgumentException e) { 125 } catch (InvalidArgumentException e) {
@@ -141,7 +140,7 @@ public class SipLayer implements SipListener { @@ -141,7 +140,7 @@ public class SipLayer implements SipListener {
141 */ 140 */
142 @Override 141 @Override
143 public void processRequest(RequestEvent evt) { 142 public void processRequest(RequestEvent evt) {
144 -// logger.debug(evt.getRequest().toString()); 143 + logger.debug(evt.getRequest().toString());
145 // 由于jainsip是单线程程序,为提高性能并发处理 144 // 由于jainsip是单线程程序,为提高性能并发处理
146 processThreadPool.execute(() -> { 145 processThreadPool.execute(() -> {
147 if (processorFactory != null) { 146 if (processorFactory != null) {
@@ -153,7 +152,7 @@ public class SipLayer implements SipListener { @@ -153,7 +152,7 @@ public class SipLayer implements SipListener {
153 @Override 152 @Override
154 public void processResponse(ResponseEvent evt) { 153 public void processResponse(ResponseEvent evt) {
155 Response response = evt.getResponse(); 154 Response response = evt.getResponse();
156 -// logger.debug(evt.getResponse().toString()); 155 + logger.debug(evt.getResponse().toString());
157 int status = response.getStatusCode(); 156 int status = response.getStatusCode();
158 if (((status >= 200) && (status < 300)) || status == 401) { // Success! 157 if (((status >= 200) && (status < 300)) || status == 401) { // Success!
159 ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); 158 ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
@@ -163,6 +162,7 @@ public class SipLayer implements SipListener { @@ -163,6 +162,7 @@ public class SipLayer implements SipListener {
163 // TODO Auto-generated catch block 162 // TODO Auto-generated catch block
164 e.printStackTrace(); 163 e.printStackTrace();
165 } 164 }
  165 +
166 if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { 166 if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) {
167 CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); 167 CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
168 if (callIdHeader != null) { 168 if (callIdHeader != null) {
@@ -220,7 +220,6 @@ public class SipLayer implements SipListener { @@ -220,7 +220,6 @@ public class SipLayer implements SipListener {
220 @Override 220 @Override
221 public void processIOException(IOExceptionEvent exceptionEvent) { 221 public void processIOException(IOExceptionEvent exceptionEvent) {
222 // TODO Auto-generated method stub 222 // TODO Auto-generated method stub
223 -  
224 } 223 }
225 224
226 /** 225 /**
@@ -236,7 +235,6 @@ public class SipLayer implements SipListener { @@ -236,7 +235,6 @@ public class SipLayer implements SipListener {
236 @Override 235 @Override
237 public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { 236 public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
238 // TODO Auto-generated method stub 237 // TODO Auto-generated method stub
239 -  
240 } 238 }
241 239
242 /** 240 /**
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import javax.sip.message.Request;
  4 +
  5 +public class SsrcTransaction {
  6 +
  7 + private String deviceId;
  8 + private String channelId;
  9 + private String ssrc;
  10 + private String streamId;
  11 + private byte[] transaction;
  12 + private byte[] dialog;
  13 + private String mediaServerId;
  14 +
  15 + public String getDeviceId() {
  16 + return deviceId;
  17 + }
  18 +
  19 + public void setDeviceId(String deviceId) {
  20 + this.deviceId = deviceId;
  21 + }
  22 +
  23 + public String getChannelId() {
  24 + return channelId;
  25 + }
  26 +
  27 + public void setChannelId(String channelId) {
  28 + this.channelId = channelId;
  29 + }
  30 +
  31 + public String getSsrc() {
  32 + return ssrc;
  33 + }
  34 +
  35 + public void setSsrc(String ssrc) {
  36 + this.ssrc = ssrc;
  37 + }
  38 +
  39 + public String getStreamId() {
  40 + return streamId;
  41 + }
  42 +
  43 + public void setStreamId(String streamId) {
  44 + this.streamId = streamId;
  45 + }
  46 +
  47 + public byte[] getTransaction() {
  48 + return transaction;
  49 + }
  50 +
  51 + public void setTransaction(byte[] transaction) {
  52 + this.transaction = transaction;
  53 + }
  54 +
  55 + public byte[] getDialog() {
  56 + return dialog;
  57 + }
  58 +
  59 + public void setDialog(byte[] dialog) {
  60 + this.dialog = dialog;
  61 + }
  62 +
  63 + public String getMediaServerId() {
  64 + return mediaServerId;
  65 + }
  66 +
  67 + public void setMediaServerId(String mediaServerId) {
  68 + this.mediaServerId = mediaServerId;
  69 + }
  70 +}
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
@@ -6,7 +6,6 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; @@ -6,7 +6,6 @@ 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; 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
11 import com.genersoft.iot.vmp.service.IMediaServerService; 10 import com.genersoft.iot.vmp.service.IMediaServerService;
12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -77,7 +76,7 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf @@ -77,7 +76,7 @@ public class PlatformNotRegisterEventLister implements ApplicationListener&lt;Platf
77 } 76 }
78 stream.append(sendRtpItem.getStreamId()); 77 stream.append(sendRtpItem.getStreamId());
79 redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId()); 78 redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId());
80 - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 79 + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
81 Map<String, Object> param = new HashMap<>(); 80 Map<String, Object> param = new HashMap<>();
82 param.put("vhost", "__defaultVhost__"); 81 param.put("vhost", "__defaultVhost__");
83 param.put("app", app.toString()); 82 param.put("app", app.toString());
src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java renamed to src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcConfig.java
1 -package com.genersoft.iot.vmp.gb28181.session;  
2 -  
3 -import java.util.ArrayList;  
4 -import java.util.List;  
5 -import java.util.Random;  
6 -  
7 -import com.genersoft.iot.vmp.conf.SipConfig;  
8 -import com.genersoft.iot.vmp.utils.SpringBeanFactory;  
9 -import org.slf4j.Logger;  
10 -import org.slf4j.LoggerFactory;  
11 -  
12 -/**  
13 - * @Description:SIP信令中的SSRC工具类。SSRC值由10位十进制整数组成的字符串,第一位为0代表实况,为1则代表回放;第二位至第六位由监控域ID的第4位到第8位组成;最后4位为不重复的4个整数  
14 - * @author: swwheihei  
15 - * @date: 2020年5月10日 上午11:57:57  
16 - */  
17 -public class SsrcUtil {  
18 -  
19 - private final static Logger logger = LoggerFactory.getLogger(SsrcUtil.class);  
20 -  
21 - private static String ssrcPrefix;  
22 -  
23 - private static List<String> isUsed;  
24 -  
25 - private static List<String> notUsed;  
26 -  
27 - private static void init() {  
28 - SipConfig sipConfig = (SipConfig) SpringBeanFactory.getBean("sipConfig");  
29 - ssrcPrefix = sipConfig.getSipDomain().substring(3, 8);  
30 - isUsed = new ArrayList<String>();  
31 - notUsed = new ArrayList<String>();  
32 - for (int i = 1; i < 10000; i++) {  
33 - if (i < 10) {  
34 - notUsed.add("000" + i);  
35 - } else if (i < 100) {  
36 - notUsed.add("00" + i);  
37 - } else if (i < 1000) {  
38 - notUsed.add("0" + i);  
39 - } else {  
40 - notUsed.add(String.valueOf(i));  
41 - }  
42 - }  
43 - }  
44 -  
45 - /**  
46 - * 获取视频预览的SSRC值,第一位固定为0  
47 - *  
48 - */  
49 - public static String getPlaySsrc() {  
50 - return "0" + getSsrcPrefix() + getSN();  
51 - }  
52 -  
53 - /**  
54 - * 获取录像回放的SSRC值,第一位固定为1  
55 - *  
56 - */  
57 - public static String getPlayBackSsrc() {  
58 - return "1" + getSsrcPrefix() + getSN();  
59 - }  
60 -  
61 - /**  
62 - * 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽  
63 - *  
64 - */  
65 - public static void releaseSsrc(String ssrc) {  
66 - if (ssrc == null) {  
67 - logger.error("要释放ssrc为null");  
68 - return;  
69 - }  
70 - String sn = ssrc.substring(6);  
71 - isUsed.remove(sn);  
72 - notUsed.add(sn);  
73 - }  
74 -  
75 - /**  
76 - * 获取后四位数SN,随机数  
77 - *  
78 - */  
79 - private static String getSN() {  
80 - String sn = null;  
81 - int index = 0;  
82 - if (notUsed.size() == 0) {  
83 - throw new RuntimeException("ssrc已经用完");  
84 - } else if (notUsed.size() == 1) {  
85 - sn = notUsed.get(0);  
86 - } else {  
87 - index = new Random().nextInt(notUsed.size() - 1);  
88 - sn = notUsed.get(index);  
89 - }  
90 - notUsed.remove(index);  
91 - isUsed.add(sn);  
92 - return sn;  
93 - }  
94 -  
95 - private static String getSsrcPrefix() {  
96 - if (ssrcPrefix == null) {  
97 - init();  
98 - }  
99 - return ssrcPrefix;  
100 - }  
101 -} 1 +package com.genersoft.iot.vmp.gb28181.session;
  2 +
  3 +import com.genersoft.iot.vmp.utils.ConfigConst;
  4 +
  5 +import java.util.ArrayList;
  6 +import java.util.List;
  7 +import java.util.Random;
  8 +import java.util.Set;
  9 +
  10 +public class SsrcConfig {
  11 +
  12 + /**
  13 + * zlm流媒体服务器Id
  14 + */
  15 + private String mediaServerId;
  16 +
  17 + private String ssrcPrefix;
  18 + /**
  19 + * zlm流媒体服务器已用会话句柄
  20 + */
  21 + private List<String> isUsed;
  22 + /**
  23 + * zlm流媒体服务器可用会话句柄
  24 + */
  25 + private List<String> notUsed;
  26 +
  27 + public SsrcConfig() {
  28 + }
  29 +
  30 + public SsrcConfig(String mediaServerId, Set<String> usedSet, String sipDomain) {
  31 + this.mediaServerId = mediaServerId;
  32 + this.isUsed = new ArrayList<>();
  33 + this.ssrcPrefix = sipDomain.substring(3, 8);
  34 + this.notUsed = new ArrayList<>();
  35 + for (int i = 1; i < ConfigConst.MAX_STRTEAM_COUNT; i++) {
  36 + String ssrc;
  37 + if (i < 10) {
  38 + ssrc = "000" + i;
  39 + } else if (i < 100) {
  40 + ssrc = "00" + i;
  41 + } else if (i < 1000) {
  42 + ssrc = "0" + i;
  43 + } else {
  44 + ssrc = String.valueOf(i);
  45 + }
  46 + if (null == usedSet || !usedSet.contains(ssrc)) {
  47 + this.notUsed.add(ssrc);
  48 + } else {
  49 + this.isUsed.add(ssrc);
  50 + }
  51 + }
  52 + }
  53 +
  54 +
  55 + /**
  56 + * 获取视频预览的SSRC值,第一位固定为0
  57 + * @return ssrc
  58 + */
  59 + public String getPlaySsrc() {
  60 + return "0" + getSsrcPrefix() + getSN();
  61 + }
  62 +
  63 + /**
  64 + * 获取录像回放的SSRC值,第一位固定为1
  65 + *
  66 + */
  67 + public String getPlayBackSsrc() {
  68 + return "1" + getSsrcPrefix() + getSN();
  69 + }
  70 +
  71 + /**
  72 + * 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽
  73 + * @param ssrc 需要重置的ssrc
  74 + */
  75 + public void releaseSsrc(String ssrc) {
  76 + if (ssrc == null) {
  77 + return;
  78 + }
  79 + String sn = ssrc.substring(6);
  80 + try {
  81 + isUsed.remove(sn);
  82 + notUsed.add(sn);
  83 + }catch (NullPointerException e){
  84 + System.out.printf("11111");
  85 + }
  86 + }
  87 +
  88 + /**
  89 + * 获取后四位数SN,随机数
  90 + *
  91 + */
  92 + private String getSN() {
  93 + String sn = null;
  94 + int index = 0;
  95 + if (notUsed.size() == 0) {
  96 + throw new RuntimeException("ssrc已经用完");
  97 + } else if (notUsed.size() == 1) {
  98 + sn = notUsed.get(0);
  99 + } else {
  100 + index = new Random().nextInt(notUsed.size() - 1);
  101 + sn = notUsed.get(index);
  102 + }
  103 + notUsed.remove(index);
  104 + isUsed.add(sn);
  105 + return sn;
  106 + }
  107 +
  108 + public String getSsrcPrefix() {
  109 + return ssrcPrefix;
  110 + }
  111 +
  112 + public String getMediaServerId() {
  113 + return mediaServerId;
  114 + }
  115 +
  116 + public void setMediaServerId(String mediaServerId) {
  117 + this.mediaServerId = mediaServerId;
  118 + }
  119 +
  120 + public void setSsrcPrefix(String ssrcPrefix) {
  121 + this.ssrcPrefix = ssrcPrefix;
  122 + }
  123 +
  124 + public List<String> getIsUsed() {
  125 + return isUsed;
  126 + }
  127 +
  128 + public void setIsUsed(List<String> isUsed) {
  129 + this.isUsed = isUsed;
  130 + }
  131 +
  132 + public List<String> getNotUsed() {
  133 + return notUsed;
  134 + }
  135 +
  136 + public void setNotUsed(List<String> notUsed) {
  137 + this.notUsed = notUsed;
  138 + }
  139 +
  140 +}
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
1 package com.genersoft.iot.vmp.gb28181.session; 1 package com.genersoft.iot.vmp.gb28181.session;
2 2
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +import java.util.Map;
3 import java.util.concurrent.ConcurrentHashMap; 6 import java.util.concurrent.ConcurrentHashMap;
4 7
5 import javax.sip.ClientTransaction; 8 import javax.sip.ClientTransaction;
  9 +import javax.sip.Dialog;
  10 +import javax.sip.message.Request;
6 11
  12 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  13 +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
  14 +import com.genersoft.iot.vmp.service.IMediaServerService;
  15 +import com.genersoft.iot.vmp.utils.SerializeUtils;
  16 +import com.genersoft.iot.vmp.utils.redis.JedisUtil;
  17 +import com.genersoft.iot.vmp.utils.redis.RedisUtil;
  18 +import gov.nist.javax.sip.stack.SIPDialog;
  19 +import org.springframework.beans.factory.annotation.Autowired;
  20 +import org.springframework.data.redis.core.RedisTemplate;
7 import org.springframework.stereotype.Component; 21 import org.springframework.stereotype.Component;
8 22
9 /** 23 /**
@@ -14,50 +28,85 @@ import org.springframework.stereotype.Component; @@ -14,50 +28,85 @@ import org.springframework.stereotype.Component;
14 @Component 28 @Component
15 public class VideoStreamSessionManager { 29 public class VideoStreamSessionManager {
16 30
17 - private ConcurrentHashMap<String, ClientTransaction> sessionMap = new ConcurrentHashMap<>();  
18 - private ConcurrentHashMap<String, String> ssrcMap = new ConcurrentHashMap<>();  
19 - private ConcurrentHashMap<String, String> streamIdMap = new ConcurrentHashMap<>(); 31 + @Autowired
  32 + private RedisUtil redisUtil;
20 33
21 - public String createPlaySsrc(){  
22 - return SsrcUtil.getPlaySsrc();  
23 - }  
24 -  
25 - public String createPlayBackSsrc(){  
26 - return SsrcUtil.getPlayBackSsrc(); 34 + public void put(String deviceId, String channelId ,String ssrc, String streamId, String mediaServerId, ClientTransaction transaction){
  35 + SsrcTransaction ssrcTransaction = new SsrcTransaction();
  36 + ssrcTransaction.setDeviceId(deviceId);
  37 + ssrcTransaction.setChannelId(channelId);
  38 + ssrcTransaction.setStreamId(streamId);
  39 + byte[] transactionByteArray = SerializeUtils.serialize(transaction);
  40 + ssrcTransaction.setTransaction(transactionByteArray);
  41 + ssrcTransaction.setSsrc(ssrc);
  42 + ssrcTransaction.setMediaServerId(mediaServerId);
  43 +
  44 + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId, ssrcTransaction);
27 } 45 }
28 -  
29 - public void put(String deviceId, String channelId ,String ssrc, String streamId, ClientTransaction transaction){  
30 - sessionMap.put(deviceId + "_" + channelId, transaction);  
31 - ssrcMap.put(deviceId + "_" + channelId, ssrc);  
32 - streamIdMap.put(deviceId + "_" + channelId, streamId); 46 +
  47 + public void put(String deviceId, String channelId , Dialog dialog){
  48 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);
  49 + if (ssrcTransaction != null) {
  50 + byte[] dialogByteArray = SerializeUtils.serialize(dialog);
  51 + ssrcTransaction.setDialog(dialogByteArray);
  52 + }
  53 + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId, ssrcTransaction);
33 } 54 }
  55 +
34 56
35 public ClientTransaction getTransaction(String deviceId, String channelId){ 57 public ClientTransaction getTransaction(String deviceId, String channelId){
36 - return sessionMap.get(deviceId + "_" + channelId); 58 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);
  59 + if (ssrcTransaction == null) return null;
  60 + byte[] transactionByteArray = ssrcTransaction.getTransaction();
  61 + ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray);
  62 + return clientTransaction;
37 } 63 }
38 64
39 - public String getStreamId(String deviceId, String channelId){  
40 - return streamIdMap.get(deviceId + "_" + channelId); 65 + public SIPDialog getDialog(String deviceId, String channelId){
  66 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);
  67 + if (ssrcTransaction == null) return null;
  68 + byte[] dialogByteArray = ssrcTransaction.getDialog();
  69 + if (dialogByteArray == null) return null;
  70 + SIPDialog dialog = (SIPDialog)SerializeUtils.deSerialize(dialogByteArray);
  71 + return dialog;
41 } 72 }
42 -  
43 - public void remove(String deviceId, String channelId) {  
44 - sessionMap.remove(deviceId + "_" + channelId);  
45 - if (ssrcMap.get(deviceId + "_" + channelId) != null) {  
46 - SsrcUtil.releaseSsrc(ssrcMap.get(deviceId + "_" + channelId));  
47 - }  
48 - ssrcMap.remove(deviceId + "_" + channelId);  
49 - streamIdMap.remove(deviceId + "_" + channelId); 73 +
  74 + public SsrcTransaction getSsrcTransaction(String deviceId, String channelId){
  75 + SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId);
  76 + return ssrcTransaction;
50 } 77 }
51 78
52 - public ConcurrentHashMap<String, ClientTransaction> getSessionMap() {  
53 - return sessionMap; 79 + public String getStreamId(String deviceId, String channelId){
  80 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);
  81 + if (ssrcTransaction == null) return null;
  82 + return ssrcTransaction.getStreamId();
  83 + }
  84 + public String getMediaServerId(String deviceId, String channelId){
  85 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);
  86 + if (ssrcTransaction == null) return null;
  87 + return ssrcTransaction.getMediaServerId();
54 } 88 }
55 89
56 - public ConcurrentHashMap<String, String> getSsrcMap() {  
57 - return ssrcMap; 90 + public String getSSRC(String deviceId, String channelId){
  91 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);
  92 + if (ssrcTransaction == null) return null;
  93 + return ssrcTransaction.getSsrc();
  94 + }
  95 +
  96 + public void remove(String deviceId, String channelId) {
  97 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);
  98 + if (ssrcTransaction == null) return;
  99 + redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId);
58 } 100 }
59 101
60 - public ConcurrentHashMap<String, String> getStreamIdMap() {  
61 - return streamIdMap; 102 + public List<SsrcTransaction> getAllSsrc() {
  103 + List<Object> ssrcTransactionKeys = redisUtil.scan(String.format("%s_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX));
  104 + List<SsrcTransaction> result= new ArrayList<>();
  105 + for (int i = 0; i < ssrcTransactionKeys.size(); i++) {
  106 + String key = (String)ssrcTransactionKeys.get(i);
  107 + SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(key);
  108 + result.add(ssrcTransaction);
  109 + }
  110 + return result;
62 } 111 }
63 } 112 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -7,6 +7,7 @@ import javax.sip.header.CSeqHeader; @@ -7,6 +7,7 @@ import javax.sip.header.CSeqHeader;
7 import javax.sip.message.Request; 7 import javax.sip.message.Request;
8 import javax.sip.message.Response; 8 import javax.sip.message.Response;
9 9
  10 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
10 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 11 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
11 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 12 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
12 import com.genersoft.iot.vmp.service.IMediaServerService; 13 import com.genersoft.iot.vmp.service.IMediaServerService;
@@ -108,7 +109,6 @@ public class SIPProcessorFactory { @@ -108,7 +109,6 @@ public class SIPProcessorFactory {
108 @Autowired 109 @Autowired
109 private IMediaServerService mediaServerService; 110 private IMediaServerService mediaServerService;
110 111
111 -  
112 // 注:这里使用注解会导致循环依赖注入,暂用springBean 112 // 注:这里使用注解会导致循环依赖注入,暂用springBean
113 private SipProvider tcpSipProvider; 113 private SipProvider tcpSipProvider;
114 114
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -3,8 +3,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; @@ -3,8 +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 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  7 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
8 8
9 /** 9 /**
10 * @Description:设备能力接口,用于定义设备的控制、查询能力 10 * @Description:设备能力接口,用于定义设备的控制、查询能力
@@ -92,7 +92,7 @@ public interface ISIPCommander { @@ -92,7 +92,7 @@ public interface ISIPCommander {
92 * @param device 视频设备 92 * @param device 视频设备
93 * @param channelId 预览通道 93 * @param channelId 预览通道
94 */ 94 */
95 - void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 95 + void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
96 96
97 /** 97 /**
98 * 请求回放视频流 98 * 请求回放视频流
@@ -102,7 +102,7 @@ public interface ISIPCommander { @@ -102,7 +102,7 @@ public interface ISIPCommander {
102 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss 102 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss
103 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss 103 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
104 */ 104 */
105 - void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 105 + void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
106 106
107 /** 107 /**
108 * 请求历史媒体下载 108 * 请求历史媒体下载
@@ -113,12 +113,10 @@ public interface ISIPCommander { @@ -113,12 +113,10 @@ public interface ISIPCommander {
113 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss 113 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
114 * @param downloadSpeed 下载倍速参数 114 * @param downloadSpeed 下载倍速参数
115 */ 115 */
116 - void downloadStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 116 + void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
117 117
118 /** 118 /**
119 * 视频流停止 119 * 视频流停止
120 - *  
121 - * @param ssrc ssrc  
122 */ 120 */
123 void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent); 121 void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent);
124 void streamByeCmd(String deviceId, String channelId); 122 void streamByeCmd(String deviceId, String channelId);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
1 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
2 2
  3 +import java.lang.reflect.Field;
3 import java.text.ParseException; 4 import java.text.ParseException;
  5 +import java.util.HashSet;
4 6
5 import javax.sip.*; 7 import javax.sip.*;
6 import javax.sip.address.SipURI; 8 import javax.sip.address.SipURI;
@@ -8,18 +10,21 @@ import javax.sip.header.CallIdHeader; @@ -8,18 +10,21 @@ import javax.sip.header.CallIdHeader;
8 import javax.sip.header.ViaHeader; 10 import javax.sip.header.ViaHeader;
9 import javax.sip.message.Request; 11 import javax.sip.message.Request;
10 12
11 -import com.alibaba.fastjson.JSONArray;  
12 import com.alibaba.fastjson.JSONObject; 13 import com.alibaba.fastjson.JSONObject;
13 -import com.genersoft.iot.vmp.common.StreamInfo;  
14 -import com.genersoft.iot.vmp.conf.MediaConfig;  
15 import com.genersoft.iot.vmp.conf.UserSetup; 14 import com.genersoft.iot.vmp.conf.UserSetup;
  15 +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
16 import com.genersoft.iot.vmp.media.zlm.*; 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.dto.IMediaServerItem;  
19 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 18 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  19 +import com.genersoft.iot.vmp.service.IMediaServerService;
  20 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 21 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 22 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  23 +import gov.nist.javax.sip.SipProviderImpl;
  24 +import gov.nist.javax.sip.SipStackImpl;
22 import gov.nist.javax.sip.message.SIPRequest; 25 import gov.nist.javax.sip.message.SIPRequest;
  26 +import gov.nist.javax.sip.stack.SIPDialog;
  27 +import gov.nist.javax.sip.stack.SIPTransaction;
23 import org.slf4j.Logger; 28 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory; 29 import org.slf4j.LoggerFactory;
25 import org.springframework.beans.factory.annotation.Autowired; 30 import org.springframework.beans.factory.annotation.Autowired;
@@ -35,7 +40,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; @@ -35,7 +40,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
35 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; 40 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
36 import com.genersoft.iot.vmp.gb28181.utils.DateUtil; 41 import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
37 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; 42 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
38 -import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;  
39 import org.springframework.util.StringUtils; 43 import org.springframework.util.StringUtils;
40 44
41 /** 45 /**
@@ -55,12 +59,12 @@ public class SIPCommander implements ISIPCommander { @@ -55,12 +59,12 @@ public class SIPCommander implements ISIPCommander {
55 @Lazy 59 @Lazy
56 @Autowired 60 @Autowired
57 @Qualifier(value="tcpSipProvider") 61 @Qualifier(value="tcpSipProvider")
58 - private SipProvider tcpSipProvider; 62 + private SipProviderImpl tcpSipProvider;
59 63
60 @Lazy 64 @Lazy
61 @Autowired 65 @Autowired
62 @Qualifier(value="udpSipProvider") 66 @Qualifier(value="udpSipProvider")
63 - private SipProvider udpSipProvider; 67 + private SipProviderImpl udpSipProvider;
64 68
65 @Autowired 69 @Autowired
66 private SIPRequestHeaderProvider headerProvider; 70 private SIPRequestHeaderProvider headerProvider;
@@ -75,9 +79,6 @@ public class SIPCommander implements ISIPCommander { @@ -75,9 +79,6 @@ public class SIPCommander implements ISIPCommander {
75 private IRedisCatchStorage redisCatchStorage; 79 private IRedisCatchStorage redisCatchStorage;
76 80
77 @Autowired 81 @Autowired
78 - private ZLMRTPServerFactory zlmrtpServerFactory;  
79 -  
80 - @Autowired  
81 private UserSetup userSetup; 82 private UserSetup userSetup;
82 83
83 @Autowired 84 @Autowired
@@ -86,6 +87,11 @@ public class SIPCommander implements ISIPCommander { @@ -86,6 +87,11 @@ public class SIPCommander implements ISIPCommander {
86 @Autowired 87 @Autowired
87 private SipSubscribe sipSubscribe; 88 private SipSubscribe sipSubscribe;
88 89
  90 + @Autowired
  91 + private IMediaServerService mediaServerService;
  92 +
  93 + private SIPDialog dialog;
  94 +
89 public SipConfig getSipConfig() { 95 public SipConfig getSipConfig() {
90 return sipConfig; 96 return sipConfig;
91 } 97 }
@@ -334,26 +340,13 @@ public class SIPCommander implements ISIPCommander { @@ -334,26 +340,13 @@ public class SIPCommander implements ISIPCommander {
334 * @param errorEvent sip错误订阅 340 * @param errorEvent sip错误订阅
335 */ 341 */
336 @Override 342 @Override
337 - public void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {  
338 - String streamId = null; 343 + public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
  344 + String streamId = ssrcInfo.getStreamId();
339 try { 345 try {
340 if (device == null) return; 346 if (device == null) return;
341 String streamMode = device.getStreamMode().toUpperCase(); 347 String streamMode = device.getStreamMode().toUpperCase();
342 348
343 - String ssrc = streamSession.createPlaySsrc();  
344 - if (mediaServerItem.isRtpEnable()) {  
345 - streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);  
346 - }else {  
347 - streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();  
348 - }  
349 - Integer mediaPort = null;  
350 - // 使用动态udp端口  
351 - if (mediaServerItem.isRtpEnable()) {  
352 - mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId);  
353 - }else {  
354 - mediaPort = mediaServerItem.getRtpProxyPort();  
355 - }  
356 - logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort); 349 + logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
357 // 添加订阅 350 // 添加订阅
358 JSONObject subscribeKey = new JSONObject(); 351 JSONObject subscribeKey = new JSONObject();
359 subscribeKey.put("app", "rtp"); 352 subscribeKey.put("app", "rtp");
@@ -361,7 +354,7 @@ public class SIPCommander implements ISIPCommander { @@ -361,7 +354,7 @@ public class SIPCommander implements ISIPCommander {
361 subscribeKey.put("regist", true); 354 subscribeKey.put("regist", true);
362 subscribeKey.put("mediaServerId", mediaServerItem.getId()); 355 subscribeKey.put("mediaServerId", mediaServerItem.getId());
363 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, 356 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
364 - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ 357 + (MediaServerItem mediaServerItemInUse, JSONObject json)->{
365 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; 358 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;
366 event.response(mediaServerItemInUse, json); 359 event.response(mediaServerItemInUse, json);
367 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); 360 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
@@ -369,7 +362,6 @@ public class SIPCommander implements ISIPCommander { @@ -369,7 +362,6 @@ public class SIPCommander implements ISIPCommander {
369 // 362 //
370 StringBuffer content = new StringBuffer(200); 363 StringBuffer content = new StringBuffer(200);
371 content.append("v=0\r\n"); 364 content.append("v=0\r\n");
372 -// content.append("o=" + sipConfig.getSipId() + " 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");  
373 content.append("o="+"00000"+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n"); 365 content.append("o="+"00000"+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
374 content.append("s=Play\r\n"); 366 content.append("s=Play\r\n");
375 content.append("c=IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n"); 367 content.append("c=IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n");
@@ -377,11 +369,11 @@ public class SIPCommander implements ISIPCommander { @@ -377,11 +369,11 @@ public class SIPCommander implements ISIPCommander {
377 369
378 if (userSetup.isSeniorSdp()) { 370 if (userSetup.isSeniorSdp()) {
379 if("TCP-PASSIVE".equals(streamMode)) { 371 if("TCP-PASSIVE".equals(streamMode)) {
380 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); 372 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
381 }else if ("TCP-ACTIVE".equals(streamMode)) { 373 }else if ("TCP-ACTIVE".equals(streamMode)) {
382 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); 374 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
383 }else if("UDP".equals(streamMode)) { 375 }else if("UDP".equals(streamMode)) {
384 - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); 376 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n");
385 } 377 }
386 content.append("a=recvonly\r\n"); 378 content.append("a=recvonly\r\n");
387 content.append("a=rtpmap:96 PS/90000\r\n"); 379 content.append("a=rtpmap:96 PS/90000\r\n");
@@ -402,11 +394,11 @@ public class SIPCommander implements ISIPCommander { @@ -402,11 +394,11 @@ public class SIPCommander implements ISIPCommander {
402 } 394 }
403 }else { 395 }else {
404 if("TCP-PASSIVE".equals(streamMode)) { 396 if("TCP-PASSIVE".equals(streamMode)) {
405 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); 397 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
406 }else if ("TCP-ACTIVE".equals(streamMode)) { 398 }else if ("TCP-ACTIVE".equals(streamMode)) {
407 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); 399 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
408 }else if("UDP".equals(streamMode)) { 400 }else if("UDP".equals(streamMode)) {
409 - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); 401 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n");
410 } 402 }
411 content.append("a=recvonly\r\n"); 403 content.append("a=recvonly\r\n");
412 content.append("a=rtpmap:96 PS/90000\r\n"); 404 content.append("a=rtpmap:96 PS/90000\r\n");
@@ -421,20 +413,25 @@ public class SIPCommander implements ISIPCommander { @@ -421,20 +413,25 @@ public class SIPCommander implements ISIPCommander {
421 } 413 }
422 } 414 }
423 415
424 - content.append("y="+ssrc+"\r\n");//ssrc 416 + content.append("y="+ssrcInfo.getSsrc()+"\r\n");//ssrc
425 417
426 String tm = Long.toString(System.currentTimeMillis()); 418 String tm = Long.toString(System.currentTimeMillis());
427 419
428 CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() 420 CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
429 : udpSipProvider.getNewCallId(); 421 : udpSipProvider.getNewCallId();
430 422
431 - Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrc, callIdHeader); 423 + Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader);
432 424
433 - ClientTransaction transaction = transmitRequest(device, request, (e -> { 425 + String finalStreamId = streamId;
  426 + transmitRequest(device, request, (e -> {
434 streamSession.remove(device.getDeviceId(), channelId); 427 streamSession.remove(device.getDeviceId(), channelId);
  428 + mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc());
435 errorEvent.response(e); 429 errorEvent.response(e);
436 - }));  
437 - streamSession.put(device.getDeviceId(), channelId ,ssrc,streamId, transaction); 430 + }), e ->{
  431 + streamSession.put(device.getDeviceId(), channelId ,ssrcInfo.getSsrc(), finalStreamId, mediaServerItem.getId(),e.getClientTransaction());
  432 + streamSession.put(device.getDeviceId(), channelId , e.getDialog());
  433 + });
  434 +
438 435
439 } catch ( SipException | ParseException | InvalidArgumentException e) { 436 } catch ( SipException | ParseException | InvalidArgumentException e) {
440 e.printStackTrace(); 437 e.printStackTrace();
@@ -450,30 +447,21 @@ public class SIPCommander implements ISIPCommander { @@ -450,30 +447,21 @@ public class SIPCommander implements ISIPCommander {
450 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss 447 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
451 */ 448 */
452 @Override 449 @Override
453 - public void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event 450 + public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event
454 , SipSubscribe.Event errorEvent) { 451 , SipSubscribe.Event errorEvent) {
455 try { 452 try {
456 - String ssrc = streamSession.createPlayBackSsrc();  
457 - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();  
458 453
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); 454 + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
467 455
468 // 添加订阅 456 // 添加订阅
469 JSONObject subscribeKey = new JSONObject(); 457 JSONObject subscribeKey = new JSONObject();
470 subscribeKey.put("app", "rtp"); 458 subscribeKey.put("app", "rtp");
471 - subscribeKey.put("stream", streamId); 459 + subscribeKey.put("stream", ssrcInfo.getStreamId());
472 subscribeKey.put("regist", true); 460 subscribeKey.put("regist", true);
473 subscribeKey.put("mediaServerId", mediaServerItem.getId()); 461 subscribeKey.put("mediaServerId", mediaServerItem.getId());
474 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 462 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
475 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, 463 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
476 - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ 464 + (MediaServerItem mediaServerItemInUse, JSONObject json)->{
477 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; 465 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;
478 event.response(mediaServerItemInUse, json); 466 event.response(mediaServerItemInUse, json);
479 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); 467 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
@@ -494,11 +482,11 @@ public class SIPCommander implements ISIPCommander { @@ -494,11 +482,11 @@ public class SIPCommander implements ISIPCommander {
494 482
495 if (userSetup.isSeniorSdp()) { 483 if (userSetup.isSeniorSdp()) {
496 if("TCP-PASSIVE".equals(streamMode)) { 484 if("TCP-PASSIVE".equals(streamMode)) {
497 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); 485 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
498 }else if ("TCP-ACTIVE".equals(streamMode)) { 486 }else if ("TCP-ACTIVE".equals(streamMode)) {
499 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); 487 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
500 }else if("UDP".equals(streamMode)) { 488 }else if("UDP".equals(streamMode)) {
501 - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); 489 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n");
502 } 490 }
503 content.append("a=recvonly\r\n"); 491 content.append("a=recvonly\r\n");
504 content.append("a=rtpmap:96 PS/90000\r\n"); 492 content.append("a=rtpmap:96 PS/90000\r\n");
@@ -519,11 +507,11 @@ public class SIPCommander implements ISIPCommander { @@ -519,11 +507,11 @@ public class SIPCommander implements ISIPCommander {
519 } 507 }
520 }else { 508 }else {
521 if("TCP-PASSIVE".equals(streamMode)) { 509 if("TCP-PASSIVE".equals(streamMode)) {
522 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); 510 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
523 }else if ("TCP-ACTIVE".equals(streamMode)) { 511 }else if ("TCP-ACTIVE".equals(streamMode)) {
524 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); 512 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
525 }else if("UDP".equals(streamMode)) { 513 }else if("UDP".equals(streamMode)) {
526 - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); 514 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n");
527 } 515 }
528 content.append("a=recvonly\r\n"); 516 content.append("a=recvonly\r\n");
529 content.append("a=rtpmap:96 PS/90000\r\n"); 517 content.append("a=rtpmap:96 PS/90000\r\n");
@@ -538,7 +526,7 @@ public class SIPCommander implements ISIPCommander { @@ -538,7 +526,7 @@ public class SIPCommander implements ISIPCommander {
538 } 526 }
539 } 527 }
540 528
541 - content.append("y="+ssrc+"\r\n");//ssrc 529 + content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
542 530
543 String tm = Long.toString(System.currentTimeMillis()); 531 String tm = Long.toString(System.currentTimeMillis());
544 532
@@ -547,9 +535,11 @@ public class SIPCommander implements ISIPCommander { @@ -547,9 +535,11 @@ public class SIPCommander implements ISIPCommander {
547 535
548 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader); 536 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader);
549 537
550 - ClientTransaction transaction = transmitRequest(device, request, errorEvent);  
551 - streamSession.put(device.getDeviceId(), channelId, ssrc, streamId, transaction);  
552 - 538 + transmitRequest(device, request, errorEvent, okEvent -> {
  539 + Dialog dialog = okEvent.getClientTransaction().getDialog();
  540 + streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), okEvent.getClientTransaction());
  541 + streamSession.put(device.getDeviceId(), channelId, dialog);
  542 + });
553 } catch ( SipException | ParseException | InvalidArgumentException e) { 543 } catch ( SipException | ParseException | InvalidArgumentException e) {
554 e.printStackTrace(); 544 e.printStackTrace();
555 } 545 }
@@ -565,30 +555,20 @@ public class SIPCommander implements ISIPCommander { @@ -565,30 +555,20 @@ public class SIPCommander implements ISIPCommander {
565 * @param downloadSpeed 下载倍速参数 555 * @param downloadSpeed 下载倍速参数
566 */ 556 */
567 @Override 557 @Override
568 - public void downloadStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event 558 + public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event
569 , SipSubscribe.Event errorEvent) { 559 , SipSubscribe.Event errorEvent) {
570 try { 560 try {
571 - String ssrc = streamSession.createPlayBackSsrc();  
572 - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();  
573 -  
574 - Integer mediaPort = null;  
575 - // 使用动态udp端口  
576 - if (mediaServerItem.isRtpEnable()) {  
577 - mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId);  
578 - }else {  
579 - mediaPort = mediaServerItem.getRtpProxyPort();  
580 - }  
581 - logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort); 561 + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
582 562
583 // 添加订阅 563 // 添加订阅
584 JSONObject subscribeKey = new JSONObject(); 564 JSONObject subscribeKey = new JSONObject();
585 subscribeKey.put("app", "rtp"); 565 subscribeKey.put("app", "rtp");
586 - subscribeKey.put("stream", streamId); 566 + subscribeKey.put("stream", ssrcInfo.getStreamId());
587 subscribeKey.put("regist", true); 567 subscribeKey.put("regist", true);
588 subscribeKey.put("mediaServerId", mediaServerItem.getId()); 568 subscribeKey.put("mediaServerId", mediaServerItem.getId());
589 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 569 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
590 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, 570 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
591 - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ 571 + (MediaServerItem mediaServerItemInUse, JSONObject json)->{
592 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; 572 if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return;
593 event.response(mediaServerItemInUse, json); 573 event.response(mediaServerItemInUse, json);
594 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); 574 subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
@@ -609,11 +589,11 @@ public class SIPCommander implements ISIPCommander { @@ -609,11 +589,11 @@ public class SIPCommander implements ISIPCommander {
609 589
610 if (userSetup.isSeniorSdp()) { 590 if (userSetup.isSeniorSdp()) {
611 if("TCP-PASSIVE".equals(streamMode)) { 591 if("TCP-PASSIVE".equals(streamMode)) {
612 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); 592 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
613 }else if ("TCP-ACTIVE".equals(streamMode)) { 593 }else if ("TCP-ACTIVE".equals(streamMode)) {
614 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); 594 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n");
615 }else if("UDP".equals(streamMode)) { 595 }else if("UDP".equals(streamMode)) {
616 - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); 596 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n");
617 } 597 }
618 content.append("a=recvonly\r\n"); 598 content.append("a=recvonly\r\n");
619 content.append("a=rtpmap:96 PS/90000\r\n"); 599 content.append("a=rtpmap:96 PS/90000\r\n");
@@ -634,11 +614,11 @@ public class SIPCommander implements ISIPCommander { @@ -634,11 +614,11 @@ public class SIPCommander implements ISIPCommander {
634 } 614 }
635 }else { 615 }else {
636 if("TCP-PASSIVE".equals(streamMode)) { 616 if("TCP-PASSIVE".equals(streamMode)) {
637 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); 617 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
638 }else if ("TCP-ACTIVE".equals(streamMode)) { 618 }else if ("TCP-ACTIVE".equals(streamMode)) {
639 - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); 619 + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n");
640 }else if("UDP".equals(streamMode)) { 620 }else if("UDP".equals(streamMode)) {
641 - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); 621 + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n");
642 } 622 }
643 content.append("a=recvonly\r\n"); 623 content.append("a=recvonly\r\n");
644 content.append("a=rtpmap:96 PS/90000\r\n"); 624 content.append("a=rtpmap:96 PS/90000\r\n");
@@ -654,7 +634,7 @@ public class SIPCommander implements ISIPCommander { @@ -654,7 +634,7 @@ public class SIPCommander implements ISIPCommander {
654 } 634 }
655 content.append("a=downloadspeed:" + downloadSpeed + "\r\n"); 635 content.append("a=downloadspeed:" + downloadSpeed + "\r\n");
656 636
657 - content.append("y="+ssrc+"\r\n");//ssrc 637 + content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
658 638
659 String tm = Long.toString(System.currentTimeMillis()); 639 String tm = Long.toString(System.currentTimeMillis());
660 640
@@ -664,7 +644,7 @@ public class SIPCommander implements ISIPCommander { @@ -664,7 +644,7 @@ public class SIPCommander implements ISIPCommander {
664 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader); 644 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader);
665 645
666 ClientTransaction transaction = transmitRequest(device, request, errorEvent); 646 ClientTransaction transaction = transmitRequest(device, request, errorEvent);
667 - streamSession.put(device.getDeviceId(), channelId, ssrc, streamId, transaction); 647 + streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), transaction);
668 648
669 } catch ( SipException | ParseException | InvalidArgumentException e) { 649 } catch ( SipException | ParseException | InvalidArgumentException e) {
670 e.printStackTrace(); 650 e.printStackTrace();
@@ -684,53 +664,35 @@ public class SIPCommander implements ISIPCommander { @@ -684,53 +664,35 @@ public class SIPCommander implements ISIPCommander {
684 */ 664 */
685 @Override 665 @Override
686 public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) { 666 public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) {
687 - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);  
688 try { 667 try {
689 ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); 668 ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId);
690 - // 服务重启后, 无法直接发送bye, 通过手动构建发送  
691 -// if (transaction == null) {  
692 -//  
693 -// if (streamInfo != null) {  
694 -// MediaServerItem mediaServerItem = redisCatchStorage.getMediaInfo(streamInfo.getMediaServerId());  
695 -// JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem,streamInfo.getApp(), streamInfo.getStreamId());  
696 -// if (mediaList != null) { // 仍在推流才发送  
697 -// if (mediaList.getInteger("code") == 0) {  
698 -// JSONArray data = mediaList.getJSONArray("data");  
699 -// if (data != null && data.size() > 0) {  
700 -// Device device = storager.queryVideoDevice(deviceId);  
701 -// if (device != null) {  
702 -// StreamInfo.TransactionInfo transactionInfo = streamInfo.getTransactionInfo();  
703 -// try {  
704 -// Request byteRequest = headerProvider.createByteRequest(device, channelId,  
705 -// transactionInfo.branch,  
706 -// transactionInfo.localTag,  
707 -// transactionInfo.remoteTag,  
708 -// transactionInfo.callId);  
709 -// transmitRequest(device, byteRequest);  
710 -// } catch (InvalidArgumentException e) {  
711 -// e.printStackTrace();  
712 -// }  
713 -// }  
714 -// }  
715 -// }  
716 -// }  
717 -// redisCatchStorage.stopPlay(streamInfo);  
718 -// }  
719 -//  
720 -// if (okEvent != null) {  
721 -// okEvent.response(null);  
722 -// }  
723 -// return;  
724 -// }  
725 if (transaction == null) { 669 if (transaction == null) {
726 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId); 670 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId);
727 return; 671 return;
728 } 672 }
729 - Dialog dialog = transaction.getDialog(); 673 + SIPDialog dialog = streamSession.getDialog(deviceId, channelId);
730 if (dialog == null) { 674 if (dialog == null) {
731 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId); 675 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId);
732 return; 676 return;
733 } 677 }
  678 + SipStack sipStack = udpSipProvider.getSipStack();
  679 + SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog);
  680 + if (dialog != sipDialog) {
  681 + dialog = sipDialog;
  682 + }else {
  683 + dialog.setSipProvider(udpSipProvider);
  684 + try {
  685 + Field sipStackField = SIPDialog.class.getDeclaredField("sipStack");
  686 + sipStackField.setAccessible(true);
  687 + sipStackField.set(dialog, sipStack);
  688 + Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners");
  689 + eventListenersField.setAccessible(true);
  690 + eventListenersField.set(dialog, new HashSet<>());
  691 + } catch (NoSuchFieldException | IllegalAccessException e) {
  692 + e.printStackTrace();
  693 + }
  694 + }
  695 +
734 Request byeRequest = dialog.createRequest(Request.BYE); 696 Request byeRequest = dialog.createRequest(Request.BYE);
735 SipURI byeURI = (SipURI) byeRequest.getRequestURI(); 697 SipURI byeURI = (SipURI) byeRequest.getRequestURI();
736 SIPRequest request = (SIPRequest)transaction.getRequest(); 698 SIPRequest request = (SIPRequest)transaction.getRequest();
@@ -752,7 +714,12 @@ public class SIPCommander implements ISIPCommander { @@ -752,7 +714,12 @@ public class SIPCommander implements ISIPCommander {
752 714
753 dialog.sendRequest(clientTransaction); 715 dialog.sendRequest(clientTransaction);
754 716
755 - streamSession.remove(deviceId, channelId); 717 + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId);
  718 + if (ssrcTransaction != null) {
  719 + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
  720 + mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc());
  721 + streamSession.remove(deviceId, channelId);
  722 + }
756 } catch (SipException | ParseException e) { 723 } catch (SipException | ParseException e) {
757 e.printStackTrace(); 724 e.printStackTrace();
758 } 725 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
@@ -13,7 +13,6 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -13,7 +13,6 @@ 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; 16 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
18 import com.genersoft.iot.vmp.service.IMediaServerService; 17 import com.genersoft.iot.vmp.service.IMediaServerService;
19 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 18 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -81,7 +80,7 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { @@ -81,7 +80,7 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
81 while (!rtpPushed) { 80 while (!rtpPushed) {
82 try { 81 try {
83 if (System.currentTimeMillis() - startTime < 30 * 1000) { 82 if (System.currentTimeMillis() - startTime < 30 * 1000) {
84 - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 83 + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
85 if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) { 84 if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) {
86 rtpPushed = true; 85 rtpPushed = true;
87 logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]", 86 logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
@@ -15,7 +15,6 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; @@ -15,7 +15,6 @@ 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; 18 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
20 import com.genersoft.iot.vmp.service.IMediaServerService; 19 import com.genersoft.iot.vmp.service.IMediaServerService;
21 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -65,7 +64,7 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { @@ -65,7 +64,7 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
65 param.put("stream",streamId); 64 param.put("stream",streamId);
66 param.put("ssrc",sendRtpItem.getSsrc()); 65 param.put("ssrc",sendRtpItem.getSsrc());
67 logger.info("停止向上级推流:" + streamId); 66 logger.info("停止向上级推流:" + streamId);
68 - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 67 + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
69 zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); 68 zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
70 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); 69 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
71 if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) { 70 if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
@@ -11,14 +11,11 @@ import javax.sip.header.*; @@ -11,14 +11,11 @@ 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;  
15 -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;  
16 import com.genersoft.iot.vmp.gb28181.bean.*; 14 import com.genersoft.iot.vmp.gb28181.bean.*;
17 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
18 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 16 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
19 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; 17 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
20 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 18 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; 19 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
23 import com.genersoft.iot.vmp.service.IMediaServerService; 20 import com.genersoft.iot.vmp.service.IMediaServerService;
24 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 21 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -97,7 +94,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { @@ -97,7 +94,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
97 // 查询平台下是否有该通道 94 // 查询平台下是否有该通道
98 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); 95 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
99 GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); 96 GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
100 - IMediaServerItem mediaServerItem = null; 97 + MediaServerItem mediaServerItem = null;
101 // 不是通道可能是直播流 98 // 不是通道可能是直播流
102 if (channel != null && gbStream == null ) { 99 if (channel != null && gbStream == null ) {
103 if (channel.getStatus() == 0) { 100 if (channel.getStatus() == 0) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
@@ -3,14 +3,18 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl; @@ -3,14 +3,18 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
3 import java.text.ParseException; 3 import java.text.ParseException;
4 4
5 import javax.sip.*; 5 import javax.sip.*;
  6 +import javax.sip.address.Address;
6 import javax.sip.address.SipURI; 7 import javax.sip.address.SipURI;
7 import javax.sip.header.CSeqHeader; 8 import javax.sip.header.CSeqHeader;
8 import javax.sip.message.Request; 9 import javax.sip.message.Request;
9 import javax.sip.message.Response; 10 import javax.sip.message.Response;
10 11
  12 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
11 import gov.nist.javax.sip.ResponseEventExt; 13 import gov.nist.javax.sip.ResponseEventExt;
  14 +import gov.nist.javax.sip.stack.SIPDialog;
12 import org.slf4j.Logger; 15 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory; 16 import org.slf4j.LoggerFactory;
  17 +import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.stereotype.Component; 18 import org.springframework.stereotype.Component;
15 19
16 import com.genersoft.iot.vmp.conf.SipConfig; 20 import com.genersoft.iot.vmp.conf.SipConfig;
@@ -28,6 +32,9 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { @@ -28,6 +32,9 @@ public class InviteResponseProcessor implements ISIPResponseProcessor {
28 32
29 private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class); 33 private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class);
30 34
  35 + @Autowired
  36 + private VideoStreamSessionManager streamSession;
  37 +
31 /** 38 /**
32 * 处理invite响应 39 * 处理invite响应
33 * 40 *
@@ -46,7 +53,7 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { @@ -46,7 +53,7 @@ public class InviteResponseProcessor implements ISIPResponseProcessor {
46 // 下发ack 53 // 下发ack
47 if (statusCode == Response.OK) { 54 if (statusCode == Response.OK) {
48 ResponseEventExt event = (ResponseEventExt)evt; 55 ResponseEventExt event = (ResponseEventExt)evt;
49 - Dialog dialog = evt.getDialog(); 56 + SIPDialog dialog = (SIPDialog)evt.getDialog();
50 CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); 57 CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
51 Request reqAck = dialog.createAck(cseq.getSeqNumber()); 58 Request reqAck = dialog.createAck(cseq.getSeqNumber());
52 SipURI requestURI = (SipURI) reqAck.getRequestURI(); 59 SipURI requestURI = (SipURI) reqAck.getRequestURI();
@@ -54,7 +61,12 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { @@ -54,7 +61,12 @@ public class InviteResponseProcessor implements ISIPResponseProcessor {
54 requestURI.setPort(event.getRemotePort()); 61 requestURI.setPort(event.getRemotePort());
55 reqAck.setRequestURI(requestURI); 62 reqAck.setRequestURI(requestURI);
56 logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack"); 63 logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack");
  64 + SipURI sipURI = (SipURI)dialog.getRemoteParty().getURI();
  65 + String deviceId = requestURI.getUser();
  66 + String channelId = sipURI.getUser();
  67 +
57 dialog.sendAck(reqAck); 68 dialog.sendAck(reqAck);
  69 +
58 } 70 }
59 } catch (InvalidArgumentException | SipException e) { 71 } catch (InvalidArgumentException | SipException e) {
60 e.printStackTrace(); 72 e.printStackTrace();
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -3,15 +3,14 @@ package com.genersoft.iot.vmp.media.zlm; @@ -3,15 +3,14 @@ package com.genersoft.iot.vmp.media.zlm;
3 import java.util.List; 3 import java.util.List;
4 import java.util.UUID; 4 import java.util.UUID;
5 5
6 -import com.alibaba.fastjson.JSON;  
7 import com.alibaba.fastjson.JSONArray; 6 import com.alibaba.fastjson.JSONArray;
8 import com.genersoft.iot.vmp.common.StreamInfo; 7 import com.genersoft.iot.vmp.common.StreamInfo;
9 import com.genersoft.iot.vmp.conf.MediaConfig; 8 import com.genersoft.iot.vmp.conf.MediaConfig;
10 import com.genersoft.iot.vmp.conf.UserSetup; 9 import com.genersoft.iot.vmp.conf.UserSetup;
11 import com.genersoft.iot.vmp.gb28181.bean.Device; 10 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; 11 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
14 import com.genersoft.iot.vmp.service.IMediaServerService; 12 import com.genersoft.iot.vmp.service.IMediaServerService;
  13 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
16 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 15 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
17 import com.genersoft.iot.vmp.service.IPlayService; 16 import com.genersoft.iot.vmp.service.IPlayService;
@@ -42,7 +41,6 @@ public class ZLMHttpHookListener { @@ -42,7 +41,6 @@ public class ZLMHttpHookListener {
42 41
43 private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); 42 private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class);
44 43
45 -  
46 @Autowired 44 @Autowired
47 private SIPCommander cmder; 45 private SIPCommander cmder;
48 46
@@ -125,7 +123,7 @@ public class ZLMHttpHookListener { @@ -125,7 +123,7 @@ public class ZLMHttpHookListener {
125 String mediaServerId = json.getString("mediaServerId"); 123 String mediaServerId = json.getString("mediaServerId");
126 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json); 124 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json);
127 if (subscribe != null ) { 125 if (subscribe != null ) {
128 - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 126 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
129 if (mediaInfo != null) { 127 if (mediaInfo != null) {
130 subscribe.response(mediaInfo, json); 128 subscribe.response(mediaInfo, json);
131 } 129 }
@@ -150,7 +148,7 @@ public class ZLMHttpHookListener { @@ -150,7 +148,7 @@ public class ZLMHttpHookListener {
150 String mediaServerId = json.getString("mediaServerId"); 148 String mediaServerId = json.getString("mediaServerId");
151 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); 149 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json);
152 if (subscribe != null) { 150 if (subscribe != null) {
153 - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 151 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
154 if (mediaInfo != null) { 152 if (mediaInfo != null) {
155 subscribe.response(mediaInfo, json); 153 subscribe.response(mediaInfo, json);
156 } 154 }
@@ -237,7 +235,7 @@ public class ZLMHttpHookListener { @@ -237,7 +235,7 @@ public class ZLMHttpHookListener {
237 String mediaServerId = json.getString("mediaServerId"); 235 String mediaServerId = json.getString("mediaServerId");
238 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json); 236 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json);
239 if (subscribe != null ) { 237 if (subscribe != null ) {
240 - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 238 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
241 if (mediaInfo != null) { 239 if (mediaInfo != null) {
242 subscribe.response(mediaInfo, json); 240 subscribe.response(mediaInfo, json);
243 } 241 }
@@ -264,7 +262,7 @@ public class ZLMHttpHookListener { @@ -264,7 +262,7 @@ public class ZLMHttpHookListener {
264 String mediaServerId = json.getString("mediaServerId"); 262 String mediaServerId = json.getString("mediaServerId");
265 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json); 263 ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json);
266 if (subscribe != null ) { 264 if (subscribe != null ) {
267 - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 265 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
268 if (mediaInfo != null) { 266 if (mediaInfo != null) {
269 subscribe.response(mediaInfo, json); 267 subscribe.response(mediaInfo, json);
270 } 268 }
@@ -297,7 +295,7 @@ public class ZLMHttpHookListener { @@ -297,7 +295,7 @@ public class ZLMHttpHookListener {
297 } 295 }
298 }else { 296 }else {
299 if (!"rtp".equals(app) ){ 297 if (!"rtp".equals(app) ){
300 - IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); 298 + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
301 if (regist) { 299 if (regist) {
302 zlmMediaListManager.addMedia(mediaServerItem, app, streamId); 300 zlmMediaListManager.addMedia(mediaServerItem, app, streamId);
303 }else { 301 }else {
@@ -369,7 +367,7 @@ public class ZLMHttpHookListener { @@ -369,7 +367,7 @@ public class ZLMHttpHookListener {
369 logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString()); 367 logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString());
370 } 368 }
371 String mediaServerId = json.getString("mediaServerId"); 369 String mediaServerId = json.getString("mediaServerId");
372 - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 370 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
373 if (userSetup.isAutoApplyPlay() && mediaInfo != null) { 371 if (userSetup.isAutoApplyPlay() && mediaInfo != null) {
374 String app = json.getString("app"); 372 String app = json.getString("app");
375 String streamId = json.getString("stream"); 373 String streamId = json.getString("stream");
@@ -381,7 +379,13 @@ public class ZLMHttpHookListener { @@ -381,7 +379,13 @@ public class ZLMHttpHookListener {
381 Device device = storager.queryVideoDevice(deviceId); 379 Device device = storager.queryVideoDevice(deviceId);
382 if (device != null) { 380 if (device != null) {
383 UUID uuid = UUID.randomUUID(); 381 UUID uuid = UUID.randomUUID();
384 - cmder.playStreamCmd(mediaInfo, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> { 382 + SSRCInfo ssrcInfo;
  383 + String streamId2 = null;
  384 + if (mediaInfo.isRtpEnable()) {
  385 + streamId2 = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
  386 + }
  387 + ssrcInfo = mediaServerService.openRTPServer(mediaInfo, streamId2);
  388 + cmder.playStreamCmd(mediaInfo, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
385 logger.info("收到订阅消息: " + response.toJSONString()); 389 logger.info("收到订阅消息: " + response.toJSONString());
386 playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); 390 playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());
387 }, null); 391 }, null);
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 com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import org.springframework.stereotype.Component; 5 import org.springframework.stereotype.Component;
7 6
@@ -32,7 +31,7 @@ public class ZLMHttpHookSubscribe { @@ -32,7 +31,7 @@ public class ZLMHttpHookSubscribe {
32 } 31 }
33 32
34 public interface Event{ 33 public interface Event{
35 - void response(IMediaServerItem mediaServerItem, JSONObject response); 34 + void response(MediaServerItem mediaServerItem, JSONObject response);
36 } 35 }
37 36
38 private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); 37 private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>();
@@ -58,6 +57,9 @@ public class ZLMHttpHookSubscribe { @@ -58,6 +57,9 @@ public class ZLMHttpHookSubscribe {
58 if (result == null) { 57 if (result == null) {
59 result = key.getString(s).equals(hookResponse.getString(s)); 58 result = key.getString(s).equals(hookResponse.getString(s));
60 }else { 59 }else {
  60 + if (key.getString(s) == null) {
  61 + continue;
  62 + }
61 result = result && key.getString(s).equals(hookResponse.getString(s)); 63 result = result && key.getString(s).equals(hookResponse.getString(s));
62 } 64 }
63 65
@@ -83,9 +85,9 @@ public class ZLMHttpHookSubscribe { @@ -83,9 +85,9 @@ public class ZLMHttpHookSubscribe {
83 if (result == null) { 85 if (result == null) {
84 result = key.getString(s).equals(hookResponse.getString(s)); 86 result = key.getString(s).equals(hookResponse.getString(s));
85 }else { 87 }else {
  88 + if (key.getString(s) == null) continue;
86 result = result && key.getString(s).equals(hookResponse.getString(s)); 89 result = result && key.getString(s).equals(hookResponse.getString(s));
87 } 90 }
88 -  
89 } 91 }
90 if (null != result && result){ 92 if (null != result && result){
91 iterator.remove(); 93 iterator.remove();
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
1 package com.genersoft.iot.vmp.media.zlm; 1 package com.genersoft.iot.vmp.media.zlm;
2 2
3 -import com.alibaba.fastjson.JSONArray;  
4 import com.alibaba.fastjson.JSONObject; 3 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; 4 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
8 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
9 -import com.genersoft.iot.vmp.gb28181.bean.GbStream;  
10 import com.genersoft.iot.vmp.service.IStreamPushService; 7 import com.genersoft.iot.vmp.service.IStreamPushService;
11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 8 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
12 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 9 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
@@ -76,7 +73,7 @@ public class ZLMMediaListManager { @@ -76,7 +73,7 @@ public class ZLMMediaListManager {
76 jsonObject.put("stream", streamPushItem.getStream()); 73 jsonObject.put("stream", streamPushItem.getStream());
77 jsonObject.put("mediaServerId", mediaServerItem.getId()); 74 jsonObject.put("mediaServerId", mediaServerItem.getId());
78 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject, 75 subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject,
79 - (IMediaServerItem mediaServerItemInuse, JSONObject response)->{ 76 + (MediaServerItem mediaServerItemInuse, JSONObject response)->{
80 updateMedia(mediaServerItem, response.getString("app"), response.getString("stream")); 77 updateMedia(mediaServerItem, response.getString("app"), response.getString("stream"));
81 } 78 }
82 ); 79 );
@@ -86,13 +83,13 @@ public class ZLMMediaListManager { @@ -86,13 +83,13 @@ public class ZLMMediaListManager {
86 83
87 } 84 }
88 85
89 - public void addMedia(IMediaServerItem mediaServerItem, String app, String streamId) { 86 + public void addMedia(MediaServerItem mediaServerItem, String app, String streamId) {
90 //使用异步更新推流 87 //使用异步更新推流
91 updateMedia(mediaServerItem, app, streamId); 88 updateMedia(mediaServerItem, app, streamId);
92 } 89 }
93 90
94 91
95 - public void updateMedia(IMediaServerItem mediaServerItem, String app, String streamId) { 92 + public void updateMedia(MediaServerItem mediaServerItem, String app, String streamId) {
96 //使用异步更新推流 93 //使用异步更新推流
97 zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{ 94 zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{
98 95
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -2,14 +2,11 @@ package com.genersoft.iot.vmp.media.zlm; @@ -2,14 +2,11 @@ package com.genersoft.iot.vmp.media.zlm;
2 2
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;  
6 -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;  
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import okhttp3.*; 6 import okhttp3.*;
9 import org.jetbrains.annotations.NotNull; 7 import org.jetbrains.annotations.NotNull;
10 import org.slf4j.Logger; 8 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 9 import org.slf4j.LoggerFactory;
12 -import org.springframework.beans.factory.annotation.Autowired;  
13 import org.springframework.stereotype.Component; 10 import org.springframework.stereotype.Component;
14 11
15 import java.io.*; 12 import java.io.*;
@@ -27,7 +24,7 @@ public class ZLMRESTfulUtils { @@ -27,7 +24,7 @@ public class ZLMRESTfulUtils {
27 void run(JSONObject response); 24 void run(JSONObject response);
28 } 25 }
29 26
30 - public JSONObject sendPost(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) { 27 + public JSONObject sendPost(MediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) {
31 OkHttpClient client = new OkHttpClient(); 28 OkHttpClient client = new OkHttpClient();
32 String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); 29 String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
33 JSONObject responseJSON = null; 30 JSONObject responseJSON = null;
@@ -93,7 +90,7 @@ public class ZLMRESTfulUtils { @@ -93,7 +90,7 @@ public class ZLMRESTfulUtils {
93 } 90 }
94 91
95 92
96 - public void sendPostForImg(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) { 93 + public void sendPostForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) {
97 OkHttpClient client = new OkHttpClient(); 94 OkHttpClient client = new OkHttpClient();
98 String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); 95 String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
99 JSONObject responseJSON = null; 96 JSONObject responseJSON = null;
@@ -139,7 +136,7 @@ public class ZLMRESTfulUtils { @@ -139,7 +136,7 @@ public class ZLMRESTfulUtils {
139 } 136 }
140 137
141 138
142 - public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream, String schema, RequestCallback callback){ 139 + public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream, String schema, RequestCallback callback){
143 Map<String, Object> param = new HashMap<>(); 140 Map<String, Object> param = new HashMap<>();
144 if (app != null) param.put("app",app); 141 if (app != null) param.put("app",app);
145 if (stream != null) param.put("stream",stream); 142 if (stream != null) param.put("stream",stream);
@@ -148,15 +145,15 @@ public class ZLMRESTfulUtils { @@ -148,15 +145,15 @@ public class ZLMRESTfulUtils {
148 return sendPost(mediaServerItem, "getMediaList",param, callback); 145 return sendPost(mediaServerItem, "getMediaList",param, callback);
149 } 146 }
150 147
151 - public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream){ 148 + public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream){
152 return getMediaList(mediaServerItem, app, stream,null, null); 149 return getMediaList(mediaServerItem, app, stream,null, null);
153 } 150 }
154 151
155 - public JSONObject getMediaList(IMediaServerItem mediaServerItem,RequestCallback callback){ 152 + public JSONObject getMediaList(MediaServerItem mediaServerItem, RequestCallback callback){
156 return sendPost(mediaServerItem, "getMediaList",null, callback); 153 return sendPost(mediaServerItem, "getMediaList",null, callback);
157 } 154 }
158 155
159 - public JSONObject getMediaInfo(IMediaServerItem mediaServerItem,String app, String schema, String stream){ 156 + public JSONObject getMediaInfo(MediaServerItem mediaServerItem, String app, String schema, String stream){
160 Map<String, Object> param = new HashMap<>(); 157 Map<String, Object> param = new HashMap<>();
161 param.put("app",app); 158 param.put("app",app);
162 param.put("schema",schema); 159 param.put("schema",schema);
@@ -165,13 +162,13 @@ public class ZLMRESTfulUtils { @@ -165,13 +162,13 @@ public class ZLMRESTfulUtils {
165 return sendPost(mediaServerItem, "getMediaInfo",param, null); 162 return sendPost(mediaServerItem, "getMediaInfo",param, null);
166 } 163 }
167 164
168 - public JSONObject getRtpInfo(IMediaServerItem mediaServerItem,String stream_id){ 165 + public JSONObject getRtpInfo(MediaServerItem mediaServerItem, String stream_id){
169 Map<String, Object> param = new HashMap<>(); 166 Map<String, Object> param = new HashMap<>();
170 param.put("stream_id",stream_id); 167 param.put("stream_id",stream_id);
171 return sendPost(mediaServerItem, "getRtpInfo",param, null); 168 return sendPost(mediaServerItem, "getRtpInfo",param, null);
172 } 169 }
173 170
174 - public JSONObject addFFmpegSource(IMediaServerItem mediaServerItem,String src_url, String dst_url, String timeout_ms, 171 + public JSONObject addFFmpegSource(MediaServerItem mediaServerItem, String src_url, String dst_url, String timeout_ms,
175 boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){ 172 boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){
176 logger.info(src_url); 173 logger.info(src_url);
177 logger.info(dst_url); 174 logger.info(dst_url);
@@ -185,41 +182,41 @@ public class ZLMRESTfulUtils { @@ -185,41 +182,41 @@ public class ZLMRESTfulUtils {
185 return sendPost(mediaServerItem, "addFFmpegSource",param, null); 182 return sendPost(mediaServerItem, "addFFmpegSource",param, null);
186 } 183 }
187 184
188 - public JSONObject delFFmpegSource(IMediaServerItem mediaServerItem,String key){ 185 + public JSONObject delFFmpegSource(MediaServerItem mediaServerItem, String key){
189 Map<String, Object> param = new HashMap<>(); 186 Map<String, Object> param = new HashMap<>();
190 param.put("key", key); 187 param.put("key", key);
191 return sendPost(mediaServerItem, "delFFmpegSource",param, null); 188 return sendPost(mediaServerItem, "delFFmpegSource",param, null);
192 } 189 }
193 190
194 - public JSONObject getMediaServerConfig(IMediaServerItem mediaServerItem){ 191 + public JSONObject getMediaServerConfig(MediaServerItem mediaServerItem){
195 return sendPost(mediaServerItem, "getServerConfig",null, null); 192 return sendPost(mediaServerItem, "getServerConfig",null, null);
196 } 193 }
197 194
198 - public JSONObject setServerConfig(IMediaServerItem mediaServerItem, Map<String, Object> param){ 195 + public JSONObject setServerConfig(MediaServerItem mediaServerItem, Map<String, Object> param){
199 return sendPost(mediaServerItem,"setServerConfig",param, null); 196 return sendPost(mediaServerItem,"setServerConfig",param, null);
200 } 197 }
201 198
202 - public JSONObject openRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param){ 199 + public JSONObject openRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param){
203 return sendPost(mediaServerItem, "openRtpServer",param, null); 200 return sendPost(mediaServerItem, "openRtpServer",param, null);
204 } 201 }
205 202
206 - public JSONObject closeRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param) { 203 + public JSONObject closeRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param) {
207 return sendPost(mediaServerItem, "closeRtpServer",param, null); 204 return sendPost(mediaServerItem, "closeRtpServer",param, null);
208 } 205 }
209 206
210 - public JSONObject listRtpServer(IMediaServerItem mediaServerItem) { 207 + public JSONObject listRtpServer(MediaServerItem mediaServerItem) {
211 return sendPost(mediaServerItem, "listRtpServer",null, null); 208 return sendPost(mediaServerItem, "listRtpServer",null, null);
212 } 209 }
213 210
214 - public JSONObject startSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) { 211 + public JSONObject startSendRtp(MediaServerItem mediaServerItem, Map<String, Object> param) {
215 return sendPost(mediaServerItem, "startSendRtp",param, null); 212 return sendPost(mediaServerItem, "startSendRtp",param, null);
216 } 213 }
217 214
218 - public JSONObject stopSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) { 215 + public JSONObject stopSendRtp(MediaServerItem mediaServerItem, Map<String, Object> param) {
219 return sendPost(mediaServerItem, "stopSendRtp",param, null); 216 return sendPost(mediaServerItem, "stopSendRtp",param, null);
220 } 217 }
221 218
222 - public JSONObject addStreamProxy(IMediaServerItem mediaServerItem,String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) { 219 + public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) {
223 Map<String, Object> param = new HashMap<>(); 220 Map<String, Object> param = new HashMap<>();
224 param.put("vhost", "__defaultVhost__"); 221 param.put("vhost", "__defaultVhost__");
225 param.put("app", app); 222 param.put("app", app);
@@ -231,7 +228,7 @@ public class ZLMRESTfulUtils { @@ -231,7 +228,7 @@ public class ZLMRESTfulUtils {
231 return sendPost(mediaServerItem, "addStreamProxy",param, null); 228 return sendPost(mediaServerItem, "addStreamProxy",param, null);
232 } 229 }
233 230
234 - public JSONObject closeStreams(IMediaServerItem mediaServerItem,String app, String stream) { 231 + public JSONObject closeStreams(MediaServerItem mediaServerItem, String app, String stream) {
235 Map<String, Object> param = new HashMap<>(); 232 Map<String, Object> param = new HashMap<>();
236 param.put("vhost", "__defaultVhost__"); 233 param.put("vhost", "__defaultVhost__");
237 param.put("app", app); 234 param.put("app", app);
@@ -240,17 +237,17 @@ public class ZLMRESTfulUtils { @@ -240,17 +237,17 @@ public class ZLMRESTfulUtils {
240 return sendPost(mediaServerItem, "close_streams",param, null); 237 return sendPost(mediaServerItem, "close_streams",param, null);
241 } 238 }
242 239
243 - public JSONObject getAllSession(IMediaServerItem mediaServerItem) { 240 + public JSONObject getAllSession(MediaServerItem mediaServerItem) {
244 return sendPost(mediaServerItem, "getAllSession",null, null); 241 return sendPost(mediaServerItem, "getAllSession",null, null);
245 } 242 }
246 243
247 - public void kickSessions(IMediaServerItem mediaServerItem, String localPortSStr) { 244 + public void kickSessions(MediaServerItem mediaServerItem, String localPortSStr) {
248 Map<String, Object> param = new HashMap<>(); 245 Map<String, Object> param = new HashMap<>();
249 param.put("local_port", localPortSStr); 246 param.put("local_port", localPortSStr);
250 sendPost(mediaServerItem, "kick_sessions",param, null); 247 sendPost(mediaServerItem, "kick_sessions",param, null);
251 } 248 }
252 249
253 - public void getSnap(IMediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { 250 + public void getSnap(MediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) {
254 Map<String, Object> param = new HashMap<>(); 251 Map<String, Object> param = new HashMap<>();
255 param.put("url", flvUrl); 252 param.put("url", flvUrl);
256 param.put("timeout_sec", timeout_sec); 253 param.put("timeout_sec", timeout_sec);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -2,10 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; @@ -2,10 +2,7 @@ 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.conf.MediaConfig;  
6 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 5 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
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; 6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
10 import org.slf4j.Logger; 7 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 8 import org.slf4j.LoggerFactory;
@@ -21,28 +18,19 @@ public class ZLMRTPServerFactory { @@ -21,28 +18,19 @@ public class ZLMRTPServerFactory {
21 private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory"); 18 private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory");
22 19
23 @Autowired 20 @Autowired
24 - private MediaConfig mediaConfig;  
25 -  
26 - @Autowired  
27 private ZLMRESTfulUtils zlmresTfulUtils; 21 private ZLMRESTfulUtils zlmresTfulUtils;
28 22
29 private int[] portRangeArray = new int[2]; 23 private int[] portRangeArray = new int[2];
30 24
31 - private int currentPort = 0;  
32 -  
33 - private Map<String, Integer> currentStreams = null;  
34 -  
35 - public int createRTPServer(IMediaServerItem mediaServerItem, String streamId) {  
36 - if (currentStreams == null) {  
37 - currentStreams = new HashMap<>();  
38 - JSONObject jsonObject = zlmresTfulUtils.listRtpServer(mediaServerItem);  
39 - if (jsonObject != null) {  
40 - JSONArray data = jsonObject.getJSONArray("data");  
41 - if (data != null) {  
42 - for (int i = 0; i < data.size(); i++) {  
43 - JSONObject dataItem = data.getJSONObject(i);  
44 - currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port"));  
45 - } 25 + public int createRTPServer(MediaServerItem mediaServerItem, String streamId) {
  26 + Map<String, Integer> currentStreams = new HashMap<>();
  27 + JSONObject listRtpServerJsonResult = zlmresTfulUtils.listRtpServer(mediaServerItem);
  28 + if (listRtpServerJsonResult != null) {
  29 + JSONArray data = listRtpServerJsonResult.getJSONArray("data");
  30 + if (data != null) {
  31 + for (int i = 0; i < data.size(); i++) {
  32 + JSONObject dataItem = data.getJSONObject(i);
  33 + currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port"));
46 } 34 }
47 } 35 }
48 } 36 }
@@ -56,18 +44,18 @@ public class ZLMRTPServerFactory { @@ -56,18 +44,18 @@ public class ZLMRTPServerFactory {
56 44
57 Map<String, Object> param = new HashMap<>(); 45 Map<String, Object> param = new HashMap<>();
58 int result = -1; 46 int result = -1;
59 - int newPort = getPortFromportRange(); 47 + int newPort = getPortFromportRange(mediaServerItem);
60 param.put("port", newPort); 48 param.put("port", newPort);
61 param.put("enable_tcp", 1); 49 param.put("enable_tcp", 1);
62 param.put("stream_id", streamId); 50 param.put("stream_id", streamId);
63 - JSONObject jsonObject = zlmresTfulUtils.openRtpServer(mediaServerItem, param); 51 + JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
64 52
65 - if (jsonObject != null) {  
66 - switch (jsonObject.getInteger("code")){ 53 + if (openRtpServerResultJson != null) {
  54 + switch (openRtpServerResultJson.getInteger("code")){
67 case 0: 55 case 0:
68 result= newPort; 56 result= newPort;
69 break; 57 break;
70 - case -300: // id已经存在, 可能已经在其他端口推流 58 + case -300: // id已经存在, 可能已经在其他端口推流, TODO 也可能是设备不等ack就直接推流了, 需要查询与设置的推流ip端口是否一致
71 Map<String, Object> closeRtpServerParam = new HashMap<>(); 59 Map<String, Object> closeRtpServerParam = new HashMap<>();
72 closeRtpServerParam.put("stream_id", streamId); 60 closeRtpServerParam.put("stream_id", streamId);
73 zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam); 61 zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam);
@@ -77,7 +65,7 @@ public class ZLMRTPServerFactory { @@ -77,7 +65,7 @@ public class ZLMRTPServerFactory {
77 result= createRTPServer(mediaServerItem, streamId); 65 result= createRTPServer(mediaServerItem, streamId);
78 break; 66 break;
79 default: 67 default:
80 - logger.error("创建RTP Server 失败 {}: " + jsonObject.getString("msg"), newPort); 68 + logger.error("创建RTP Server 失败 {}: " + openRtpServerResultJson.getString("msg"), newPort);
81 break; 69 break;
82 } 70 }
83 }else { 71 }else {
@@ -87,7 +75,7 @@ public class ZLMRTPServerFactory { @@ -87,7 +75,7 @@ public class ZLMRTPServerFactory {
87 return result; 75 return result;
88 } 76 }
89 77
90 - public boolean closeRTPServer(IMediaServerItem serverItem, String streamId) { 78 + public boolean closeRTPServer(MediaServerItem serverItem, String streamId) {
91 boolean result = false; 79 boolean result = false;
92 if (serverItem !=null){ 80 if (serverItem !=null){
93 Map<String, Object> param = new HashMap<>(); 81 Map<String, Object> param = new HashMap<>();
@@ -107,21 +95,25 @@ public class ZLMRTPServerFactory { @@ -107,21 +95,25 @@ public class ZLMRTPServerFactory {
107 return result; 95 return result;
108 } 96 }
109 97
110 - private int getPortFromportRange() { 98 + private int getPortFromportRange(MediaServerItem mediaServerItem) {
  99 + int currentPort = mediaServerItem.getCurrentPort();
111 if (currentPort == 0) { 100 if (currentPort == 0) {
112 - String[] portRangeStrArray = mediaConfig.getRtpPortRange().split(","); 101 + String[] portRangeStrArray = mediaServerItem.getRtpPortRange().split(",");
113 portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]); 102 portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]);
114 portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]); 103 portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]);
115 } 104 }
116 105
117 if (currentPort == 0 || currentPort++ > portRangeArray[1]) { 106 if (currentPort == 0 || currentPort++ > portRangeArray[1]) {
118 currentPort = portRangeArray[0]; 107 currentPort = portRangeArray[0];
  108 + mediaServerItem.setCurrentPort(currentPort);
119 return portRangeArray[0]; 109 return portRangeArray[0];
120 } else { 110 } else {
121 if (currentPort % 2 == 1) { 111 if (currentPort % 2 == 1) {
122 currentPort++; 112 currentPort++;
123 } 113 }
124 - return currentPort++; 114 + currentPort++;
  115 + mediaServerItem.setCurrentPort(currentPort);
  116 + return currentPort;
125 } 117 }
126 } 118 }
127 119
@@ -135,10 +127,14 @@ public class ZLMRTPServerFactory { @@ -135,10 +127,14 @@ public class ZLMRTPServerFactory {
135 * @param tcp 是否为tcp 127 * @param tcp 是否为tcp
136 * @return SendRtpItem 128 * @return SendRtpItem
137 */ 129 */
138 - public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){  
139 - String playSsrc = SsrcUtil.getPlaySsrc();  
140 - int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc()); 130 + public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){
  131 +
  132 + // 使用RTPServer 功能找一个可用的端口
  133 + String playSsrc = serverItem.getSsrcConfig().getPlaySsrc();
  134 + int localPort = createRTPServer(serverItem, playSsrc);
141 if (localPort != -1) { 135 if (localPort != -1) {
  136 + // TODO 高并发时可能因为未放入缓存而ssrc冲突
  137 + serverItem.getSsrcConfig().releaseSsrc(playSsrc);
142 closeRTPServer(serverItem, playSsrc); 138 closeRTPServer(serverItem, playSsrc);
143 }else { 139 }else {
144 logger.error("没有可用的端口"); 140 logger.error("没有可用的端口");
@@ -168,10 +164,12 @@ public class ZLMRTPServerFactory { @@ -168,10 +164,12 @@ public class ZLMRTPServerFactory {
168 * @param tcp 是否为tcp 164 * @param tcp 是否为tcp
169 * @return SendRtpItem 165 * @return SendRtpItem
170 */ 166 */
171 - public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){  
172 - String playSsrc = SsrcUtil.getPlaySsrc();  
173 - int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc()); 167 + public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
  168 + String playSsrc = serverItem.getSsrcConfig().getPlaySsrc();
  169 + int localPort = createRTPServer(serverItem, playSsrc);
174 if (localPort != -1) { 170 if (localPort != -1) {
  171 + // TODO 高并发时可能因为未放入缓存而ssrc冲突
  172 + serverItem.getSsrcConfig().releaseSsrc(ssrc);
175 closeRTPServer(serverItem, playSsrc); 173 closeRTPServer(serverItem, playSsrc);
176 }else { 174 }else {
177 logger.error("没有可用的端口"); 175 logger.error("没有可用的端口");
@@ -194,7 +192,7 @@ public class ZLMRTPServerFactory { @@ -194,7 +192,7 @@ public class ZLMRTPServerFactory {
194 /** 192 /**
195 * 调用zlm RESTful API —— startSendRtp 193 * 调用zlm RESTful API —— startSendRtp
196 */ 194 */
197 - public Boolean startSendRtpStream(IMediaServerItem mediaServerItem, Map<String, Object>param) { 195 + public Boolean startSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) {
198 Boolean result = false; 196 Boolean result = false;
199 JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param); 197 JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param);
200 if (jsonObject == null) { 198 if (jsonObject == null) {
@@ -219,7 +217,7 @@ public class ZLMRTPServerFactory { @@ -219,7 +217,7 @@ public class ZLMRTPServerFactory {
219 /** 217 /**
220 * 查询待转推的流是否就绪 218 * 查询待转推的流是否就绪
221 */ 219 */
222 - public Boolean isStreamReady(IMediaServerItem mediaServerItem, String app, String streamId) { 220 + public Boolean isStreamReady(MediaServerItem mediaServerItem, String app, String streamId) {
223 JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); 221 JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
224 return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")); 222 return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
225 } 223 }
@@ -229,7 +227,7 @@ public class ZLMRTPServerFactory { @@ -229,7 +227,7 @@ public class ZLMRTPServerFactory {
229 * @param streamId 227 * @param streamId
230 * @return 228 * @return
231 */ 229 */
232 - public int totalReaderCount(IMediaServerItem mediaServerItem, String app, String streamId) { 230 + public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) {
233 JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); 231 JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
234 return mediaInfo.getInteger("totalReaderCount"); 232 return mediaInfo.getInteger("totalReaderCount");
235 } 233 }
@@ -237,7 +235,7 @@ public class ZLMRTPServerFactory { @@ -237,7 +235,7 @@ public class ZLMRTPServerFactory {
237 /** 235 /**
238 * 调用zlm RESTful API —— stopSendRtp 236 * 调用zlm RESTful API —— stopSendRtp
239 */ 237 */
240 - public Boolean stopSendRtpStream(IMediaServerItem mediaServerItem,Map<String, Object>param) { 238 + public Boolean stopSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) {
241 Boolean result = false; 239 Boolean result = false;
242 JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param); 240 JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param);
243 if (jsonObject == null) { 241 if (jsonObject == null) {
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -4,22 +4,16 @@ import com.alibaba.fastjson.JSON; @@ -4,22 +4,16 @@ 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.MediaServerItem;
9 -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;  
10 import com.genersoft.iot.vmp.service.IMediaServerService; 8 import com.genersoft.iot.vmp.service.IMediaServerService;
11 -import com.genersoft.iot.vmp.storager.IVideoManagerStorager;  
12 import com.genersoft.iot.vmp.service.IStreamProxyService; 9 import com.genersoft.iot.vmp.service.IStreamProxyService;
13 import org.slf4j.Logger; 10 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
15 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
16 -import org.springframework.beans.factory.annotation.Value;  
17 import org.springframework.boot.CommandLineRunner; 13 import org.springframework.boot.CommandLineRunner;
18 import org.springframework.core.annotation.Order; 14 import org.springframework.core.annotation.Order;
19 import org.springframework.stereotype.Component; 15 import org.springframework.stereotype.Component;
20 -import org.springframework.util.StringUtils;  
21 16
22 -import javax.print.attribute.standard.Media;  
23 import java.util.*; 17 import java.util.*;
24 18
25 @Component 19 @Component
@@ -47,16 +41,26 @@ public class ZLMRunner implements CommandLineRunner { @@ -47,16 +41,26 @@ public class ZLMRunner implements CommandLineRunner {
47 41
48 @Override 42 @Override
49 public void run(String... strings) throws Exception { 43 public void run(String... strings) throws Exception {
50 - IMediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort( 44 + // 清楚redis缓存的在线zlm信息
  45 + mediaServerService.clearMediaServerForOnline();
  46 +
  47 + // 将配置文件的meida配置写入数据库
  48 + MediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort(
51 mediaConfig.getIp(), mediaConfig.getHttpPort()); 49 mediaConfig.getIp(), mediaConfig.getHttpPort());
52 if (presetMediaServer != null) { 50 if (presetMediaServer != null) {
53 - mediaConfig.setId(presetMediaServer.getId());  
54 - mediaServerService.update(mediaConfig); 51 + MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem();
  52 + mediaSerItem.setId(presetMediaServer.getId());
  53 + mediaServerService.update(mediaSerItem);
  54 + }else {
  55 + if (mediaConfig.getId() != null) {
  56 + MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem();
  57 + mediaServerService.add(mediaSerItem);
  58 + }
55 } 59 }
56 60
57 // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 61 // 订阅 zlm启动事件, 新的zlm也会从这里进入系统
58 hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null, 62 hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null,
59 - (IMediaServerItem mediaServerItem, JSONObject response)->{ 63 + (MediaServerItem mediaServerItem, JSONObject response)->{
60 ZLMServerConfig zlmServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class); 64 ZLMServerConfig zlmServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class);
61 if (zlmServerConfig !=null ) { 65 if (zlmServerConfig !=null ) {
62 startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId()); 66 startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId());
@@ -69,23 +73,25 @@ public class ZLMRunner implements CommandLineRunner { @@ -69,23 +73,25 @@ public class ZLMRunner implements CommandLineRunner {
69 logger.info("等待默认zlm接入..."); 73 logger.info("等待默认zlm接入...");
70 74
71 // 获取所有的zlm, 并开启主动连接 75 // 获取所有的zlm, 并开启主动连接
72 - List<IMediaServerItem> all = mediaServerService.getAll(); 76 + List<MediaServerItem> all = mediaServerService.getAll();
73 if (presetMediaServer == null) { 77 if (presetMediaServer == null) {
74 all.add(mediaConfig.getMediaSerItem()); 78 all.add(mediaConfig.getMediaSerItem());
75 } 79 }
76 - for (IMediaServerItem mediaServerItem : all) { 80 + for (MediaServerItem mediaServerItem : all) {
77 if (startGetMedia == null) startGetMedia = new HashMap<>(); 81 if (startGetMedia == null) startGetMedia = new HashMap<>();
78 startGetMedia.put(mediaServerItem.getId(), true); 82 startGetMedia.put(mediaServerItem.getId(), true);
79 new Thread(() -> { 83 new Thread(() -> {
80 ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem); 84 ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem);
81 if (zlmServerConfig != null) { 85 if (zlmServerConfig != null) {
  86 + zlmServerConfig.setIp(mediaServerItem.getIp());
  87 + zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort());
82 startGetMedia.remove(mediaServerItem.getId()); 88 startGetMedia.remove(mediaServerItem.getId());
83 mediaServerService.handLeZLMServerConfig(zlmServerConfig); 89 mediaServerService.handLeZLMServerConfig(zlmServerConfig);
84 } 90 }
85 }).start(); 91 }).start();
86 } 92 }
87 Timer timer = new Timer(); 93 Timer timer = new Timer();
88 - // 1分钟后未连接到则不再去主动连接 94 + // 2分钟后未连接到则不再去主动连接, TODO 并对重启前使用此在zlm的通道发送bye
89 timer.schedule(new TimerTask() { 95 timer.schedule(new TimerTask() {
90 @Override 96 @Override
91 public void run() { 97 public void run() {
@@ -100,7 +106,7 @@ public class ZLMRunner implements CommandLineRunner { @@ -100,7 +106,7 @@ public class ZLMRunner implements CommandLineRunner {
100 }, 60 * 1000 * 2); 106 }, 60 * 1000 * 2);
101 } 107 }
102 108
103 - public ZLMServerConfig getMediaServerConfig(IMediaServerItem mediaServerItem) { 109 + public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) {
104 if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) return null; 110 if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) return null;
105 JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); 111 JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
106 ZLMServerConfig ZLMServerConfig = null; 112 ZLMServerConfig ZLMServerConfig = null;
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java deleted 100644 → 0
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/MediaServerItem.java
1 package com.genersoft.iot.vmp.media.zlm.dto; 1 package com.genersoft.iot.vmp.media.zlm.dto;
2 2
3 3
  4 +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
4 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 5 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
5 import org.springframework.util.StringUtils; 6 import org.springframework.util.StringUtils;
6 7
7 -public class MediaServerItem implements IMediaServerItem{ 8 +import java.util.HashMap;
  9 +
  10 +public class MediaServerItem{
8 11
9 private String id; 12 private String id;
10 13
@@ -46,9 +49,18 @@ public class MediaServerItem implements IMediaServerItem{ @@ -46,9 +49,18 @@ public class MediaServerItem implements IMediaServerItem{
46 49
47 private String updateTime; 50 private String updateTime;
48 51
49 - private boolean docker; 52 + private boolean defaultServer;
  53 +
  54 + private SsrcConfig ssrcConfig;
  55 +
  56 + private int currentPort;
  57 +
50 58
51 - private int count; 59 + /**
  60 + * 每一台ZLM都有一套独立的SSRC列表
  61 + * 在ApplicationCheckRunner里对mediaServerSsrcMap进行初始化
  62 + */
  63 + private HashMap<String, SsrcConfig> mediaServerSsrcMap;
52 64
53 public MediaServerItem() { 65 public MediaServerItem() {
54 } 66 }
@@ -218,14 +230,12 @@ public class MediaServerItem implements IMediaServerItem{ @@ -218,14 +230,12 @@ public class MediaServerItem implements IMediaServerItem{
218 this.recordAssistPort = recordAssistPort; 230 this.recordAssistPort = recordAssistPort;
219 } 231 }
220 232
221 - @Override  
222 - public boolean isDocker() {  
223 - return docker; 233 + public boolean isDefaultServer() {
  234 + return defaultServer;
224 } 235 }
225 236
226 - @Override  
227 - public void setDocker(boolean docker) {  
228 - this.docker = docker; 237 + public void setDefaultServer(boolean defaultServer) {
  238 + this.defaultServer = defaultServer;
229 } 239 }
230 240
231 public String getCreateTime() { 241 public String getCreateTime() {
@@ -244,11 +254,29 @@ public class MediaServerItem implements IMediaServerItem{ @@ -244,11 +254,29 @@ public class MediaServerItem implements IMediaServerItem{
244 this.updateTime = updateTime; 254 this.updateTime = updateTime;
245 } 255 }
246 256
247 - public int getCount() {  
248 - return count; 257 + public HashMap<String, SsrcConfig> getMediaServerSsrcMap() {
  258 + return mediaServerSsrcMap;
  259 + }
  260 +
  261 + public void setMediaServerSsrcMap(HashMap<String, SsrcConfig> mediaServerSsrcMap) {
  262 + this.mediaServerSsrcMap = mediaServerSsrcMap;
  263 + }
  264 +
  265 + public SsrcConfig getSsrcConfig() {
  266 + return ssrcConfig;
  267 + }
  268 +
  269 + public void setSsrcConfig(SsrcConfig ssrcConfig) {
  270 + this.ssrcConfig = ssrcConfig;
249 } 271 }
250 272
251 - public void setCount(int count) {  
252 - this.count = count; 273 + public int getCurrentPort() {
  274 + return currentPort;
253 } 275 }
  276 +
  277 + public void setCurrentPort(int currentPort) {
  278 + this.currentPort = currentPort;
  279 + }
  280 +
  281 +
254 } 282 }
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -3,8 +3,8 @@ package com.genersoft.iot.vmp.service; @@ -3,8 +3,8 @@ package com.genersoft.iot.vmp.service;
3 import com.genersoft.iot.vmp.conf.MediaConfig; 3 import com.genersoft.iot.vmp.conf.MediaConfig;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 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; 6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  7 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
8 8
9 import java.util.List; 9 import java.util.List;
10 10
@@ -13,11 +13,13 @@ import java.util.List; @@ -13,11 +13,13 @@ import java.util.List;
13 */ 13 */
14 public interface IMediaServerService { 14 public interface IMediaServerService {
15 15
16 - List<IMediaServerItem> getAll(); 16 + List<MediaServerItem> getAll();
17 17
18 - IMediaServerItem getOne(String generalMediaServerId); 18 + List<MediaServerItem> getAllOnline();
19 19
20 - IMediaServerItem getOneByHostAndPort(String host, int port); 20 + MediaServerItem getOne(String generalMediaServerId);
  21 +
  22 + MediaServerItem getOneByHostAndPort(String host, int port);
21 23
22 /** 24 /**
23 * 新的节点加入 25 * 新的节点加入
@@ -26,19 +28,27 @@ public interface IMediaServerService { @@ -26,19 +28,27 @@ public interface IMediaServerService {
26 */ 28 */
27 void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig); 29 void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig);
28 30
29 - void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean b);  
30 -  
31 - IMediaServerItem getMediaServerForMinimumLoad(); 31 + MediaServerItem getMediaServerForMinimumLoad();
32 32
33 - void setZLMConfig(IMediaServerItem mediaServerItem); 33 + void setZLMConfig(MediaServerItem mediaServerItem);
34 34
35 - void init(); 35 + SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId);
36 36
37 void closeRTPServer(Device device, String channelId); 37 void closeRTPServer(Device device, String channelId);
38 38
39 - void update(MediaConfig mediaConfig); 39 + void clearRTPServer(MediaServerItem mediaServerItem);
  40 +
  41 + void update(MediaServerItem mediaSerItem);
40 42
41 void addCount(String mediaServerId); 43 void addCount(String mediaServerId);
42 44
43 void removeCount(String mediaServerId); 45 void removeCount(String mediaServerId);
  46 +
  47 + void releaseSsrc(MediaServerItem mediaServerItem, String ssrc);
  48 +
  49 + void clearMediaServerForOnline();
  50 +
  51 + void add(MediaServerItem mediaSerItem);
  52 +
  53 + void resetOnlineServerItem(MediaServerItem serverItem);
44 } 54 }
src/main/java/com/genersoft/iot/vmp/service/IMediaService.java
@@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.service; @@ -2,7 +2,6 @@ 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 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 6
8 /** 7 /**
@@ -33,7 +32,7 @@ public interface IMediaService { @@ -33,7 +32,7 @@ public interface IMediaService {
33 * @param stream 32 * @param stream
34 * @return 33 * @return
35 */ 34 */
36 - StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaServerItem, String app, String stream, JSONArray tracks); 35 + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, JSONArray tracks);
37 36
38 /** 37 /**
39 * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 38 * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况
@@ -41,5 +40,5 @@ public interface IMediaService { @@ -41,5 +40,5 @@ public interface IMediaService {
41 * @param stream 40 * @param stream
42 * @return 41 * @return
43 */ 42 */
44 - StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr); 43 + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr);
45 } 44 }
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONObject; @@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONObject;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
6 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; 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
9 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 8 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
10 9
@@ -13,10 +12,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; @@ -13,10 +12,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
13 */ 12 */
14 public interface IPlayService { 13 public interface IPlayService {
15 14
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 + void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
  16 + void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
18 17
19 - PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 18 + PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
20 19
21 - IMediaServerItem getNewMediaServerItem(Device device); 20 + MediaServerItem getNewMediaServerItem(Device device);
22 } 21 }
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.MediaServerItem;
6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
7 import com.github.pagehelper.PageInfo; 6 import com.github.pagehelper.PageInfo;
@@ -63,5 +62,5 @@ public interface IStreamProxyService { @@ -63,5 +62,5 @@ public interface IStreamProxyService {
63 * 获取ffmpeg.cmd模板 62 * 获取ffmpeg.cmd模板
64 * @return 63 * @return
65 */ 64 */
66 - JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem); 65 + JSONObject getFFmpegCMDs(MediaServerItem mediaServerItem);
67 } 66 }
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.MediaServerItem;
5 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
6 import com.github.pagehelper.PageInfo; 6 import com.github.pagehelper.PageInfo;
7 7
@@ -9,7 +9,7 @@ import java.util.List; @@ -9,7 +9,7 @@ import java.util.List;
9 9
10 public interface IStreamPushService { 10 public interface IStreamPushService {
11 11
12 - List<StreamPushItem> handleJSON(String json, IMediaServerItem mediaServerItem); 12 + List<StreamPushItem> handleJSON(String json, MediaServerItem mediaServerItem);
13 13
14 /** 14 /**
15 * 将应用名和流ID加入国标关联 15 * 将应用名和流ID加入国标关联
src/main/java/com/genersoft/iot/vmp/service/bean/SSRCInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.bean;
  2 +
  3 +public class SSRCInfo {
  4 +
  5 + private int port;
  6 + private String ssrc;
  7 + private String StreamId;
  8 +
  9 + public SSRCInfo(int port, String ssrc, String streamId) {
  10 + this.port = port;
  11 + this.ssrc = ssrc;
  12 + StreamId = streamId;
  13 + }
  14 +
  15 + public int getPort() {
  16 + return port;
  17 + }
  18 +
  19 + public void setPort(int port) {
  20 + this.port = port;
  21 + }
  22 +
  23 + public String getSsrc() {
  24 + return ssrc;
  25 + }
  26 +
  27 + public void setSsrc(String ssrc) {
  28 + this.ssrc = ssrc;
  29 + }
  30 +
  31 + public String getStreamId() {
  32 + return StreamId;
  33 + }
  34 +
  35 + public void setStreamId(String streamId) {
  36 + StreamId = streamId;
  37 + }
  38 +}
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
1 package com.genersoft.iot.vmp.service.impl; 1 package com.genersoft.iot.vmp.service.impl;
2 2
3 -import com.alibaba.fastjson.JSON;  
4 import com.alibaba.fastjson.JSONArray; 3 import com.alibaba.fastjson.JSONArray;
5 import com.alibaba.fastjson.JSONObject; 4 import com.alibaba.fastjson.JSONObject;
6 -import com.genersoft.iot.vmp.common.StreamInfo; 5 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
7 import com.genersoft.iot.vmp.conf.MediaConfig; 6 import com.genersoft.iot.vmp.conf.MediaConfig;
8 -import com.genersoft.iot.vmp.conf.ProxyServletConfig; 7 +import com.genersoft.iot.vmp.conf.SipConfig;
9 import com.genersoft.iot.vmp.gb28181.bean.Device; 8 import com.genersoft.iot.vmp.gb28181.bean.Device;
  9 +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
10 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 10 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
11 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 11 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
12 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 12 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
13 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 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; 14 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; 15 import com.genersoft.iot.vmp.service.IMediaServerService;
  16 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
18 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 17 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
19 import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; 18 import com.genersoft.iot.vmp.storager.dao.MediaServerMapper;
20 -import org.mitre.dsmiley.httpproxy.ProxyServlet; 19 +import com.genersoft.iot.vmp.utils.redis.JedisUtil;
  20 +import com.genersoft.iot.vmp.utils.redis.RedisUtil;
21 import org.slf4j.Logger; 21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory; 22 import org.slf4j.LoggerFactory;
23 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
24 import org.springframework.beans.factory.annotation.Value; 24 import org.springframework.beans.factory.annotation.Value;
  25 +import org.springframework.boot.CommandLineRunner;
  26 +import org.springframework.core.annotation.Order;
25 import org.springframework.stereotype.Service; 27 import org.springframework.stereotype.Service;
26 28
  29 +import java.sql.Array;
27 import java.text.SimpleDateFormat; 30 import java.text.SimpleDateFormat;
28 import java.util.*; 31 import java.util.*;
29 32
@@ -31,15 +34,13 @@ import java.util.*; @@ -31,15 +34,13 @@ import java.util.*;
31 * 媒体服务器节点管理 34 * 媒体服务器节点管理
32 */ 35 */
33 @Service 36 @Service
34 -public class MediaServerServiceImpl implements IMediaServerService { 37 +@Order(value=2)
  38 +public class MediaServerServiceImpl implements IMediaServerService, CommandLineRunner {
35 39
36 private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); 40 private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class);
37 41
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; 42 + @Autowired
  43 + private SipConfig sipConfig;
43 44
44 @Value("${server.ssl.enabled:false}") 45 @Value("${server.ssl.enabled:false}")
45 private boolean sslEnabled; 46 private boolean sslEnabled;
@@ -56,7 +57,6 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -56,7 +57,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
56 @Autowired 57 @Autowired
57 private MediaServerMapper mediaServerMapper; 58 private MediaServerMapper mediaServerMapper;
58 59
59 -  
60 @Autowired 60 @Autowired
61 private IRedisCatchStorage redisCatchStorage; 61 private IRedisCatchStorage redisCatchStorage;
62 62
@@ -66,53 +66,134 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -66,53 +66,134 @@ public class MediaServerServiceImpl implements IMediaServerService {
66 @Autowired 66 @Autowired
67 private ZLMRTPServerFactory zlmrtpServerFactory; 67 private ZLMRTPServerFactory zlmrtpServerFactory;
68 68
69 - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 69 + @Autowired
  70 + private RedisUtil redisUtil;
  71 +
  72 + @Autowired
  73 + JedisUtil jedisUtil;
  74 +
  75 + private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
70 76
71 /** 77 /**
72 * 初始化 78 * 初始化
73 */ 79 */
74 @Override 80 @Override
75 - public void init() {  
76 - zlmServers.clear();  
77 - zlmServerStatus.clear(); 81 + public void run(String... args) throws Exception {
  82 + logger.info("Media Server 缓存初始化");
78 List<MediaServerItem> mediaServerItemList = mediaServerMapper.queryAll(); 83 List<MediaServerItem> mediaServerItemList = mediaServerMapper.queryAll();
79 - for (IMediaServerItem mediaServerItem : mediaServerItemList) {  
80 - zlmServers.put(mediaServerItem.getId(), mediaServerItem); 84 + for (MediaServerItem mediaServerItem : mediaServerItemList) {
  85 + // 更新
  86 + if (mediaServerItem.getSsrcConfig() == null) {
  87 + SsrcConfig ssrcConfig = new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getSipDomain());
  88 + mediaServerItem.setSsrcConfig(ssrcConfig);
  89 + redisUtil.set(VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(), mediaServerItem);
  90 + }
  91 + // 查询redis是否存在此mediaServer
  92 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId();
  93 + if (!redisUtil.hasKey(key)) {
  94 + redisUtil.set(key, mediaServerItem);
  95 + }
  96 + }
  97 + }
  98 +
  99 + @Override
  100 + public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId) {
  101 + if (mediaServerItem == null || mediaServerItem.getId() == null) return null;
  102 + // 获取mediaServer可用的ssrc
  103 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId();
  104 +
  105 + SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig();
  106 + if (ssrcConfig == null) {
  107 + logger.info("media server [ {} ] ssrcConfig is null", mediaServerItem.getId());
  108 + return null;
  109 + }else {
  110 + String ssrc = ssrcConfig.getPlaySsrc();
  111 + if (streamId == null) streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
  112 + int rtpServerPort = mediaServerItem.getRtpProxyPort();
  113 + if (mediaServerItem.isRtpEnable()) {
  114 + rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId);
  115 + }
  116 + redisUtil.set(key, mediaServerItem);
  117 + return new SSRCInfo(rtpServerPort, ssrc, streamId);
81 } 118 }
82 } 119 }
83 120
84 @Override 121 @Override
85 public void closeRTPServer(Device device, String channelId) { 122 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()); 123 + String mediaServerId = streamSession.getMediaServerId(device.getDeviceId(), channelId);
  124 + MediaServerItem mediaServerItem = this.getOne(mediaServerId);
  125 + if (mediaServerItem != null) {
  126 + String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
  127 + zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
  128 + releaseSsrc(mediaServerItem, streamSession.getSSRC(device.getDeviceId(), channelId));
90 } 129 }
91 - String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);  
92 - zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);  
93 streamSession.remove(device.getDeviceId(), channelId); 130 streamSession.remove(device.getDeviceId(), channelId);
94 } 131 }
95 132
96 @Override 133 @Override
97 - public void update(MediaConfig mediaConfig) { 134 + public void releaseSsrc(MediaServerItem mediaServerItem, String ssrc) {
  135 + if (mediaServerItem == null || ssrc == null) return;
  136 + SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig();
  137 + ssrcConfig.releaseSsrc(ssrc);
  138 + mediaServerItem.setSsrcConfig(ssrcConfig);
  139 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId();
  140 + redisUtil.set(key, mediaServerItem);
  141 + }
98 142
  143 + /**
  144 + * zlm 重启后重置他的推流信息, TODO 给正在使用的设备发送停止命令
  145 + * @param mediaServerItem
  146 + */
  147 + @Override
  148 + public void clearRTPServer(MediaServerItem mediaServerItem) {
  149 + mediaServerItem.setSsrcConfig(new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getSipDomain()));
  150 + redisUtil.zAdd(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX, mediaServerItem.getId(), 0);
99 } 151 }
100 152
  153 +
101 @Override 154 @Override
102 - public List<IMediaServerItem> getAll() {  
103 - if (zlmServers.size() == 0) {  
104 - init(); 155 + public void update(MediaServerItem mediaSerItem) {
  156 + mediaServerMapper.update(mediaSerItem);
  157 + MediaServerItem mediaServerItemInRedis = getOne(mediaSerItem.getId());
  158 + MediaServerItem mediaServerItemInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId());
  159 + if (mediaServerItemInRedis != null && mediaServerItemInRedis.getSsrcConfig() != null) {
  160 + mediaServerItemInDataBase.setSsrcConfig(mediaServerItemInRedis.getSsrcConfig());
  161 + }else {
  162 + mediaServerItemInDataBase.setSsrcConfig(
  163 + new SsrcConfig(
  164 + mediaServerItemInDataBase.getId(),
  165 + null,
  166 + sipConfig.getSipDomain()
  167 + )
  168 + );
105 } 169 }
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); 170 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItemInDataBase.getId();
  171 + redisUtil.set(key, mediaServerItemInDataBase);
  172 + }
  173 +
  174 + @Override
  175 + public List<MediaServerItem> getAll() {
  176 + List<MediaServerItem> result = new ArrayList<>();
  177 + List<Object> mediaServerKeys = redisUtil.scan(String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX));
  178 + for (int i = 0; i < mediaServerKeys.size(); i++) {
  179 + String key = (String) mediaServerKeys.get(i);
  180 + result.add((MediaServerItem)redisUtil.get(key));
111 } 181 }
112 return result; 182 return result;
  183 + }
113 184
114 -  
115 -// return mediaServerMapper.queryAll(); 185 + @Override
  186 + public List<MediaServerItem> getAllOnline() {
  187 + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX;
  188 + Set<String> mediaServerIdSet = redisUtil.zRevRange(key, 0, -1);
  189 + List<MediaServerItem> result = new ArrayList<>();
  190 + if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) {
  191 + for (String mediaServerId : mediaServerIdSet) {
  192 + String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerId;
  193 + result.add((MediaServerItem) redisUtil.get(serverKey));
  194 + }
  195 + }
  196 + return result;
116 } 197 }
117 198
118 /** 199 /**
@@ -121,26 +202,28 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -121,26 +202,28 @@ public class MediaServerServiceImpl implements IMediaServerService {
121 * @return MediaServerItem 202 * @return MediaServerItem
122 */ 203 */
123 @Override 204 @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 - } 205 + public MediaServerItem getOne(String mediaServerId) {
  206 + if (mediaServerId == null) return null;
  207 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerId;
  208 + return (MediaServerItem)redisUtil.get(key);
137 } 209 }
138 210
139 @Override 211 @Override
140 - public IMediaServerItem getOneByHostAndPort(String host, int port) { 212 + public MediaServerItem getOneByHostAndPort(String host, int port) {
141 return mediaServerMapper.queryOneByHostAndPort(host, port); 213 return mediaServerMapper.queryOneByHostAndPort(host, port);
142 } 214 }
143 215
  216 + @Override
  217 + public void clearMediaServerForOnline() {
  218 + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX;
  219 + redisUtil.del(key);
  220 + }
  221 +
  222 + @Override
  223 + public void add(MediaServerItem mediaSerItem) {
  224 + mediaServerMapper.add(mediaSerItem);
  225 + }
  226 +
144 /** 227 /**
145 * 处理zlm上线 228 * 处理zlm上线
146 * @param zlmServerConfig zlm上线携带的参数 229 * @param zlmServerConfig zlm上线携带的参数
@@ -150,111 +233,100 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -150,111 +233,100 @@ public class MediaServerServiceImpl implements IMediaServerService {
150 logger.info("[ {} ]-[ {}:{} ]已连接", 233 logger.info("[ {} ]-[ {}:{} ]已连接",
151 zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); 234 zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort());
152 235
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()); 236 + MediaServerItem serverItem = mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId());
  237 + if (serverItem == null) {
  238 + serverItem = mediaServerMapper.queryOneByHostAndPort(zlmServerConfig.getIp(), zlmServerConfig.getHttpPort());
  239 + }
  240 + if (zlmServerConfig.getGeneralMediaServerId().equals(mediaConfig.getId())
  241 + || (zlmServerConfig.getIp().equals(mediaConfig.getIp()) && zlmServerConfig.getHttpPort() == mediaConfig.getHttpPort())) {
  242 + // 配置文件的zlm
158 // 如果是配置文件中的zlm。 也就是默认zlm。 一切以配置文件内容为准 243 // 如果是配置文件中的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 - 244 + // docker部署不会使用zlm配置的端口号不是默认的则不做更新, 配置修改需要自行修改server配置;
  245 + MediaServerItem serverItemFromConfig = mediaConfig.getMediaSerItem();
  246 + serverItemFromConfig.setId(zlmServerConfig.getGeneralMediaServerId());
  247 + if (mediaConfig.getHttpPort() == 0) serverItemFromConfig.setHttpPort(zlmServerConfig.getHttpPort());
  248 + if (mediaConfig.getHttpSSlPort() == 0) serverItemFromConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport());
  249 + if (mediaConfig.getRtmpPort() == 0) serverItemFromConfig.setRtmpPort(zlmServerConfig.getRtmpPort());
  250 + if (mediaConfig.getRtmpSSlPort() == 0) serverItemFromConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
  251 + if (mediaConfig.getRtspPort() == 0) serverItemFromConfig.setRtspPort(zlmServerConfig.getRtspPort());
  252 + if (mediaConfig.getRtspSSLPort() == 0) serverItemFromConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport());
  253 + if (mediaConfig.getRtpProxyPort() == 0) serverItemFromConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
  254 + if (serverItem != null){
  255 + // 可能是同一个zlm但id发生了变化
  256 + if (!serverItem.getId().equals(zlmServerConfig.getGeneralMediaServerId())) {
  257 + mediaServerMapper.delOne(serverItem.getId());
  258 + redisUtil.del(VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItem.getId());
  259 +
  260 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItemFromConfig.getId();
  261 + serverItemFromConfig.setSsrcConfig(new SsrcConfig(serverItemFromConfig.getId(), null, sipConfig.getSipDomain()));
  262 + redisUtil.set(key, serverItemFromConfig);
  263 + mediaServerMapper.add(serverItemFromConfig);
  264 + }else {
  265 + mediaServerMapper.update(serverItemFromConfig);
186 } 266 }
187 - serverItem.setUpdateTime(now);  
188 - mediaServerMapper.update(serverItem);  
189 - setZLMConfig(serverItem); 267 + }else {
  268 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItemFromConfig.getId();
  269 + serverItemFromConfig.setSsrcConfig(new SsrcConfig(serverItemFromConfig.getId(), null, sipConfig.getSipDomain()));
  270 + redisUtil.set(key, serverItemFromConfig);
  271 + mediaServerMapper.add(serverItemFromConfig);
190 } 272 }
  273 + resetOnlineServerItem(serverItemFromConfig);
  274 + setZLMConfig(serverItemFromConfig);
191 }else { 275 }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.getMediaSerItem();  
198 - mediaServerMapper.add(mediaConfig);  
199 - }else {  
200 - // 一个新的zlm接入wvp  
201 - serverItem = new MediaServerItem(zlmServerConfig, sipIp);  
202 - serverItem.setCreateTime(now);  
203 - serverItem.setUpdateTime(now); 276 + String now = this.format.format(new Date(System.currentTimeMillis()));
  277 + if (serverItem == null){
  278 + // 一个新的zlm接入wvp
  279 + serverItem = new MediaServerItem(zlmServerConfig, sipConfig.getSipIp());
  280 + serverItem.setCreateTime(now);
  281 + serverItem.setUpdateTime(now);
  282 + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItem.getId();
  283 + serverItem.setSsrcConfig(new SsrcConfig(serverItem.getId(), null, sipConfig.getSipDomain()));
  284 + redisUtil.set(key, serverItem);
  285 + // 存入数据库
204 mediaServerMapper.add(serverItem); 286 mediaServerMapper.add(serverItem);
  287 + setZLMConfig(serverItem);
205 } 288 }
  289 + resetOnlineServerItem(serverItem);
206 } 290 }
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 } 291 }
228 292
229 - /**  
230 - * 更新缓存  
231 - * @param mediaServerItem zlm服务  
232 - * @param count 在线数  
233 - * @param online 在线状态  
234 - */  
235 @Override 293 @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 - } 294 + public void resetOnlineServerItem(MediaServerItem serverItem) {
  295 + // 更新缓存
  296 + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX;
  297 + // 使用zset的分数作为当前并发量, 默认值设置为0
  298 + if (redisUtil.zScore(key, serverItem.getId()) == null) { // 不存在则设置默认值 已存在则重置
  299 + redisUtil.zAdd(key, serverItem.getId(), 0L);
  300 + // 查询服务流数量
  301 + zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{
  302 + Integer code = mediaList.getInteger("code");
  303 + if (code == 0) {
  304 + JSONArray data = mediaList.getJSONArray("data");
  305 + if (data != null) {
  306 + redisUtil.zAdd(key, serverItem.getId(), data.size());
  307 + }
  308 + }
  309 + }));
  310 + }else {
  311 + clearRTPServer(serverItem);
243 } 312 }
  313 +
244 } 314 }
245 315
  316 +
246 @Override 317 @Override
247 public void addCount(String mediaServerId) { 318 public void addCount(String mediaServerId) {
248 - if (zlmServerStatus.get(mediaServerId) != null) {  
249 - zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) + 1);  
250 - } 319 + if (mediaServerId == null) return;
  320 + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX;
  321 + Double aDouble = redisUtil.zScore(key, mediaServerId);
  322 + redisUtil.zIncrScore(key, mediaServerId, 1);
  323 +
251 } 324 }
252 325
253 @Override 326 @Override
254 public void removeCount(String mediaServerId) { 327 public void removeCount(String mediaServerId) {
255 - if (zlmServerStatus.get(mediaServerId) != null) {  
256 - zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) - 1);  
257 - } 328 + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX;
  329 + redisUtil.zIncrScore(key, mediaServerId, - 1);
258 } 330 }
259 331
260 /** 332 /**
@@ -262,35 +334,18 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -262,35 +334,18 @@ public class MediaServerServiceImpl implements IMediaServerService {
262 * @return MediaServerItem 334 * @return MediaServerItem
263 */ 335 */
264 @Override 336 @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 - } 337 + public MediaServerItem getMediaServerForMinimumLoad() {
  338 + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX;
287 339
288 - if (key == null) { 340 + if (redisUtil.zSize(key) == null || redisUtil.zSize(key) == 0) {
289 logger.info("获取负载最低的节点时无在线节点"); 341 logger.info("获取负载最低的节点时无在线节点");
290 - return null;  
291 - }else{  
292 - return zlmServers.get(key);  
293 } 342 }
  343 +
  344 + // 获取分数最低的,及并发最低的
  345 + Set<Object> objects = redisUtil.ZRange(key, 0, -1);
  346 + ArrayList<Object> MediaServerObjectS = new ArrayList<>(objects);
  347 + String mediaServerId = (String)MediaServerObjectS.get(0);
  348 + return getOne(mediaServerId);
294 } 349 }
295 350
296 /** 351 /**
@@ -298,7 +353,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -298,7 +353,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
298 * @param mediaServerItem 服务ID 353 * @param mediaServerItem 服务ID
299 */ 354 */
300 @Override 355 @Override
301 - public void setZLMConfig(IMediaServerItem mediaServerItem) { 356 + public void setZLMConfig(MediaServerItem mediaServerItem) {
302 logger.info("[ {} ]-[ {}:{} ]设置zlm", 357 logger.info("[ {} ]-[ {}:{} ]设置zlm",
303 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); 358 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
304 String protocol = sslEnabled ? "https" : "http"; 359 String protocol = sslEnabled ? "https" : "http";
@@ -333,8 +388,10 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -333,8 +388,10 @@ public class MediaServerServiceImpl implements IMediaServerService {
333 logger.info("[ {} ]-[ {}:{} ]设置zlm成功", 388 logger.info("[ {} ]-[ {}:{} ]设置zlm成功",
334 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); 389 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
335 }else { 390 }else {
336 - logger.info("[ {} ]-[ {}:{} ]设置zlm失败" + responseJSON.getString("msg"), 391 + logger.info("[ {} ]-[ {}:{} ]设置zlm失败",
337 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); 392 mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
338 } 393 }
339 } 394 }
  395 +
  396 +
340 } 397 }
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
@@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSON; @@ -4,9 +4,7 @@ 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.common.StreamInfo; 6 import com.genersoft.iot.vmp.common.StreamInfo;
7 -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;  
8 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 7 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; 8 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
11 import com.genersoft.iot.vmp.service.IMediaServerService; 9 import com.genersoft.iot.vmp.service.IMediaServerService;
12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -33,14 +31,14 @@ public class MediaServiceImpl implements IMediaService { @@ -33,14 +31,14 @@ public class MediaServiceImpl implements IMediaService {
33 31
34 32
35 @Override 33 @Override
36 - public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks) { 34 + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks) {
37 return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null); 35 return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null);
38 } 36 }
39 37
40 @Override 38 @Override
41 public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) { 39 public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) {
42 StreamInfo streamInfo = null; 40 StreamInfo streamInfo = null;
43 - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 41 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
44 if (mediaInfo == null) { 42 if (mediaInfo == null) {
45 return streamInfo; 43 return streamInfo;
46 } 44 }
@@ -63,7 +61,7 @@ public class MediaServiceImpl implements IMediaService { @@ -63,7 +61,7 @@ public class MediaServiceImpl implements IMediaService {
63 } 61 }
64 62
65 @Override 63 @Override
66 - public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr) { 64 + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr) {
67 StreamInfo streamInfoResult = new StreamInfo(); 65 StreamInfo streamInfoResult = new StreamInfo();
68 streamInfoResult.setStreamId(stream); 66 streamInfoResult.setStreamId(stream);
69 streamInfoResult.setApp(app); 67 streamInfoResult.setApp(app);
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -14,11 +14,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; @@ -14,11 +14,12 @@ 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; 17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
19 import com.genersoft.iot.vmp.service.IMediaServerService; 18 import com.genersoft.iot.vmp.service.IMediaServerService;
  19 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 21 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  22 +import com.genersoft.iot.vmp.utils.redis.RedisUtil;
22 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 23 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
23 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 24 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
24 import com.genersoft.iot.vmp.service.IMediaService; 25 import com.genersoft.iot.vmp.service.IMediaService;
@@ -54,6 +55,9 @@ public class PlayServiceImpl implements IPlayService { @@ -54,6 +55,9 @@ public class PlayServiceImpl implements IPlayService {
54 private IRedisCatchStorage redisCatchStorage; 55 private IRedisCatchStorage redisCatchStorage;
55 56
56 @Autowired 57 @Autowired
  58 + private RedisUtil redis;
  59 +
  60 + @Autowired
57 private DeferredResultHolder resultHolder; 61 private DeferredResultHolder resultHolder;
58 62
59 @Autowired 63 @Autowired
@@ -73,7 +77,7 @@ public class PlayServiceImpl implements IPlayService { @@ -73,7 +77,7 @@ public class PlayServiceImpl implements IPlayService {
73 77
74 78
75 @Override 79 @Override
76 - public PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { 80 + public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) {
77 PlayResult playResult = new PlayResult(); 81 PlayResult playResult = new PlayResult();
78 if (mediaServerItem == null) { 82 if (mediaServerItem == null) {
79 RequestMessage msg = new RequestMessage(); 83 RequestMessage msg = new RequestMessage();
@@ -97,14 +101,21 @@ public class PlayServiceImpl implements IPlayService { @@ -97,14 +101,21 @@ public class PlayServiceImpl implements IPlayService {
97 // 超时处理 101 // 超时处理
98 result.onTimeout(()->{ 102 result.onTimeout(()->{
99 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 103 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
100 - // 释放rtpserver  
101 - mediaServerService.closeRTPServer(playResult.getDevice(), channelId);  
102 RequestMessage msg = new RequestMessage(); 104 RequestMessage msg = new RequestMessage();
103 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid()); 105 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid());
104 WVPResult wvpResult = new WVPResult(); 106 WVPResult wvpResult = new WVPResult();
105 wvpResult.setCode(-1); 107 wvpResult.setCode(-1);
106 - wvpResult.setMsg("Timeout"); 108 + SIPDialog dialog = streamSession.getDialog(deviceId, channelId);
  109 + if (dialog != null) {
  110 + wvpResult.setMsg("收流超时,请稍候重试");
  111 + }else {
  112 + wvpResult.setMsg("点播超时,请稍候重试");
  113 + }
107 msg.setData(wvpResult); 114 msg.setData(wvpResult);
  115 + // 点播超时回复BYE
  116 + cmder.streamByeCmd(device.getDeviceId(), channelId);
  117 + // 释放rtpserver
  118 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
108 resultHolder.invokeResult(msg); 119 resultHolder.invokeResult(msg);
109 }); 120 });
110 result.onCompletion(()->{ 121 result.onCompletion(()->{
@@ -131,7 +142,7 @@ public class PlayServiceImpl implements IPlayService { @@ -131,7 +142,7 @@ public class PlayServiceImpl implements IPlayService {
131 WVPResult wvpResult = (WVPResult)responseEntity.getBody(); 142 WVPResult wvpResult = (WVPResult)responseEntity.getBody();
132 if (wvpResult.getCode() == 0) { 143 if (wvpResult.getCode() == 0) {
133 StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData(); 144 StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
134 - IMediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId()); 145 + MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
135 String streamUrl = streamInfoForSuccess.getFmp4(); 146 String streamUrl = streamInfoForSuccess.getFmp4();
136 // 请求截图 147 // 请求截图
137 zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName); 148 zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
@@ -142,14 +153,23 @@ public class PlayServiceImpl implements IPlayService { @@ -142,14 +153,23 @@ public class PlayServiceImpl implements IPlayService {
142 } 153 }
143 }); 154 });
144 if (streamInfo == null) { 155 if (streamInfo == null) {
  156 + SSRCInfo ssrcInfo;
  157 + String streamId = null;
  158 + if (mediaServerItem.isRtpEnable()) {
  159 + streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
  160 + }
  161 +
  162 + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);
  163 +
145 // 发送点播消息 164 // 发送点播消息
146 - cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInUse, JSONObject response) -> { 165 + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> {
147 logger.info("收到订阅消息: " + response.toJSONString()); 166 logger.info("收到订阅消息: " + response.toJSONString());
148 onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid.toString()); 167 onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid.toString());
149 if (hookEvent != null) { 168 if (hookEvent != null) {
150 hookEvent.response(mediaServerItem, response); 169 hookEvent.response(mediaServerItem, response);
151 } 170 }
152 }, (event) -> { 171 }, (event) -> {
  172 + // 点播返回sip错误
153 RequestMessage msg = new RequestMessage(); 173 RequestMessage msg = new RequestMessage();
154 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); 174 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
155 Response response = event.getResponse(); 175 Response response = event.getResponse();
@@ -162,6 +182,7 @@ public class PlayServiceImpl implements IPlayService { @@ -162,6 +182,7 @@ public class PlayServiceImpl implements IPlayService {
162 if (errorEvent != null) { 182 if (errorEvent != null) {
163 errorEvent.response(event); 183 errorEvent.response(event);
164 } 184 }
  185 +
165 }); 186 });
166 } else { 187 } else {
167 String streamId = streamInfo.getStreamId(); 188 String streamId = streamInfo.getStreamId();
@@ -176,7 +197,7 @@ public class PlayServiceImpl implements IPlayService { @@ -176,7 +197,7 @@ public class PlayServiceImpl implements IPlayService {
176 return playResult; 197 return playResult;
177 } 198 }
178 String mediaServerId = streamInfo.getMediaServerId(); 199 String mediaServerId = streamInfo.getMediaServerId();
179 - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 200 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
180 201
181 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); 202 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId);
182 if (rtpInfo != null && rtpInfo.getBoolean("exist")) { 203 if (rtpInfo != null && rtpInfo.getBoolean("exist")) {
@@ -194,9 +215,17 @@ public class PlayServiceImpl implements IPlayService { @@ -194,9 +215,17 @@ public class PlayServiceImpl implements IPlayService {
194 hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo))); 215 hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo)));
195 } 216 }
196 } else { 217 } else {
  218 + // TODO 点播前是否重置状态
197 redisCatchStorage.stopPlay(streamInfo); 219 redisCatchStorage.stopPlay(streamInfo);
198 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 220 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
199 - cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> { 221 + SSRCInfo ssrcInfo;
  222 + String streamId2 = null;
  223 + if (mediaServerItem.isRtpEnable()) {
  224 + streamId2 = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
  225 + }
  226 + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2);
  227 +
  228 + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
200 logger.info("收到订阅消息: " + response.toJSONString()); 229 logger.info("收到订阅消息: " + response.toJSONString());
201 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); 230 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());
202 }, (event) -> { 231 }, (event) -> {
@@ -218,7 +247,7 @@ public class PlayServiceImpl implements IPlayService { @@ -218,7 +247,7 @@ public class PlayServiceImpl implements IPlayService {
218 } 247 }
219 248
220 @Override 249 @Override
221 - public void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { 250 + public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
222 RequestMessage msg = new RequestMessage(); 251 RequestMessage msg = new RequestMessage();
223 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); 252 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
224 StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); 253 StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);
@@ -228,14 +257,6 @@ public class PlayServiceImpl implements IPlayService { @@ -228,14 +257,6 @@ public class PlayServiceImpl implements IPlayService {
228 deviceChannel.setStreamId(streamInfo.getStreamId()); 257 deviceChannel.setStreamId(streamInfo.getStreamId());
229 storager.startPlay(deviceId, channelId, streamInfo.getStreamId()); 258 storager.startPlay(deviceId, channelId, streamInfo.getStreamId());
230 } 259 }
231 - ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId);  
232 - SIPDialog dialog = (SIPDialog)transaction.getDialog();  
233 - StreamInfo.TransactionInfo transactionInfo = new StreamInfo.TransactionInfo();  
234 - transactionInfo.callId = dialog.getCallId().getCallId();  
235 - transactionInfo.localTag = dialog.getLocalTag();  
236 - transactionInfo.remoteTag = dialog.getRemoteTag();  
237 - transactionInfo.branch = dialog.getFirstTransactionInt().getBranchId();  
238 - streamInfo.setTransactionInfo(transactionInfo);  
239 redisCatchStorage.startPlay(streamInfo); 260 redisCatchStorage.startPlay(streamInfo);
240 msg.setData(JSON.toJSONString(streamInfo)); 261 msg.setData(JSON.toJSONString(streamInfo));
241 262
@@ -254,10 +275,10 @@ public class PlayServiceImpl implements IPlayService { @@ -254,10 +275,10 @@ public class PlayServiceImpl implements IPlayService {
254 } 275 }
255 276
256 @Override 277 @Override
257 - public IMediaServerItem getNewMediaServerItem(Device device) { 278 + public MediaServerItem getNewMediaServerItem(Device device) {
258 if (device == null) return null; 279 if (device == null) return null;
259 String mediaServerId = device.getMediaServerId(); 280 String mediaServerId = device.getMediaServerId();
260 - IMediaServerItem mediaServerItem = null; 281 + MediaServerItem mediaServerItem = null;
261 if (mediaServerId == null) { 282 if (mediaServerId == null) {
262 mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(); 283 mediaServerItem = mediaServerService.getMediaServerForMinimumLoad();
263 }else { 284 }else {
@@ -270,7 +291,7 @@ public class PlayServiceImpl implements IPlayService { @@ -270,7 +291,7 @@ public class PlayServiceImpl implements IPlayService {
270 } 291 }
271 292
272 @Override 293 @Override
273 - public void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { 294 + public void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
274 RequestMessage msg = new RequestMessage(); 295 RequestMessage msg = new RequestMessage();
275 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); 296 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
276 StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); 297 StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);
@@ -285,7 +306,7 @@ public class PlayServiceImpl implements IPlayService { @@ -285,7 +306,7 @@ public class PlayServiceImpl implements IPlayService {
285 } 306 }
286 } 307 }
287 308
288 - public StreamInfo onPublishHandler(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { 309 + public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) {
289 String streamId = resonse.getString("stream"); 310 String streamId = resonse.getString("stream");
290 JSONArray tracks = resonse.getJSONArray("tracks"); 311 JSONArray tracks = resonse.getJSONArray("tracks");
291 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks); 312 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks);
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.service.impl; @@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.service.impl;
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.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; 6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
9 import com.genersoft.iot.vmp.service.IGbStreamService; 8 import com.genersoft.iot.vmp.service.IGbStreamService;
@@ -58,7 +57,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -58,7 +57,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
58 57
59 @Override 58 @Override
60 public String save(StreamProxyItem param) { 59 public String save(StreamProxyItem param) {
61 - IMediaServerItem mediaInfo; 60 + MediaServerItem mediaInfo;
62 if ("auto".equals(param.getMediaServerId())){ 61 if ("auto".equals(param.getMediaServerId())){
63 mediaInfo = mediaServerService.getMediaServerForMinimumLoad(); 62 mediaInfo = mediaServerService.getMediaServerForMinimumLoad();
64 }else { 63 }else {
@@ -120,7 +119,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -120,7 +119,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
120 @Override 119 @Override
121 public JSONObject addStreamProxyToZlm(StreamProxyItem param) { 120 public JSONObject addStreamProxyToZlm(StreamProxyItem param) {
122 JSONObject result = null; 121 JSONObject result = null;
123 - IMediaServerItem mediaServerItem = null; 122 + MediaServerItem mediaServerItem = null;
124 if (param.getMediaServerId() == null) { 123 if (param.getMediaServerId() == null) {
125 logger.warn("添加代理时MediaServerId 为null"); 124 logger.warn("添加代理时MediaServerId 为null");
126 return null; 125 return null;
@@ -141,7 +140,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -141,7 +140,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
141 @Override 140 @Override
142 public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) { 141 public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) {
143 if (param ==null) return null; 142 if (param ==null) return null;
144 - IMediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); 143 + MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
145 JSONObject result = zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream()); 144 JSONObject result = zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream());
146 return result; 145 return result;
147 } 146 }
@@ -198,7 +197,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -198,7 +197,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
198 } 197 }
199 198
200 @Override 199 @Override
201 - public JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem) { 200 + public JSONObject getFFmpegCMDs(MediaServerItem mediaServerItem) {
202 JSONObject result = new JSONObject(); 201 JSONObject result = new JSONObject();
203 JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); 202 JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
204 if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0 203 if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -5,7 +5,6 @@ import com.alibaba.fastjson.JSONObject; @@ -5,7 +5,6 @@ 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;  
9 import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; 8 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.MediaServerItem;
11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 10 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
@@ -43,7 +42,7 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -43,7 +42,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
43 private IMediaServerService mediaServerService; 42 private IMediaServerService mediaServerService;
44 43
45 @Override 44 @Override
46 - public List<StreamPushItem> handleJSON(String jsonData, IMediaServerItem mediaServerItem) { 45 + public List<StreamPushItem> handleJSON(String jsonData, MediaServerItem mediaServerItem) {
47 if (jsonData == null) return null; 46 if (jsonData == null) return null;
48 47
49 Map<String, StreamPushItem> result = new HashMap<>(); 48 Map<String, StreamPushItem> result = new HashMap<>();
@@ -98,7 +97,7 @@ public class StreamPushServiceImpl implements IStreamPushService { @@ -98,7 +97,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
98 @Override 97 @Override
99 public boolean removeFromGB(GbStream stream) { 98 public boolean removeFromGB(GbStream stream) {
100 int del = gbStreamMapper.del(stream.getApp(), stream.getStream()); 99 int del = gbStreamMapper.del(stream.getApp(), stream.getStream());
101 - IMediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); 100 + MediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId());
102 JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream()); 101 JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream());
103 if (mediaList == null) { 102 if (mediaList == null) {
104 streamPushMapper.del(stream.getApp(), stream.getStream()); 103 streamPushMapper.del(stream.getApp(), stream.getStream());
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -5,8 +5,6 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -5,8 +5,6 @@ import com.genersoft.iot.vmp.common.StreamInfo;
5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
7 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;  
10 8
11 import java.util.List; 9 import java.util.List;
12 import java.util.Map; 10 import java.util.Map;
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.storager; @@ -3,7 +3,6 @@ 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.MediaServerItem;
8 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
9 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 8 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
1 package com.genersoft.iot.vmp.storager.dao; 1 package com.genersoft.iot.vmp.storager.dao;
2 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; 3 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import org.apache.ibatis.annotations.Insert; 4 import org.apache.ibatis.annotations.Insert;
7 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
@@ -35,6 +33,7 @@ public interface MediaServerMapper { @@ -35,6 +33,7 @@ public interface MediaServerMapper {
35 "rtpEnable, " + 33 "rtpEnable, " +
36 "rtpPortRange, " + 34 "rtpPortRange, " +
37 "recordAssistPort, " + 35 "recordAssistPort, " +
  36 + "defaultServer, " +
38 "createTime, " + 37 "createTime, " +
39 "updateTime" + 38 "updateTime" +
40 ") VALUES " + 39 ") VALUES " +
@@ -57,9 +56,10 @@ public interface MediaServerMapper { @@ -57,9 +56,10 @@ public interface MediaServerMapper {
57 "${rtpEnable}, " + 56 "${rtpEnable}, " +
58 "'${rtpPortRange}', " + 57 "'${rtpPortRange}', " +
59 "${recordAssistPort}, " + 58 "${recordAssistPort}, " +
  59 + "${defaultServer}, " +
60 "'${createTime}', " + 60 "'${createTime}', " +
61 "'${updateTime}')") 61 "'${updateTime}')")
62 - int add(IMediaServerItem mediaServerItem); 62 + int add(MediaServerItem mediaServerItem);
63 63
64 @Update(value = {" <script>" + 64 @Update(value = {" <script>" +
65 "UPDATE media_server " + 65 "UPDATE media_server " +
@@ -83,7 +83,7 @@ public interface MediaServerMapper { @@ -83,7 +83,7 @@ public interface MediaServerMapper {
83 "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" + 83 "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +
84 "WHERE id='${id}'"+ 84 "WHERE id='${id}'"+
85 " </script>"}) 85 " </script>"})
86 - int update(IMediaServerItem mediaServerItem); 86 + int update(MediaServerItem mediaServerItem);
87 87
88 @Select("SELECT * FROM media_server WHERE id='${id}'") 88 @Select("SELECT * FROM media_server WHERE id='${id}'")
89 MediaServerItem queryOne(String id); 89 MediaServerItem queryOne(String id);
@@ -92,7 +92,7 @@ public interface MediaServerMapper { @@ -92,7 +92,7 @@ public interface MediaServerMapper {
92 List<MediaServerItem> queryAll(); 92 List<MediaServerItem> queryAll();
93 93
94 @Select("DELETE FROM media_server WHERE id='${id}'") 94 @Select("DELETE FROM media_server WHERE id='${id}'")
95 - int delOne(String secret); 95 + void delOne(String id);
96 96
97 @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}") 97 @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}")
98 MediaServerItem queryOneByHostAndPort(String host, int port); 98 MediaServerItem queryOneByHostAndPort(String host, int port);
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -3,10 +3,7 @@ package com.genersoft.iot.vmp.storager.impl; @@ -3,10 +3,7 @@ package com.genersoft.iot.vmp.storager.impl;
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.common.VideoManagerConstants; 5 import com.genersoft.iot.vmp.common.VideoManagerConstants;
6 -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;  
7 import com.genersoft.iot.vmp.gb28181.bean.*; 6 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;  
10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 7 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; 8 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
12 import com.genersoft.iot.vmp.utils.redis.RedisUtil; 9 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
src/main/java/com/genersoft/iot/vmp/utils/ConfigConst.java 0 → 100644
  1 +package com.genersoft.iot.vmp.utils;
  2 +
  3 +public class ConfigConst {
  4 + /**
  5 + * 播流最大并发个数
  6 + */
  7 + public static final Integer MAX_STRTEAM_COUNT = 10000;
  8 +}
src/main/java/com/genersoft/iot/vmp/utils/SerializeUtils.java 0 → 100644
  1 +package com.genersoft.iot.vmp.utils;
  2 +
  3 +import java.io.*;
  4 +
  5 +public class SerializeUtils {
  6 + public static byte[] serialize(Object obj){
  7 + byte[] bytes = null;
  8 + try {
  9 + ByteArrayOutputStream baos=new ByteArrayOutputStream();;
  10 + ObjectOutputStream oos=new ObjectOutputStream(baos);
  11 + oos.writeObject(obj);
  12 + bytes=baos.toByteArray();
  13 + baos.close();
  14 + oos.close();
  15 + } catch (IOException e) {
  16 + e.printStackTrace();
  17 + }
  18 + return bytes;
  19 + }
  20 + public static Object deSerialize(byte[] bytes){
  21 + Object obj=null;
  22 + try {
  23 + ByteArrayInputStream bais=new ByteArrayInputStream(bytes);
  24 + ObjectInputStream ois=new ObjectInputStream(bais);
  25 + obj=ois.readObject();
  26 + } catch (Exception e) {
  27 + e.printStackTrace();
  28 + }
  29 + return obj;
  30 + }
  31 +}
src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java 0 → 100644
  1 +package com.genersoft.iot.vmp.utils.redis;
  2 +
  3 +import org.springframework.beans.factory.annotation.Autowired;
  4 +import org.springframework.stereotype.Component;
  5 +import redis.clients.jedis.Jedis;
  6 +import redis.clients.jedis.JedisPool;
  7 +
  8 +import java.util.Set;
  9 +
  10 +/**
  11 + * @Description:Jedis工具类
  12 + * @author: wangshaopeng@sunnybs.com
  13 + * @date: 2021年03月22日 下午8:27:29
  14 + */
  15 +@Component
  16 +public class JedisUtil {
  17 +
  18 + @Autowired
  19 + private JedisPool jedisPool;
  20 +
  21 + // ============================== Key ==============================
  22 +
  23 + /**
  24 + * 检查给定 key 是否存在。
  25 + *
  26 + * @param key
  27 + * @return
  28 + */
  29 + public Boolean exists(String key) {
  30 + Jedis jedis = null;
  31 + try {
  32 + jedis = jedisPool.getResource();
  33 + Boolean exists = jedis.exists(key);
  34 + return exists;
  35 + } finally {
  36 + returnToPool(jedis);
  37 + }
  38 + }
  39 +
  40 +
  41 + // ============================== Set ==============================
  42 +
  43 + /**
  44 + * SADD key member [member ...]
  45 + * 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
  46 + * 假如 key 不存在,则创建一个只包含 member 元素作成员的集合。
  47 + * 当 key 不是集合类型时,返回一个错误。
  48 + */
  49 + public Long sadd(String key, String... members) {
  50 + Jedis jedis = null;
  51 + try {
  52 + jedis = jedisPool.getResource();
  53 + Long smove = jedis.sadd(key, members);
  54 + return smove;
  55 + } finally {
  56 + returnToPool(jedis);
  57 + }
  58 + }
  59 +
  60 + /**
  61 + * SMEMBERS key
  62 + * 返回集合 key 中的所有成员。
  63 + * 不存在的 key 被视为空集合。
  64 + */
  65 + public Set<String> smembers(String key) {
  66 + Jedis jedis = null;
  67 + try {
  68 + jedis = jedisPool.getResource();
  69 + Set<String> smembers = jedis.smembers(key);
  70 + return smembers;
  71 + } finally {
  72 + returnToPool(jedis);
  73 + }
  74 + }
  75 +
  76 +
  77 + /**
  78 + * SREM key member1 [member2]
  79 + * 移除集合中一个或多个成员
  80 + */
  81 + public Long srem(String key, String... member) {
  82 + Jedis jedis = null;
  83 + try {
  84 + jedis = jedisPool.getResource();
  85 + Long srem = jedis.srem(key, member);
  86 + return srem;
  87 + } finally {
  88 + returnToPool(jedis);
  89 + }
  90 + }
  91 +
  92 + private void returnToPool(Jedis jedis) {
  93 + if (jedis != null) {
  94 + jedis.close();
  95 + }
  96 + }
  97 +}
0 \ No newline at end of file 98 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
@@ -415,10 +415,10 @@ public class RedisUtil { @@ -415,10 +415,10 @@ public class RedisUtil {
415 * 415 *
416 * @param key 416 * @param key
417 * @param value 417 * @param value
418 - * @param score 418 + * @param delta -1 表示减 1 表示加1
419 */ 419 */
420 - public Double zIncrScore(Object key, Object value, double score) {  
421 - return redisTemplate.opsForZSet().incrementScore(key, value, score); 420 + public Double zIncrScore(Object key, Object value, double delta) {
  421 + return redisTemplate.opsForZSet().incrementScore(key, value, delta);
422 } 422 }
423 423
424 /** 424 /**
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
@@ -2,13 +2,12 @@ package com.genersoft.iot.vmp.vmanager.gb28181.play; @@ -2,13 +2,12 @@ package com.genersoft.iot.vmp.vmanager.gb28181.play;
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.gb28181.bean.SsrcTransaction;
5 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 6 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
6 -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;  
7 import com.genersoft.iot.vmp.gb28181.bean.Device; 7 import com.genersoft.iot.vmp.gb28181.bean.Device;
8 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 8 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
9 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 9 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
10 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 10 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
11 -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;  
12 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 11 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
13 import com.genersoft.iot.vmp.service.IMediaServerService; 12 import com.genersoft.iot.vmp.service.IMediaServerService;
14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -37,7 +36,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; @@ -37,7 +36,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
37 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 36 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
38 import org.springframework.web.context.request.async.DeferredResult; 37 import org.springframework.web.context.request.async.DeferredResult;
39 38
40 -import java.util.Enumeration; 39 +import java.util.List;
41 import java.util.Map; 40 import java.util.Map;
42 import java.util.UUID; 41 import java.util.UUID;
43 42
@@ -89,7 +88,7 @@ public class PlayController { @@ -89,7 +88,7 @@ public class PlayController {
89 88
90 // 获取可用的zlm 89 // 获取可用的zlm
91 Device device = storager.queryVideoDevice(deviceId); 90 Device device = storager.queryVideoDevice(deviceId);
92 - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); 91 + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
93 PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null); 92 PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null);
94 93
95 return playResult.getResult(); 94 return playResult.getResult();
@@ -174,7 +173,7 @@ public class PlayController { @@ -174,7 +173,7 @@ public class PlayController {
174 logger.warn("视频转码API调用失败!, 视频流已经停止!"); 173 logger.warn("视频转码API调用失败!, 视频流已经停止!");
175 return new ResponseEntity<String>("未找到视频流信息, 视频流可能已经停止", HttpStatus.OK); 174 return new ResponseEntity<String>("未找到视频流信息, 视频流可能已经停止", HttpStatus.OK);
176 } 175 }
177 - IMediaServerItem mediaInfo = mediaServerService.getOne(streamInfo.getMediaServerId()); 176 + MediaServerItem mediaInfo = mediaServerService.getOne(streamInfo.getMediaServerId());
178 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); 177 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId);
179 if (!rtpInfo.getBoolean("exist")) { 178 if (!rtpInfo.getBoolean("exist")) {
180 logger.warn("视频转码API调用失败!, 视频流已停止推流!"); 179 logger.warn("视频转码API调用失败!, 视频流已停止推流!");
@@ -219,7 +218,7 @@ public class PlayController { @@ -219,7 +218,7 @@ public class PlayController {
219 result.put("msg", "mediaServerId is null"); 218 result.put("msg", "mediaServerId is null");
220 return new ResponseEntity<String>( result.toJSONString(), HttpStatus.BAD_REQUEST); 219 return new ResponseEntity<String>( result.toJSONString(), HttpStatus.BAD_REQUEST);
221 } 220 }
222 - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 221 + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
223 if (mediaInfo == null) { 222 if (mediaInfo == null) {
224 result.put("code", 0); 223 result.put("code", 0);
225 result.put("msg", "使用的流媒体已经停止运行"); 224 result.put("msg", "使用的流媒体已经停止运行");
@@ -307,16 +306,16 @@ public class PlayController { @@ -307,16 +306,16 @@ public class PlayController {
307 logger.debug("获取所有的ssrc"); 306 logger.debug("获取所有的ssrc");
308 } 307 }
309 JSONArray objects = new JSONArray(); 308 JSONArray objects = new JSONArray();
310 - for(Map.Entry<String, String> entry: streamSession.getSsrcMap().entrySet()) {  
311 - System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); 309 + List<SsrcTransaction> allSsrc = streamSession.getAllSsrc();
  310 + for (SsrcTransaction transaction : allSsrc) {
312 JSONObject jsonObject = new JSONObject(); 311 JSONObject jsonObject = new JSONObject();
313 - String[] keyArray = entry.getKey().split("_");  
314 - jsonObject.put("deviceId", keyArray[0]);  
315 - jsonObject.put("channelId", keyArray[1]);  
316 - jsonObject.put("ssrc", entry.getValue());  
317 - jsonObject.put("streamId", streamSession.getStreamIdMap().get(entry.getKey())); 312 + jsonObject.put("deviceId", transaction.getDeviceId());
  313 + jsonObject.put("channelId", transaction.getChannelId());
  314 + jsonObject.put("ssrc", transaction.getSsrc());
  315 + jsonObject.put("streamId", transaction.getStreamId());
318 objects.add(jsonObject); 316 objects.add(jsonObject);
319 } 317 }
  318 +
320 WVPResult<JSONObject> result = new WVPResult<>(); 319 WVPResult<JSONObject> result = new WVPResult<>();
321 result.setCode(0); 320 result.setCode(0);
322 result.setMsg("success"); 321 result.setMsg("success");
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java
@@ -3,9 +3,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.playback; @@ -3,9 +3,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.playback;
3 import com.genersoft.iot.vmp.common.StreamInfo; 3 import com.genersoft.iot.vmp.common.StreamInfo;
4 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 4 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
5 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 5 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
6 -//import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;  
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.media.zlm.dto.MediaServerItem;
  7 +import com.genersoft.iot.vmp.service.IMediaServerService;
  8 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
10 import com.genersoft.iot.vmp.service.IPlayService; 10 import com.genersoft.iot.vmp.service.IPlayService;
11 import io.swagger.annotations.Api; 11 import io.swagger.annotations.Api;
@@ -58,6 +58,9 @@ public class DownloadController { @@ -58,6 +58,9 @@ public class DownloadController {
58 @Autowired 58 @Autowired
59 private DeferredResultHolder resultHolder; 59 private DeferredResultHolder resultHolder;
60 60
  61 + @Autowired
  62 + private IMediaServerService mediaServerService;
  63 +
61 @ApiOperation("开始历史媒体下载") 64 @ApiOperation("开始历史媒体下载")
62 @ApiImplicitParams({ 65 @ApiImplicitParams({
63 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), 66 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class),
@@ -90,7 +93,7 @@ public class DownloadController { @@ -90,7 +93,7 @@ public class DownloadController {
90 cmder.streamByeCmd(deviceId, channelId); 93 cmder.streamByeCmd(deviceId, channelId);
91 } 94 }
92 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); 95 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
93 - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); 96 + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
94 if (newMediaServerItem == null) { 97 if (newMediaServerItem == null) {
95 logger.warn(String.format("设备下载响应超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 98 logger.warn(String.format("设备下载响应超时,deviceId:%s ,channelId:%s", deviceId, channelId));
96 RequestMessage msg = new RequestMessage(); 99 RequestMessage msg = new RequestMessage();
@@ -99,7 +102,10 @@ public class DownloadController { @@ -99,7 +102,10 @@ public class DownloadController {
99 resultHolder.invokeResult(msg); 102 resultHolder.invokeResult(msg);
100 return result; 103 return result;
101 } 104 }
102 - cmder.downloadStreamCmd(newMediaServerItem, device, channelId, startTime, endTime, downloadSpeed, (IMediaServerItem mediaServerItem, JSONObject response) -> { 105 +
  106 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null);
  107 +
  108 + cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> {
103 logger.info("收到订阅消息: " + response.toJSONString()); 109 logger.info("收到订阅消息: " + response.toJSONString());
104 playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString()); 110 playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString());
105 }, event -> { 111 }, event -> {
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
@@ -4,8 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -4,8 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo;
4 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 4 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
5 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 5 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
6 //import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 6 //import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
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.MediaServerItem;
  8 +import com.genersoft.iot.vmp.service.IMediaServerService;
  9 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
9 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
10 import com.genersoft.iot.vmp.service.IPlayService; 11 import com.genersoft.iot.vmp.service.IPlayService;
11 import io.swagger.annotations.Api; 12 import io.swagger.annotations.Api;
@@ -58,6 +59,9 @@ public class PlaybackController { @@ -58,6 +59,9 @@ public class PlaybackController {
58 @Autowired 59 @Autowired
59 private DeferredResultHolder resultHolder; 60 private DeferredResultHolder resultHolder;
60 61
  62 + @Autowired
  63 + private IMediaServerService mediaServerService;
  64 +
61 @ApiOperation("开始视频回放") 65 @ApiOperation("开始视频回放")
62 @ApiImplicitParams({ 66 @ApiImplicitParams({
63 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), 67 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class),
@@ -74,6 +78,15 @@ public class PlaybackController { @@ -74,6 +78,15 @@ public class PlaybackController {
74 } 78 }
75 UUID uuid = UUID.randomUUID(); 79 UUID uuid = UUID.randomUUID();
76 DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L); 80 DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L);
  81 +
  82 + Device device = storager.queryVideoDevice(deviceId);
  83 + if (device == null) {
  84 + result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
  85 + return result;
  86 + }
  87 + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
  88 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null);
  89 +
77 // 超时处理 90 // 超时处理
78 result.onTimeout(()->{ 91 result.onTimeout(()->{
79 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 92 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
@@ -82,14 +95,14 @@ public class PlaybackController { @@ -82,14 +95,14 @@ public class PlaybackController {
82 msg.setData("Timeout"); 95 msg.setData("Timeout");
83 resultHolder.invokeResult(msg); 96 resultHolder.invokeResult(msg);
84 }); 97 });
85 - Device device = storager.queryVideoDevice(deviceId); 98 +
86 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); 99 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);
87 if (streamInfo != null) { 100 if (streamInfo != null) {
88 // 停止之前的回放 101 // 停止之前的回放
89 cmder.streamByeCmd(deviceId, channelId); 102 cmder.streamByeCmd(deviceId, channelId);
90 } 103 }
91 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); 104 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
92 - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); 105 +
93 if (newMediaServerItem == null) { 106 if (newMediaServerItem == null) {
94 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 107 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
95 RequestMessage msg = new RequestMessage(); 108 RequestMessage msg = new RequestMessage();
@@ -98,7 +111,8 @@ public class PlaybackController { @@ -98,7 +111,8 @@ public class PlaybackController {
98 resultHolder.invokeResult(msg); 111 resultHolder.invokeResult(msg);
99 return result; 112 return result;
100 } 113 }
101 - cmder.playbackStreamCmd(newMediaServerItem, device, channelId, startTime, endTime, (IMediaServerItem mediaServerItem, JSONObject response) -> { 114 +
  115 + cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> {
102 logger.info("收到订阅消息: " + response.toJSONString()); 116 logger.info("收到订阅消息: " + response.toJSONString());
103 playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString()); 117 playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString());
104 }, event -> { 118 }, event -> {
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/session/PlayTypeEnum.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.gb28181.session;
  2 +
  3 +public enum PlayTypeEnum {
  4 +
  5 + PLAY("0", "直播"),
  6 + PLAY_BACK("1", "回放");
  7 +
  8 + private String value;
  9 + private String name;
  10 +
  11 + PlayTypeEnum(String value, String name) {
  12 + this.value = value;
  13 + this.name = name;
  14 + }
  15 +
  16 + public String getValue() {
  17 + return value;
  18 + }
  19 +
  20 + public String getName() {
  21 + return name;
  22 + }
  23 +}
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
1 package com.genersoft.iot.vmp.vmanager.server; 1 package com.genersoft.iot.vmp.vmanager.server;
2 2
3 import com.genersoft.iot.vmp.VManageBootstrap; 3 import com.genersoft.iot.vmp.VManageBootstrap;
4 -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;  
5 -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; 4 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
6 import com.genersoft.iot.vmp.service.IMediaServerService; 5 import com.genersoft.iot.vmp.service.IMediaServerService;
7 -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;  
8 import com.genersoft.iot.vmp.utils.SpringBeanFactory; 6 import com.genersoft.iot.vmp.utils.SpringBeanFactory;
9 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 7 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
10 import gov.nist.javax.sip.SipStackImpl; 8 import gov.nist.javax.sip.SipStackImpl;
@@ -17,7 +15,6 @@ import org.springframework.web.bind.annotation.*; @@ -17,7 +15,6 @@ import org.springframework.web.bind.annotation.*;
17 import javax.sip.ListeningPoint; 15 import javax.sip.ListeningPoint;
18 import javax.sip.ObjectInUseException; 16 import javax.sip.ObjectInUseException;
19 import javax.sip.SipProvider; 17 import javax.sip.SipProvider;
20 -import java.util.ArrayList;  
21 import java.util.Iterator; 18 import java.util.Iterator;
22 import java.util.List; 19 import java.util.List;
23 20
@@ -38,19 +35,30 @@ public class ServerController { @@ -38,19 +35,30 @@ public class ServerController {
38 @ApiOperation("流媒体服务列表") 35 @ApiOperation("流媒体服务列表")
39 @GetMapping(value = "/media_server/list") 36 @GetMapping(value = "/media_server/list")
40 @ResponseBody 37 @ResponseBody
41 - public WVPResult<List<IMediaServerItem>> getMediaServerList(){  
42 - WVPResult<List<IMediaServerItem>> result = new WVPResult<>(); 38 + public WVPResult<List<MediaServerItem>> getMediaServerList(){
  39 + WVPResult<List<MediaServerItem>> result = new WVPResult<>();
43 result.setCode(0); 40 result.setCode(0);
44 result.setMsg("success"); 41 result.setMsg("success");
45 result.setData(mediaServerService.getAll()); 42 result.setData(mediaServerService.getAll());
46 return result; 43 return result;
47 } 44 }
48 45
  46 + @ApiOperation("在线流媒体服务列表")
  47 + @GetMapping(value = "/media_server/online/list")
  48 + @ResponseBody
  49 + public WVPResult<List<MediaServerItem>> getOnlineMediaServerList(){
  50 + WVPResult<List<MediaServerItem>> result = new WVPResult<>();
  51 + result.setCode(0);
  52 + result.setMsg("success");
  53 + result.setData(mediaServerService.getAllOnline());
  54 + return result;
  55 + }
  56 +
49 @ApiOperation("获取流媒体服务") 57 @ApiOperation("获取流媒体服务")
50 @GetMapping(value = "/media_server/one/{id}") 58 @GetMapping(value = "/media_server/one/{id}")
51 @ResponseBody 59 @ResponseBody
52 - public WVPResult<IMediaServerItem> getMediaServer(@PathVariable String id){  
53 - WVPResult<IMediaServerItem> result = new WVPResult<>(); 60 + public WVPResult<MediaServerItem> getMediaServer(@PathVariable String id){
  61 + WVPResult<MediaServerItem> result = new WVPResult<>();
54 result.setCode(0); 62 result.setCode(0);
55 result.setMsg("success"); 63 result.setMsg("success");
56 result.setData(mediaServerService.getOne(id)); 64 result.setData(mediaServerService.getOne(id));
src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
1 package com.genersoft.iot.vmp.vmanager.streamProxy; 1 package com.genersoft.iot.vmp.vmanager.streamProxy;
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.MediaServerItem;
6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
7 import com.genersoft.iot.vmp.service.IMediaServerService; 6 import com.genersoft.iot.vmp.service.IMediaServerService;
@@ -9,7 +8,6 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -9,7 +8,6 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
9 import com.genersoft.iot.vmp.service.IStreamProxyService; 8 import com.genersoft.iot.vmp.service.IStreamProxyService;
10 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 9 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
11 import com.github.pagehelper.PageInfo; 10 import com.github.pagehelper.PageInfo;
12 -import io.netty.util.internal.StringUtil;  
13 import io.swagger.annotations.Api; 11 import io.swagger.annotations.Api;
14 import io.swagger.annotations.ApiImplicitParam; 12 import io.swagger.annotations.ApiImplicitParam;
15 import io.swagger.annotations.ApiImplicitParams; 13 import io.swagger.annotations.ApiImplicitParams;
@@ -86,7 +84,7 @@ public class StreamProxyController { @@ -86,7 +84,7 @@ public class StreamProxyController {
86 public WVPResult getFFmpegCMDs(@RequestParam String mediaServerId){ 84 public WVPResult getFFmpegCMDs(@RequestParam String mediaServerId){
87 logger.debug("获取节点[ {} ]ffmpeg.cmd模板", mediaServerId ); 85 logger.debug("获取节点[ {} ]ffmpeg.cmd模板", mediaServerId );
88 86
89 - IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); 87 + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
90 JSONObject data = streamProxyService.getFFmpegCMDs(mediaServerItem); 88 JSONObject data = streamProxyService.getFFmpegCMDs(mediaServerItem);
91 WVPResult<JSONObject> result = new WVPResult<>(); 89 WVPResult<JSONObject> result = new WVPResult<>();
92 result.setCode(0); 90 result.setCode(0);
src/main/resources/all-application.yml
@@ -17,6 +17,12 @@ spring: @@ -17,6 +17,12 @@ spring:
17 password: 17 password:
18 # [可选] 超时时间 18 # [可选] 超时时间
19 timeout: 10000 19 timeout: 10000
  20 + # [可选] 一个pool最多可分配多少个jedis实例
  21 + poolMaxTotal: 1000
  22 + # [可选] 一个pool最多有多少个状态为idle(空闲)的jedis实例
  23 + poolMaxIdle: 500
  24 + # [可选] 最大的等待时间(秒)
  25 + poolMaxWait: 5
20 # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置 26 # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置
21 datasource: 27 datasource:
22 # 使用mysql 打开23-28行注释, 删除29-36行 28 # 使用mysql 打开23-28行注释, 删除29-36行
@@ -124,6 +130,7 @@ logging: @@ -124,6 +130,7 @@ logging:
124 level: 130 level:
125 com.genersoft.iot: debug 131 com.genersoft.iot: debug
126 com.genersoft.iot.vmp.storager.dao: info 132 com.genersoft.iot.vmp.storager.dao: info
  133 + com.genersoft.iot.vmp.gb28181: info
127 # [根据业务需求配置] 134 # [根据业务需求配置]
128 user-settings: 135 user-settings:
129 # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true 136 # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true
src/main/resources/application-dev.yml
@@ -76,6 +76,8 @@ logging: @@ -76,6 +76,8 @@ logging:
76 level: 76 level:
77 com.genersoft.iot: debug 77 com.genersoft.iot: debug
78 com.genersoft.iot.vmp.storager.dao: info 78 com.genersoft.iot.vmp.storager.dao: info
  79 + com.genersoft.iot.vmp.gb28181: info
  80 +
79 # [根据业务需求配置] 81 # [根据业务需求配置]
80 user-settings: 82 user-settings:
81 # 推流直播是否录制 83 # 推流直播是否录制
src/main/resources/wvp.sqlite
No preview for this file type
web_src/src/components/service/MediaServer.js
@@ -9,7 +9,7 @@ class MediaServer{ @@ -9,7 +9,7 @@ class MediaServer{
9 getMediaServerList(callback){ 9 getMediaServerList(callback){
10 this.$axios({ 10 this.$axios({
11 method: 'get', 11 method: 'get',
12 - url:`/api/server/media_server/list`, 12 + url:`/api/server/media_server/online/list`,
13 }).then(function (res) { 13 }).then(function (res) {
14 if (typeof (callback) == "function") callback(res.data) 14 if (typeof (callback) == "function") callback(res.data)
15 }).catch(function (error) { 15 }).catch(function (error) {