Commit 42901d03746d534d701ea3b8663e1c6d2c938c6d

Authored by mrjackwang
Committed by GitHub
2 parents 1cb2b2cc 28e5c1ae

Merge branch 'wvp-28181-2.0' into wvp-28181-2.0

Showing 47 changed files with 759 additions and 548 deletions
DOCKERFILE
@@ -85,7 +85,7 @@ RUN echo '#!/bin/bash' > run.sh && \ @@ -85,7 +85,7 @@ RUN echo '#!/bin/bash' > run.sh && \
85 echo 'nohup /opt/media/MediaServer -d -m 3 &' >> run.sh && \ 85 echo 'nohup /opt/media/MediaServer -d -m 3 &' >> run.sh && \
86 echo 'cd /opt/wvp' >> run.sh && \ 86 echo 'cd /opt/wvp' >> run.sh && \
87 echo 'if [${WVP_CONFIG}]; then' >> run.sh && \ 87 echo 'if [${WVP_CONFIG}]; then' >> run.sh && \
88 - echo ' java -jar *.jar --spring.confi g.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 ${WVP_CONFIG}' >> run.sh && \ 88 + echo ' java -jar *.jar --spring.config.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 ${WVP_CONFIG}' >> run.sh && \
89 echo 'else' >> run.sh && \ 89 echo 'else' >> run.sh && \
90 echo ' java -jar *.jar --spring.config.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 --media.ip=127.0.0.1 --media.sdp-ip=${WVP_IP} --sip.ip=${WVP_IP} --media.stream-ip=${WVP_IP}' >> run.sh && \ 90 echo ' java -jar *.jar --spring.config.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 --media.ip=127.0.0.1 --media.sdp-ip=${WVP_IP} --sip.ip=${WVP_IP} --media.stream-ip=${WVP_IP}' >> run.sh && \
91 echo 'fi' >> run.sh 91 echo 'fi' >> run.sh
@@ -169,13 +169,6 @@ @@ -169,13 +169,6 @@
169 <version>1.2.73</version> 169 <version>1.2.73</version>
170 </dependency> 170 </dependency>
171 171
172 - <!--Guava是一种基于开源的Java库-->  
173 - <dependency>  
174 - <groupId>com.google.guava</groupId>  
175 - <artifactId>guava</artifactId>  
176 - <version>30.0-jre</version>  
177 - </dependency>  
178 -  
179 <!-- okhttp --> 172 <!-- okhttp -->
180 <dependency> 173 <dependency>
181 <groupId>com.squareup.okhttp3</groupId> 174 <groupId>com.squareup.okhttp3</groupId>
@@ -279,6 +272,9 @@ @@ -279,6 +272,9 @@
279 <plugin> 272 <plugin>
280 <groupId>pl.project13.maven</groupId> 273 <groupId>pl.project13.maven</groupId>
281 <artifactId>git-commit-id-plugin</artifactId> 274 <artifactId>git-commit-id-plugin</artifactId>
  275 + <configuration>
  276 + <offline>true</offline>
  277 + </configuration>
