Commit 42901d03746d534d701ea3b8663e1c6d2c938c6d
Committed by
GitHub
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 |
pom.xml
| @@ -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
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<OnlineEvent> { | @@ -68,8 +68,6 @@ public class OnlineEventListener implements ApplicationListener<OnlineEvent> { | ||
| 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<OnlineEvent> { | @@ -98,7 +96,8 @@ public class OnlineEventListener implements ApplicationListener<OnlineEvent> { | ||
| 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<CatalogEvent> { | @@ -74,7 +74,7 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> { | ||
| 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<CatalogEvent> { | @@ -117,8 +117,6 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> { | ||
| 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
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