282 </plugin> 278 </plugin>
283 279
284 <plugin> 280 <plugin>
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
@@ -60,12 +60,9 @@ public class SipPlatformRunner implements CommandLineRunner { @@ -60,12 +60,9 @@ public class SipPlatformRunner implements CommandLineRunner {
60 60
61 // 取消订阅 61 // 取消订阅
62 sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{ 62 sipCommanderForPlatform.unregister(parentPlatform, null, (eventResult)->{
63 - ParentPlatform platform = storager.queryParentPlatByServerGBId(parentPlatform.getServerGBId());  
64 - sipCommanderForPlatform.register(platform, null, null); 63 + // 发送平台未注册消息
  64 + publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId());
65 }); 65 });
66 -  
67 - // 发送平台未注册消息  
68 - publisher.platformNotRegisterEventPublish(parentPlatform.getServerGBId());  
69 } 66 }
70 } 67 }
71 } 68 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamCallback.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +public interface InviteStreamCallback {
  4 + void call(InviteStreamInfo inviteStreamInfo);
  5 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/InviteStreamInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  5 +
  6 +public class InviteStreamInfo {
  7 +
  8 + public InviteStreamInfo(MediaServerItem mediaServerItem, JSONObject response, String callId, String app, String stream) {
  9 + this.mediaServerItem = mediaServerItem;
  10 + this.response = response;
  11 + this.callId = callId;
  12 + this.app = app;
  13 + this.stream = stream;
  14 + }
  15 +
  16 + private MediaServerItem mediaServerItem;
  17 + private JSONObject response;
  18 + private String callId;
  19 + private String app;
  20 + private String stream;
  21 +
  22 + public MediaServerItem getMediaServerItem() {
  23 + return mediaServerItem;
  24 + }
  25 +
  26 + public void setMediaServerItem(MediaServerItem mediaServerItem) {
  27 + this.mediaServerItem = mediaServerItem;
  28 + }
  29 +
  30 + public JSONObject getResponse() {
  31 + return response;
  32 + }
  33 +
  34 + public void setResponse(JSONObject response) {
  35 + this.response = response;
  36 + }
  37 +
  38 + public String getCallId() {
  39 + return callId;
  40 + }
  41 +
  42 + public void setCallId(String callId) {
  43 + this.callId = callId;
  44 + }
  45 +
  46 + public String getApp() {
  47 + return app;
  48 + }
  49 +
  50 + public void setApp(String app) {
  51 + this.app = app;
  52 + }
  53 +
  54 + public String getStream() {
  55 + return stream;
  56 + }
  57 +
  58 + public void setStream(String stream) {
  59 + this.stream = stream;
  60 + }
  61 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
@@ -114,6 +114,21 @@ public class ParentPlatform { @@ -114,6 +114,21 @@ public class ParentPlatform {
114 */ 114 */
115 private String catalogId; 115 private String catalogId;
116 116
  117 + /**
  118 + * 已被订阅目录信息
  119 + */
  120 + private boolean catalogSubscribe;
  121 +
  122 + /**
  123 + * 已被订阅报警信息
  124 + */
  125 + private boolean alarmSubscribe;
  126 +
  127 + /**
  128 + * 已被订阅GPS信息
  129 + */
  130 + private boolean gpsSubscribe;
  131 +
117 public Integer getId() { 132 public Integer getId() {
118 return id; 133 return id;
119 } 134 }
@@ -290,4 +305,28 @@ public class ParentPlatform { @@ -290,4 +305,28 @@ public class ParentPlatform {
290 public void setCatalogId(String catalogId) { 305 public void setCatalogId(String catalogId) {
291 this.catalogId = catalogId; 306 this.catalogId = catalogId;
292 } 307 }
  308 +
  309 + public boolean isCatalogSubscribe() {
  310 + return catalogSubscribe;
  311 + }
  312 +
  313 + public void setCatalogSubscribe(boolean catalogSubscribe) {
  314 + this.catalogSubscribe = catalogSubscribe;
  315 + }
  316 +
  317 + public boolean isAlarmSubscribe() {
  318 + return alarmSubscribe;
  319 + }
  320 +
  321 + public void setAlarmSubscribe(boolean alarmSubscribe) {
  322 + this.alarmSubscribe = alarmSubscribe;
  323 + }
  324 +
  325 + public boolean isGpsSubscribe() {
  326 + return gpsSubscribe;
  327 + }
  328 +
  329 + public void setGpsSubscribe(boolean gpsSubscribe) {
  330 + this.gpsSubscribe = gpsSubscribe;
  331 + }
293 } 332 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeHolder.java
@@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.gb28181.bean; @@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.gb28181.bean;
2 2
3 import org.springframework.stereotype.Component; 3 import org.springframework.stereotype.Component;
4 4
  5 +import java.util.ArrayList;
  6 +import java.util.List;
5 import java.util.concurrent.ConcurrentHashMap; 7 import java.util.concurrent.ConcurrentHashMap;
6 8
7 @Component 9 @Component
@@ -34,4 +36,14 @@ public class SubscribeHolder { @@ -34,4 +36,14 @@ public class SubscribeHolder {
34 public void removeMobilePositionSubscribe(String platformId) { 36 public void removeMobilePositionSubscribe(String platformId) {
35 mobilePositionMap.remove(platformId); 37 mobilePositionMap.remove(platformId);
36 } 38 }
  39 +
  40 + public List<String> getAllCatalogSubscribePlatform() {
  41 + List<String> platforms = new ArrayList<>();
  42 + if(catalogMap.size() > 0) {
  43 + for (String key : catalogMap.keySet()) {
  44 + platforms.add(catalogMap.get(key).getId());
  45 + }
  46 + }
  47 + return platforms;
  48 + }
37 } 49 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SubscribeInfo.java
@@ -14,19 +14,15 @@ public class SubscribeInfo { @@ -14,19 +14,15 @@ public class SubscribeInfo {
14 public SubscribeInfo(RequestEvent evt, String id) { 14 public SubscribeInfo(RequestEvent evt, String id) {
15 this.id = id; 15 this.id = id;
16 Request request = evt.getRequest(); 16 Request request = evt.getRequest();
17 - CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);  
18 - this.callId = callIdHeader.getCallId();  
19 - FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);  
20 - this.fromTag = fromHeader.getTag();  
21 ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME); 17 ExpiresHeader expiresHeader = (ExpiresHeader)request.getHeader(ExpiresHeader.NAME);
22 this.expires = expiresHeader.getExpires(); 18 this.expires = expiresHeader.getExpires();
23 EventHeader eventHeader = (EventHeader)request.getHeader(EventHeader.NAME); 19 EventHeader eventHeader = (EventHeader)request.getHeader(EventHeader.NAME);
24 this.eventId = eventHeader.getEventId(); 20 this.eventId = eventHeader.getEventId();
25 this.eventType = eventHeader.getEventType(); 21 this.eventType = eventHeader.getEventType();
26 - ViaHeader viaHeader = (ViaHeader)request.getHeader(ViaHeader.NAME);  
27 - this.branch = viaHeader.getBranch();  
28 this.transaction = evt.getServerTransaction(); 22 this.transaction = evt.getServerTransaction();
29 this.dialog = evt.getDialog(); 23 this.dialog = evt.getDialog();
  24 + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
  25 + this.callId = callIdHeader.getCallId();
30 } 26 }
31 27
32 private String id; 28 private String id;
@@ -34,9 +30,6 @@ public class SubscribeInfo { @@ -34,9 +30,6 @@ public class SubscribeInfo {
34 private String callId; 30 private String callId;
35 private String eventId; 31 private String eventId;
36 private String eventType; 32 private String eventType;
37 - private String fromTag;  
38 - private String toTag;  
39 - private String branch;  
40 private ServerTransaction transaction; 33 private ServerTransaction transaction;
41 private Dialog dialog; 34 private Dialog dialog;
42 35
@@ -52,18 +45,6 @@ public class SubscribeInfo { @@ -52,18 +45,6 @@ public class SubscribeInfo {
52 return callId; 45 return callId;
53 } 46 }
54 47
55 - public String getFromTag() {  
56 - return fromTag;  
57 - }  
58 -  
59 - public void setToTag(String toTag) {  
60 - this.toTag = toTag;  
61 - }  
62 -  
63 - public String getToTag() {  
64 - return toTag;  
65 - }  
66 -  
67 public void setId(String id) { 48 public void setId(String id) {
68 this.id = id; 49 this.id = id;
69 } 50 }
@@ -76,10 +57,6 @@ public class SubscribeInfo { @@ -76,10 +57,6 @@ public class SubscribeInfo {
76 this.callId = callId; 57 this.callId = callId;
77 } 58 }
78 59
79 - public void setFromTag(String fromTag) {  
80 - this.fromTag = fromTag;  
81 - }  
82 -  
83 public String getEventId() { 60 public String getEventId() {
84 return eventId; 61 return eventId;
85 } 62 }
@@ -96,14 +73,6 @@ public class SubscribeInfo { @@ -96,14 +73,6 @@ public class SubscribeInfo {
96 this.eventType = eventType; 73 this.eventType = eventType;
97 } 74 }
98 75
99 - public String getBranch() {  
100 - return branch;  
101 - }  
102 -  
103 - public void setBranch(String branch) {  
104 - this.branch = branch;  
105 - }  
106 -  
107 public ServerTransaction getTransaction() { 76 public ServerTransaction getTransaction() {
108 return transaction; 77 return transaction;
109 } 78 }
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
@@ -30,7 +30,7 @@ public class SipSubscribe { @@ -30,7 +30,7 @@ public class SipSubscribe {
30 // @Scheduled(fixedRate= 100 * 60 * 60 ) 30 // @Scheduled(fixedRate= 100 * 60 * 60 )
31 @Scheduled(cron="0 0/5 * * * ?") //每5分钟执行一次 31 @Scheduled(cron="0 0/5 * * * ?") //每5分钟执行一次
32 public void execute(){ 32 public void execute(){
33 - logger.info("[定时任务] 清理过期的订阅信息"); 33 + logger.info("[定时任务] 清理过期的SIP订阅信息");
34 Calendar calendar = Calendar.getInstance(); 34 Calendar calendar = Calendar.getInstance();
35 calendar.setTime(new Date()); 35 calendar.setTime(new Date());
36 calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - 5); 36 calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - 5);
@@ -49,10 +49,10 @@ public class SipSubscribe { @@ -49,10 +49,10 @@ public class SipSubscribe {
49 errorTimeSubscribes.remove(key); 49 errorTimeSubscribes.remove(key);
50 } 50 }
51 } 51 }
52 - logger.info("okTimeSubscribes.size:{}",okTimeSubscribes.size());  
53 - logger.info("okSubscribes.size:{}",okSubscribes.size());  
54 - logger.info("errorTimeSubscribes.size:{}",errorTimeSubscribes.size());  
55 - logger.info("errorSubscribes.size:{}",errorSubscribes.size()); 52 + logger.debug("okTimeSubscribes.size:{}",okTimeSubscribes.size());
  53 + logger.debug("okSubscribes.size:{}",okSubscribes.size());
  54 + logger.debug("errorTimeSubscribes.size:{}",errorTimeSubscribes.size());
  55 + logger.debug("errorSubscribes.size:{}",errorSubscribes.size());
56 } 56 }
57 57
58 public interface Event { 58 public interface Event {
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java
@@ -68,8 +68,6 @@ public class OnlineEventListener implements ApplicationListener&lt;OnlineEvent&gt; { @@ -68,8 +68,6 @@ public class OnlineEventListener implements ApplicationListener&lt;OnlineEvent&gt; {
68 String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetup.getServerId() + "_" + event.getDevice().getDeviceId(); 68 String key = VideoManagerConstants.KEEPLIVEKEY_PREFIX + userSetup.getServerId() + "_" + event.getDevice().getDeviceId();
69 Device deviceInStore = storager.queryVideoDevice(device.getDeviceId()); 69 Device deviceInStore = storager.queryVideoDevice(device.getDeviceId());
70 device.setOnline(1); 70 device.setOnline(1);
71 - // 处理上线监听  
72 - storager.updateDevice(device);  
73 switch (event.getFrom()) { 71 switch (event.getFrom()) {
74 // 注册时触发的在线事件,先在redis中增加超时超时监听 72 // 注册时触发的在线事件,先在redis中增加超时超时监听
75 case VideoManagerConstants.EVENT_ONLINE_REGISTER: 73 case VideoManagerConstants.EVENT_ONLINE_REGISTER:
@@ -98,7 +96,8 @@ public class OnlineEventListener implements ApplicationListener&lt;OnlineEvent&gt; { @@ -98,7 +96,8 @@ public class OnlineEventListener implements ApplicationListener&lt;OnlineEvent&gt; {
98 96
99 break; 97 break;
100 } 98 }
101 - 99 + // 处理上线监听
  100 + storager.updateDevice(device);
102 List<DeviceChannel> deviceChannelList = storager.queryOnlineChannelsByDeviceId(device.getDeviceId()); 101 List<DeviceChannel> deviceChannelList = storager.queryOnlineChannelsByDeviceId(device.getDeviceId());
103 eventPublisher.catalogEventPublish(null, deviceChannelList, CatalogEvent.ON); 102 eventPublisher.catalogEventPublish(null, deviceChannelList, CatalogEvent.ON);
104 // 上线添加订阅 103 // 上线添加订阅
src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
@@ -74,7 +74,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -74,7 +74,7 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
74 } 74 }
75 }else { 75 }else {
76 // 获取所用订阅 76 // 获取所用订阅
77 - List<String> platforms = redisCatchStorage.getAllSubscribePlatform(); 77 + List<String> platforms = subscribeHolder.getAllCatalogSubscribePlatform();
78 if (event.getDeviceChannels() != null) { 78 if (event.getDeviceChannels() != null) {
79 if (platforms.size() > 0) { 79 if (platforms.size() > 0) {
80 for (DeviceChannel deviceChannel : event.getDeviceChannels()) { 80 for (DeviceChannel deviceChannel : event.getDeviceChannels()) {
@@ -117,8 +117,6 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; { @@ -117,8 +117,6 @@ public class CatalogEventLister implements ApplicationListener&lt;CatalogEvent&gt; {
117 List<ParentPlatform> parentPlatforms = parentPlatformMap.get(gbId); 117 List<ParentPlatform> parentPlatforms = parentPlatformMap.get(gbId);
118 if (parentPlatforms != null && parentPlatforms.size() > 0) { 118 if (parentPlatforms != null && parentPlatforms.size() > 0) {
119 for (ParentPlatform platform : parentPlatforms) { 119 for (ParentPlatform platform : parentPlatforms) {
120 - String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_Catalog_" + platform.getServerGBId();  
121 -// SubscribeInfo subscribeInfo = redisCatchStorage.getSubscribe(key);  
122 SubscribeInfo subscribeInfo = subscribeHolder.getCatalogSubscribe(platform.getServerGBId()); 120 SubscribeInfo subscribeInfo = subscribeHolder.getCatalogSubscribe(platform.getServerGBId());
123 if (subscribeInfo == null) continue; 121 if (subscribeInfo == null) continue;
124 logger.info("[Catalog事件: {}]平台:{},影响通道{}", event.getType(), platform.getServerGBId(), gbId); 122 logger.info("[Catalog事件: {}]平台:{},影响通道{}", event.getType(), platform.getServerGBId(), gbId);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
@@ -95,14 +95,14 @@ public class SIPProcessorObserver implements ISIPProcessorObserver { @@ -95,14 +95,14 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
95 logger.debug("\n收到响应:\n{}", responseEvent.getResponse()); 95 logger.debug("\n收到响应:\n{}", responseEvent.getResponse());
96 int status = response.getStatusCode(); 96 int status = response.getStatusCode();
97 97
98 - if (((status >= 200) && (status < 300)) || status == 401) { // Success! 98 + if (((status >= 200) && (status < 300)) || status == Response.UNAUTHORIZED) { // Success!
99 CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME); 99 CSeqHeader cseqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
100 String method = cseqHeader.getMethod(); 100 String method = cseqHeader.getMethod();
101 ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method); 101 ISIPResponseProcessor sipRequestProcessor = responseProcessorMap.get(method);
102 if (sipRequestProcessor != null) { 102 if (sipRequestProcessor != null) {
103 sipRequestProcessor.process(responseEvent); 103 sipRequestProcessor.process(responseEvent);
104 } 104 }
105 - if (responseEvent.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { 105 + if (status != Response.UNAUTHORIZED && responseEvent.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) {
106 CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME); 106 CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME);
107 if (callIdHeader != null) { 107 if (callIdHeader != null) {
108 SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId()); 108 SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd;
2 2
3 import com.genersoft.iot.vmp.common.StreamInfo; 3 import com.genersoft.iot.vmp.common.StreamInfo;
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.bean.InviteStreamCallback;
5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 6 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
6 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 7 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 8 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
@@ -103,7 +104,7 @@ public interface ISIPCommander { @@ -103,7 +104,7 @@ public interface ISIPCommander {
103 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss 104 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss
104 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss 105 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
105 */ 106 */
106 - void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 107 + void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,InviteStreamCallback inviteStreamCallback, InviteStreamCallback event, SipSubscribe.Event errorEvent);
107 108
108 /** 109 /**
109 * 请求历史媒体下载 110 * 请求历史媒体下载
@@ -114,13 +115,13 @@ public interface ISIPCommander { @@ -114,13 +115,13 @@ public interface ISIPCommander {
114 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss 115 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
115 * @param downloadSpeed 下载倍速参数 116 * @param downloadSpeed 下载倍速参数
116 */ 117 */
117 - void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 118 + void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, InviteStreamCallback event, SipSubscribe.Event errorEvent);
118 119
119 /** 120 /**
120 * 视频流停止 121 * 视频流停止
121 */ 122 */
122 - void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent);  
123 - void streamByeCmd(String deviceId, String channelId, String stream); 123 + void streamByeCmd(String deviceId, String channelId, String stream, String callId, SipSubscribe.Event okEvent);
  124 + void streamByeCmd(String deviceId, String channelId, String stream, String callId);
124 125
125 /** 126 /**
126 * 回放暂停 127 * 回放暂停
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -6,6 +6,8 @@ import com.genersoft.iot.vmp.conf.DynamicTask; @@ -6,6 +6,8 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
6 import com.genersoft.iot.vmp.conf.SipConfig; 6 import com.genersoft.iot.vmp.conf.SipConfig;
7 import com.genersoft.iot.vmp.conf.UserSetup; 7 import com.genersoft.iot.vmp.conf.UserSetup;
8 import com.genersoft.iot.vmp.gb28181.bean.Device; 8 import com.genersoft.iot.vmp.gb28181.bean.Device;
  9 +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback;
  10 +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo;
9 import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; 11 import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
10 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 12 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
11 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 13 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
@@ -445,27 +447,13 @@ public class SIPCommander implements ISIPCommander { @@ -445,27 +447,13 @@ public class SIPCommander implements ISIPCommander {
445 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss 447 * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss
446 */ 448 */
447 @Override 449 @Override
448 - public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event  
449 - , SipSubscribe.Event errorEvent) { 450 + public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
  451 + String startTime, String endTime, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent,
  452 + SipSubscribe.Event errorEvent) {
450 try { 453 try {
451 454
452 logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); 455 logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
453 456
454 - // 添加订阅  
455 - JSONObject subscribeKey = new JSONObject();  
456 - subscribeKey.put("app", "rtp");  
457 - subscribeKey.put("stream", ssrcInfo.getStream());  
458 - subscribeKey.put("regist", true);  
459 - subscribeKey.put("schema", "rtmp");  
460 - subscribeKey.put("mediaServerId", mediaServerItem.getId());  
461 - logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());  
462 - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,  
463 - (MediaServerItem mediaServerItemInUse, JSONObject json)->{  
464 - if (event != null) {  
465 - event.response(mediaServerItemInUse, json);  
466 - }  
467 - });  
468 -  
469 StringBuffer content = new StringBuffer(200); 457 StringBuffer content = new StringBuffer(200);
470 content.append("v=0\r\n"); 458 content.append("v=0\r\n");
471 content.append("o="+sipConfig.getId()+" 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n"); 459 content.append("o="+sipConfig.getId()+" 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
@@ -530,6 +518,21 @@ public class SIPCommander implements ISIPCommander { @@ -530,6 +518,21 @@ public class SIPCommander implements ISIPCommander {
530 CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() 518 CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
531 : udpSipProvider.getNewCallId(); 519 : udpSipProvider.getNewCallId();
532 520
  521 + // 添加订阅
  522 + JSONObject subscribeKey = new JSONObject();
  523 + subscribeKey.put("app", "rtp");
  524 + subscribeKey.put("stream", ssrcInfo.getStream());
  525 + subscribeKey.put("regist", true);
  526 + subscribeKey.put("schema", "rtmp");
  527 + subscribeKey.put("mediaServerId", mediaServerItem.getId());
  528 + logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey);
  529 + subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
  530 + (MediaServerItem mediaServerItemInUse, JSONObject json)->{
  531 + if (hookEvent != null) {
  532 + InviteStreamInfo inviteStreamInfo = new InviteStreamInfo(mediaServerItemInUse, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream());
  533 + hookEvent.call(inviteStreamInfo);
  534 + }
  535 + });
533 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc()); 536 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
534 537
535 transmitRequest(device, request, errorEvent, okEvent -> { 538 transmitRequest(device, request, errorEvent, okEvent -> {
@@ -537,6 +540,9 @@ public class SIPCommander implements ISIPCommander { @@ -537,6 +540,9 @@ public class SIPCommander implements ISIPCommander {
537 streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction()); 540 streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction());
538 streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), okEvent.dialog); 541 streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), okEvent.dialog);
539 }); 542 });
  543 + if (inviteStreamCallback != null) {
  544 + inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));
  545 + }
540 } catch ( SipException | ParseException | InvalidArgumentException e) { 546 } catch ( SipException | ParseException | InvalidArgumentException e) {
541 e.printStackTrace(); 547 e.printStackTrace();
542 } 548 }
@@ -552,24 +558,11 @@ public class SIPCommander implements ISIPCommander { @@ -552,24 +558,11 @@ public class SIPCommander implements ISIPCommander {
552 * @param downloadSpeed 下载倍速参数 558 * @param downloadSpeed 下载倍速参数
553 */ 559 */
554 @Override 560 @Override
555 - public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event 561 + public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, InviteStreamCallback event
556 , SipSubscribe.Event errorEvent) { 562 , SipSubscribe.Event errorEvent) {
557 try { 563 try {
558 logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); 564 logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
559 565
560 - // 添加订阅  
561 - JSONObject subscribeKey = new JSONObject();  
562 - subscribeKey.put("app", "rtp");  
563 - subscribeKey.put("stream", ssrcInfo.getStream());  
564 - subscribeKey.put("regist", true);  
565 - subscribeKey.put("mediaServerId", mediaServerItem.getId());  
566 - logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());  
567 - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,  
568 - (MediaServerItem mediaServerItemInUse, JSONObject json)->{  
569 - event.response(mediaServerItemInUse, json);  
570 - subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);  
571 - });  
572 -  
573 StringBuffer content = new StringBuffer(200); 566 StringBuffer content = new StringBuffer(200);
574 content.append("v=0\r\n"); 567 content.append("v=0\r\n");
575 content.append("o="+sipConfig.getId()+" 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n"); 568 content.append("o="+sipConfig.getId()+" 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
@@ -637,6 +630,19 @@ public class SIPCommander implements ISIPCommander { @@ -637,6 +630,19 @@ public class SIPCommander implements ISIPCommander {
637 CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() 630 CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
638 : udpSipProvider.getNewCallId(); 631 : udpSipProvider.getNewCallId();
639 632
  633 + // 添加订阅
  634 + JSONObject subscribeKey = new JSONObject();
  635 + subscribeKey.put("app", "rtp");
  636 + subscribeKey.put("stream", ssrcInfo.getStream());
  637 + subscribeKey.put("regist", true);
  638 + subscribeKey.put("mediaServerId", mediaServerItem.getId());
  639 + logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
  640 + subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
  641 + (MediaServerItem mediaServerItemInUse, JSONObject json)->{
  642 + event.call(new InviteStreamInfo(mediaServerItem, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));
  643 + subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey);
  644 + });
  645 +
640 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc()); 646 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
641 647
642 ClientTransaction transaction = transmitRequest(device, request, errorEvent); 648 ClientTransaction transaction = transmitRequest(device, request, errorEvent);
@@ -652,15 +658,15 @@ public class SIPCommander implements ISIPCommander { @@ -652,15 +658,15 @@ public class SIPCommander implements ISIPCommander {
652 * 视频流停止, 不使用回调 658 * 视频流停止, 不使用回调
653 */ 659 */
654 @Override 660 @Override
655 - public void streamByeCmd(String deviceId, String channelId, String stream) {  
656 - streamByeCmd(deviceId, channelId, stream, null); 661 + public void streamByeCmd(String deviceId, String channelId, String stream, String callId) {
  662 + streamByeCmd(deviceId, channelId, stream, callId, null);
657 } 663 }
658 664
659 /** 665 /**
660 * 视频流停止 666 * 视频流停止
661 */ 667 */
662 @Override 668 @Override
663 - public void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent) { 669 + public void streamByeCmd(String deviceId, String channelId, String stream, String callId, SipSubscribe.Event okEvent) {
664 try { 670 try {
665 SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, null, stream); 671 SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, null, stream);
666 ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream); 672 ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream);
@@ -672,7 +678,15 @@ public class SIPCommander implements ISIPCommander { @@ -672,7 +678,15 @@ public class SIPCommander implements ISIPCommander {
672 } 678 }
673 return; 679 return;
674 } 680 }
675 - SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, stream); 681 + SIPDialog dialog;
  682 + if (callId != null) {
  683 + dialog = streamSession.getDialogByCallId(deviceId, channelId, callId);
  684 + }else {
  685 + if (stream == null) return;
  686 + dialog = streamSession.getDialogByStream(deviceId, channelId, stream);
  687 + }
  688 +
  689 +
676 if (dialog == null) { 690 if (dialog == null) {
677 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId); 691 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId);
678 return; 692 return;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 import com.genersoft.iot.vmp.utils.SerializeUtils; 13 import com.genersoft.iot.vmp.utils.SerializeUtils;
14 import gov.nist.javax.sip.SipProviderImpl; 14 import gov.nist.javax.sip.SipProviderImpl;
15 import gov.nist.javax.sip.SipStackImpl; 15 import gov.nist.javax.sip.SipStackImpl;
  16 +import gov.nist.javax.sip.message.MessageFactoryImpl;
16 import gov.nist.javax.sip.message.SIPRequest; 17 import gov.nist.javax.sip.message.SIPRequest;
17 import gov.nist.javax.sip.stack.SIPDialog; 18 import gov.nist.javax.sip.stack.SIPDialog;
18 import org.slf4j.Logger; 19 import org.slf4j.Logger;
@@ -77,11 +78,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -77,11 +78,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
77 @Override 78 @Override
78 public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { 79 public boolean unregister(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
79 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); 80 ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
  81 + parentPlatform.setExpires("0");
80 if (parentPlatformCatch != null) { 82 if (parentPlatformCatch != null) {
81 parentPlatformCatch.setParentPlatform(parentPlatform); 83 parentPlatformCatch.setParentPlatform(parentPlatform);
82 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); 84 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
83 } 85 }
84 - parentPlatform.setExpires("0");  
85 return register(parentPlatform, null, null, errorEvent, okEvent, false); 86 return register(parentPlatform, null, null, errorEvent, okEvent, false);
86 } 87 }
87 88
@@ -101,7 +102,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -101,7 +102,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
101 callIdHeader = udpSipProvider.getNewCallId(); 102 callIdHeader = udpSipProvider.getNewCallId();
102 } 103 }
103 104
104 - request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(Request.REGISTER), "FromRegister" + tm, null, callIdHeader); 105 + request = headerProviderPlarformProvider.createRegisterRequest(parentPlatform,
  106 + redisCatchStorage.getCSEQ(Request.REGISTER), "FromRegister" + tm,
  107 + "z9hG4bK-" + UUID.randomUUID().toString().replace("-", ""), callIdHeader);
105 // 将 callid 写入缓存, 等注册成功可以更新状态 108 // 将 callid 写入缓存, 等注册成功可以更新状态
106 String callIdFromHeader = callIdHeader.getCallId(); 109 String callIdFromHeader = callIdHeader.getCallId();
107 redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, parentPlatform.getServerGBId()); 110 redisCatchStorage.updatePlatformRegisterInfo(callIdFromHeader, parentPlatform.getServerGBId());
@@ -414,11 +417,13 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -414,11 +417,13 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
414 private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent, 417 private void sendNotify(ParentPlatform parentPlatform, String catalogXmlContent,
415 SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent ) 418 SubscribeInfo subscribeInfo, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent )
416 throws NoSuchFieldException, IllegalAccessException, SipException, ParseException { 419 throws NoSuchFieldException, IllegalAccessException, SipException, ParseException {
  420 + MessageFactoryImpl messageFactory = (MessageFactoryImpl) sipFactory.createMessageFactory();
  421 + // 设置编码, 防止中文乱码
  422 + messageFactory.setDefaultContentEncodingCharset("gb2312");
417 Dialog dialog = subscribeInfo.getDialog(); 423 Dialog dialog = subscribeInfo.getDialog();
418 - Request notifyRequest = dialog.createRequest(Request.NOTIFY);  
419 - 424 + if (dialog == null) return;
  425 + SIPRequest notifyRequest = (SIPRequest)dialog.createRequest(Request.NOTIFY);
420 ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); 426 ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
421 -  
422 notifyRequest.setContent(catalogXmlContent, contentTypeHeader); 427 notifyRequest.setContent(catalogXmlContent, contentTypeHeader);
423 428
424 SubscriptionStateHeader subscriptionState = sipFactory.createHeaderFactory() 429 SubscriptionStateHeader subscriptionState = sipFactory.createHeaderFactory()
@@ -509,7 +514,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -509,7 +514,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
509 } 514 }
510 515
511 @Override 516 @Override
512 - public boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) { 517 + public boolean sendNotifyForCatalogOther(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels,
  518 + SubscribeInfo subscribeInfo, Integer index) {
513 if (parentPlatform == null 519 if (parentPlatform == null
514 || deviceChannels == null 520 || deviceChannels == null
515 || deviceChannels.size() == 0 521 || deviceChannels.size() == 0
@@ -577,24 +583,30 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -577,24 +583,30 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
577 recordXml.append("<SN>" +recordInfo.getSn() + "</SN>\r\n"); 583 recordXml.append("<SN>" +recordInfo.getSn() + "</SN>\r\n");
578 recordXml.append("<DeviceID>" + recordInfo.getDeviceId() + "</DeviceID>\r\n"); 584 recordXml.append("<DeviceID>" + recordInfo.getDeviceId() + "</DeviceID>\r\n");
579 recordXml.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n"); 585 recordXml.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n");
580 - recordXml.append("<RecordList Num=\"" + recordInfo.getRecordList().size()+"\">\r\n");  
581 - for (RecordItem recordItem : recordInfo.getRecordList()) {  
582 - recordXml.append("<Item>\r\n");  
583 - if (deviceChannel != null) {  
584 - recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n");  
585 - recordXml.append("<Name>" + recordItem.getName() + "</Name>\r\n");  
586 - recordXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\r\n");  
587 - recordXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n");  
588 - recordXml.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n");  
589 - recordXml.append("<Type>" + recordItem.getType() + "</Type>\r\n");  
590 - if (!StringUtils.isEmpty(recordItem.getFileSize())) {  
591 - recordXml.append("<FileSize>" + recordItem.getFileSize() + "</FileSize>\r\n");  
592 - }  
593 - if (!StringUtils.isEmpty(recordItem.getFilePath())) {  
594 - recordXml.append("<FilePath>" + recordItem.getFilePath() + "</FilePath>\r\n"); 586 + if (recordInfo.getRecordList() == null ) {
  587 + recordXml.append("<RecordList Num=\"0\">\r\n");
  588 + }else {
  589 + recordXml.append("<RecordList Num=\"" + recordInfo.getRecordList().size()+"\">\r\n");
  590 + if (recordInfo.getRecordList().size() > 0) {
  591 + for (RecordItem recordItem : recordInfo.getRecordList()) {
  592 + recordXml.append("<Item>\r\n");
  593 + if (deviceChannel != null) {
  594 + recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n");
  595 + recordXml.append("<Name>" + recordItem.getName() + "</Name>\r\n");
  596 + recordXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\r\n");
  597 + recordXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n");
  598 + recordXml.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n");
  599 + recordXml.append("<Type>" + recordItem.getType() + "</Type>\r\n");
  600 + if (!StringUtils.isEmpty(recordItem.getFileSize())) {
  601 + recordXml.append("<FileSize>" + recordItem.getFileSize() + "</FileSize>\r\n");
  602 + }
  603 + if (!StringUtils.isEmpty(recordItem.getFilePath())) {
  604 + recordXml.append("<FilePath>" + recordItem.getFilePath() + "</FilePath>\r\n");
  605 + }
  606 + }
  607 + recordXml.append("</Item>\r\n");
595 } 608 }
596 } 609 }
597 - recordXml.append("</Item>\r\n");  
598 } 610 }
599 611
600 recordXml.append("</RecordList>\r\n"); 612 recordXml.append("</RecordList>\r\n");
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
@@ -27,10 +27,7 @@ import javax.sip.header.CallIdHeader; @@ -27,10 +27,7 @@ import javax.sip.header.CallIdHeader;
27 import javax.sip.header.FromHeader; 27 import javax.sip.header.FromHeader;
28 import javax.sip.header.HeaderAddress; 28 import javax.sip.header.HeaderAddress;
29 import javax.sip.header.ToHeader; 29 import javax.sip.header.ToHeader;
30 -import java.util.HashMap;  
31 -import java.util.Map;  
32 -import java.util.Timer;  
33 -import java.util.TimerTask; 30 +import java.util.*;
34 31
35 /** 32 /**
36 * SIP命令类型: ACK请求 33 * SIP命令类型: ACK请求
@@ -84,44 +81,72 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -84,44 +81,72 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
84 String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); 81 String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser();
85 SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId()); 82 SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId, null, callIdHeader.getCallId());
86 String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; 83 String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
87 - String deviceId = sendRtpItem.getDeviceId();  
88 - StreamInfo streamInfo = null;  
89 - if (sendRtpItem.isPlay()) {  
90 - streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);  
91 - }else {  
92 - streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);  
93 - }  
94 - if (streamInfo == null) {  
95 - streamInfo = new StreamInfo();  
96 - streamInfo.setApp(sendRtpItem.getApp());  
97 - streamInfo.setStream(sendRtpItem.getStreamId());  
98 - }  
99 - redisCatchStorage.updateSendRTPSever(sendRtpItem); 84 + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
  85 + logger.info("收到ACK,开始向上级推流 rtp/{}", sendRtpItem.getStreamId());
100 Map<String, Object> param = new HashMap<>(); 86 Map<String, Object> param = new HashMap<>();
101 param.put("vhost","__defaultVhost__"); 87 param.put("vhost","__defaultVhost__");
102 - param.put("app",streamInfo.getApp());  
103 - param.put("stream",streamInfo.getStream()); 88 + param.put("app",sendRtpItem.getApp());
  89 + param.put("stream",sendRtpItem.getStreamId());
104 param.put("ssrc", sendRtpItem.getSsrc()); 90 param.put("ssrc", sendRtpItem.getSsrc());
105 param.put("dst_url",sendRtpItem.getIp()); 91 param.put("dst_url",sendRtpItem.getIp());
106 param.put("dst_port", sendRtpItem.getPort()); 92 param.put("dst_port", sendRtpItem.getPort());
107 param.put("is_udp", is_Udp); 93 param.put("is_udp", is_Udp);
108 - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());  
109 - JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);  
110 - if (jsonObject.getInteger("code") != 0) {  
111 - logger.info("监听流以等待流上线{}/{}", streamInfo.getApp(), streamInfo.getStream());  
112 - // 监听流上线  
113 - // 添加订阅  
114 - JSONObject subscribeKey = new JSONObject();  
115 - subscribeKey.put("app", "rtp");  
116 - subscribeKey.put("stream", streamInfo.getStream());  
117 - subscribeKey.put("regist", true);  
118 - subscribeKey.put("schema", "rtmp");  
119 - subscribeKey.put("mediaServerId", sendRtpItem.getMediaServerId());  
120 - subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,  
121 - (MediaServerItem mediaServerItemInUse, JSONObject json)->{  
122 - zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);  
123 - });  
124 - } 94 + param.put("src_port", sendRtpItem.getLocalPort());
  95 + zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  96 +
  97 +
  98 +
  99 +// if (streamInfo == null) { // 流还没上来,对方就回复ack
  100 +// logger.info("监听流以等待流上线1 rtp/{}", sendRtpItem.getStreamId());
  101 +// // 监听流上线
  102 +// // 添加订阅
  103 +// JSONObject subscribeKey = new JSONObject();
  104 +// subscribeKey.put("app", "rtp");
  105 +// subscribeKey.put("stream", sendRtpItem.getStreamId());
  106 +// subscribeKey.put("regist", true);
  107 +// subscribeKey.put("schema", "rtmp");
  108 +// subscribeKey.put("mediaServerId", sendRtpItem.getMediaServerId());
  109 +// subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
  110 +// (MediaServerItem mediaServerItemInUse, JSONObject json)->{
  111 +// Map<String, Object> param = new HashMap<>();
  112 +// param.put("vhost","__defaultVhost__");
  113 +// param.put("app",json.getString("app"));
  114 +// param.put("stream",json.getString("stream"));
  115 +// param.put("ssrc", sendRtpItem.getSsrc());
  116 +// param.put("dst_url",sendRtpItem.getIp());
  117 +// param.put("dst_port", sendRtpItem.getPort());
  118 +// param.put("is_udp", is_Udp);
  119 +// param.put("src_port", sendRtpItem.getLocalPort());
  120 +// zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  121 +// });
  122 +// }else {
  123 +// Map<String, Object> param = new HashMap<>();
  124 +// param.put("vhost","__defaultVhost__");
  125 +// param.put("app",streamInfo.getApp());
  126 +// param.put("stream",streamInfo.getStream());
  127 +// param.put("ssrc", sendRtpItem.getSsrc());
  128 +// param.put("dst_url",sendRtpItem.getIp());
  129 +// param.put("dst_port", sendRtpItem.getPort());
  130 +// param.put("is_udp", is_Udp);
  131 +// param.put("src_port", sendRtpItem.getLocalPort());
  132 +//
  133 +// JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  134 +// if (jsonObject.getInteger("code") != 0) {
  135 +// logger.info("监听流以等待流上线2 {}/{}", streamInfo.getApp(), streamInfo.getStream());
  136 +// // 监听流上线
  137 +// // 添加订阅
  138 +// JSONObject subscribeKey = new JSONObject();
  139 +// subscribeKey.put("app", "rtp");
  140 +// subscribeKey.put("stream", streamInfo.getStream());
  141 +// subscribeKey.put("regist", true);
  142 +// subscribeKey.put("schema", "rtmp");
  143 +// subscribeKey.put("mediaServerId", sendRtpItem.getMediaServerId());
  144 +// subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
  145 +// (MediaServerItem mediaServerItemInUse, JSONObject json)->{
  146 +// zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  147 +// });
  148 +// }
  149 +// }
125 } 150 }
126 } 151 }
127 } 152 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -93,14 +93,16 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In @@ -93,14 +93,16 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
93 param.put("app",sendRtpItem.getApp()); 93 param.put("app",sendRtpItem.getApp());
94 param.put("stream",streamId); 94 param.put("stream",streamId);
95 param.put("ssrc",sendRtpItem.getSsrc()); 95 param.put("ssrc",sendRtpItem.getSsrc());
96 - logger.info("停止向上级推流:" + streamId); 96 + logger.info("收到bye:停止向上级推流:" + streamId);
97 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 97 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
98 zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); 98 zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
99 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null); 99 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null);
100 int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); 100 int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
101 if (totalReaderCount <= 0) { 101 if (totalReaderCount <= 0) {
102 - logger.info(streamId + "无其它观看者,通知设备停止推流");  
103 - cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId); 102 + logger.info("收到bye: {}无其它观看者,通知设备停止推流", streamId);
  103 + if (sendRtpItem.isPlay()) {
  104 + cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId, null);
  105 + }
104 } 106 }
105 } 107 }
106 // 可能是设备主动停止 108 // 可能是设备主动停止
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.common.StreamInfo;
6 import com.genersoft.iot.vmp.conf.DynamicTask; 6 import com.genersoft.iot.vmp.conf.DynamicTask;
7 import com.genersoft.iot.vmp.gb28181.bean.*; 7 import com.genersoft.iot.vmp.gb28181.bean.*;
8 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 8 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  9 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 10 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
10 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 11 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
11 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; 12 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
@@ -91,6 +92,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -91,6 +92,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
91 @Autowired 92 @Autowired
92 private SIPProcessorObserver sipProcessorObserver; 93 private SIPProcessorObserver sipProcessorObserver;
93 94
  95 + @Autowired
  96 + private VideoStreamSessionManager sessionManager;
  97 +
94 98
95 @Override 99 @Override
96 public void afterPropertiesSet() throws Exception { 100 public void afterPropertiesSet() throws Exception {
@@ -233,6 +237,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -233,6 +237,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
233 } 237 }
234 String username = sdp.getOrigin().getUsername(); 238 String username = sdp.getOrigin().getUsername();
235 String addressStr = sdp.getOrigin().getAddress(); 239 String addressStr = sdp.getOrigin().getAddress();
  240 +
236 logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc); 241 logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc);
237 Device device = null; 242 Device device = null;
238 // 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标 243 // 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标
@@ -266,13 +271,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -266,13 +271,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
266 sendRtpItem.setDialog(dialogByteArray); 271 sendRtpItem.setDialog(dialogByteArray);
267 byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction()); 272 byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
268 sendRtpItem.setTransaction(transactionByteArray); 273 sendRtpItem.setTransaction(transactionByteArray);
269 - // 写入redis, 超时时回复  
270 - redisCatchStorage.updateSendRTPSever(sendRtpItem); 274 +
271 275
272 Long finalStartTime = startTime; 276 Long finalStartTime = startTime;
273 Long finalStopTime = stopTime; 277 Long finalStopTime = stopTime;
274 ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON)->{ 278 ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON)->{
275 - logger.info("[上级点播]下级已经开始推流。 回复200OK(SDP), {}/{}", sendRtpItem.getApp(), sendRtpItem.getStreamId()); 279 + String app = responseJSON.getString("app");
  280 + String stream = responseJSON.getString("stream");
  281 + logger.info("[上级点播]下级已经开始推流。 回复200OK(SDP), {}/{}", app, stream);
276 // * 0 等待设备推流上来 282 // * 0 等待设备推流上来
277 // * 1 下级已经推流,等待上级平台回复ack 283 // * 1 下级已经推流,等待上级平台回复ack
278 // * 2 推流中 284 // * 2 推流中
@@ -325,46 +331,66 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -325,46 +331,66 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
325 e.printStackTrace(); 331 e.printStackTrace();
326 } 332 }
327 }); 333 });
  334 + sendRtpItem.setApp("rtp");
328 if ("Playback".equals(sessionName)) { 335 if ("Playback".equals(sessionName)) {
329 sendRtpItem.setPlay(false); 336 sendRtpItem.setPlay(false);
330 - sendRtpItem.setStreamId(ssrc); 337 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true);
  338 + sendRtpItem.setStreamId(ssrcInfo.getStream());
  339 + // 写入redis, 超时时回复
  340 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
331 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 341 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
332 - playService.playBack(device.getDeviceId(), channelId, format.format(start), format.format(end),result -> {  
333 - if (result.getCode() != 0){  
334 - logger.warn("录像回放失败");  
335 - if (result.getEvent() != null) {  
336 - errorEvent.response(result.getEvent());  
337 - }  
338 - redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);  
339 - try {  
340 - responseAck(evt, Response.REQUEST_TIMEOUT);  
341 - } catch (SipException e) {  
342 - e.printStackTrace();  
343 - } catch (InvalidArgumentException e) {  
344 - e.printStackTrace();  
345 - } catch (ParseException e) {  
346 - e.printStackTrace(); 342 + playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, format.format(start),
  343 + format.format(end), null, result -> {
  344 + if (result.getCode() != 0){
  345 + logger.warn("录像回放失败");
  346 + if (result.getEvent() != null) {
  347 + errorEvent.response(result.getEvent());
  348 + }
  349 + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
  350 + try {
  351 + responseAck(evt, Response.REQUEST_TIMEOUT);
  352 + } catch (SipException e) {
  353 + e.printStackTrace();
  354 + } catch (InvalidArgumentException e) {
  355 + e.printStackTrace();
  356 + } catch (ParseException e) {
  357 + e.printStackTrace();
  358 + }
  359 + }else {
  360 + if (result.getMediaServerItem() != null) {
  361 + hookEvent.response(result.getMediaServerItem(), result.getResponse());
  362 + }
347 } 363 }
348 - }else {  
349 - if (result.getMediaServerItem() != null) {  
350 - hookEvent.response(result.getMediaServerItem(), result.getResponse());  
351 - }  
352 - }  
353 - }); 364 + });
354 }else { 365 }else {
355 sendRtpItem.setPlay(true); 366 sendRtpItem.setPlay(true);
356 - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);  
357 - if (streamInfo == null) { 367 + SsrcTransaction playTransaction = sessionManager.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
  368 + if (playTransaction != null) {
  369 + Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, "rtp", playTransaction.getStream());
  370 + if (!streamReady) {
  371 + playTransaction = null;
  372 + }
  373 + }
  374 + if (playTransaction == null) {
  375 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true);
358 if (mediaServerItem.isRtpEnable()) { 376 if (mediaServerItem.isRtpEnable()) {
359 sendRtpItem.setStreamId(String.format("%s_%s", device.getDeviceId(), channelId)); 377 sendRtpItem.setStreamId(String.format("%s_%s", device.getDeviceId(), channelId));
  378 + }else {
  379 + sendRtpItem.setStreamId(ssrcInfo.getStream());
360 } 380 }
361 - sendRtpItem.setPlay(false);  
362 - playService.play(mediaServerItem,device.getDeviceId(), channelId, hookEvent, errorEvent, ()->{ 381 + // 写入redis, 超时时回复
  382 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
  383 + playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg)->{
363 redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); 384 redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
364 - }); 385 + }, null);
365 }else { 386 }else {
366 - sendRtpItem.setStreamId(streamInfo.getStream());  
367 - hookEvent.response(mediaServerItem, null); 387 + sendRtpItem.setStreamId(playTransaction.getStream());
  388 + // 写入redis, 超时时回复
  389 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
  390 + JSONObject jsonObject = new JSONObject();
  391 + jsonObject.put("app", sendRtpItem.getApp());
  392 + jsonObject.put("stream", sendRtpItem.getStreamId());
  393 + hookEvent.response(mediaServerItem, jsonObject);
368 } 394 }
369 } 395 }
370 }else if (gbStream != null) { 396 }else if (gbStream != null) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
@@ -233,7 +233,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @@ -233,7 +233,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements
233 */ 233 */
234 private void processNotifyCatalogList(RequestEvent evt) { 234 private void processNotifyCatalogList(RequestEvent evt) {
235 try { 235 try {
236 - System.out.println(343434);  
237 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); 236 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
238 String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); 237 String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader);
239 238
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
@@ -158,20 +158,14 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -158,20 +158,14 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
158 String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔 158 String interval = XmlUtil.getText(rootElement, "Interval"); // GPS上报时间间隔
159 dynamicTask.startCron(key, new GPSSubscribeTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key, subscribeHolder), Integer.parseInt(interval)); 159 dynamicTask.startCron(key, new GPSSubscribeTask(redisCatchStorage, sipCommanderForPlatform, storager, platformId, sn, key, subscribeHolder), Integer.parseInt(interval));
160 subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo); 160 subscribeHolder.putMobilePositionSubscribe(platformId, subscribeInfo);
161 -// redisCatchStorage.updateSubscribe(key, subscribeInfo);  
162 }else if (subscribeInfo.getExpires() == 0) { 161 }else if (subscribeInfo.getExpires() == 0) {
163 dynamicTask.stop(key); 162 dynamicTask.stop(key);
164 -// redisCatchStorage.delSubscribe(key);  
165 subscribeHolder.removeMobilePositionSubscribe(platformId); 163 subscribeHolder.removeMobilePositionSubscribe(platformId);
166 } 164 }
167 165
168 try { 166 try {
169 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); 167 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
170 - Response response = responseXmlAck(evt, resultXml.toString(), parentPlatform);  
171 - ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME);  
172 - subscribeInfo.setToTag(toHeader.getTag());  
173 - redisCatchStorage.updateSubscribe(key, subscribeInfo);  
174 - 168 + responseXmlAck(evt, resultXml.toString(), parentPlatform);
175 } catch (SipException e) { 169 } catch (SipException e) {
176 e.printStackTrace(); 170 e.printStackTrace();
177 } catch (InvalidArgumentException e) { 171 } catch (InvalidArgumentException e) {
@@ -211,21 +205,14 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme @@ -211,21 +205,14 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
211 .append("</Response>\r\n"); 205 .append("</Response>\r\n");
212 206
213 if (subscribeInfo.getExpires() > 0) { 207 if (subscribeInfo.getExpires() > 0) {
214 -// redisCatchStorage.updateSubscribe(key, subscribeInfo);  
215 subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo); 208 subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo);
216 }else if (subscribeInfo.getExpires() == 0) { 209 }else if (subscribeInfo.getExpires() == 0) {
217 -// redisCatchStorage.delSubscribe(key);  
218 subscribeHolder.removeCatalogSubscribe(platformId); 210 subscribeHolder.removeCatalogSubscribe(platformId);
219 } 211 }
220 212
221 try { 213 try {
222 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId); 214 ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformId);
223 - Response response = responseXmlAck(evt, resultXml.toString(), parentPlatform);  
224 - ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME);  
225 - subscribeInfo.setToTag(toHeader.getTag());  
226 -// redisCatchStorage.updateSubscribe(key, subscribeInfo);  
227 - subscribeHolder.putCatalogSubscribe(platformId, subscribeInfo);  
228 - 215 + responseXmlAck(evt, resultXml.toString(), parentPlatform);
229 } catch (SipException e) { 216 } catch (SipException e) {
230 e.printStackTrace(); 217 e.printStackTrace();
231 } catch (InvalidArgumentException e) { 218 } catch (InvalidArgumentException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
@@ -67,9 +67,6 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement @@ -67,9 +67,6 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
67 // 查询设备是否存在 67 // 查询设备是否存在
68 CSeqHeader cseqHeader = (CSeqHeader) evt.getRequest().getHeader(CSeqHeader.NAME); 68 CSeqHeader cseqHeader = (CSeqHeader) evt.getRequest().getHeader(CSeqHeader.NAME);
69 String method = cseqHeader.getMethod(); 69 String method = cseqHeader.getMethod();
70 - if (method.equals("MESSAGE")) {  
71 - System.out.println();  
72 - }  
73 Device device = redisCatchStorage.getDevice(deviceId); 70 Device device = redisCatchStorage.getDevice(deviceId);
74 // 查询上级平台是否存在 71 // 查询上级平台是否存在
75 ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(deviceId); 72 ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(deviceId);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
@@ -18,6 +18,7 @@ import org.springframework.stereotype.Component; @@ -18,6 +18,7 @@ import org.springframework.stereotype.Component;
18 import javax.sip.InvalidArgumentException; 18 import javax.sip.InvalidArgumentException;
19 import javax.sip.RequestEvent; 19 import javax.sip.RequestEvent;
20 import javax.sip.SipException; 20 import javax.sip.SipException;
  21 +import javax.sip.header.CallIdHeader;
21 import javax.sip.message.Response; 22 import javax.sip.message.Response;
22 import java.text.ParseException; 23 import java.text.ParseException;
23 24
@@ -56,14 +57,15 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i @@ -56,14 +57,15 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
56 } catch (ParseException e) { 57 } catch (ParseException e) {
57 e.printStackTrace(); 58 e.printStackTrace();
58 } 59 }
  60 + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
59 String NotifyType =getText(rootElement, "NotifyType"); 61 String NotifyType =getText(rootElement, "NotifyType");
60 if (NotifyType.equals("121")){ 62 if (NotifyType.equals("121")){
61 logger.info("媒体播放完毕,通知关流"); 63 logger.info("媒体播放完毕,通知关流");
62 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), "*");  
63 - if (streamInfo != null) {  
64 - redisCatchStorage.stopPlayback(streamInfo);  
65 - cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId(), streamInfo.getStream());  
66 - } 64 + String channelId =getText(rootElement, "DeviceID");
  65 + redisCatchStorage.stopPlayback(device.getDeviceId(), channelId, null, callIdHeader.getCallId());
  66 + cmder.streamByeCmd(device.getDeviceId(), channelId, null, callIdHeader.getCallId());
  67 + // TODO 如果级联播放,需要给上级发送此通知
  68 +
67 } 69 }
68 } 70 }
69 71
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java
@@ -88,7 +88,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp @@ -88,7 +88,7 @@ public class RecordInfoQueryMessageHandler extends SIPRequestProcessorParent imp
88 Element secrecyElement = rootElement.element("Secrecy"); 88 Element secrecyElement = rootElement.element("Secrecy");
89 int secrecy = 0; 89 int secrecy = 0;
90 if (secrecyElement != null) { 90 if (secrecyElement != null) {
91 - secrecy = Integer.parseInt(secrecyElement.getText()); 91 + secrecy = Integer.parseInt(secrecyElement.getText().trim());
92 } 92 }
93 String type = "all"; 93 String type = "all";
94 Element typeElement = rootElement.element("Type"); 94 Element typeElement = rootElement.element("Type");
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl;
2 2
3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
  5 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
5 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 6 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
6 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
7 import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; 8 import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract;
@@ -40,6 +41,9 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @@ -40,6 +41,9 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
40 @Autowired 41 @Autowired
41 private SIPProcessorObserver sipProcessorObserver; 42 private SIPProcessorObserver sipProcessorObserver;
42 43
  44 + @Autowired
  45 + private SubscribeHolder subscribeHolder;
  46 +
43 @Override 47 @Override
44 public void afterPropertiesSet() throws Exception { 48 public void afterPropertiesSet() throws Exception {
45 // 添加消息处理的订阅 49 // 添加消息处理的订阅
@@ -83,19 +87,19 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @@ -83,19 +87,19 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
83 // 注册/注销成功 87 // 注册/注销成功
84 logger.info(String.format("%s %s成功", platformGBId, action)); 88 logger.info(String.format("%s %s成功", platformGBId, action));
85 redisCatchStorage.delPlatformRegisterInfo(callId); 89 redisCatchStorage.delPlatformRegisterInfo(callId);
86 - parentPlatform.setStatus("注册".equals(action)); 90 + redisCatchStorage.delPlatformCatchInfo(platformGBId);
87 // 取回Expires设置,避免注销过程中被置为0 91 // 取回Expires设置,避免注销过程中被置为0
88 - if (!parentPlatformCatch.getParentPlatform().getExpires().equals("0")) {  
89 - ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId);  
90 - String expires = parentPlatformTmp.getExpires();  
91 - parentPlatform.setExpires(expires);  
92 - parentPlatform.setId(parentPlatformTmp.getId());  
93 - redisCatchStorage.updatePlatformRegister(parentPlatform);  
94 - redisCatchStorage.updatePlatformKeepalive(parentPlatform);  
95 - parentPlatformCatch.setParentPlatform(parentPlatform);  
96 - redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);  
97 - } 92 + ParentPlatform parentPlatformTmp = storager.queryParentPlatByServerGBId(platformGBId);
  93 + parentPlatformTmp.setStatus("注册".equals(action));
  94 + redisCatchStorage.updatePlatformRegister(parentPlatformTmp);
  95 + redisCatchStorage.updatePlatformKeepalive(parentPlatformTmp);
  96 + parentPlatformCatch.setParentPlatform(parentPlatformTmp);
  97 + redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
98 storager.updateParentPlatformStatus(platformGBId, "注册".equals(action)); 98 storager.updateParentPlatformStatus(platformGBId, "注册".equals(action));
  99 + if ("注销".equals(action)) {
  100 + subscribeHolder.removeCatalogSubscribe(platformGBId);
  101 + subscribeHolder.removeMobilePositionSubscribe(platformGBId);
  102 + }
99 103
100 } 104 }
101 } 105 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -9,9 +9,12 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -9,9 +9,12 @@ import com.genersoft.iot.vmp.common.StreamInfo;
9 import com.genersoft.iot.vmp.conf.MediaConfig; 9 import com.genersoft.iot.vmp.conf.MediaConfig;
10 import com.genersoft.iot.vmp.conf.UserSetup; 10 import com.genersoft.iot.vmp.conf.UserSetup;
11 import com.genersoft.iot.vmp.gb28181.bean.Device; 11 import com.genersoft.iot.vmp.gb28181.bean.Device;
  12 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
12 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 13 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  14 +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
13 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 15 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
14 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; 16 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
  17 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
15 import com.genersoft.iot.vmp.media.zlm.dto.*; 18 import com.genersoft.iot.vmp.media.zlm.dto.*;
16 import com.genersoft.iot.vmp.service.*; 19 import com.genersoft.iot.vmp.service.*;
17 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 20 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -81,7 +84,7 @@ public class ZLMHttpHookListener { @@ -81,7 +84,7 @@ public class ZLMHttpHookListener {
81 private UserSetup userSetup; 84 private UserSetup userSetup;
82 85
83 @Autowired 86 @Autowired
84 - private MediaConfig mediaConfig; 87 + private VideoStreamSessionManager sessionManager;
85 88
86 @Autowired 89 @Autowired
87 private ZLMRESTfulUtils zlmresTfulUtils; 90 private ZLMRESTfulUtils zlmresTfulUtils;
@@ -207,15 +210,15 @@ public class ZLMHttpHookListener { @@ -207,15 +210,15 @@ public class ZLMHttpHookListener {
207 }else { 210 }else {
208 ret.put("enableMP4", userSetup.isRecordPushLive()); 211 ret.put("enableMP4", userSetup.isRecordPushLive());
209 } 212 }
210 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(stream);  
211 -  
212 - // 录像回放时不进行录像下载  
213 - if (streamInfo != null) {  
214 - ret.put("enableMP4", false);  
215 - }else {  
216 - ret.put("enableMP4", userSetup.isRecordPushLive()); 213 + List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, stream);
  214 + if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) {
  215 + String deviceId = ssrcTransactionForAll.get(0).getDeviceId();
  216 + String channelId = ssrcTransactionForAll.get(0).getChannelId();
  217 + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
  218 + if (deviceChannel != null) {
  219 + ret.put("enable_audio", deviceChannel.isHasAudio());
  220 + }
217 } 221 }
218 -  
219 return new ResponseEntity<String>(ret.toString(), HttpStatus.OK); 222 return new ResponseEntity<String>(ret.toString(), HttpStatus.OK);
220 } 223 }
221 224
@@ -350,8 +353,12 @@ public class ZLMHttpHookListener { @@ -350,8 +353,12 @@ public class ZLMHttpHookListener {
350 redisCatchStorage.stopPlay(streamInfo); 353 redisCatchStorage.stopPlay(streamInfo);
351 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 354 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
352 }else{ 355 }else{
353 - streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId);  
354 - redisCatchStorage.stopPlayback(streamInfo); 356 + streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
  357 + if (streamInfo != null) {
  358 + redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(),
  359 + streamInfo.getStream(), null);
  360 + }
  361 +
355 } 362 }
356 }else { 363 }else {
357 if (!"rtp".equals(app)){ 364 if (!"rtp".equals(app)){
@@ -443,18 +450,19 @@ public class ZLMHttpHookListener { @@ -443,18 +450,19 @@ public class ZLMHttpHookListener {
443 ret.put("close", false); 450 ret.put("close", false);
444 } else { 451 } else {
445 cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(), 452 cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(),
446 - streamInfoForPlayCatch.getStream()); 453 + streamInfoForPlayCatch.getStream(), null);
447 redisCatchStorage.stopPlay(streamInfoForPlayCatch); 454 redisCatchStorage.stopPlay(streamInfoForPlayCatch);
448 storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); 455 storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
449 } 456 }
450 }else{ 457 }else{
451 - StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlaybackByStreamId(streamId); 458 + StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, streamId, null);
452 if (streamInfoForPlayBackCatch != null) { 459 if (streamInfoForPlayBackCatch != null) {
453 cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(), 460 cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(),
454 - streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream());  
455 - redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch); 461 + streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream(), null);
  462 + redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch.getDeviceID(),
  463 + streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream(), null);
456 }else { 464 }else {
457 - StreamInfo streamInfoForDownload = redisCatchStorage.queryDownloadByStreamId(streamId); 465 + StreamInfo streamInfoForDownload = redisCatchStorage.queryDownload(null, null, streamId, null);
458 // 进行录像下载时无人观看不断流 466 // 进行录像下载时无人观看不断流
459 if (streamInfoForDownload != null) { 467 if (streamInfoForDownload != null) {
460 ret.put("close", false); 468 ret.put("close", false);
@@ -462,7 +470,7 @@ public class ZLMHttpHookListener { @@ -462,7 +470,7 @@ public class ZLMHttpHookListener {
462 } 470 }
463 } 471 }
464 MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); 472 MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
465 - if (mediaServerItem != null && "-1".equals(mediaServerItem.getStreamNoneReaderDelayMS())) { 473 + if (mediaServerItem != null && mediaServerItem.getStreamNoneReaderDelayMS() == -1) {
466 ret.put("close", false); 474 ret.put("close", false);
467 } 475 }
468 return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); 476 return new ResponseEntity<String>(ret.toString(),HttpStatus.OK);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -45,12 +45,8 @@ public class ZLMRTPServerFactory { @@ -45,12 +45,8 @@ public class ZLMRTPServerFactory {
45 45
46 Map<String, Object> param = new HashMap<>(); 46 Map<String, Object> param = new HashMap<>();
47 int result = -1; 47 int result = -1;
48 - /**  
49 - * 不设置推流端口端则使用随机端口  
50 - */  
51 - if (StringUtils.isEmpty(mediaServerItem.getSendRtpPortRange())){  
52 - param.put("port", 0);  
53 - }else { 48 + // 不设置推流端口端则使用随机端口
  49 + if (!StringUtils.isEmpty(mediaServerItem.getSendRtpPortRange())){
54 int newPort = getPortFromportRange(mediaServerItem); 50 int newPort = getPortFromportRange(mediaServerItem);
55 param.put("port", newPort); 51 param.put("port", newPort);
56 } 52 }
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -2,10 +2,14 @@ package com.genersoft.iot.vmp.service; @@ -2,10 +2,14 @@ package com.genersoft.iot.vmp.service;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
  5 +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback;
  6 +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo;
5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 7 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
6 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 8 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 9 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  10 +import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
8 import com.genersoft.iot.vmp.service.bean.PlayBackCallback; 11 import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
  12 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
9 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 13 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
10 import org.springframework.http.ResponseEntity; 14 import org.springframework.http.ResponseEntity;
11 import org.springframework.web.context.request.async.DeferredResult; 15 import org.springframework.web.context.request.async.DeferredResult;
@@ -17,13 +21,17 @@ public interface IPlayService { @@ -17,13 +21,17 @@ public interface IPlayService {
17 21
18 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); 22 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
19 23
  24 + void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
  25 + ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
  26 + InviteTimeOutCallback timeoutCallback, String uuid);
20 PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback); 27 PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent, Runnable timeoutCallback);
21 28
22 MediaServerItem getNewMediaServerItem(Device device); 29 MediaServerItem getNewMediaServerItem(Device device);
23 30
24 - void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String toString); 31 + void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String toString);
25 32
26 - DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback errorCallBack); 33 + DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
  34 + DeferredResult<ResponseEntity<String>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
27 35
28 void zlmServerOffline(String mediaServerId); 36 void zlmServerOffline(String mediaServerId);
29 } 37 }
src/main/java/com/genersoft/iot/vmp/service/bean/InviteTimeOutCallback.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.bean;
  2 +
  3 +public interface InviteTimeOutCallback {
  4 +
  5 + void run(int code, String msg); // code: 0 sip超时, 1 收流超时
  6 +}
src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java
@@ -7,9 +7,9 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -7,9 +7,9 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 import javax.sip.RequestEvent; 7 import javax.sip.RequestEvent;
8 8
9 public class PlayBackResult<T> { 9 public class PlayBackResult<T> {
10 - private int code;  
11 - private T data;  
12 - private MediaServerItem mediaServerItem; 10 + private int code;
  11 + private T data;
  12 + private MediaServerItem mediaServerItem;
13 private JSONObject response; 13 private JSONObject response;
14 private SipSubscribe.EventResult event; 14 private SipSubscribe.EventResult event;
15 15
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -512,7 +512,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -512,7 +512,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
512 param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex)); 512 param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
513 param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex)); 513 param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex));
514 param.put("hook.timeoutSec","20"); 514 param.put("hook.timeoutSec","20");
515 - param.put("general.streamNoneReaderDelayMS","-1".equals(mediaServerItem.getStreamNoneReaderDelayMS())?"3600000":mediaServerItem.getStreamNoneReaderDelayMS() ); 515 + param.put("general.streamNoneReaderDelayMS",mediaServerItem.getStreamNoneReaderDelayMS()==-1?"3600000":mediaServerItem.getStreamNoneReaderDelayMS() );
516 // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 516 // 推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。
517 // 置0关闭此特性(推流断开会导致立即断开播放器) 517 // 置0关闭此特性(推流断开会导致立即断开播放器)
518 // 此参数不应大于播放器超时时间 518 // 此参数不应大于播放器超时时间
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -16,6 +16,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; @@ -16,6 +16,7 @@ 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.MediaServerItem; 17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
18 import com.genersoft.iot.vmp.service.IMediaServerService; 18 import com.genersoft.iot.vmp.service.IMediaServerService;
  19 +import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
19 import com.genersoft.iot.vmp.service.bean.PlayBackCallback; 20 import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
20 import com.genersoft.iot.vmp.service.bean.PlayBackResult; 21 import com.genersoft.iot.vmp.service.bean.PlayBackResult;
21 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 22 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -27,6 +28,7 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; @@ -27,6 +28,7 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
27 import com.genersoft.iot.vmp.service.IMediaService; 28 import com.genersoft.iot.vmp.service.IMediaService;
28 import com.genersoft.iot.vmp.service.IPlayService; 29 import com.genersoft.iot.vmp.service.IPlayService;
29 import gov.nist.javax.sip.stack.SIPDialog; 30 import gov.nist.javax.sip.stack.SIPDialog;
  31 +import jdk.nashorn.internal.ir.RuntimeNode;
30 import org.slf4j.Logger; 32 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory; 33 import org.slf4j.LoggerFactory;
32 import org.springframework.beans.factory.annotation.Autowired; 34 import org.springframework.beans.factory.annotation.Autowired;
@@ -36,6 +38,9 @@ import org.springframework.stereotype.Service; @@ -36,6 +38,9 @@ import org.springframework.stereotype.Service;
36 import org.springframework.util.ResourceUtils; 38 import org.springframework.util.ResourceUtils;
37 import org.springframework.web.context.request.async.DeferredResult; 39 import org.springframework.web.context.request.async.DeferredResult;
38 40
  41 +import javax.sip.header.CallIdHeader;
  42 +import javax.sip.header.Header;
  43 +import javax.sip.message.Request;
39 import java.io.FileNotFoundException; 44 import java.io.FileNotFoundException;
40 import java.util.*; 45 import java.util.*;
41 46
@@ -79,6 +84,8 @@ public class PlayServiceImpl implements IPlayService { @@ -79,6 +84,8 @@ public class PlayServiceImpl implements IPlayService {
79 private UserSetup userSetup; 84 private UserSetup userSetup;
80 85
81 86
  87 +
  88 +
82 @Override 89 @Override
83 public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, 90 public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId,
84 ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, 91 ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
@@ -141,67 +148,7 @@ public class PlayServiceImpl implements IPlayService { @@ -141,67 +148,7 @@ public class PlayServiceImpl implements IPlayService {
141 e.printStackTrace(); 148 e.printStackTrace();
142 } 149 }
143 }); 150 });
144 - if (streamInfo == null) {  
145 - String streamId = null;  
146 - if (mediaServerItem.isRtpEnable()) {  
147 - streamId = String.format("%s_%s", device.getDeviceId(), channelId);  
148 - }  
149 - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);  
150 - // 超时处理  
151 - Timer timer = new Timer();  
152 - timer.schedule(new TimerTask() {  
153 - @Override  
154 - public void run() {  
155 - logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));  
156 - if (timeoutCallback != null) {  
157 - timeoutCallback.run();  
158 - }  
159 - WVPResult wvpResult = new WVPResult();  
160 - wvpResult.setCode(-1);  
161 - SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());  
162 - if (dialog != null) {  
163 - wvpResult.setMsg("收流超时,请稍候重试");  
164 - // 点播超时回复BYE 同时释放ssrc以及此次点播的资源  
165 - cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream());  
166 - }else {  
167 - wvpResult.setMsg("点播超时,请稍候重试");  
168 - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());  
169 - mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream());  
170 - streamSession.remove(deviceId, channelId, ssrcInfo.getStream());  
171 - }  
172 -  
173 - msg.setData(wvpResult);  
174 -  
175 - // 回复之前所有的点播请求  
176 - resultHolder.invokeAllResult(msg);  
177 - }  
178 - }, userSetup.getPlayTimeout());  
179 - // 发送点播消息  
180 - cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> {  
181 - logger.info("收到订阅消息: " + response.toJSONString());  
182 - timer.cancel();  
183 - onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid);  
184 - if (hookEvent != null) {  
185 - hookEvent.response(mediaServerItem, response);  
186 - }  
187 - }, (event) -> {  
188 - timer.cancel();  
189 - WVPResult wvpResult = new WVPResult();  
190 - wvpResult.setCode(-1);  
191 - // 点播返回sip错误  
192 - mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream());  
193 - // 释放ssrc  
194 - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());  
195 - streamSession.remove(deviceId, channelId, ssrcInfo.getStream());  
196 -  
197 - wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));  
198 - msg.setData(wvpResult);  
199 - resultHolder.invokeAllResult(msg);  
200 - if (errorEvent != null) {  
201 - errorEvent.response(event);  
202 - }  
203 - });  
204 - } else { 151 + if (streamInfo != null) {
205 String streamId = streamInfo.getStream(); 152 String streamId = streamInfo.getStream();
206 if (streamId == null) { 153 if (streamId == null) {
207 WVPResult wvpResult = new WVPResult(); 154 WVPResult wvpResult = new WVPResult();
@@ -227,67 +174,109 @@ public class PlayServiceImpl implements IPlayService { @@ -227,67 +174,109 @@ public class PlayServiceImpl implements IPlayService {
227 if (hookEvent != null) { 174 if (hookEvent != null) {
228 hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo))); 175 hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo)));
229 } 176 }
230 - } else {  
231 - // TODO 点播前是否重置状态 177 + }else {
232 redisCatchStorage.stopPlay(streamInfo); 178 redisCatchStorage.stopPlay(streamInfo);
233 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 179 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
234 - String streamId2 = null;  
235 - if (mediaServerItem.isRtpEnable()) {  
236 - streamId2 = String.format("%s_%s", device.getDeviceId(), channelId);  
237 - }  
238 - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2);  
239 - // 超时处理  
240 - Timer timer = new Timer();  
241 - timer.schedule(new TimerTask() {  
242 - @Override  
243 - public void run() {  
244 - logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));  
245 - if (timeoutCallback != null) {  
246 - timeoutCallback.run();  
247 - }  
248 - WVPResult wvpResult = new WVPResult();  
249 - wvpResult.setCode(-1);  
250 - SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());  
251 - if (dialog != null) {  
252 - wvpResult.setMsg("收流超时,请稍候重试");  
253 - // 点播超时回复BYE 同时释放ssrc以及此次点播的资源  
254 - cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream());  
255 - }else {  
256 - wvpResult.setMsg("点播超时,请稍候重试");  
257 - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());  
258 - mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream());  
259 - streamSession.remove(deviceId, channelId, ssrcInfo.getStream());  
260 - }  
261 -  
262 - msg.setData(wvpResult);  
263 - // 回复之前所有的点播请求  
264 - resultHolder.invokeAllResult(msg);  
265 - }  
266 - }, userSetup.getPlayTimeout());  
267 - cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {  
268 - logger.info("收到订阅消息: " + response.toJSONString());  
269 - onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid);  
270 - }, (event) -> {  
271 - mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream());  
272 - // 释放ssrc  
273 - mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());  
274 - streamSession.remove(deviceId, channelId, ssrcInfo.getStream());  
275 - WVPResult wvpResult = new WVPResult();  
276 - wvpResult.setCode(-1);  
277 - wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));  
278 - msg.setData(wvpResult);  
279 - resultHolder.invokeAllResult(msg);  
280 - }); 180 + streamInfo = null;
281 } 181 }
282 - }  
283 182
  183 + }
  184 + if (streamInfo == null) {
  185 + String streamId = null;
  186 + if (mediaServerItem.isRtpEnable()) {
  187 + streamId = String.format("%s_%s", device.getDeviceId(), channelId);
  188 + }
  189 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);
  190 + play(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInUse, response)->{
  191 + if (hookEvent != null) {
  192 + hookEvent.response(mediaServerItem, response);
  193 + }
  194 + }, event -> {
  195 + // sip error错误
  196 + WVPResult wvpResult = new WVPResult();
  197 + wvpResult.setCode(-1);
  198 + wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
  199 + msg.setData(wvpResult);
  200 + resultHolder.invokeAllResult(msg);
  201 + if (errorEvent != null) {
  202 + errorEvent.response(event);
  203 + }
  204 + }, (code, msgStr)->{
  205 + // invite点播超时
  206 + WVPResult wvpResult = new WVPResult();
  207 + wvpResult.setCode(-1);
  208 + if (code == 0) {
  209 + wvpResult.setMsg("点播超时,请稍候重试");
  210 + }else if (code == 1) {
  211 + wvpResult.setMsg("收流超时,请稍候重试");
  212 + }
  213 + msg.setData(wvpResult);
  214 + // 回复之前所有的点播请求
  215 + resultHolder.invokeAllResult(msg);
  216 + }, uuid);
  217 + }
284 return playResult; 218 return playResult;
285 } 219 }
286 220
  221 +
  222 +
  223 + @Override
  224 + public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
  225 + ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
  226 + InviteTimeOutCallback timeoutCallback, String uuid) {
  227 +
  228 + String streamId = null;
  229 + if (mediaServerItem.isRtpEnable()) {
  230 + streamId = String.format("%s_%s", device.getDeviceId(), channelId);
  231 + }
  232 + if (ssrcInfo == null) {
  233 + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);
  234 + }
  235 +
  236 + // 超时处理
  237 + Timer timer = new Timer();
  238 + SSRCInfo finalSsrcInfo = ssrcInfo;
  239 + timer.schedule(new TimerTask() {
  240 + @Override
  241 + public void run() {
  242 + logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", device.getDeviceId(), channelId));
  243 +
  244 + SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
  245 + if (dialog != null) {
  246 + timeoutCallback.run(1, "收流超时");
  247 + // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
  248 + cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null);
  249 + }else {
  250 + timeoutCallback.run(0, "点播超时");
  251 + mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
  252 + mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
  253 + streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
  254 + }
  255 + }
  256 + }, userSetup.getPlayTimeout());
  257 +
  258 + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
  259 + logger.info("收到订阅消息: " + response.toJSONString());
  260 + timer.cancel();
  261 + // hook响应
  262 + onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid);
  263 + hookEvent.response(mediaServerItemInuse, response);
  264 + }, (event) -> {
  265 + timer.cancel();
  266 + mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
  267 + // 释放ssrc
  268 + mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
  269 + streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
  270 + errorEvent.response(event);
  271 + });
  272 + }
  273 +
287 @Override 274 @Override
288 public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) { 275 public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) {
289 RequestMessage msg = new RequestMessage(); 276 RequestMessage msg = new RequestMessage();
290 - msg.setId(uuid); 277 + if (uuid != null) {
  278 + msg.setId(uuid);
  279 + }
291 msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId); 280 msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId);
292 StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); 281 StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
293 if (streamInfo != null) { 282 if (streamInfo != null) {
@@ -297,7 +286,6 @@ public class PlayServiceImpl implements IPlayService { @@ -297,7 +286,6 @@ public class PlayServiceImpl implements IPlayService {
297 storager.startPlay(deviceId, channelId, streamInfo.getStream()); 286 storager.startPlay(deviceId, channelId, streamInfo.getStream());
298 } 287 }
299 redisCatchStorage.startPlay(streamInfo); 288 redisCatchStorage.startPlay(streamInfo);
300 - msg.setData(JSON.toJSONString(streamInfo));  
301 289
302 WVPResult wvpResult = new WVPResult(); 290 WVPResult wvpResult = new WVPResult();
303 wvpResult.setCode(0); 291 wvpResult.setCode(0);
@@ -329,9 +317,24 @@ public class PlayServiceImpl implements IPlayService { @@ -329,9 +317,24 @@ public class PlayServiceImpl implements IPlayService {
329 return mediaServerItem; 317 return mediaServerItem;
330 } 318 }
331 319
  320 + @Override
  321 + public DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime,
  322 + String endTime,InviteStreamCallback inviteStreamCallback,
  323 + PlayBackCallback callback) {
  324 + Device device = storager.queryVideoDevice(deviceId);
  325 + if (device == null) return null;
  326 + MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
  327 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);
  328 +
  329 + return playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback);
  330 + }
332 331
333 @Override 332 @Override
334 - public DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback callback) { 333 + public DeferredResult<ResponseEntity<String>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
  334 + String deviceId, String channelId, String startTime,
  335 + String endTime, InviteStreamCallback infoCallBack,
  336 + PlayBackCallback playBackCallback) {
  337 + if (mediaServerItem == null || ssrcInfo == null) return null;
335 String uuid = UUID.randomUUID().toString(); 338 String uuid = UUID.randomUUID().toString();
336 String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId; 339 String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
337 DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L); 340 DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L);
@@ -341,8 +344,6 @@ public class PlayServiceImpl implements IPlayService { @@ -341,8 +344,6 @@ public class PlayServiceImpl implements IPlayService {
341 return result; 344 return result;
342 } 345 }
343 346
344 - MediaServerItem newMediaServerItem = getNewMediaServerItem(device);  
345 - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);  
346 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId, uuid, result); 347 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId, uuid, result);
347 RequestMessage msg = new RequestMessage(); 348 RequestMessage msg = new RequestMessage();
348 msg.setId(uuid); 349 msg.setId(uuid);
@@ -356,63 +357,62 @@ public class PlayServiceImpl implements IPlayService { @@ -356,63 +357,62 @@ public class PlayServiceImpl implements IPlayService {
356 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 357 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
357 playBackResult.setCode(-1); 358 playBackResult.setCode(-1);
358 playBackResult.setData(msg); 359 playBackResult.setData(msg);
359 - callback.call(playBackResult); 360 + playBackCallback.call(playBackResult);
360 SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); 361 SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream());
361 // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 362 // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
362 if (dialog != null) { 363 if (dialog != null) {
363 // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 364 // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
364 - cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); 365 + cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
365 }else { 366 }else {
366 - mediaServerService.releaseSsrc(newMediaServerItem.getId(), ssrcInfo.getSsrc()); 367 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
367 mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); 368 mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream());
368 streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); 369 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
369 } 370 }
370 - cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); 371 + cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null);
371 // 回复之前所有的点播请求 372 // 回复之前所有的点播请求
372 - callback.call(playBackResult); 373 + playBackCallback.call(playBackResult);
373 } 374 }
374 }, userSetup.getPlayTimeout()); 375 }, userSetup.getPlayTimeout());
375 - cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> {  
376 - logger.info("收到订阅消息: " + response.toJSONString());  
377 - timer.cancel();  
378 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);  
379 - if (streamInfo == null) {  
380 - logger.warn("设备回放API调用失败!");  
381 - msg.setData("设备回放API调用失败!");  
382 - playBackResult.setCode(-1);  
383 - playBackResult.setData(msg);  
384 - callback.call(playBackResult);  
385 - return;  
386 - }  
387 - redisCatchStorage.startPlayback(streamInfo);  
388 - msg.setData(JSON.toJSONString(streamInfo));  
389 - playBackResult.setCode(0);  
390 - playBackResult.setData(msg);  
391 - playBackResult.setMediaServerItem(mediaServerItem);  
392 - playBackResult.setResponse(response);  
393 - callback.call(playBackResult);  
394 - }, event -> {  
395 - timer.cancel();  
396 - msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));  
397 - playBackResult.setCode(-1);  
398 - playBackResult.setData(msg);  
399 - playBackResult.setEvent(event);  
400 - callback.call(playBackResult);  
401 - streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());  
402 - }); 376 + cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack,
  377 + (InviteStreamInfo inviteStreamInfo) -> {
  378 + logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString());
  379 + timer.cancel();
  380 + StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId);
  381 + if (streamInfo == null) {
  382 + logger.warn("设备回放API调用失败!");
  383 + msg.setData("设备回放API调用失败!");
  384 + playBackResult.setCode(-1);
  385 + playBackResult.setData(msg);
  386 + playBackCallback.call(playBackResult);
  387 + return;
  388 + }
  389 + redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId());
  390 + msg.setData(JSON.toJSONString(streamInfo));
  391 + playBackResult.setCode(0);
  392 + playBackResult.setData(msg);
  393 + playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
  394 + playBackResult.setResponse(inviteStreamInfo.getResponse());
  395 + playBackCallback.call(playBackResult);
  396 + }, event -> {
  397 + timer.cancel();
  398 + msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
  399 + playBackResult.setCode(-1);
  400 + playBackResult.setData(msg);
  401 + playBackResult.setEvent(event);
  402 + playBackCallback.call(playBackResult);
  403 + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
  404 + });
403 return result; 405 return result;
404 } 406 }
405 407
406 -  
407 -  
408 @Override 408 @Override
409 - public void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) { 409 + public void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String uuid) {
410 RequestMessage msg = new RequestMessage(); 410 RequestMessage msg = new RequestMessage();
411 msg.setKey(DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId); 411 msg.setKey(DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId);
412 msg.setId(uuid); 412 msg.setId(uuid);
413 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); 413 + StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId);
414 if (streamInfo != null) { 414 if (streamInfo != null) {
415 - redisCatchStorage.startDownload(streamInfo); 415 + redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId());
416 msg.setData(JSON.toJSONString(streamInfo)); 416 msg.setData(JSON.toJSONString(streamInfo));
417 resultHolder.invokeResult(msg); 417 resultHolder.invokeResult(msg);
418 } else { 418 } else {
@@ -449,7 +449,8 @@ public class PlayServiceImpl implements IPlayService { @@ -449,7 +449,8 @@ public class PlayServiceImpl implements IPlayService {
449 if (allSsrc.size() > 0) { 449 if (allSsrc.size() > 0) {
450 for (SsrcTransaction ssrcTransaction : allSsrc) { 450 for (SsrcTransaction ssrcTransaction : allSsrc) {
451 if(ssrcTransaction.getMediaServerId().equals(mediaServerId)) { 451 if(ssrcTransaction.getMediaServerId().equals(mediaServerId)) {
452 - cmder.streamByeCmd(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); 452 + cmder.streamByeCmd(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(),
  453 + ssrcTransaction.getStream(), null);
453 } 454 }
454 } 455 }
455 } 456 }
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -47,17 +47,15 @@ public interface IRedisCatchStorage { @@ -47,17 +47,15 @@ public interface IRedisCatchStorage {
47 47
48 StreamInfo queryPlayByStreamId(String steamId); 48 StreamInfo queryPlayByStreamId(String steamId);
49 49
50 - StreamInfo queryPlaybackByStreamId(String steamId);  
51 -  
52 StreamInfo queryPlayByDevice(String deviceId, String channelId); 50 StreamInfo queryPlayByDevice(String deviceId, String channelId);
53 51
54 Map<String, StreamInfo> queryPlayByDeviceId(String deviceId); 52 Map<String, StreamInfo> queryPlayByDeviceId(String deviceId);
55 53
56 - boolean startPlayback(StreamInfo stream); 54 + boolean startPlayback(StreamInfo stream, String callId);
57 55
58 - boolean stopPlayback(StreamInfo streamInfo); 56 + boolean stopPlayback(String deviceId, String channelId, String stream, String callId);
59 57
60 - StreamInfo queryPlaybackByDevice(String deviceId, String code); 58 + StreamInfo queryPlayback(String deviceId, String channelID, String stream, String callId);
61 59
62 void updatePlatformCatchInfo(ParentPlatformCatch parentPlatformCatch); 60 void updatePlatformCatchInfo(ParentPlatformCatch parentPlatformCatch);
63 61
@@ -167,9 +165,9 @@ public interface IRedisCatchStorage { @@ -167,9 +165,9 @@ public interface IRedisCatchStorage {
167 * 开始下载录像时存入 165 * 开始下载录像时存入
168 * @param streamInfo 166 * @param streamInfo
169 */ 167 */
170 - boolean startDownload(StreamInfo streamInfo); 168 + boolean startDownload(StreamInfo streamInfo, String callId);
171 169
172 - StreamInfo queryDownloadByStreamId(String streamId); 170 + StreamInfo queryDownload(String deviceId, String channelId, String stream, String callId);
173 171
174 /** 172 /**
175 * 查找第三方系统留下的国标预设值 173 * 查找第三方系统留下的国标预设值
@@ -204,18 +202,8 @@ public interface IRedisCatchStorage { @@ -204,18 +202,8 @@ public interface IRedisCatchStorage {
204 202
205 void resetAllSN(); 203 void resetAllSN();
206 204
207 - void updateSubscribe(String key, SubscribeInfo subscribeInfo);  
208 -  
209 - SubscribeInfo getSubscribe(String key);  
210 -  
211 - void delSubscribe(String key);  
212 -  
213 MediaItem getStreamInfo(String app, String streamId, String mediaServerId); 205 MediaItem getStreamInfo(String app, String streamId, String mediaServerId);
214 206
215 - List<SubscribeInfo> getAllSubscribe();  
216 -  
217 - List<String> getAllSubscribePlatform();  
218 -  
219 void addCpuInfo(double cpuInfo); 207 void addCpuInfo(double cpuInfo);
220 208
221 void addMemInfo(double memInfo); 209 void addMemInfo(double memInfo);
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -231,7 +231,6 @@ public interface DeviceChannelMapper { @@ -231,7 +231,6 @@ public interface DeviceChannelMapper {
231 " name as title,\n" + 231 " name as title,\n" +
232 " channelId as \"value\",\n" + 232 " channelId as \"value\",\n" +
233 " channelId as \"key\",\n" + 233 " channelId as \"key\",\n" +
234 - " channelId,\n" +  
235 " longitude,\n" + 234 " longitude,\n" +
236 " latitude\n" + 235 " latitude\n" +
237 " from device_channel\n" + 236 " from device_channel\n" +
@@ -248,4 +247,13 @@ public interface DeviceChannelMapper { @@ -248,4 +247,13 @@ public interface DeviceChannelMapper {
248 "<foreach collection='channels' item='item' open='(' separator=',' close=')' > #{item.channelId}</foreach>" + 247 "<foreach collection='channels' item='item' open='(' separator=',' close=')' > #{item.channelId}</foreach>" +
249 " </script>"}) 248 " </script>"})
250 int cleanChannelsNotInList(String deviceId, List<DeviceChannel> channels); 249 int cleanChannelsNotInList(String deviceId, List<DeviceChannel> channels);
  250 +
  251 + @Update(" update device_channel" +
  252 + " set subCount = (select *" +
  253 + " from (select count(0)" +
  254 + " from device_channel" +
  255 + " where deviceId = #{deviceId} and parentId = #{channelId}) as temp)" +
  256 + " where deviceId = #{deviceId} " +
  257 + " and channelId = #{channelId}")
  258 + int updateChannelSubCount(String deviceId, String channelId);
251 } 259 }
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java
@@ -55,7 +55,7 @@ public interface PlatformChannelMapper { @@ -55,7 +55,7 @@ public interface PlatformChannelMapper {
55 int cleanChannelForGB(String platformId); 55 int cleanChannelForGB(String platformId);
56 56
57 @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}' and pgc.platformId='${platformId}'") 57 @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}' and pgc.platformId='${platformId}'")
58 - DeviceChannel queryChannelInParentPlatform(String platformId, String channelId); 58 + List<DeviceChannel> queryChannelInParentPlatform(String platformId, String channelId);
59 59
60 @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " + 60 @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " +
61 " from device_channel dc left join platform_gb_channel pgc on dc.id = pgc.deviceChannelId " + 61 " from device_channel dc left join platform_gb_channel pgc on dc.id = pgc.deviceChannelId " +
@@ -67,7 +67,7 @@ public interface PlatformChannelMapper { @@ -67,7 +67,7 @@ public interface PlatformChannelMapper {
67 " left join device_channel dc on dc.id = pgc.deviceChannelId\n" + 67 " left join device_channel dc on dc.id = pgc.deviceChannelId\n" +
68 " left join device d on dc.deviceId = d.deviceId\n" + 68 " left join device d on dc.deviceId = d.deviceId\n" +
69 "where dc.channelId = #{channelId} and pgc.platformId=#{platformId}") 69 "where dc.channelId = #{channelId} and pgc.platformId=#{platformId}")
70 - Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId); 70 + List<Device> queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
71 71
72 @Delete("<script> "+ 72 @Delete("<script> "+
73 "DELETE FROM platform_gb_channel WHERE catalogId=#{id}" + 73 "DELETE FROM platform_gb_channel WHERE catalogId=#{id}" +
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -134,13 +134,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -134,13 +134,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
134 } 134 }
135 135
136 @Override 136 @Override
137 - public StreamInfo queryPlaybackByStreamId(String streamId) {  
138 - List<Object> playLeys = redis.scan(String.format("%S_%s_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, userSetup.getServerId(), streamId));  
139 - if (playLeys == null || playLeys.size() == 0) return null;  
140 - return (StreamInfo)redis.get(playLeys.get(0).toString());  
141 - }  
142 -  
143 - @Override  
144 public StreamInfo queryPlayByDevice(String deviceId, String channelId) { 137 public StreamInfo queryPlayByDevice(String deviceId, String channelId) {
145 List<Object> playLeys = redis.scan(String.format("%S_%s_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX, 138 List<Object> playLeys = redis.scan(String.format("%S_%s_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
146 userSetup.getServerId(), 139 userSetup.getServerId(),
@@ -166,49 +159,67 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -166,49 +159,67 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
166 159
167 160
168 @Override 161 @Override
169 - public boolean startPlayback(StreamInfo stream) {  
170 - return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,  
171 - userSetup.getServerId(), stream.getStream(), stream.getDeviceID(), stream.getChannelId()), stream); 162 + public boolean startPlayback(StreamInfo stream, String callId) {
  163 + return redis.set(String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
  164 + userSetup.getServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream);
172 } 165 }
173 166
174 @Override 167 @Override
175 - public boolean startDownload(StreamInfo streamInfo) {  
176 - return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, userSetup.getServerId(),  
177 - streamInfo.getStream(), streamInfo.getDeviceID(), streamInfo.getChannelId()), streamInfo); 168 + public boolean startDownload(StreamInfo stream, String callId) {
  169 + return redis.set(String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX,
  170 + userSetup.getServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream);
178 } 171 }
179 172
180 @Override 173 @Override
181 - public boolean stopPlayback(StreamInfo streamInfo) {  
182 - if (streamInfo == null) return false;  
183 - DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(streamInfo.getDeviceID(), streamInfo.getChannelId()); 174 + public boolean stopPlayback(String deviceId, String channelId, String stream, String callId) {
  175 + DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId);
184 if (deviceChannel != null) { 176 if (deviceChannel != null) {
185 deviceChannel.setStreamId(null); 177 deviceChannel.setStreamId(null);
186 - deviceChannel.setDeviceId(streamInfo.getDeviceID()); 178 + deviceChannel.setDeviceId(deviceId);
187 deviceChannelMapper.update(deviceChannel); 179 deviceChannelMapper.update(deviceChannel);
188 } 180 }
189 - return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, 181 + if (deviceId == null) deviceId = "*";
  182 + if (channelId == null) channelId = "*";
  183 + if (stream == null) stream = "*";
  184 + if (callId == null) callId = "*";
  185 + String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
190 userSetup.getServerId(), 186 userSetup.getServerId(),
191 - streamInfo.getStream(),  
192 - streamInfo.getDeviceID(),  
193 - streamInfo.getChannelId())); 187 + deviceId,
  188 + channelId,
  189 + stream,
  190 + callId
  191 + );
  192 + List<Object> scan = redis.scan(key);
  193 + if (scan.size() > 0) {
  194 + for (Object keyObj : scan) {
  195 + redis.del((String) keyObj);
  196 + }
  197 + }
  198 + return true;
194 } 199 }
195 200
196 @Override 201 @Override
197 - public StreamInfo queryPlaybackByDevice(String deviceId, String code) {  
198 - // String format = String.format("%S_*_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,  
199 - // deviceId,  
200 - // code);  
201 - List<Object> playLeys = redis.scan(String.format("%S_%s_*_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, 202 + public StreamInfo queryPlayback(String deviceId, String channelId, String stream, String callId) {
  203 + if (stream == null && callId == null) {
  204 + return null;
  205 + }
  206 + if (deviceId == null) deviceId = "*";
  207 + if (channelId == null) channelId = "*";
  208 + if (stream == null) stream = "*";
  209 + if (callId == null) callId = "*";
  210 + String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
202 userSetup.getServerId(), 211 userSetup.getServerId(),
203 deviceId, 212 deviceId,
204 - code));  
205 - if (playLeys == null || playLeys.size() == 0) {  
206 - playLeys = redis.scan(String.format("%S_%s_*_*_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,  
207 - userSetup.getServerId(),  
208 - deviceId)); 213 + channelId,
  214 + stream,
  215 + callId
  216 + );
  217 + List<Object> streamInfoScan = redis.scan(key);
  218 + if (streamInfoScan.size() > 0) {
  219 + return (StreamInfo) redis.get((String) streamInfoScan.get(0));
  220 + }else {
  221 + return null;
209 } 222 }
210 - if (playLeys == null || playLeys.size() == 0) return null;  
211 - return (StreamInfo)redis.get(playLeys.get(0).toString());  
212 } 223 }
213 224
214 @Override 225 @Override
@@ -361,7 +372,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -361,7 +372,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
361 } 372 }
362 } 373 }
363 374
364 - List<Object> playBackers = redis.scan(String.format("%S_%s_*_%s_*", VideoManagerConstants.PLAY_BLACK_PREFIX, 375 + List<Object> playBackers = redis.scan(String.format("%S_%s_%s_*_*_*", VideoManagerConstants.PLAY_BLACK_PREFIX,
365 userSetup.getServerId(), 376 userSetup.getServerId(),
366 deviceId)); 377 deviceId));
367 if (playBackers.size() > 0) { 378 if (playBackers.size() > 0) {
@@ -426,10 +437,27 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -426,10 +437,27 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
426 } 437 }
427 438
428 @Override 439 @Override
429 - public StreamInfo queryDownloadByStreamId(String streamId) {  
430 - List<Object> playLeys = redis.scan(String.format("%S_%s_%s_*", VideoManagerConstants.DOWNLOAD_PREFIX, userSetup.getServerId(), streamId));  
431 - if (playLeys == null || playLeys.size() == 0) return null;  
432 - return (StreamInfo)redis.get(playLeys.get(0).toString()); 440 + public StreamInfo queryDownload(String deviceId, String channelId, String stream, String callId) {
  441 + if (stream == null && callId == null) {
  442 + return null;
  443 + }
  444 + if (deviceId == null) deviceId = "*";
  445 + if (channelId == null) channelId = "*";
  446 + if (stream == null) stream = "*";
  447 + if (callId == null) callId = "*";
  448 + String key = String.format("%S_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX,
  449 + userSetup.getServerId(),
  450 + deviceId,
  451 + channelId,
  452 + stream,
  453 + callId
  454 + );
  455 + List<Object> streamInfoScan = redis.scan(key);
  456 + if (streamInfoScan.size() > 0) {
  457 + return (StreamInfo) redis.get((String) streamInfoScan.get(0));
  458 + }else {
  459 + return null;
  460 + }
433 } 461 }
434 462
435 @Override 463 @Override
@@ -491,21 +519,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -491,21 +519,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
491 } 519 }
492 520
493 @Override 521 @Override
494 - public void updateSubscribe(String key, SubscribeInfo subscribeInfo) {  
495 - redis.set(key, subscribeInfo, subscribeInfo.getExpires());  
496 - }  
497 -  
498 - @Override  
499 - public SubscribeInfo getSubscribe(String key) {  
500 - return (SubscribeInfo)redis.get(key);  
501 - }  
502 -  
503 - @Override  
504 - public void delSubscribe(String key) {  
505 - redis.del(key);  
506 - }  
507 -  
508 - @Override  
509 public List<GPSMsgInfo> getAllGpsMsgInfo() { 522 public List<GPSMsgInfo> getAllGpsMsgInfo() {
510 String scanKey = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetup.getServerId() + "_*"; 523 String scanKey = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetup.getServerId() + "_*";
511 List<GPSMsgInfo> result = new ArrayList<>(); 524 List<GPSMsgInfo> result = new ArrayList<>();
@@ -536,32 +549,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -536,32 +549,6 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
536 } 549 }
537 550
538 @Override 551 @Override
539 - public List<SubscribeInfo> getAllSubscribe() {  
540 - String scanKey = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_Catalog_*";  
541 - List<SubscribeInfo> result = new ArrayList<>();  
542 - List<Object> keys = redis.scan(scanKey);  
543 - for (int i = 0; i < keys.size(); i++) {  
544 - String key = (String) keys.get(i);  
545 - SubscribeInfo subscribeInfo = (SubscribeInfo) redis.get(key);  
546 - result.add(subscribeInfo);  
547 - }  
548 - return result;  
549 - }  
550 -  
551 - @Override  
552 - public List<String> getAllSubscribePlatform() {  
553 - String scanKey = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + userSetup.getServerId() + "_Catalog_*";  
554 - List<String> result = new ArrayList<>();  
555 - List<Object> keys = redis.scan(scanKey);  
556 - for (int i = 0; i < keys.size(); i++) {  
557 - String key = (String) keys.get(i);  
558 - String platformId = key.substring(scanKey.length() - 1);  
559 - result.add(platformId);  
560 - }  
561 - return result;  
562 - }  
563 -  
564 - @Override  
565 public void addCpuInfo(double cpuInfo) { 552 public void addCpuInfo(double cpuInfo) {
566 String key = VideoManagerConstants.SYSTEM_INFO_CPU_PREFIX + userSetup.getServerId(); 553 String key = VideoManagerConstants.SYSTEM_INFO_CPU_PREFIX + userSetup.getServerId();
567 SystemInfoDto<Double> systemInfoDto = new SystemInfoDto<>(); 554 SystemInfoDto<Double> systemInfoDto = new SystemInfoDto<>();
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -42,7 +42,7 @@ import java.util.*; @@ -42,7 +42,7 @@ import java.util.*;
42 @Component 42 @Component
43 public class VideoManagerStoragerImpl implements IVideoManagerStorager { 43 public class VideoManagerStoragerImpl implements IVideoManagerStorager {
44 44
45 - private Logger logger = LoggerFactory.getLogger(VideoManagerStoragerImpl.class); 45 + private final Logger logger = LoggerFactory.getLogger(VideoManagerStoragerImpl.class);
46 46
47 @Autowired 47 @Autowired
48 EventPublisher eventPublisher; 48 EventPublisher eventPublisher;
@@ -171,6 +171,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -171,6 +171,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
171 }else { 171 }else {
172 deviceChannelMapper.update(channel); 172 deviceChannelMapper.update(channel);
173 } 173 }
  174 + deviceChannelMapper.updateChannelSubCount(deviceId,channel.getParentId());
174 } 175 }
175 176
176 @Override 177 @Override
@@ -542,7 +543,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -542,7 +543,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
542 if (parentPlatformCatch == null) { // serverGBId 已变化 543 if (parentPlatformCatch == null) { // serverGBId 已变化
543 ParentPlatform parentPlatById = platformMapper.getParentPlatById(parentPlatform.getId()); 544 ParentPlatform parentPlatById = platformMapper.getParentPlatById(parentPlatform.getId());
544 // 使用旧的查出缓存ID 545 // 使用旧的查出缓存ID
545 - parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatById.getServerGBId()); 546 + parentPlatformCatch = new ParentPlatformCatch();
546 parentPlatformCatch.setId(parentPlatform.getServerGBId()); 547 parentPlatformCatch.setId(parentPlatform.getServerGBId());
547 redisCatchStorage.delPlatformCatchInfo(parentPlatById.getServerGBId()); 548 redisCatchStorage.delPlatformCatchInfo(parentPlatById.getServerGBId());
548 } 549 }
@@ -662,8 +663,16 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -662,8 +663,16 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
662 663
663 @Override 664 @Override
664 public DeviceChannel queryChannelInParentPlatform(String platformId, String channelId) { 665 public DeviceChannel queryChannelInParentPlatform(String platformId, String channelId) {
665 - DeviceChannel channel = platformChannelMapper.queryChannelInParentPlatform(platformId, channelId);  
666 - return channel; 666 + List<DeviceChannel> channels = platformChannelMapper.queryChannelInParentPlatform(platformId, channelId);
  667 + if (channels.size() > 1) {
  668 + // 出现长度大于0的时候肯定是国标通道的ID重复了
  669 + logger.warn("国标ID存在重复:{}", channelId);
  670 + }
  671 + if (channels.size() == 0) {
  672 + return null;
  673 + }else {
  674 + return channels.get(0);
  675 + }
667 } 676 }
668 677
669 @Override 678 @Override
@@ -680,8 +689,18 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -680,8 +689,18 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
680 689
681 @Override 690 @Override
682 public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) { 691 public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) {
683 - Device device = platformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);  
684 - return device; 692 + List<Device> devices = platformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
  693 + if (devices.size() > 1) {
  694 + // 出现长度大于0的时候肯定是国标通道的ID重复了
  695 + logger.warn("国标ID存在重复:{}", channelId);
  696 + }
  697 + if (devices.size() == 0) {
  698 + return null;
  699 + }else {
  700 + return devices.get(0);
  701 + }
  702 +
  703 +
685 } 704 }
686 705
687 /** 706 /**
@@ -1083,6 +1102,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -1083,6 +1102,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
1083 1102
1084 @Override 1103 @Override
1085 public List<ParentPlatform> queryPlatFormListForStreamWithGBId(String app, String stream, List<String> platforms) { 1104 public List<ParentPlatform> queryPlatFormListForStreamWithGBId(String app, String stream, List<String> platforms) {
  1105 + if (platforms == null || platforms.size() == 0) {
  1106 + return new ArrayList<>();
  1107 + }
1086 return platformGbStreamMapper.queryPlatFormListForGBWithGBId(app, stream, platforms); 1108 return platformGbStreamMapper.queryPlatFormListForGBWithGBId(app, stream, platforms);
1087 } 1109 }
1088 1110
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
7 import com.genersoft.iot.vmp.conf.UserSetup; 7 import com.genersoft.iot.vmp.conf.UserSetup;
8 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 8 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
9 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; 9 import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
  10 +import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
10 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; 11 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
11 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
12 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 13 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
@@ -50,6 +51,9 @@ public class PlatformController { @@ -50,6 +51,9 @@ public class PlatformController {
50 private IRedisCatchStorage redisCatchStorage; 51 private IRedisCatchStorage redisCatchStorage;
51 52
52 @Autowired 53 @Autowired
  54 + private SubscribeHolder subscribeHolder;
  55 +
  56 + @Autowired
53 private ISIPCommanderForPlatform commanderForPlatform; 57 private ISIPCommanderForPlatform commanderForPlatform;
54 58
55 @Autowired 59 @Autowired
@@ -110,10 +114,14 @@ public class PlatformController { @@ -110,10 +114,14 @@ public class PlatformController {
110 }) 114 })
111 public PageInfo<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count) { 115 public PageInfo<ParentPlatform> platforms(@PathVariable int page, @PathVariable int count) {
112 116
113 -// if (logger.isDebugEnabled()) {  
114 -// logger.debug("查询所有上级设备API调用");  
115 -// }  
116 - return storager.queryParentPlatformList(page, count); 117 + PageInfo<ParentPlatform> parentPlatformPageInfo = storager.queryParentPlatformList(page, count);
  118 + if (parentPlatformPageInfo.getList().size() > 0) {
  119 + for (ParentPlatform platform : parentPlatformPageInfo.getList()) {
  120 + platform.setGpsSubscribe(subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId()) != null);
  121 + platform.setCatalogSubscribe(subscribeHolder.getCatalogSubscribe(platform.getServerGBId()) != null);
  122 + }
  123 + }
  124 + return parentPlatformPageInfo;
117 } 125 }
118 126
119 /** 127 /**
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
@@ -120,7 +120,7 @@ public class PlayController { @@ -120,7 +120,7 @@ public class PlayController {
120 storager.stopPlay(deviceId, channelId); 120 storager.stopPlay(deviceId, channelId);
121 return result; 121 return result;
122 } 122 }
123 - cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), (event) -> { 123 + cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), null, (event) -> {
124 redisCatchStorage.stopPlay(streamInfo); 124 redisCatchStorage.stopPlay(streamInfo);
125 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 125 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
126 RequestMessage msg = new RequestMessage(); 126 RequestMessage msg = new RequestMessage();
@@ -174,7 +174,7 @@ public class PlayController { @@ -174,7 +174,7 @@ public class PlayController {
174 public ResponseEntity<String> playConvert(@PathVariable String streamId) { 174 public ResponseEntity<String> playConvert(@PathVariable String streamId) {
175 StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); 175 StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
176 if (streamInfo == null) { 176 if (streamInfo == null) {
177 - streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); 177 + streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
178 } 178 }
179 if (streamInfo == null) { 179 if (streamInfo == null) {
180 logger.warn("视频转码API调用失败!, 视频流已经停止!"); 180 logger.warn("视频转码API调用失败!, 视频流已经停止!");
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java
1 package com.genersoft.iot.vmp.vmanager.gb28181.playback; 1 package com.genersoft.iot.vmp.vmanager.gb28181.playback;
2 2
3 import com.genersoft.iot.vmp.common.StreamInfo; 3 import com.genersoft.iot.vmp.common.StreamInfo;
  4 +import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo;
4 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 5 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
5 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 6 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
@@ -93,11 +94,6 @@ public class DownloadController { @@ -93,11 +94,6 @@ public class DownloadController {
93 } 94 }
94 resultHolder.put(key, uuid, result); 95 resultHolder.put(key, uuid, result);
95 Device device = storager.queryVideoDevice(deviceId); 96 Device device = storager.queryVideoDevice(deviceId);
96 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);  
97 - if (streamInfo != null) {  
98 - // 停止之前的下载  
99 - cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream());  
100 - }  
101 97
102 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); 98 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
103 if (newMediaServerItem == null) { 99 if (newMediaServerItem == null) {
@@ -112,9 +108,9 @@ public class DownloadController { @@ -112,9 +108,9 @@ public class DownloadController {
112 108
113 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true); 109 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);
114 110
115 - cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> {  
116 - logger.info("收到订阅消息: " + response.toJSONString());  
117 - playService.onPublishHandlerForDownload(mediaServerItem, response, deviceId, channelId, uuid); 111 + cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (InviteStreamInfo inviteStreamInfo) -> {
  112 + logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString());
  113 + playService.onPublishHandlerForDownload(inviteStreamInfo, deviceId, channelId, uuid);
118 }, event -> { 114 }, event -> {
119 RequestMessage msg = new RequestMessage(); 115 RequestMessage msg = new RequestMessage();
120 msg.setId(uuid); 116 msg.setId(uuid);
@@ -135,7 +131,7 @@ public class DownloadController { @@ -135,7 +131,7 @@ public class DownloadController {
135 @GetMapping("/stop/{deviceId}/{channelId}/{stream}") 131 @GetMapping("/stop/{deviceId}/{channelId}/{stream}")
136 public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) { 132 public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
137 133
138 - cmder.streamByeCmd(deviceId, channelId, stream); 134 + cmder.streamByeCmd(deviceId, channelId, stream, null);
139 135
140 if (logger.isDebugEnabled()) { 136 if (logger.isDebugEnabled()) {
141 logger.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId)); 137 logger.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId));
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
@@ -77,7 +77,7 @@ public class PlaybackController { @@ -77,7 +77,7 @@ public class PlaybackController {
77 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId)); 77 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId));
78 } 78 }
79 79
80 - DeferredResult<ResponseEntity<String>> result = playService.playBack(deviceId, channelId, startTime, endTime, wvpResult->{ 80 + DeferredResult<ResponseEntity<String>> result = playService.playBack(deviceId, channelId, startTime, endTime, null, wvpResult->{
81 resultHolder.invokeResult(wvpResult.getData()); 81 resultHolder.invokeResult(wvpResult.getData());
82 }); 82 });
83 83
@@ -96,7 +96,7 @@ public class PlaybackController { @@ -96,7 +96,7 @@ public class PlaybackController {
96 @PathVariable String channelId, 96 @PathVariable String channelId,
97 @PathVariable String stream) { 97 @PathVariable String stream) {
98 98
99 - cmder.streamByeCmd(deviceId, channelId, stream); 99 + cmder.streamByeCmd(deviceId, channelId, stream, null);
100 100
101 if (logger.isDebugEnabled()) { 101 if (logger.isDebugEnabled()) {
102 logger.debug(String.format("设备录像回放停止 API调用,deviceId/channelId:%s/%s", deviceId, channelId)); 102 logger.debug(String.format("设备录像回放停止 API调用,deviceId/channelId:%s/%s", deviceId, channelId));
@@ -124,7 +124,7 @@ public class PlaybackController { @@ -124,7 +124,7 @@ public class PlaybackController {
124 public ResponseEntity<String> playPause(@PathVariable String streamId) { 124 public ResponseEntity<String> playPause(@PathVariable String streamId) {
125 logger.info("playPause: "+streamId); 125 logger.info("playPause: "+streamId);
126 JSONObject json = new JSONObject(); 126 JSONObject json = new JSONObject();
127 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); 127 + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
128 if (null == streamInfo) { 128 if (null == streamInfo) {
129 json.put("msg", "streamId不存在"); 129 json.put("msg", "streamId不存在");
130 logger.warn("streamId不存在!"); 130 logger.warn("streamId不存在!");
@@ -144,7 +144,7 @@ public class PlaybackController { @@ -144,7 +144,7 @@ public class PlaybackController {
144 public ResponseEntity<String> playResume(@PathVariable String streamId) { 144 public ResponseEntity<String> playResume(@PathVariable String streamId) {
145 logger.info("playResume: "+streamId); 145 logger.info("playResume: "+streamId);
146 JSONObject json = new JSONObject(); 146 JSONObject json = new JSONObject();
147 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); 147 + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
148 if (null == streamInfo) { 148 if (null == streamInfo) {
149 json.put("msg", "streamId不存在"); 149 json.put("msg", "streamId不存在");
150 logger.warn("streamId不存在!"); 150 logger.warn("streamId不存在!");
@@ -165,7 +165,7 @@ public class PlaybackController { @@ -165,7 +165,7 @@ public class PlaybackController {
165 public ResponseEntity<String> playSeek(@PathVariable String streamId, @PathVariable long seekTime) { 165 public ResponseEntity<String> playSeek(@PathVariable String streamId, @PathVariable long seekTime) {
166 logger.info("playSeek: "+streamId+", "+seekTime); 166 logger.info("playSeek: "+streamId+", "+seekTime);
167 JSONObject json = new JSONObject(); 167 JSONObject json = new JSONObject();
168 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); 168 + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
169 if (null == streamInfo) { 169 if (null == streamInfo) {
170 json.put("msg", "streamId不存在"); 170 json.put("msg", "streamId不存在");
171 logger.warn("streamId不存在!"); 171 logger.warn("streamId不存在!");
@@ -186,7 +186,7 @@ public class PlaybackController { @@ -186,7 +186,7 @@ public class PlaybackController {
186 public ResponseEntity<String> playSpeed(@PathVariable String streamId, @PathVariable Double speed) { 186 public ResponseEntity<String> playSpeed(@PathVariable String streamId, @PathVariable Double speed) {
187 logger.info("playSpeed: "+streamId+", "+speed); 187 logger.info("playSpeed: "+streamId+", "+speed);
188 JSONObject json = new JSONObject(); 188 JSONObject json = new JSONObject();
189 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); 189 + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
190 if (null == streamInfo) { 190 if (null == streamInfo) {
191 json.put("msg", "streamId不存在"); 191 json.put("msg", "streamId不存在");
192 logger.warn("streamId不存在!"); 192 logger.warn("streamId不存在!");
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
@@ -177,7 +177,7 @@ public class ApiStreamController { @@ -177,7 +177,7 @@ public class ApiStreamController {
177 result.put("error","未找到流信息"); 177 result.put("error","未找到流信息");
178 return result; 178 return result;
179 } 179 }
180 - cmder.streamByeCmd(serial, code, streamInfo.getStream()); 180 + cmder.streamByeCmd(serial, code, streamInfo.getStream(), null);
181 redisCatchStorage.stopPlay(streamInfo); 181 redisCatchStorage.stopPlay(streamInfo);
182 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 182 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
183 return null; 183 return null;
web_src/src/components/ParentPlatformList.vue
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 </div> 13 </div>
14 <!--设备列表--> 14 <!--设备列表-->
15 <el-table :data="platformList" border style="width: 100%" :height="winHeight"> 15 <el-table :data="platformList" border style="width: 100%" :height="winHeight">
16 - <el-table-column prop="name" label="名称" width="240" align="center"></el-table-column> 16 + <el-table-column prop="name" label="名称" align="center"></el-table-column>
17 <el-table-column prop="serverGBId" label="平台编号" width="180" align="center"></el-table-column> 17 <el-table-column prop="serverGBId" label="平台编号" width="180" align="center"></el-table-column>
18 <el-table-column label="是否启用" width="120" align="center"> 18 <el-table-column label="是否启用" width="120" align="center">
19 <template slot-scope="scope"> 19 <template slot-scope="scope">
@@ -38,9 +38,19 @@ @@ -38,9 +38,19 @@
38 </div> 38 </div>
39 </template> 39 </template>
40 </el-table-column> 40 </el-table-column>
41 - <el-table-column prop="deviceGBId" label="设备国标编号" width="240" align="center"></el-table-column> 41 + <el-table-column prop="deviceGBId" label="设备国标编号" width="200" align="center"></el-table-column>
42 <el-table-column prop="transport" label="信令传输模式" width="120" align="center"></el-table-column> 42 <el-table-column prop="transport" label="信令传输模式" width="120" align="center"></el-table-column>
43 - <el-table-column prop="channelCount" label="通道数" align="center"></el-table-column> 43 + <el-table-column prop="channelCount" label="通道数" width="120" align="center"></el-table-column>
  44 + <el-table-column label="订阅信息" width="240" align="center" fixed="right">
  45 + <template slot-scope="scope">
  46 + <i v-if="scope.row.alarmSubscribe" style="font-size: 1.5rem;" title="报警订阅" class="subscribe-on iconfont icon-gbaojings" ></i>
  47 + <i v-if="!scope.row.alarmSubscribe" style="font-size: 1.5rem;" title="报警订阅" class="subscribe-off iconfont icon-gbaojings" ></i>
  48 + <i v-if="scope.row.catalogSubscribe" title="目录订阅" class="subscribe-on iconfont icon-gjichus" ></i>
  49 + <i v-if="!scope.row.catalogSubscribe" title="目录订阅" class="subscribe-off iconfont icon-gjichus" ></i>
  50 + <i v-if="scope.row.gpsSubscribe" title="位置订阅" class="subscribe-on iconfont icon-gxunjians" ></i>
  51 + <i v-if="!scope.row.gpsSubscribe" title="位置订阅" class="subscribe-off iconfont icon-gxunjians" ></i>
  52 + </template>
  53 + </el-table-column>
44 54
45 <el-table-column label="操作" width="300" align="center" fixed="right"> 55 <el-table-column label="操作" width="300" align="center" fixed="right">
46 <template slot-scope="scope"> 56 <template slot-scope="scope">
@@ -169,3 +179,13 @@ export default { @@ -169,3 +179,13 @@ export default {
169 } 179 }
170 }; 180 };
171 </script> 181 </script>
  182 +<style>
  183 +.subscribe-on{
  184 + color: #409EFF;
  185 + font-size: 1.3rem;
  186 +}
  187 +.subscribe-off{
  188 + color: #afafb3;
  189 + font-size: 1.3rem;
  190 +}
  191 +</style>
web_src/src/components/dialog/StreamProxyEdit.vue
@@ -193,6 +193,7 @@ export default { @@ -193,6 +193,7 @@ export default {
193 this.mediaServer.getOnlineMediaServerList((data)=>{ 193 this.mediaServer.getOnlineMediaServerList((data)=>{
194 this.mediaServerList = data.data; 194 this.mediaServerList = data.data;
195 this.proxyParam.mediaServerId = this.mediaServerList[0].id 195 this.proxyParam.mediaServerId = this.mediaServerList[0].id
  196 + this.mediaServerIdChange()
196 }) 197 })
197 }, 198 },
198 mediaServerIdChange:function (){ 199 mediaServerIdChange:function (){
@@ -206,6 +207,7 @@ export default { @@ -206,6 +207,7 @@ export default {
206 } 207 }
207 }).then(function (res) { 208 }).then(function (res) {
208 that.ffmpegCmdList = res.data.data; 209 that.ffmpegCmdList = res.data.data;
  210 + that.proxyParam.ffmpeg_cmd_key = Object.keys(res.data.data)[0];
209 }).catch(function (error) { 211 }).catch(function (error) {
210 console.log(error); 212 console.log(error);
211 }); 213 });
web_src/src/components/dialog/chooseChannelForGb.vue
1 <template> 1 <template>
2 <div id="chooseChannelForGb" > 2 <div id="chooseChannelForGb" >
3 <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;"> 3 <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;">
4 - <span v-if="catalogId == null">{{catalogName}}的直播流</span>  
5 - <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的直播流</span> 4 + <span v-if="catalogId == null">{{catalogName}}的国标通道</span>
  5 + <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的国标通道</span>
6 </div> 6 </div>
7 <div style="background-color: #FFFFFF; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> 7 <div style="background-color: #FFFFFF; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
8 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> 8 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input>
web_src/src/components/dialog/chooseChannelForStream.vue
1 <template> 1 <template>
2 <div id="chooseChannelFoStream" > 2 <div id="chooseChannelFoStream" >
3 <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;"> 3 <div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;">
4 - <span v-if="catalogId == null">{{catalogName}}的直播流</span>  
5 - <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的直播流</span> 4 + <span v-if="catalogId == null">{{catalogName}}的直播通道</span>
  5 + <span v-if="catalogId != null">{{catalogName}}({{catalogId}})的直播通道</span>
6 </div> 6 </div>
7 <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> 7 <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
8 8
web_src/static/css/iconfont.css
1 @font-face { 1 @font-face {
2 font-family: "iconfont"; /* Project id 1291092 */ 2 font-family: "iconfont"; /* Project id 1291092 */
3 - src: url('iconfont.woff2?t=1644809302709') format('woff2'),  
4 - url('iconfont.woff?t=1644809302709') format('woff'),  
5 - url('iconfont.ttf?t=1644809302709') format('truetype'); 3 + src: url('iconfont.woff2?t=1647245982270') format('woff2'),
  4 + url('iconfont.woff?t=1647245982270') format('woff'),
  5 + url('iconfont.ttf?t=1647245982270') format('truetype');
6 } 6 }
7 7
8 .iconfont { 8 .iconfont {
@@ -13,6 +13,22 @@ @@ -13,6 +13,22 @@
13 -moz-osx-font-smoothing: grayscale; 13 -moz-osx-font-smoothing: grayscale;
14 } 14 }
15 15
  16 +.icon-xitongxinxi:before {
  17 + content: "\e7d6";
  18 +}
  19 +
  20 +.icon-gbaojings:before {
  21 + content: "\e7d7";
  22 +}
  23 +
  24 +.icon-gjichus:before {
  25 + content: "\e7d8";
  26 +}
  27 +
  28 +.icon-gxunjians:before {
  29 + content: "\e7d9";
  30 +}
  31 +
16 .icon-ziyuan:before { 32 .icon-ziyuan:before {
17 content: "\e7d5"; 33 content: "\e7d5";
18 } 34 }
web_src/static/css/iconfont.woff2
No preview for this file type