From 4ad711f61a1a760a0f8f7f8475b75ec93e31d8ae Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Thu, 13 Jun 2024 16:21:34 +0800
Subject: [PATCH 01/12] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E8=B0=83=E8=AF=95?=
=?UTF-8?q?=E6=97=A5=E5=BF=97=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../request/impl/NotifyRequestForCatalogProcessor.java | 8 ++++----
.../impl/NotifyRequestForMobilePositionProcessor.java | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
index 6185cda4..155d5f73 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
@@ -315,8 +315,8 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
}
}
- @Scheduled(fixedRate = 10000) //每1秒执行一次
- public void execute(){
- logger.info("[待处理Notify-目录订阅消息数量]: {}", taskQueue.size());
- }
+// @Scheduled(fixedRate = 10000) //每1秒执行一次
+// public void execute(){
+// logger.info("[待处理Notify-目录订阅消息数量]: {}", taskQueue.size());
+// }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForMobilePositionProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForMobilePositionProcessor.java
index c8111778..75a3b0d2 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForMobilePositionProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForMobilePositionProcessor.java
@@ -188,8 +188,8 @@ public class NotifyRequestForMobilePositionProcessor extends SIPRequestProcessor
}
taskQueue.clear();
}
- @Scheduled(fixedRate = 10000)
- public void execute(){
- logger.info("[待处理Notify-移动位置订阅消息数量]: {}", taskQueue.size());
- }
+// @Scheduled(fixedRate = 10000)
+// public void execute(){
+// logger.debug("[待处理Notify-移动位置订阅消息数量]: {}", taskQueue.size());
+// }
}
From f3ea07bdcd722d667e16b7a880f41a30b9374732 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Fri, 14 Jun 2024 17:03:55 +0800
Subject: [PATCH 02/12] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=BD=AC=E7=A0=81?=
=?UTF-8?q?=E5=90=8E=E7=9A=84=E6=B5=81=E7=9A=84=E8=BE=93=E5=87=BA=E4=BD=8D?=
=?UTF-8?q?=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../com/genersoft/iot/vmp/common/StreamInfo.java | 11 +++++++++++
.../iot/vmp/service/impl/MediaServiceImpl.java | 12 ++++++++----
.../iot/vmp/vmanager/bean/StreamContent.java | 14 ++++++++++++++
src/main/resources/application.yml | 2 +-
4 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
index 979f54a5..2d940347 100644
--- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
+++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
@@ -83,6 +83,9 @@ public class StreamInfo implements Serializable, Cloneable{
@Schema(description = "是否暂停(录像回放使用)")
private boolean pause;
+ @Schema(description = "转码后的视频流")
+ private StreamInfo transcodeStream;
+
public void setFlv(StreamURL flv) {
this.flv = flv;
}
@@ -521,6 +524,14 @@ public class StreamInfo implements Serializable, Cloneable{
this.transactionInfo = transactionInfo;
}
+ public StreamInfo getTranscodeStream() {
+ return transcodeStream;
+ }
+
+ public void setTranscodeStream(StreamInfo transcodeStream) {
+ this.transcodeStream = transcodeStream;
+ }
+
@Override
public StreamInfo clone() {
StreamInfo instance = null;
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
index ead5052e..d68261bd 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
@@ -95,10 +95,6 @@ public class MediaServiceImpl implements IMediaService {
if (addr == null) {
addr = mediaInfo.getStreamIp();
}
- if (!"broadcast".equalsIgnoreCase(app) && !ObjectUtils.isEmpty(mediaInfo.getTranscodeSuffix()) && !"null".equalsIgnoreCase(mediaInfo.getTranscodeSuffix())) {
- stream = stream + "_" + mediaInfo.getTranscodeSuffix();
-// streamInfoResult.setStream(stream);
- }
streamInfoResult.setIp(addr);
streamInfoResult.setMediaServerId(mediaInfo.getId());
@@ -112,6 +108,14 @@ public class MediaServiceImpl implements IMediaService {
streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam, isPlay);
streamInfoResult.setTracks(tracks);
+
+ if (!"broadcast".equalsIgnoreCase(app) && !ObjectUtils.isEmpty(mediaInfo.getTranscodeSuffix()) && !"null".equalsIgnoreCase(mediaInfo.getTranscodeSuffix())) {
+ String newStream = stream + "_" + mediaInfo.getTranscodeSuffix();
+ mediaInfo.setTranscodeSuffix(null);
+ StreamInfo transcodeStreamInfo = getStreamInfoByAppAndStream(mediaInfo, app, newStream, tracks, addr, callId, isPlay);
+ streamInfoResult.setTranscodeStream(transcodeStreamInfo);
+ }
+
return streamInfoResult;
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java
index 4974209a..f9857385 100755
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java
@@ -97,6 +97,9 @@ public class StreamContent {
@Schema(description = "文件下载地址(录像下载使用)")
private DownloadFileInfo downLoadFilePath;
+ @Schema(description = "转码后的视频流")
+ private StreamContent transcodeStream;
+
private double progress;
public StreamContent(StreamInfo streamInfo) {
@@ -178,6 +181,17 @@ public class StreamContent {
if (streamInfo.getDownLoadFilePath() != null) {
this.downLoadFilePath = streamInfo.getDownLoadFilePath();
}
+ if (streamInfo.getTranscodeStream() != null) {
+ this.transcodeStream = new StreamContent(streamInfo.getTranscodeStream());
+ }
+ }
+
+ public StreamContent getTranscodeStream() {
+ return transcodeStream;
+ }
+
+ public void setTranscodeStream(StreamContent transcodeStream) {
+ this.transcodeStream = transcodeStream;
}
public String getApp() {
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 3f478442..ddb05dee 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -2,4 +2,4 @@ spring:
application:
name: wvp
profiles:
- active: local
\ No newline at end of file
+ active: local271
\ No newline at end of file
From 107caf11710ee07e511da47312f748339e003fb2 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Fri, 14 Jun 2024 17:24:57 +0800
Subject: [PATCH 03/12] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=89=8D=E7=AB=AF?=
=?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=BD=AC=E7=A0=81=E5=90=8E=E7=9A=84=E6=B5=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../iot/vmp/web/gb28181/ApiStreamController.java | 3 +++
web_src/src/components/dialog/devicePlayer.vue | 8 ++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
index 63d9f310..4f42efd1 100644
--- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
+++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
@@ -120,6 +120,9 @@ public class ApiStreamController {
if (errorCode == InviteErrorCode.SUCCESS.getCode()) {
if (data != null) {
StreamInfo streamInfo = (StreamInfo)data;
+ if (streamInfo.getTranscodeStream() != null) {
+ streamInfo = streamInfo.getTranscodeStream();
+ }
JSONObject resultJjson = new JSONObject();
resultJjson.put("StreamID", streamInfo.getStream());
resultJjson.put("DeviceID", serial);
diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue
index f6bd2b23..64c61f56 100755
--- a/web_src/src/components/dialog/devicePlayer.vue
+++ b/web_src/src/components/dialog/devicePlayer.vue
@@ -473,10 +473,14 @@ export default {
},
getUrlByStreamInfo() {
console.log(this.streamInfo)
+ let streamInfo = this.streamInfo
+ if (this.streamInfo.transcodeStream) {
+ streamInfo = this.streamInfo.transcodeStream;
+ }
if (location.protocol === "https:") {
- this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]]
+ this.videoUrl = streamInfo[this.player[this.activePlayer][1]]
} else {
- this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]]
+ this.videoUrl = streamInfo[this.player[this.activePlayer][0]]
}
return this.videoUrl;
From f5abf8df4c05439a288a88dedad0f7065901ca21 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Wed, 19 Jun 2024 16:00:26 +0800
Subject: [PATCH 04/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=92=E5=BA=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../dao/CloudRecordServiceMapper.java | 2 +-
.../vmp/web/gb28181/ApiStreamController.java | 32 ++++++++++++++-----
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java
index b446148a..f641071a 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java
@@ -53,7 +53,7 @@ public interface CloudRecordServiceMapper {
" and id in " +
" #{item}" +
" " +
- " order by start_time DESC" +
+ " order by start_time ASC" +
" ")
List getList(@Param("query") String query, @Param("app") String app, @Param("stream") String stream,
@Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp,
diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
index 4f42efd1..1d1919a6 100644
--- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
+++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
@@ -120,22 +120,38 @@ public class ApiStreamController {
if (errorCode == InviteErrorCode.SUCCESS.getCode()) {
if (data != null) {
StreamInfo streamInfo = (StreamInfo)data;
- if (streamInfo.getTranscodeStream() != null) {
- streamInfo = streamInfo.getTranscodeStream();
- }
JSONObject resultJjson = new JSONObject();
resultJjson.put("StreamID", streamInfo.getStream());
resultJjson.put("DeviceID", serial);
resultJjson.put("ChannelID", code);
resultJjson.put("ChannelName", deviceChannel.getName());
resultJjson.put("ChannelCustomName", "");
- resultJjson.put("FLV", streamInfo.getFlv().getUrl());
- if(streamInfo.getHttps_flv() != null) {
- resultJjson.put("HTTPS_FLV", streamInfo.getHttps_flv().getUrl());
+ if (streamInfo.getTranscodeStream() != null) {
+ resultJjson.put("FLV", streamInfo.getTranscodeStream().getFlv().getUrl());
+ }else {
+ resultJjson.put("FLV", streamInfo.getFlv().getUrl());
+
}
- resultJjson.put("WS_FLV", streamInfo.getWs_flv().getUrl());
+ if(streamInfo.getHttps_flv() != null) {
+ if (streamInfo.getTranscodeStream() != null) {
+ resultJjson.put("HTTPS_FLV", streamInfo.getTranscodeStream().getHttps_flv().getUrl());
+ }else {
+ resultJjson.put("HTTPS_FLV", streamInfo.getHttps_flv().getUrl());
+ }
+ }
+
+ if (streamInfo.getTranscodeStream() != null) {
+ resultJjson.put("WS_FLV", streamInfo.getTranscodeStream().getWs_flv().getUrl());
+ }else {
+ resultJjson.put("WS_FLV", streamInfo.getWs_flv().getUrl());
+ }
+
if(streamInfo.getWss_flv() != null) {
- resultJjson.put("WSS_FLV", streamInfo.getWss_flv().getUrl());
+ if (streamInfo.getTranscodeStream() != null) {
+ resultJjson.put("WSS_FLV", streamInfo.getTranscodeStream().getWss_flv().getUrl());
+ }else {
+ resultJjson.put("WSS_FLV", streamInfo.getWss_flv().getUrl());
+ }
}
resultJjson.put("RTMP", streamInfo.getRtmp().getUrl());
if (streamInfo.getRtmps() != null) {
From 6e4268a670a796a884261ab77d70b59dc95cb909 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Thu, 20 Jun 2024 18:12:35 +0800
Subject: [PATCH 05/12] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=8E=A8=E6=B5=81?=
=?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=86=99=E5=85=A5redis?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../vmp/media/zlm/ZLMHttpHookListener.java | 21 ++++++++++++-------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
index 63239b78..73f20bf4 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -375,8 +375,20 @@ public class ZLMHttpHookListener {
streamAuthorityInfo.setOriginTypeStr(param.getOriginTypeStr());
}
redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
+
+ Map params = MediaServerUtils.urlParamToMap(param.getParams());
+ param.setParamMap(params);
+ StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo,
+ param.getApp(), param.getStream(), tracks, params.get("callId"));
+ param.setStreamInfo(new StreamContent(streamInfoByAppAndStream));
+
+ param.setSeverId(userSetting.getServerId());
+ streamPushService.updatePush(param);
+ // 冗余数据,自己系统中自用
+ redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param);
}
}
+ // TODO 修改为第一个为准 后续不再处理
if ("rtsp".equals(param.getSchema())) {
logger.info("流变化:注册->{}, app->{}, stream->{}", param.isRegist(), param.getApp(), param.getStream());
if (param.isRegist()) {
@@ -464,14 +476,7 @@ public class ZLMHttpHookListener {
param.setStreamInfo(new StreamContent(streamInfoByAppAndStream));
redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param);
- if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
- || param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
- || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
- param.setSeverId(userSetting.getServerId());
- streamPushService.updatePush(param);
- // 冗余数据,自己系统中自用
- redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param);
- }
+
} else {
// 兼容流注销时类型从redis记录获取
OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo(
From 099c65ff40eefd1ad58626c7376c95fb3cf28395 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Thu, 20 Jun 2024 19:30:25 +0800
Subject: [PATCH 06/12] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=82=B9=E6=92=AD?=
=?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=B6=85=E6=97=B6=E6=97=B6=E9=97=B4=E4=B8=BA?=
=?UTF-8?q?10=E7=A7=92?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
index 96253d6e..7a025de0 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -21,7 +21,7 @@ public class UserSetting {
private Boolean seniorSdp = Boolean.FALSE;
- private Integer playTimeout = 18000;
+ private Integer playTimeout = 10000;
private int platformPlayTimeout = 20000;
From 050882d6a614f87d33d90bc5b344c774d9f6e71d Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Thu, 20 Jun 2024 22:35:48 +0800
Subject: [PATCH 07/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8E=A8=E6=B5=81?=
=?UTF-8?q?=E6=97=B6=E5=AD=98=E5=85=A5=E6=8E=A8=E6=B5=81=E6=95=B0=E6=8D=AE?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../vmp/media/zlm/ZLMHttpHookListener.java | 22 +++++++++++--------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
index 73f20bf4..a676fb92 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -376,17 +376,21 @@ public class ZLMHttpHookListener {
}
redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
- Map params = MediaServerUtils.urlParamToMap(param.getParams());
- param.setParamMap(params);
- StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo,
- param.getApp(), param.getStream(), tracks, params.get("callId"));
- param.setStreamInfo(new StreamContent(streamInfoByAppAndStream));
+ if (!"broadcast".equals(param.getApp()) && !"talk".equals(param.getApp())) {
+ Map params = MediaServerUtils.urlParamToMap(param.getParams());
+ param.setParamMap(params);
+ StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo,
+ param.getApp(), param.getStream(), tracks, params.get("callId"));
+ param.setStreamInfo(new StreamContent(streamInfoByAppAndStream));
- param.setSeverId(userSetting.getServerId());
- streamPushService.updatePush(param);
- // 冗余数据,自己系统中自用
- redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param);
+ param.setSeverId(userSetting.getServerId());
+ streamPushService.updatePush(param);
+ // 冗余数据,自己系统中自用
+ redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param);
+ }
}
+ }else {
+ redisCatchStorage.removePushListItem(param.getApp(), param.getStream(), param.getMediaServerId());
}
// TODO 修改为第一个为准 后续不再处理
if ("rtsp".equals(param.getSchema())) {
From 87c071fd5e774091c7d87f3d7c24fd2360148d58 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Tue, 25 Jun 2024 10:24:35 +0800
Subject: [PATCH 08/12] =?UTF-8?q?=E5=90=88=E5=B9=B6271=E5=88=86=E6=94=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../request/impl/InviteRequestProcessor.java | 6 ++---
.../media/event/media/MediaArrivalEvent.java | 24 ++++++++++++++++++-
.../service/impl/MediaServerServiceImpl.java | 7 ++++++
.../service/impl/StreamPushServiceImpl.java | 18 ++++++--------
.../iot/vmp/storager/IRedisCatchStorage.java | 4 ++--
.../storager/impl/RedisCatchStorageImpl.java | 14 ++++-------
6 files changed, 47 insertions(+), 26 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
index ec6f901f..411c40fd 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -27,6 +27,7 @@ import com.genersoft.iot.vmp.media.event.hook.HookType;
import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.IStreamProxyService;
import com.genersoft.iot.vmp.service.IStreamPushService;
@@ -593,12 +594,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
sendRtpItem.setPlayType(InviteStreamType.PUSH);
if (streamPushItem != null) {
// 从redis查询是否正在接收这个推流
- StreamPushItem pushListItem = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream());
+ OnStreamChangedHookParam pushListItem = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream());
if (pushListItem != null) {
- sendRtpItem.setServerId(pushListItem.getServerId());
+ sendRtpItem.setServerId(pushListItem.getSeverId());
sendRtpItem.setMediaServerId(pushListItem.getMediaServerId());
- pushListItem.setSelf(userSetting.getServerId().equals(pushListItem.getServerId()));
redisCatchStorage.updateSendRTPSever(sendRtpItem);
// 开始推流
sendPushStream(sendRtpItem, mediaServerItem, platform, request);
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java
index 2379321a..2f51a3e2 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java
@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.media.event.media;
import com.genersoft.iot.vmp.media.bean.MediaInfo;
import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
/**
* 流到来事件
@@ -19,7 +20,8 @@ public class MediaArrivalEvent extends MediaEvent {
mediaArrivalEvent.setStream(hookParam.getStream());
mediaArrivalEvent.setMediaServer(mediaServer);
mediaArrivalEvent.setSchema(hookParam.getSchema());
- mediaArrivalEvent.setCallId(hookParam.getCallId());
+ mediaArrivalEvent.setSchema(hookParam.getSchema());
+ mediaArrivalEvent.setHookParam(hookParam);
return mediaArrivalEvent;
}
@@ -27,6 +29,10 @@ public class MediaArrivalEvent extends MediaEvent {
private String callId;
+ private OnStreamChangedHookParam hookParam;
+
+ private StreamContent streamInfo;
+
public MediaInfo getMediaInfo() {
return mediaInfo;
}
@@ -43,4 +49,20 @@ public class MediaArrivalEvent extends MediaEvent {
public void setCallId(String callId) {
this.callId = callId;
}
+
+ public OnStreamChangedHookParam getHookParam() {
+ return hookParam;
+ }
+
+ public void setHookParam(OnStreamChangedHookParam hookParam) {
+ this.hookParam = hookParam;
+ }
+
+ public StreamContent getStreamInfo() {
+ return streamInfo;
+ }
+
+ public void setStreamInfo(StreamContent streamInfo) {
+ this.streamInfo = streamInfo;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java
index a0b33413..d8f5ba95 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java
@@ -809,6 +809,13 @@ public class MediaServerServiceImpl implements IMediaServerService {
streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay);
streamInfoResult.setMediaInfo(mediaInfo);
+
+ if (!"broadcast".equalsIgnoreCase(app) && !ObjectUtils.isEmpty(mediaServer.getTranscodeSuffix()) && !"null".equalsIgnoreCase(mediaServer.getTranscodeSuffix())) {
+ String newStream = stream + "_" + mediaServer.getTranscodeSuffix();
+ mediaServer.setTranscodeSuffix(null);
+ StreamInfo transcodeStreamInfo = getStreamInfoByAppAndStream(mediaServer, app, newStream, null, addr, callId, isPlay);
+ streamInfoResult.setTranscodeStream(transcodeStreamInfo);
+ }
return streamInfoResult;
}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
index 3213eb98..18de78a0 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -26,6 +26,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.*;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
+import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
@@ -126,18 +127,13 @@ public class StreamPushServiceImpl implements IStreamPushService {
streamPushMapper.update(transform);
gbStreamMapper.updateMediaServer(event.getApp(), event.getStream(), event.getMediaServer().getId());
}
- // TODO 相关的事件自行管理,不需要写入ZLMMediaListManager
-// ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(transform.getApp(), transform.getStream());
-// if ( channelOnlineEventLister != null) {
-// try {
-// channelOnlineEventLister.run(transform.getApp(), transform.getStream(), transform.getServerId());;
-// } catch (ParseException e) {
-// logger.error("addPush: ", e);
-// }
-// removedChannelOnlineEventLister(transform.getApp(), transform.getStream());
-// }
// 冗余数据,自己系统中自用
- redisCatchStorage.addPushListItem(event.getApp(), event.getStream(), event);
+ if (!"broadcast".equals(event.getApp()) && !"talk".equals(event.getApp())) {
+ StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(
+ event.getMediaServer(), event.getApp(), event.getStream(), event.getMediaInfo(), event.getCallId());
+ event.getHookParam().setStreamInfo(new StreamContent(streamInfo));
+ redisCatchStorage.addPushListItem(event.getApp(), event.getStream(), event);
+ }
// 发送流变化redis消息
JSONObject jsonObject = new JSONObject();
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
index 66b483b7..869d39bf 100755
--- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo;
import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
-import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
@@ -216,7 +216,7 @@ public interface IRedisCatchStorage {
void addPushListItem(String app, String stream, MediaArrivalEvent param);
- StreamPushItem getPushListItem(String app, String stream);
+ OnStreamChangedHookParam getPushListItem(String app, String stream);
void removePushListItem(String app, String stream, String mediaServerId);
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
index 9f09e8a4..e70e195c 100755
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -5,16 +5,13 @@ import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.SystemAllInfo;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.UserSetting;
-import com.genersoft.iot.vmp.gb28181.bean.AlarmChannelMessage;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
-import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
+import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.media.bean.MediaInfo;
import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
-import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -698,14 +695,13 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
@Override
public void addPushListItem(String app, String stream, MediaArrivalEvent event) {
String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream;
- StreamPushItem streamPushItem = StreamPushItem.getInstance(event, userSetting.getServerId());
- redisTemplate.opsForValue().set(key, streamPushItem);
+ redisTemplate.opsForValue().set(key, event.getHookParam());
}
@Override
- public StreamPushItem getPushListItem(String app, String stream) {
+ public OnStreamChangedHookParam getPushListItem(String app, String stream) {
String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream;
- return (StreamPushItem)redisTemplate.opsForValue().get(key);
+ return (OnStreamChangedHookParam)redisTemplate.opsForValue().get(key);
}
@Override
From 68fce9177fb3ac2605d6de7f5b0e0d8532d733e2 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Tue, 25 Jun 2024 16:45:31 +0800
Subject: [PATCH 09/12] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../vmp/gb28181/bean/CatalogChannelEvent.java | 38 +
.../iot/vmp/gb28181/bean/CatalogEvent.java | 9 -
.../iot/vmp/gb28181/bean/DeviceChannel.java | 206 ++---
.../subscribe/catalog/CatalogEventLister.java | 30 +-
.../NotifyRequestForCatalogProcessor.java | 139 +--
.../cmd/CatalogResponseMessageHandler.java | 6 +-
.../iot/vmp/gb28181/utils/XmlUtil.java | 810 +++++++++---------
.../iot/vmp/service/IGbStreamService.java | 5 +-
.../iot/vmp/service/IStreamPushService.java | 3 +
.../vmp/service/impl/GbStreamServiceImpl.java | 12 +-
.../service/impl/StreamPushServiceImpl.java | 23 +-
.../RedisPushStreamStatusListMsgListener.java | 40 +-
.../vmp/storager/dao/StreamPushMapper.java | 6 +
src/main/resources/application.yml | 2 +-
14 files changed, 654 insertions(+), 675 deletions(-)
create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogChannelEvent.java
delete mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogEvent.java
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogChannelEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogChannelEvent.java
new file mode 100644
index 00000000..cf7c9cbd
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogChannelEvent.java
@@ -0,0 +1,38 @@
+package com.genersoft.iot.vmp.gb28181.bean;
+
+import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.extern.slf4j.Slf4j;
+import org.dom4j.Element;
+
+import java.lang.reflect.InvocationTargetException;
+
+@Data
+@Slf4j
+@EqualsAndHashCode(callSuper = true)
+public class CatalogChannelEvent extends DeviceChannel{
+
+ private String event;
+
+ private DeviceChannel channel;
+
+ public static CatalogChannelEvent decode(Element element) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
+ Element eventElement = element.element("Event");
+ CatalogChannelEvent catalogChannelEvent = new CatalogChannelEvent();
+ if (eventElement != null) {
+ catalogChannelEvent.setEvent(eventElement.getText());
+ }else {
+ catalogChannelEvent.setEvent(CatalogEvent.ADD);
+ }
+ DeviceChannel deviceChannel;
+ if (CatalogEvent.ADD.equalsIgnoreCase(catalogChannelEvent.getEvent()) ||
+ CatalogEvent.UPDATE.equalsIgnoreCase(catalogChannelEvent.getEvent()) ){
+ deviceChannel = DeviceChannel.decode(element);
+ }else {
+ deviceChannel = DeviceChannel.decodeWithOnlyDeviceId(element);
+ }
+ catalogChannelEvent.setChannel(deviceChannel);
+ return catalogChannelEvent;
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogEvent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogEvent.java
deleted file mode 100644
index a3fcdee8..00000000
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogEvent.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.genersoft.iot.vmp.gb28181.bean;
-
-import com.genersoft.iot.vmp.gb28181.utils.MessageElement;
-
-public class CatalogEvent extends DeviceChannel{
-
- @MessageElement("Event")
- private String event;
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
index 5ddf1c46..09f28785 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
@@ -1,257 +1,170 @@
package com.genersoft.iot.vmp.gb28181.bean;
import com.genersoft.iot.vmp.gb28181.utils.MessageElement;
+import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
+import lombok.extern.slf4j.Slf4j;
+import org.dom4j.Element;
+
+import java.lang.reflect.InvocationTargetException;
@Data
+@Slf4j
@Schema(description = "通道信息")
@EqualsAndHashCode(callSuper = true)
public class DeviceChannel extends CommonGBChannel {
+ @Schema(description = "数据库自增ID")
+ private int id;
+
@MessageElement("DeviceID")
@Schema(description = "编码")
private String deviceId;
- @MessageElement("DeviceID")
+ @MessageElement("Name")
@Schema(description = "名称")
private String name;
- @MessageElement("DeviceID")
+ @MessageElement("Manufacturer")
@Schema(description = "设备厂商")
private String manufacturer;
- @MessageElement("DeviceID")
+ @MessageElement("Model")
@Schema(description = "设备型号")
private String model;
// 2016
- @MessageElement("DeviceID")
+ @MessageElement("Owner")
@Schema(description = "设备归属")
private String owner;
- @MessageElement("DeviceID")
+ @MessageElement("CivilCode")
@Schema(description = "行政区域")
private String civilCode;
- @MessageElement("DeviceID")
+ @MessageElement("Block")
@Schema(description = "警区")
private String block;
- @MessageElement("DeviceID")
+ @MessageElement("Address")
@Schema(description = "安装地址")
private String address;
- @MessageElement("DeviceID")
- @Schema(description = "是否有子设备")
- private Boolean parental;
+ @MessageElement("Parental")
+ @Schema(description = "是否有子设备(必选)1有,0没有")
+ private Integer parental;
- @MessageElement("DeviceID")
+ @MessageElement("ParentID")
@Schema(description = "父节点ID")
private String parentId;
// 2016
- @MessageElement("DeviceID")
+ @MessageElement("SafetyWay")
@Schema(description = "信令安全模式")
private Integer safetyWay;
- @MessageElement("DeviceID")
+ @MessageElement("RegisterWay")
@Schema(description = "注册方式")
private Integer registerWay;
// 2016
- @MessageElement("DeviceID")
+ @MessageElement("CertNum")
@Schema(description = "证书序列号")
- private Integer certNum;
+ private String certNum;
// 2016
- @MessageElement("DeviceID")
- @Schema(description = "证书有效标识")
+ @MessageElement("Certifiable")
+ @Schema(description = "证书有效标识, 缺省为0;证书有效标识:0:无效 1:有效")
private Integer certifiable;
// 2016
- @MessageElement("DeviceID")
+ @MessageElement("ErrCode")
@Schema(description = "无效原因码(有证书且证书无效的设备必选)")
private Integer errCode;
// 2016
- @MessageElement("DeviceID")
+ @MessageElement("EndTime")
@Schema(description = "证书终止有效期(有证书且证书无效的设备必选)")
- private Integer endTime;
+ private String endTime;
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机安全能力等级代码")
- private String securityLevelCode;
-
- @MessageElement("DeviceID")
+ @MessageElement("Secrecy")
@Schema(description = "保密属性(必选)缺省为0;0-不涉密,1-涉密")
private Integer secrecy;
- @MessageElement("DeviceID")
+ @MessageElement("IPAddress")
@Schema(description = "设备/系统IPv4/IPv6地址")
private String ipAddress;
- @MessageElement("DeviceID")
+ @MessageElement("Port")
@Schema(description = "设备/系统端口")
private Integer port;
- @MessageElement("DeviceID")
+ @MessageElement("Password")
@Schema(description = "设备口令")
private String password;
- @MessageElement("DeviceID")
+ @MessageElement("Status")
@Schema(description = "设备状态")
- private Boolean status;
+ private String status;
- @MessageElement("DeviceID")
+ @MessageElement("Longitude")
@Schema(description = "经度 WGS-84坐标系")
private Double longitude;
- @MessageElement("DeviceID")
+ @MessageElement("Latitude")
@Schema(description = ",纬度 WGS-84坐标系")
private Double latitude;
- @MessageElement("DeviceID")
- @Schema(description = "虚拟组织所属的业务分组ID")
- private String businessGroupId;
-
- @MessageElement("DeviceID")
+ @MessageElement("Info.PTZType")
@Schema(description = "摄像机结构类型,标识摄像机类型: 1-球机; 2-半球; 3-固定枪机; 4-遥控枪机;5-遥控半球;6-多目设备的全景/拼接通道;7-多目设备的分割通道")
private Integer ptzType;
- @MessageElement("DeviceID")
- @Schema(description = "摄像机光电成像类型。1-可见光成像;2-热成像;3-雷达成像;4-X光成像;5-深度光场成像;9-其他。可多值,")
- private String photoelectricImagingTyp;
+ @MessageElement("Info.PositionType")
+ @Schema(description = "摄像机位置类型扩展。1-省际检查站、2-党政机关、3-车站码头、4-中心广场、5-体育场馆、" +
+ "6-商业中心、7-宗教场所、8-校园周边、9-治安复杂区域、10-交通干线")
+ private Integer positionType;
- @MessageElement("DeviceID")
- @Schema(description = "摄像机采集部位类型")
- private String capturePositionType;
-
- @MessageElement("DeviceID")
+ @MessageElement("Info.RoomType")
@Schema(description = "摄像机安装位置室外、室内属性。1-室外、2-室内。")
private Integer roomType;
- // 2016
- @MessageElement("DeviceID")
- @Schema(description = "用途属性")
+ @MessageElement("Info.UseType")
+ @Schema(description = "用途属性, 1-治安、2-交通、3-重点。")
private Integer useType;
- @MessageElement("DeviceID")
+ @MessageElement("Info.SupplyLightType")
@Schema(description = "摄像机补光属性。1-无补光;2-红外补光;3-白光补光;4-激光补光;9-其他")
private Integer supplyLightType;
- @MessageElement("DeviceID")
+ @MessageElement("Info.DirectionType")
@Schema(description = "摄像机监视方位(光轴方向)属性。1-东(西向东)、2-西(东向西)、3-南(北向南)、4-北(南向北)、" +
"5-东南(西北到东南)、6-东北(西南到东北)、7-西南(东北到西南)、8-西北(东南到西北)")
private Integer directionType;
- @MessageElement("DeviceID")
+ @MessageElement("Info.Resolution")
@Schema(description = "摄像机支持的分辨率,可多值")
private String resolution;
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机支持的码流编号列表,用于实时点播时指定码流编号(可选)")
- private String streamNumberList;
+ @MessageElement("Info.BusinessGroupID")
+ @Schema(description = "虚拟组织所属的业务分组ID")
+ private String businessGroupId;
- @MessageElement("DeviceID")
+ @MessageElement("Info.DownloadSpeed")
@Schema(description = "下载倍速(可选),可多值")
private String downloadSpeed;
- @MessageElement("DeviceID")
+ @MessageElement("Info.SVCSpaceSupportMode")
@Schema(description = "空域编码能力,取值0-不支持;1-1级增强(1个增强层);2-2级增强(2个增强层);3-3级增强(3个增强层)")
private Integer svcSpaceSupportMod;
- @MessageElement("DeviceID")
+ @MessageElement("Info.SVCTimeSupportMode")
@Schema(description = "时域编码能力,取值0-不支持;1-1级增强;2-2级增强;3-3级增强(可选)")
private Integer svcTimeSupportMode;
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = " SSVC增强层与基本层比例能力 ")
- private String ssvcRatioSupportList;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "移动采集设备类型(仅移动采集设备适用,必选);1-移动机器人载摄像机;2-执法记录仪;3-移动单兵设备;" +
- "4-车载视频记录设备;5-无人机载摄像机;9-其他")
- private Integer mobileDeviceType;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机水平视场角(可选),取值范围大于0度小于等于360度")
- private Double horizontalFieldAngle;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机竖直视场角(可选),取值范围大于0度小于等于360度 ")
- private Double verticalFieldAngle;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机可视距离(可选),单位:米")
- private Double maxViewDistance;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "基层组织编码(必选,非基层建设时为“000000”)")
- private String grassrootsCode;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "监控点位类型(当为摄像机时必选),1-一类视频监控点;2-二类视频监控点;3-三类视频监控点;9-其他点位。")
- private Integer poType;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "点位俗称")
- private String poCommonName;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "设备MAC地址(可选),用“XX-XX-XX-XX-XX-XX”格式表达")
- private String mac;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机卡口功能类型,01-人脸卡口;02-人员卡口;03-机动车卡口;04-非机动车卡口;05-物品卡口;99-其他")
- private String functionType;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机视频编码格式")
- private String encodeType;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机安装使用时间")
- private String installTime;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机所属管理单位名称")
- private String managementUnit;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "摄像机所属管理单位联系人的联系方式(电话号码,可多值,用英文半角“/”分割)")
- private String contactInfo;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "录像保存天数(可选)")
- private Integer recordSaveDays;
-
- // 2022
- @MessageElement("DeviceID")
- @Schema(description = "国民经济行业分类代码(可选)")
- private String industrialClassification;
-
-
@Schema(description = "云台类型描述字符串")
private String ptzTypeText;
@@ -306,4 +219,15 @@ public class DeviceChannel extends CommonGBChannel {
break;
}
}
+
+ public static DeviceChannel decode(Element element) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
+ return XmlUtil.elementDecode(element, DeviceChannel.class);
+ }
+
+ public static DeviceChannel decodeWithOnlyDeviceId(Element element) {
+ Element deviceElement = element.element("DeviceID");
+ DeviceChannel deviceChannel = new DeviceChannel();
+ deviceChannel.setDeviceId(deviceElement.getText());
+ return deviceChannel;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
index 18ad2b01..9c65b873 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/subscribe/catalog/CatalogEventLister.java
@@ -5,8 +5,7 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.service.IGbStreamService;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@@ -23,11 +22,10 @@ import java.util.Map;
/**
* catalog事件
*/
+@Slf4j
@Component
public class CatalogEventLister implements ApplicationListener {
- private final static Logger logger = LoggerFactory.getLogger(CatalogEventLister.class);
-
@Autowired
private IVideoManagerStorage storager;
@@ -66,9 +64,9 @@ public class CatalogEventLister implements ApplicationListener {
if (event.getDeviceChannels() != null) {
if (platforms.size() > 0) {
for (DeviceChannel deviceChannel : event.getDeviceChannels()) {
- List parentPlatformsForGB = storager.queryPlatFormListForGBWithGBId(deviceChannel.getChannelId(), platforms);
- parentPlatformMap.put(deviceChannel.getChannelId(), parentPlatformsForGB);
- channelMap.put(deviceChannel.getChannelId(), deviceChannel);
+ List parentPlatformsForGB = storager.queryPlatFormListForGBWithGBId(deviceChannel.getDeviceId(), platforms);
+ parentPlatformMap.put(deviceChannel.getDeviceId(), parentPlatformsForGB);
+ channelMap.put(deviceChannel.getDeviceId(), deviceChannel);
}
}
}else if (event.getGbStreams() != null) {
@@ -106,12 +104,12 @@ public class CatalogEventLister implements ApplicationListener {
}
}
if (deviceChannelList.size() > 0) {
- logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
+ log.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
try {
sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
IllegalAccessException e) {
- logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
+ log.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
}
}
}else if (parentPlatformMap.keySet().size() > 0) {
@@ -123,16 +121,16 @@ public class CatalogEventLister implements ApplicationListener {
if (subscribeInfo == null) {
continue;
}
- logger.info("[Catalog事件: {}]平台:{},影响通道{}", event.getType(), platform.getServerGBId(), gbId);
+ log.info("[Catalog事件: {}]平台:{},影响通道{}", event.getType(), platform.getServerGBId(), gbId);
List deviceChannelList = new ArrayList<>();
DeviceChannel deviceChannel = new DeviceChannel();
- deviceChannel.setChannelId(gbId);
+ deviceChannel.setDeviceId(gbId);
deviceChannelList.add(deviceChannel);
try {
sipCommanderFroPlatform.sendNotifyForCatalogOther(event.getType(), platform, deviceChannelList, subscribeInfo, null);
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
IllegalAccessException e) {
- logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
+ log.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
}
}
}
@@ -157,12 +155,12 @@ public class CatalogEventLister implements ApplicationListener {
}
}
if (!deviceChannelList.isEmpty()) {
- logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
+ log.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
try {
sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
} catch (InvalidArgumentException | ParseException | NoSuchFieldException | SipException |
IllegalAccessException e) {
- logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
+ log.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
}
}
}else if (!parentPlatformMap.keySet().isEmpty()) {
@@ -174,7 +172,7 @@ public class CatalogEventLister implements ApplicationListener {
if (subscribeInfo == null) {
continue;
}
- logger.info("[Catalog事件: {}]平台:{},影响通道{}", event.getType(), platform.getServerGBId(), gbId);
+ log.info("[Catalog事件: {}]平台:{},影响通道{}", event.getType(), platform.getServerGBId(), gbId);
List deviceChannelList = new ArrayList<>();
DeviceChannel deviceChannel = channelMap.get(gbId);
deviceChannelList.add(deviceChannel);
@@ -187,7 +185,7 @@ public class CatalogEventLister implements ApplicationListener {
sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), platform, deviceChannelList, subscribeInfo, null);
} catch (InvalidArgumentException | ParseException | NoSuchFieldException |
SipException | IllegalAccessException e) {
- logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
+ log.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
}
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
index c832161a..f90b93fc 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
+import com.genersoft.iot.vmp.gb28181.bean.CatalogChannelEvent;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.HandlerCatchData;
@@ -10,14 +11,12 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
-import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
import com.genersoft.iot.vmp.service.IDeviceChannelService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.utils.DateUtil;
+import lombok.extern.slf4j.Slf4j;
import org.dom4j.DocumentException;
import org.dom4j.Element;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -25,6 +24,8 @@ import org.springframework.transaction.annotation.Transactional;
import javax.sip.RequestEvent;
import javax.sip.header.FromHeader;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -36,12 +37,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* SIP命令类型: NOTIFY请求中的目录请求处理
*/
+@Slf4j
@Component
public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent {
-
- private final static Logger logger = LoggerFactory.getLogger(NotifyRequestForCatalogProcessor.class);
-
private final List updateChannelOnlineList = new CopyOnWriteArrayList<>();
private final List updateChannelOfflineList = new CopyOnWriteArrayList<>();
private final Map updateChannelMap = new ConcurrentHashMap<>();
@@ -72,7 +71,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
@Transactional
public void process(RequestEvent evt) {
if (taskQueue.size() >= userSetting.getMaxNotifyCountQueue()) {
- logger.error("[notify-目录订阅] 待处理消息队列已满 {},返回486 BUSY_HERE,消息不做处理", userSetting.getMaxNotifyCountQueue());
+ log.error("[notify-目录订阅] 待处理消息队列已满 {},返回486 BUSY_HERE,消息不做处理", userSetting.getMaxNotifyCountQueue());
return;
}
taskQueue.offer(new HandlerCatchData(evt, null, null));
@@ -95,12 +94,12 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
Device device = redisCatchStorage.getDevice(deviceId);
if (device == null || !device.isOnLine()) {
- logger.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId() : ""));
+ log.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId() : ""));
return;
}
Element rootElement = getRootElement(evt, device.getCharset());
if (rootElement == null) {
- logger.warn("[ 收到目录订阅 ] content cannot be null, {}", evt.getRequest());
+ log.warn("[ 收到目录订阅 ] content cannot be null, {}", evt.getRequest());
return;
}
Element deviceListElement = rootElement.element("DeviceList");
@@ -113,132 +112,134 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
// 遍历DeviceList
while (deviceListIterator.hasNext()) {
Element itemDevice = deviceListIterator.next();
- Element eventElement = itemDevice.element("Event");
- String event;
- if (eventElement == null) {
- logger.warn("[收到目录订阅]:{}, 但是Event为空, 设为默认值 ADD", (device != null ? device.getDeviceId() : ""));
- event = CatalogEvent.ADD;
- } else {
- event = eventElement.getText().toUpperCase();
- }
- DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event);
-
-
- if (channel == null) {
- logger.info("[收到目录订阅]:但是解析失败 {}", new String(evt.getRequest().getRawContent()));
+ CatalogChannelEvent catalogChannelEvent = null;
+ try {
+ catalogChannelEvent = CatalogChannelEvent.decode(itemDevice);
+ if (catalogChannelEvent.getChannel() == null) {
+ log.info("[解析CatalogChannelEvent]成功:但是解析通道信息失败, 原文如下: \n{}", new String(evt.getRequest().getRawContent()));
+ continue;
+ }
+ } catch (InvocationTargetException | NoSuchMethodException | InstantiationException |
+ IllegalAccessException e) {
+ log.error("[解析CatalogChannelEvent]失败,", e);
+ log.error("[解析CatalogChannelEvent]失败原文: \n{}", new String(evt.getRequest().getRawContent(), Charset.forName(device.getCharset())));
+ continue;
+ }
+ if (catalogChannelEvent == null) {
continue;
}
- if (channel.getParentId() != null && channel.getParentId().equals(sipConfig.getId())) {
- channel.setParentId(null);
- }
- channel.setDeviceId(device.getDeviceId());
- logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getDeviceId());
- switch (event) {
+
+ log.info("[收到目录订阅]:{}/{}-{}", device.getDeviceId(),
+ catalogChannelEvent.getChannel().getDeviceId(), catalogChannelEvent.getEvent());
+ switch (catalogChannelEvent.getEvent()) {
case CatalogEvent.ON:
// 上线
- logger.info("[收到通道上线通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
- updateChannelOnlineList.add(channel);
+ log.info("[收到通道上线通知] 来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
+ updateChannelOnlineList.add(catalogChannelEvent.getChannel());
if (userSetting.getDeviceStatusNotify()) {
// 发送redis消息
- redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), true);
+ redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId(), true);
}
break;
case CatalogEvent.OFF:
// 离线
- logger.info("[收到通道离线通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[收到通道离线通知] 来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
if (userSetting.getRefuseChannelStatusChannelFormNotify()) {
- logger.info("[收到通道离线通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[收到通道离线通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
} else {
- updateChannelOfflineList.add(channel);
+ updateChannelOfflineList.add(catalogChannelEvent.getChannel());
if (userSetting.getDeviceStatusNotify()) {
// 发送redis消息
- redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false);
+ redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId(), false);
}
}
break;
case CatalogEvent.VLOST:
// 视频丢失
- logger.info("[收到通道视频丢失通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[收到通道视频丢失通知] 来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
if (userSetting.getRefuseChannelStatusChannelFormNotify()) {
- logger.info("[收到通道视频丢失通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[收到通道视频丢失通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
} else {
- updateChannelOfflineList.add(channel);
+ updateChannelOfflineList.add(catalogChannelEvent.getChannel());
if (userSetting.getDeviceStatusNotify()) {
// 发送redis消息
- redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false);
+ redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId(), false);
}
}
break;
case CatalogEvent.DEFECT:
// 故障
- logger.info("[收到通道视频故障通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[收到通道视频故障通知] 来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
if (userSetting.getRefuseChannelStatusChannelFormNotify()) {
- logger.info("[收到通道视频故障通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[收到通道视频故障通知] 但是平台已配置拒绝此消息,来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
} else {
- updateChannelOfflineList.add(channel);
+ updateChannelOfflineList.add(catalogChannelEvent.getChannel());
if (userSetting.getDeviceStatusNotify()) {
// 发送redis消息
- redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), channel.getChannelId(), false);
+ redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId(), false);
}
}
break;
case CatalogEvent.ADD:
// 增加
- logger.info("[收到增加通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[收到增加通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
// 判断此通道是否存在
- DeviceChannel deviceChannel = deviceChannelService.getOne(deviceId, channel.getChannelId());
+ DeviceChannel deviceChannel = deviceChannelService.getOne(deviceId, catalogChannelEvent.getChannel().getDeviceId());
if (deviceChannel != null) {
- logger.info("[增加通道] 已存在,不发送通知只更新,设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[增加通道] 已存在,不发送通知只更新,设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
+ DeviceChannel channel = catalogChannelEvent.getChannel();
channel.setId(deviceChannel.getId());
- channel.setHasAudio(null);
- updateChannelMap.put(channel.getChannelId(), channel);
+ channel.setHasAudio(deviceChannel.getHasAudio());
+ channel.setUpdateTime(DateUtil.getNow());
+ updateChannelMap.put(catalogChannelEvent.getChannel().getDeviceId(), channel);
} else {
- addChannelMap.put(channel.getChannelId(), channel);
+ addChannelMap.put(catalogChannelEvent.getChannel().getDeviceId(), catalogChannelEvent.getChannel());
if (userSetting.getDeviceStatusNotify()) {
// 发送redis消息
- redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true);
+ redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId(), true);
}
}
break;
case CatalogEvent.DEL:
// 删除
- logger.info("[收到删除通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
- deleteChannelList.add(channel);
+ log.info("[收到删除通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
+ deleteChannelList.add(catalogChannelEvent.getChannel());
if (userSetting.getDeviceStatusNotify()) {
// 发送redis消息
- redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), false);
+ redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId(), false);
}
break;
case CatalogEvent.UPDATE:
// 更新
- logger.info("[收到更新通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
+ log.info("[收到更新通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId());
// 判断此通道是否存在
- DeviceChannel deviceChannelForUpdate = deviceChannelService.getOne(deviceId, channel.getChannelId());
+ DeviceChannel deviceChannelForUpdate = deviceChannelService.getOne(deviceId, catalogChannelEvent.getChannel().getDeviceId());
if (deviceChannelForUpdate != null) {
+ DeviceChannel channel = catalogChannelEvent.getChannel();
channel.setId(deviceChannelForUpdate.getId());
+ channel.setHasAudio(deviceChannelForUpdate.getHasAudio());
channel.setUpdateTime(DateUtil.getNow());
- channel.setHasAudio(null);
- updateChannelMap.put(channel.getChannelId(), channel);
+ updateChannelMap.put(catalogChannelEvent.getChannel().getDeviceId(), channel);
} else {
- addChannelMap.put(channel.getChannelId(), channel);
+ addChannelMap.put(catalogChannelEvent.getChannel().getDeviceId(), catalogChannelEvent.getChannel());
if (userSetting.getDeviceStatusNotify()) {
// 发送redis消息
- redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true);
+ redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), catalogChannelEvent.getChannel().getDeviceId(), true);
}
}
break;
default:
- logger.warn("[ NotifyCatalog ] event not found : {}", event);
+ log.warn("[ NotifyCatalog ] event not found : {}", catalogChannelEvent.getEvent());
}
// 转发变化信息
- eventPublisher.catalogEventPublish(null, channel, event);
+ eventPublisher.catalogEventPublish(null, catalogChannelEvent.getChannel(), catalogChannelEvent.getEvent());
}
}
} catch (DocumentException e) {
- logger.error("未处理的异常 ", e);
+ log.error("未处理的异常 ", e);
}
}
taskQueue.clear();
@@ -255,33 +256,33 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
try {
executeSaveForAdd();
} catch (Exception e) {
- logger.error("[存储收到的增加通道] 异常: ", e );
+ log.error("[存储收到的增加通道] 异常: ", e );
}
try {
executeSaveForOnline();
} catch (Exception e) {
- logger.error("[存储收到的通道上线] 异常: ", e );
+ log.error("[存储收到的通道上线] 异常: ", e );
}
try {
executeSaveForOffline();
} catch (Exception e) {
- logger.error("[存储收到的通道离线] 异常: ", e );
+ log.error("[存储收到的通道离线] 异常: ", e );
}
try {
executeSaveForUpdate();
} catch (Exception e) {
- logger.error("[存储收到的更新通道] 异常: ", e );
+ log.error("[存储收到的更新通道] 异常: ", e );
}
try {
executeSaveForDelete();
} catch (Exception e) {
- logger.error("[存储收到的删除通道] 异常: ", e );
+ log.error("[存储收到的删除通道] 异常: ", e );
}
}
private void executeSaveForUpdate(){
if (!updateChannelMap.values().isEmpty()) {
- logger.info("[存储收到的更新通道], 数量: {}", updateChannelMap.size());
+ log.info("[存储收到的更新通道], 数量: {}", updateChannelMap.size());
ArrayList deviceChannels = new ArrayList<>(updateChannelMap.values());
deviceChannelService.batchUpdateChannel(deviceChannels);
updateChannelMap.clear();
@@ -319,6 +320,6 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
@Scheduled(fixedRate = 10000) //每1秒执行一次
public void execute(){
- logger.info("[待处理Notify-目录订阅消息数量]: {}", taskQueue.size());
+ log.info("[待处理Notify-目录订阅消息数量]: {}", taskQueue.size());
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
index c16d7f56..c2b0b2de 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
@@ -7,7 +7,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
-import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import gov.nist.javax.sip.message.SIPRequest;
import org.dom4j.DocumentException;
@@ -114,8 +113,9 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp
if (channelDeviceElement == null) {
continue;
}
- DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, null);
- if (channel == null) {
+ DeviceChannel channel = DeviceChannel.decode(itemDevice);
+// DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, null);
+ if (channel == null || channel.getDeviceId() == null) {
logger.info("[收到目录订阅]:但是解析失败 {}", new String(evt.getRequest().getRawContent()));
continue;
}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
index cb874802..46e92480 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
@@ -2,13 +2,6 @@ package com.genersoft.iot.vmp.gb28181.utils;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
-import com.genersoft.iot.vmp.common.CivilCodePo;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
-import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
-import com.genersoft.iot.vmp.utils.CivilCodeUtil;
-import com.genersoft.iot.vmp.utils.DateUtil;
-import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
@@ -240,388 +233,387 @@ public class XmlUtil {
CivilCode, BusinessGroup,VirtualOrganization,Other
}
- public static DeviceChannel channelContentHandler(Element itemDevice, Device device, String event){
- loadElement(itemDevice, DeviceChannel.class)
- DeviceChannel deviceChannel = new DeviceChannel();
- deviceChannel.setDeviceId(device.getDeviceId());
- Element channdelIdElement = itemDevice.element("DeviceID");
- if (channdelIdElement == null) {
- logger.warn("解析Catalog消息时发现缺少 DeviceID");
- return null;
- }
- String channelId = channdelIdElement.getTextTrim();
- if (ObjectUtils.isEmpty(channelId)) {
- logger.warn("解析Catalog消息时发现缺少 DeviceID");
- return null;
- }
- deviceChannel.setChannelId(channelId);
- if (event != null && !event.equals(CatalogEvent.ADD) && !event.equals(CatalogEvent.UPDATE)) {
- // 除了ADD和update情况下需要识别全部内容,
- return deviceChannel;
- }
- Element nameElement = itemDevice.element("Name");
- // 当通道名称为空时,设置通道名称为通道编码,避免级联时因通道名称为空导致上级接收通道失败
- if (nameElement != null && StringUtils.isNotBlank(nameElement.getText())) {
- deviceChannel.setName(nameElement.getText());
- } else {
- deviceChannel.setName(channelId);
- }
- if(channelId.length() <= 8) {
- deviceChannel.setHasAudio(false);
- CivilCodePo parentCode = CivilCodeUtil.INSTANCE.getParentCode(channelId);
- if (parentCode != null) {
- deviceChannel.setParentId(parentCode.getCode());
- deviceChannel.setCivilCode(parentCode.getCode());
- }else {
- logger.warn("[xml解析] 无法确定行政区划{}的上级行政区划", channelId);
- }
- deviceChannel.setStatus(true);
- return deviceChannel;
- }else {
- if(channelId.length() != 20) {
- logger.warn("[xml解析] 失败,编号不符合国标28181定义: {}", channelId);
- return null;
- }
-
- int code = Integer.parseInt(channelId.substring(10, 13));
- if (code == 136 || code == 137 || code == 138) {
- deviceChannel.setHasAudio(true);
- }else {
- deviceChannel.setHasAudio(false);
- }
- // 设备厂商
- String manufacturer = getText(itemDevice, "Manufacturer");
- // 设备型号
- String model = getText(itemDevice, "Model");
- // 设备归属
- String owner = getText(itemDevice, "Owner");
- // 行政区域
- String civilCode = getText(itemDevice, "CivilCode");
- // 虚拟组织所属的业务分组ID,业务分组根据特定的业务需求制定,一个业务分组包含一组特定的虚拟组织
- String businessGroupID = getText(itemDevice, "BusinessGroupID");
- // 父设备/区域/系统ID
- String parentID = getText(itemDevice, "ParentID");
- if (parentID != null && parentID.equalsIgnoreCase("null")) {
- parentID = null;
- }
- // 注册方式(必选)缺省为1;1:符合IETFRFC3261标准的认证注册模式;2:基于口令的双向认证注册模式;3:基于数字证书的双向认证注册模式
- String registerWay = getText(itemDevice, "RegisterWay");
- // 保密属性(必选)缺省为0;0:不涉密,1:涉密
- String secrecy = getText(itemDevice, "Secrecy");
- // 安装地址
- String address = getText(itemDevice, "Address");
-
- switch (code){
- case 200:
- // 系统目录
- if (!ObjectUtils.isEmpty(manufacturer)) {
- deviceChannel.setManufacture(manufacturer);
- }
- if (!ObjectUtils.isEmpty(model)) {
- deviceChannel.setModel(model);
- }
- if (!ObjectUtils.isEmpty(owner)) {
- deviceChannel.setOwner(owner);
- }
- if (!ObjectUtils.isEmpty(civilCode)) {
- deviceChannel.setCivilCode(civilCode);
- deviceChannel.setParentId(civilCode);
- }else {
- if (!ObjectUtils.isEmpty(parentID)) {
- deviceChannel.setParentId(parentID);
- }
- }
- if (!ObjectUtils.isEmpty(address)) {
- deviceChannel.setAddress(address);
- }
- deviceChannel.setStatus(true);
- if (!ObjectUtils.isEmpty(registerWay)) {
- try {
- deviceChannel.setRegisterWay(Integer.parseInt(registerWay));
- }catch (NumberFormatException exception) {
- logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay);
- }
- }
- if (!ObjectUtils.isEmpty(secrecy)) {
- deviceChannel.setSecrecy(secrecy);
- }
- return deviceChannel;
- case 215:
- // 业务分组
- deviceChannel.setStatus(true);
- if (!ObjectUtils.isEmpty(parentID)) {
- if (!parentID.trim().equalsIgnoreCase(device.getDeviceId())) {
- deviceChannel.setParentId(parentID);
- }
- }else {
- logger.warn("[xml解析] 业务分组数据中缺少关键信息->ParentId");
- if (!ObjectUtils.isEmpty(civilCode)) {
- deviceChannel.setCivilCode(civilCode);
- }
- }
- break;
- case 216:
- // 虚拟组织
- deviceChannel.setStatus(true);
- if (!ObjectUtils.isEmpty(businessGroupID)) {
- deviceChannel.setBusinessGroupId(businessGroupID);
- }
-
- if (!ObjectUtils.isEmpty(parentID)) {
- if (parentID.contains("/")) {
- String[] parentIdArray = parentID.split("/");
- parentID = parentIdArray[parentIdArray.length - 1];
- }
- deviceChannel.setParentId(parentID);
- }else {
- if (!ObjectUtils.isEmpty(businessGroupID)) {
- deviceChannel.setParentId(businessGroupID);
- }
- }
- break;
- default:
- // 设备目录
- if (!ObjectUtils.isEmpty(manufacturer)) {
- deviceChannel.setManufacture(manufacturer);
- }
- if (!ObjectUtils.isEmpty(model)) {
- deviceChannel.setModel(model);
- }
- if (!ObjectUtils.isEmpty(owner)) {
- deviceChannel.setOwner(owner);
- }
- if (!ObjectUtils.isEmpty(civilCode)
- && civilCode.length() <= 8
- && NumberUtils.isParsable(civilCode)
- && civilCode.length()%2 == 0
- ) {
- deviceChannel.setCivilCode(civilCode);
- }
- if (!ObjectUtils.isEmpty(businessGroupID)) {
- deviceChannel.setBusinessGroupId(businessGroupID);
- }
-
- // 警区
- String block = getText(itemDevice, "Block");
- if (!ObjectUtils.isEmpty(block)) {
- deviceChannel.setBlock(block);
- }
- if (!ObjectUtils.isEmpty(address)) {
- deviceChannel.setAddress(address);
- }
-
- if (!ObjectUtils.isEmpty(secrecy)) {
- deviceChannel.setSecrecy(secrecy);
- }
-
- // 当为设备时,是否有子设备(必选)1有,0没有
- String parental = getText(itemDevice, "Parental");
- if (!ObjectUtils.isEmpty(parental)) {
- try {
- // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
- if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
- deviceChannel.setParental(0);
- }else {
- deviceChannel.setParental(1);
- }
- }catch (NumberFormatException e) {
- logger.warn("[xml解析] 从通道数据获取 parental失败: {}", parental);
- }
- }
- // 父设备/区域/系统ID
-
- if (!ObjectUtils.isEmpty(parentID) ) {
- if (parentID.contains("/")) {
- String[] parentIdArray = parentID.split("/");
- deviceChannel.setParentId(parentIdArray[parentIdArray.length - 1]);
- }else {
- if (parentID.length()%2 == 0) {
- deviceChannel.setParentId(parentID);
- }else {
- logger.warn("[xml解析] 不规范的parentID:{}, 已舍弃", parentID);
- }
- }
- }else {
- if (!ObjectUtils.isEmpty(businessGroupID)) {
- deviceChannel.setParentId(businessGroupID);
- }else {
- if (!ObjectUtils.isEmpty(deviceChannel.getCivilCode())) {
- deviceChannel.setParentId(deviceChannel.getCivilCode());
- }
- }
- }
- // 注册方式
- if (!ObjectUtils.isEmpty(registerWay)) {
- try {
- int registerWayInt = Integer.parseInt(registerWay);
- deviceChannel.setRegisterWay(registerWayInt);
- }catch (NumberFormatException exception) {
- logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay);
- deviceChannel.setRegisterWay(1);
- }
- }else {
- deviceChannel.setRegisterWay(1);
- }
-
- // 信令安全模式(可选)缺省为0; 0:不采用;2:S/MIME 签名方式;3:S/MIME加密签名同时采用方式;4:数字摘要方式
- String safetyWay = getText(itemDevice, "SafetyWay");
- if (!ObjectUtils.isEmpty(safetyWay)) {
- try {
- deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));
- }catch (NumberFormatException e) {
- logger.warn("[xml解析] 从通道数据获取 safetyWay失败: {}", safetyWay);
- }
- }
-
- // 证书序列号(有证书的设备必选)
- String certNum = getText(itemDevice, "CertNum");
- if (!ObjectUtils.isEmpty(certNum)) {
- deviceChannel.setCertNum(certNum);
- }
-
- // 证书有效标识(有证书的设备必选)缺省为0;证书有效标识:0:无效 1:有效
- String certifiable = getText(itemDevice, "Certifiable");
- if (!ObjectUtils.isEmpty(certifiable)) {
- try {
- deviceChannel.setCertifiable(Integer.parseInt(certifiable));
- }catch (NumberFormatException e) {
- logger.warn("[xml解析] 从通道数据获取 Certifiable失败: {}", certifiable);
- }
- }
-
- // 无效原因码(有证书且证书无效的设备必选)
- String errCode = getText(itemDevice, "ErrCode");
- if (!ObjectUtils.isEmpty(errCode)) {
- try {
- deviceChannel.setErrCode(Integer.parseInt(errCode));
- }catch (NumberFormatException e) {
- logger.warn("[xml解析] 从通道数据获取 ErrCode失败: {}", errCode);
- }
- }
-
- // 证书终止有效期(有证书的设备必选)
- String endTime = getText(itemDevice, "EndTime");
- if (!ObjectUtils.isEmpty(endTime)) {
- deviceChannel.setEndTime(endTime);
- }
-
-
- // 设备/区域/系统IP地址
- String ipAddress = getText(itemDevice, "IPAddress");
- if (!ObjectUtils.isEmpty(ipAddress)) {
- deviceChannel.setIpAddress(ipAddress);
- }
-
- // 设备/区域/系统端口
- String port = getText(itemDevice, "Port");
- if (!ObjectUtils.isEmpty(port)) {
- try {
- deviceChannel.setPort(Integer.parseInt(port));
- }catch (NumberFormatException e) {
- logger.warn("[xml解析] 从通道数据获取 Port失败: {}", port);
- }
- }
-
- // 设备口令
- String password = getText(itemDevice, "Password");
- if (!ObjectUtils.isEmpty(password)) {
- deviceChannel.setPassword(password);
- }
-
-
- // 设备状态
- String status = getText(itemDevice, "Status");
- if (status != null) {
- // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
- if (status.equalsIgnoreCase("ON") || status.equalsIgnoreCase("On") || status.equalsIgnoreCase("ONLINE") || status.equalsIgnoreCase("OK")) {
- deviceChannel.setStatus(true);
- }
- if (status.equalsIgnoreCase("OFF") || status.equalsIgnoreCase("Off") || status.equalsIgnoreCase("OFFLINE")) {
- deviceChannel.setStatus(false);
- }
- }else {
- deviceChannel.setStatus(true);
- }
-// logger.info("状态字符串: {}", status);
-// logger.info("状态结果: {}", deviceChannel.isStatus());
- // 经度
- String longitude = getText(itemDevice, "Longitude");
- if (NumericUtil.isDouble(longitude)) {
- deviceChannel.setLongitude(Double.parseDouble(longitude));
- } else {
- deviceChannel.setLongitude(0.00);
- }
-
- // 纬度
- String latitude = getText(itemDevice, "Latitude");
- if (NumericUtil.isDouble(latitude)) {
- deviceChannel.setLatitude(Double.parseDouble(latitude));
- } else {
- deviceChannel.setLatitude(0.00);
- }
-
- deviceChannel.setGpsTime(DateUtil.getNow());
-
- // -摄像机类型扩展,标识摄像机类型:1-球机;2-半球;3-固定枪机;4-遥控枪机。当目录项为摄像机时可选
- String ptzType = getText(itemDevice, "PTZType");
- if (ObjectUtils.isEmpty(ptzType)) {
- //兼容INFO中的信息
- Element info = itemDevice.element("Info");
- String ptzTypeFromInfo = XmlUtil.getText(info, "PTZType");
- if(!ObjectUtils.isEmpty(ptzTypeFromInfo)){
- try {
- deviceChannel.setPtzType(Integer.parseInt(ptzTypeFromInfo));
- }catch (NumberFormatException e){
- logger.warn("[xml解析] 从通道数据info中获取PTZType失败: {}", ptzTypeFromInfo);
- }
- }
- } else {
- try {
- deviceChannel.setPtzType(Integer.parseInt(ptzType));
- }catch (NumberFormatException e){
- logger.warn("[xml解析] 从通道数据中获取PTZType失败: {}", ptzType);
- }
- }
-
- // TODO 摄像机位置类型扩展。
- // 1-省际检查站、
- // 2-党政机关、
- // 3-车站码头、
- // 4-中心广场、
- // 5-体育场馆、
- // 6-商业中心、
- // 7-宗教场所、
- // 8-校园周边、
- // 9-治安复杂区域、
- // 10-交通干线。
- // String positionType = getText(itemDevice, "PositionType");
-
- // TODO 摄像机安装位置室外、室内属性。1-室外、2-室内。
- // String roomType = getText(itemDevice, "RoomType");
- // TODO 摄像机用途属性
- // String useType = getText(itemDevice, "UseType");
- // TODO 摄像机补光属性。1-无补光、2-红外补光、3-白光补光
- // String supplyLightType = getText(itemDevice, "SupplyLightType");
- // TODO 摄像机监视方位属性。1-东、2-西、3-南、4-北、5-东南、6-东北、7-西南、8-西北。
- // String directionType = getText(itemDevice, "DirectionType");
- // TODO 摄像机支持的分辨率,可有多个分辨率值,各个取值间以“/”分隔。分辨率取值参见附录 F中SDPf字段规定
- // String resolution = getText(itemDevice, "Resolution");
-
- // TODO 下载倍速范围(可选),各可选参数以“/”分隔,如设备支持1,2,4倍速下载则应写为“1/2/4
- // String downloadSpeed = getText(itemDevice, "DownloadSpeed");
- // TODO 空域编码能力,取值0:不支持;1:1级增强(1个增强层);2:2级增强(2个增强层);3:3级增强(3个增强层)
- // String svcSpaceSupportMode = getText(itemDevice, "SVCSpaceSupportMode");
- // TODO 时域编码能力,取值0:不支持;1:1级增强;2:2级增强;3:3级增强
- // String svcTimeSupportMode = getText(itemDevice, "SVCTimeSupportMode");
-
-
- deviceChannel.setSecrecy(secrecy);
- break;
- }
- }
-
- return deviceChannel;
- }
+// public static DeviceChannel channelContentHandler(Element itemDevice, Device device, String event){
+// DeviceChannel deviceChannel = new DeviceChannel();
+// deviceChannel.setDeviceId(device.getDeviceId());
+// Element channdelIdElement = itemDevice.element("DeviceID");
+// if (channdelIdElement == null) {
+// logger.warn("解析Catalog消息时发现缺少 DeviceID");
+// return null;
+// }
+// String channelId = channdelIdElement.getTextTrim();
+// if (ObjectUtils.isEmpty(channelId)) {
+// logger.warn("解析Catalog消息时发现缺少 DeviceID");
+// return null;
+// }
+// deviceChannel.setDeviceId(channelId);
+// if (event != null && !event.equals(CatalogEvent.ADD) && !event.equals(CatalogEvent.UPDATE)) {
+// // 除了ADD和update情况下需要识别全部内容,
+// return deviceChannel;
+// }
+// Element nameElement = itemDevice.element("Name");
+// // 当通道名称为空时,设置通道名称为通道编码,避免级联时因通道名称为空导致上级接收通道失败
+// if (nameElement != null && StringUtils.isNotBlank(nameElement.getText())) {
+// deviceChannel.setName(nameElement.getText());
+// } else {
+// deviceChannel.setName(channelId);
+// }
+// if(channelId.length() <= 8) {
+// deviceChannel.setHasAudio(false);
+// CivilCodePo parentCode = CivilCodeUtil.INSTANCE.getParentCode(channelId);
+// if (parentCode != null) {
+// deviceChannel.setParentId(parentCode.getCode());
+// deviceChannel.setCivilCode(parentCode.getCode());
+// }else {
+// logger.warn("[xml解析] 无法确定行政区划{}的上级行政区划", channelId);
+// }
+// deviceChannel.setStatus("ON");
+// return deviceChannel;
+// }else {
+// if(channelId.length() != 20) {
+// logger.warn("[xml解析] 失败,编号不符合国标28181定义: {}", channelId);
+// return null;
+// }
+//
+// int code = Integer.parseInt(channelId.substring(10, 13));
+// if (code == 136 || code == 137 || code == 138) {
+// deviceChannel.setHasAudio(true);
+// }else {
+// deviceChannel.setHasAudio(false);
+// }
+// // 设备厂商
+// String manufacturer = getText(itemDevice, "Manufacturer");
+// // 设备型号
+// String model = getText(itemDevice, "Model");
+// // 设备归属
+// String owner = getText(itemDevice, "Owner");
+// // 行政区域
+// String civilCode = getText(itemDevice, "CivilCode");
+// // 虚拟组织所属的业务分组ID,业务分组根据特定的业务需求制定,一个业务分组包含一组特定的虚拟组织
+// String businessGroupID = getText(itemDevice, "BusinessGroupID");
+// // 父设备/区域/系统ID
+// String parentID = getText(itemDevice, "ParentID");
+// if (parentID != null && parentID.equalsIgnoreCase("null")) {
+// parentID = null;
+// }
+// // 注册方式(必选)缺省为1;1:符合IETFRFC3261标准的认证注册模式;2:基于口令的双向认证注册模式;3:基于数字证书的双向认证注册模式
+// String registerWay = getText(itemDevice, "RegisterWay");
+// // 保密属性(必选)缺省为0;0:不涉密,1:涉密
+// String secrecy = getText(itemDevice, "Secrecy");
+// // 安装地址
+// String address = getText(itemDevice, "Address");
+//
+// switch (code){
+// case 200:
+// // 系统目录
+// if (!ObjectUtils.isEmpty(manufacturer)) {
+// deviceChannel.setManufacture(manufacturer);
+// }
+// if (!ObjectUtils.isEmpty(model)) {
+// deviceChannel.setModel(model);
+// }
+// if (!ObjectUtils.isEmpty(owner)) {
+// deviceChannel.setOwner(owner);
+// }
+// if (!ObjectUtils.isEmpty(civilCode)) {
+// deviceChannel.setCivilCode(civilCode);
+// deviceChannel.setParentId(civilCode);
+// }else {
+// if (!ObjectUtils.isEmpty(parentID)) {
+// deviceChannel.setParentId(parentID);
+// }
+// }
+// if (!ObjectUtils.isEmpty(address)) {
+// deviceChannel.setAddress(address);
+// }
+// deviceChannel.setStatus(true);
+// if (!ObjectUtils.isEmpty(registerWay)) {
+// try {
+// deviceChannel.setRegisterWay(Integer.parseInt(registerWay));
+// }catch (NumberFormatException exception) {
+// logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay);
+// }
+// }
+// if (!ObjectUtils.isEmpty(secrecy)) {
+// deviceChannel.setSecrecy(secrecy);
+// }
+// return deviceChannel;
+// case 215:
+// // 业务分组
+// deviceChannel.setStatus(true);
+// if (!ObjectUtils.isEmpty(parentID)) {
+// if (!parentID.trim().equalsIgnoreCase(device.getDeviceId())) {
+// deviceChannel.setParentId(parentID);
+// }
+// }else {
+// logger.warn("[xml解析] 业务分组数据中缺少关键信息->ParentId");
+// if (!ObjectUtils.isEmpty(civilCode)) {
+// deviceChannel.setCivilCode(civilCode);
+// }
+// }
+// break;
+// case 216:
+// // 虚拟组织
+// deviceChannel.setStatus(true);
+// if (!ObjectUtils.isEmpty(businessGroupID)) {
+// deviceChannel.setBusinessGroupId(businessGroupID);
+// }
+//
+// if (!ObjectUtils.isEmpty(parentID)) {
+// if (parentID.contains("/")) {
+// String[] parentIdArray = parentID.split("/");
+// parentID = parentIdArray[parentIdArray.length - 1];
+// }
+// deviceChannel.setParentId(parentID);
+// }else {
+// if (!ObjectUtils.isEmpty(businessGroupID)) {
+// deviceChannel.setParentId(businessGroupID);
+// }
+// }
+// break;
+// default:
+// // 设备目录
+// if (!ObjectUtils.isEmpty(manufacturer)) {
+// deviceChannel.setManufacture(manufacturer);
+// }
+// if (!ObjectUtils.isEmpty(model)) {
+// deviceChannel.setModel(model);
+// }
+// if (!ObjectUtils.isEmpty(owner)) {
+// deviceChannel.setOwner(owner);
+// }
+// if (!ObjectUtils.isEmpty(civilCode)
+// && civilCode.length() <= 8
+// && NumberUtils.isParsable(civilCode)
+// && civilCode.length()%2 == 0
+// ) {
+// deviceChannel.setCivilCode(civilCode);
+// }
+// if (!ObjectUtils.isEmpty(businessGroupID)) {
+// deviceChannel.setBusinessGroupId(businessGroupID);
+// }
+//
+// // 警区
+// String block = getText(itemDevice, "Block");
+// if (!ObjectUtils.isEmpty(block)) {
+// deviceChannel.setBlock(block);
+// }
+// if (!ObjectUtils.isEmpty(address)) {
+// deviceChannel.setAddress(address);
+// }
+//
+// if (!ObjectUtils.isEmpty(secrecy)) {
+// deviceChannel.setSecrecy(secrecy);
+// }
+//
+// // 当为设备时,是否有子设备(必选)1有,0没有
+// String parental = getText(itemDevice, "Parental");
+// if (!ObjectUtils.isEmpty(parental)) {
+// try {
+// // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1
+// if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) {
+// deviceChannel.setParental(0);
+// }else {
+// deviceChannel.setParental(1);
+// }
+// }catch (NumberFormatException e) {
+// logger.warn("[xml解析] 从通道数据获取 parental失败: {}", parental);
+// }
+// }
+// // 父设备/区域/系统ID
+//
+// if (!ObjectUtils.isEmpty(parentID) ) {
+// if (parentID.contains("/")) {
+// String[] parentIdArray = parentID.split("/");
+// deviceChannel.setParentId(parentIdArray[parentIdArray.length - 1]);
+// }else {
+// if (parentID.length()%2 == 0) {
+// deviceChannel.setParentId(parentID);
+// }else {
+// logger.warn("[xml解析] 不规范的parentID:{}, 已舍弃", parentID);
+// }
+// }
+// }else {
+// if (!ObjectUtils.isEmpty(businessGroupID)) {
+// deviceChannel.setParentId(businessGroupID);
+// }else {
+// if (!ObjectUtils.isEmpty(deviceChannel.getCivilCode())) {
+// deviceChannel.setParentId(deviceChannel.getCivilCode());
+// }
+// }
+// }
+// // 注册方式
+// if (!ObjectUtils.isEmpty(registerWay)) {
+// try {
+// int registerWayInt = Integer.parseInt(registerWay);
+// deviceChannel.setRegisterWay(registerWayInt);
+// }catch (NumberFormatException exception) {
+// logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay);
+// deviceChannel.setRegisterWay(1);
+// }
+// }else {
+// deviceChannel.setRegisterWay(1);
+// }
+//
+// // 信令安全模式(可选)缺省为0; 0:不采用;2:S/MIME 签名方式;3:S/MIME加密签名同时采用方式;4:数字摘要方式
+// String safetyWay = getText(itemDevice, "SafetyWay");
+// if (!ObjectUtils.isEmpty(safetyWay)) {
+// try {
+// deviceChannel.setSafetyWay(Integer.parseInt(safetyWay));
+// }catch (NumberFormatException e) {
+// logger.warn("[xml解析] 从通道数据获取 safetyWay失败: {}", safetyWay);
+// }
+// }
+//
+// // 证书序列号(有证书的设备必选)
+// String certNum = getText(itemDevice, "CertNum");
+// if (!ObjectUtils.isEmpty(certNum)) {
+// deviceChannel.setCertNum(certNum);
+// }
+//
+// // 证书有效标识(有证书的设备必选)缺省为0;证书有效标识:0:无效 1:有效
+// String certifiable = getText(itemDevice, "Certifiable");
+// if (!ObjectUtils.isEmpty(certifiable)) {
+// try {
+// deviceChannel.setCertifiable(Integer.parseInt(certifiable));
+// }catch (NumberFormatException e) {
+// logger.warn("[xml解析] 从通道数据获取 Certifiable失败: {}", certifiable);
+// }
+// }
+//
+// // 无效原因码(有证书且证书无效的设备必选)
+// String errCode = getText(itemDevice, "ErrCode");
+// if (!ObjectUtils.isEmpty(errCode)) {
+// try {
+// deviceChannel.setErrCode(Integer.parseInt(errCode));
+// }catch (NumberFormatException e) {
+// logger.warn("[xml解析] 从通道数据获取 ErrCode失败: {}", errCode);
+// }
+// }
+//
+// // 证书终止有效期(有证书的设备必选)
+// String endTime = getText(itemDevice, "EndTime");
+// if (!ObjectUtils.isEmpty(endTime)) {
+// deviceChannel.setEndTime(endTime);
+// }
+//
+//
+// // 设备/区域/系统IP地址
+// String ipAddress = getText(itemDevice, "IPAddress");
+// if (!ObjectUtils.isEmpty(ipAddress)) {
+// deviceChannel.setIpAddress(ipAddress);
+// }
+//
+// // 设备/区域/系统端口
+// String port = getText(itemDevice, "Port");
+// if (!ObjectUtils.isEmpty(port)) {
+// try {
+// deviceChannel.setPort(Integer.parseInt(port));
+// }catch (NumberFormatException e) {
+// logger.warn("[xml解析] 从通道数据获取 Port失败: {}", port);
+// }
+// }
+//
+// // 设备口令
+// String password = getText(itemDevice, "Password");
+// if (!ObjectUtils.isEmpty(password)) {
+// deviceChannel.setPassword(password);
+// }
+//
+//
+// // 设备状态
+// String status = getText(itemDevice, "Status");
+// if (status != null) {
+// // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
+// if (status.equalsIgnoreCase("ON") || status.equalsIgnoreCase("On") || status.equalsIgnoreCase("ONLINE") || status.equalsIgnoreCase("OK")) {
+// deviceChannel.setStatus(true);
+// }
+// if (status.equalsIgnoreCase("OFF") || status.equalsIgnoreCase("Off") || status.equalsIgnoreCase("OFFLINE")) {
+// deviceChannel.setStatus(false);
+// }
+// }else {
+// deviceChannel.setStatus(true);
+// }
+//// logger.info("状态字符串: {}", status);
+//// logger.info("状态结果: {}", deviceChannel.isStatus());
+// // 经度
+// String longitude = getText(itemDevice, "Longitude");
+// if (NumericUtil.isDouble(longitude)) {
+// deviceChannel.setLongitude(Double.parseDouble(longitude));
+// } else {
+// deviceChannel.setLongitude(0.00);
+// }
+//
+// // 纬度
+// String latitude = getText(itemDevice, "Latitude");
+// if (NumericUtil.isDouble(latitude)) {
+// deviceChannel.setLatitude(Double.parseDouble(latitude));
+// } else {
+// deviceChannel.setLatitude(0.00);
+// }
+//
+// deviceChannel.setGpsTime(DateUtil.getNow());
+//
+// // -摄像机类型扩展,标识摄像机类型:1-球机;2-半球;3-固定枪机;4-遥控枪机。当目录项为摄像机时可选
+// String ptzType = getText(itemDevice, "PTZType");
+// if (ObjectUtils.isEmpty(ptzType)) {
+// //兼容INFO中的信息
+// Element info = itemDevice.element("Info");
+// String ptzTypeFromInfo = XmlUtil.getText(info, "PTZType");
+// if(!ObjectUtils.isEmpty(ptzTypeFromInfo)){
+// try {
+// deviceChannel.setPtzType(Integer.parseInt(ptzTypeFromInfo));
+// }catch (NumberFormatException e){
+// logger.warn("[xml解析] 从通道数据info中获取PTZType失败: {}", ptzTypeFromInfo);
+// }
+// }
+// } else {
+// try {
+// deviceChannel.setPtzType(Integer.parseInt(ptzType));
+// }catch (NumberFormatException e){
+// logger.warn("[xml解析] 从通道数据中获取PTZType失败: {}", ptzType);
+// }
+// }
+//
+// // TODO 摄像机位置类型扩展。
+// // 1-省际检查站、
+// // 2-党政机关、
+// // 3-车站码头、
+// // 4-中心广场、
+// // 5-体育场馆、
+// // 6-商业中心、
+// // 7-宗教场所、
+// // 8-校园周边、
+// // 9-治安复杂区域、
+// // 10-交通干线。
+// // String positionType = getText(itemDevice, "PositionType");
+//
+// // TODO 摄像机安装位置室外、室内属性。1-室外、2-室内。
+// // String roomType = getText(itemDevice, "RoomType");
+// // TODO 摄像机用途属性
+// // String useType = getText(itemDevice, "UseType");
+// // TODO 摄像机补光属性。1-无补光、2-红外补光、3-白光补光
+// // String supplyLightType = getText(itemDevice, "SupplyLightType");
+// // TODO 摄像机监视方位属性。1-东、2-西、3-南、4-北、5-东南、6-东北、7-西南、8-西北。
+// // String directionType = getText(itemDevice, "DirectionType");
+// // TODO 摄像机支持的分辨率,可有多个分辨率值,各个取值间以“/”分隔。分辨率取值参见附录 F中SDPf字段规定
+// // String resolution = getText(itemDevice, "Resolution");
+//
+// // TODO 下载倍速范围(可选),各可选参数以“/”分隔,如设备支持1,2,4倍速下载则应写为“1/2/4
+// // String downloadSpeed = getText(itemDevice, "DownloadSpeed");
+// // TODO 空域编码能力,取值0:不支持;1:1级增强(1个增强层);2:2级增强(2个增强层);3:3级增强(3个增强层)
+// // String svcSpaceSupportMode = getText(itemDevice, "SVCSpaceSupportMode");
+// // TODO 时域编码能力,取值0:不支持;1:1级增强;2:2级增强;3:3级增强
+// // String svcTimeSupportMode = getText(itemDevice, "SVCTimeSupportMode");
+//
+//
+// deviceChannel.setSecrecy(secrecy);
+// break;
+// }
+// }
+//
+// return deviceChannel;
+// }
/**
* 新增方法支持内部嵌套
@@ -672,6 +664,46 @@ public class XmlUtil {
return t;
}
+ public static T elementDecode(Element element, Class clazz) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
+ Field[] fields = clazz.getDeclaredFields();
+ T t = clazz.getDeclaredConstructor().newInstance();
+ for (Field field : fields) {
+ ReflectionUtils.makeAccessible(field);
+ MessageElement annotation = field.getAnnotation(MessageElement.class);
+ if (annotation == null) {
+ continue;
+ }
+ String value = annotation.value();
+ boolean subVal = value.contains(".");
+ Element element1 = element.element(value);
+ if (element1 == null) {
+ continue;
+ }
+ if (!subVal) {
+ // 无下级数据
+ Object fieldVal = element1.isTextOnly() ? element1.getText() : loadElement(element1, field.getType());
+ Object o = simpleTypeDeal(field.getType(), fieldVal);
+ ReflectionUtils.setField(field, t, o);
+ } else {
+ String[] pathArray = value.split(".");
+ Element subElement = element1;
+ for (String path : pathArray) {
+ subElement = subElement.element(path);
+ if (subElement == null) {
+ break;
+ }
+ }
+ if (subElement == null) {
+ continue;
+ }
+ Object fieldVal = subElement.isTextOnly() ? subElement.getText() : loadElement(subElement, field.getType());
+ Object o = simpleTypeDeal(field.getType(), fieldVal);
+ ReflectionUtils.setField(field, t, o);
+ }
+ }
+ return t;
+ }
+
/**
* 简单类型处理
*
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java b/src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
index f37539cd..f4477283 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
@@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.service;
+import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
@@ -45,8 +46,8 @@ public interface IGbStreamService {
DeviceChannel getDeviceChannelListByStream(GbStream gbStream, String catalogId, ParentPlatform platform);
- void sendCatalogMsg(GbStream gbStream, String type);
- void sendCatalogMsgs(List gbStreams, String type);
+ void sendCatalogMsg(CommonGBChannel gbStream, String type);
+ void sendCatalogMsgs(List gbStreams, String type);
/**
* 修改gbId或name
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
index b99106e7..8936c642 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
@@ -116,4 +116,7 @@ public interface IStreamPushService {
void updatePush(OnStreamChangedHookParam param);
+
+ Map getAllGBId();
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
index 46b70f18..0f199378 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
@@ -157,16 +157,16 @@ public class GbStreamServiceImpl implements IGbStreamService {
}
@Override
- public void sendCatalogMsg(GbStream gbStream, String type) {
- if (gbStream == null || type == null) {
+ public void sendCatalogMsg(CommonGBChannel channel, String type) {
+ if (channel == null || type == null) {
logger.warn("[发送目录订阅]类型:流信息或类型为NULL");
return;
}
- List gbStreams = new ArrayList<>();
- if (gbStream.getGbId() != null) {
- gbStreams.add(gbStream);
+ List gbStreams = new ArrayList<>();
+ if (channel.getGbDeviceId() != null) {
+ gbStreams.add(channel);
}else {
- GbStream gbStreamIndb = gbStreamMapper.selectOne(gbStream.getApp(), gbStream.getStream());
+ GbStream gbStreamIndb = gbStreamMapper.selectOne(channel.getApp(), channel.getStream());
if (gbStreamIndb != null && gbStreamIndb.getGbId() != null){
gbStreams.add(gbStreamIndb);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
index 0d8a8ec6..c73b055c 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -48,9 +48,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
private final static Logger logger = LoggerFactory.getLogger(StreamPushServiceImpl.class);
- @Autowired
- private GbStreamMapper gbStreamMapper;
-
@Autowired
private StreamPushMapper streamPushMapper;
@@ -66,9 +63,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Autowired
private PlatformGbStreamMapper platformGbStreamMapper;
- @Autowired
- private IGbStreamService gbStreamService;
-
@Autowired
private EventPublisher eventPublisher;
@@ -126,16 +120,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
streamPushMapper.update(transform);
gbStreamMapper.updateMediaServer(event.getApp(), event.getStream(), event.getMediaServer().getId());
}
- // TODO 相关的事件自行管理,不需要写入ZLMMediaListManager
-// ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(transform.getApp(), transform.getStream());
-// if ( channelOnlineEventLister != null) {
-// try {
-// channelOnlineEventLister.run(transform.getApp(), transform.getStream(), transform.getServerId());;
-// } catch (ParseException e) {
-// logger.error("addPush: ", e);
-// }
-// removedChannelOnlineEventLister(transform.getApp(), transform.getStream());
-// }
+
// 冗余数据,自己系统中自用
redisCatchStorage.addPushListItem(event.getApp(), event.getStream(), event);
@@ -216,7 +201,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
streamPushItem.setMediaServerId(item.getMediaServerId());
streamPushItem.setStream(item.getStream());
streamPushItem.setCreateTime(DateUtil.getNow());
- streamPushItem.setVhost(item.getVhost());
streamPushItem.setServerId(item.getSeverId());
return streamPushItem;
}
@@ -625,6 +609,11 @@ public class StreamPushServiceImpl implements IStreamPushService {
return streamPushMapper.getAllAppAndStreamMap();
}
+ @Override
+ public Map getAllGBId() {
+ return streamPushMapper.getAllGBId();
+ }
+
@Override
public void updatePush(OnStreamChangedHookParam param) {
StreamPush transform = transform(param);
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java
index 48b08eac..842277a8 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java
@@ -2,10 +2,9 @@ package com.genersoft.iot.vmp.service.redisMsg;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
-import com.genersoft.iot.vmp.gb28181.bean.GbStream;
+import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPush;
import com.genersoft.iot.vmp.service.IGbStreamService;
-import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IStreamPushService;
import com.genersoft.iot.vmp.utils.DateUtil;
import org.slf4j.Logger;
@@ -60,43 +59,40 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener {
List streamPushItems = JSON.parseArray(new String(msg.getBody()), StreamPush.class);
//查询全部的app+stream 用于判断是添加还是修改
Map allAppAndStream = streamPushService.getAllAppAndStreamMap();
- Map allGBId = gbStreamService.getAllGBId();
+ Map allGBId = streamPushService.getAllGBId();
/**
* 用于存储更具APP+Stream过滤后的数据,可以直接存入stream_push表与gb_stream表
*/
List streamPushItemForSave = new ArrayList<>();
List streamPushItemForUpdate = new ArrayList<>();
- for (StreamPush streamPushItem : streamPushItems) {
- String app = streamPushItem.getApp();
- String stream = streamPushItem.getStream();
+ for (StreamPush streamPush : streamPushItems) {
+ String app = streamPush.getApp();
+ String stream = streamPush.getStream();
boolean contains = allAppAndStream.containsKey(app + stream);
//不存在就添加
if (!contains) {
- if (allGBId.containsKey(streamPushItem.getGbId())) {
- GbStream gbStream = allGBId.get(streamPushItem.getGbId());
+ if (allGBId.containsKey(streamPush.getGbDeviceId())) {
+ StreamPush streamPushInDb = allGBId.get(streamPush.getGbDeviceId());
logger.warn("[REDIS消息-推流设备列表更新-INSERT] 国标编号重复: {}, 已分配给{}/{}",
- streamPushItem.getGbId(), gbStream.getApp(), gbStream.getStream());
+ streamPushInDb.getGbDeviceId(), streamPushInDb.getApp(), streamPushInDb.getStream());
continue;
}
- streamPushItem.setStreamType("push");
- streamPushItem.setCreateTime(DateUtil.getNow());
- streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId());
- streamPushItem.setOriginType(2);
- streamPushItem.setOriginTypeStr("rtsp_push");
- streamPushItem.setTotalReaderCount(0);
- streamPushItemForSave.add(streamPushItem);
- allGBId.put(streamPushItem.getGbId(), streamPushItem);
+ streamPush.setCreateTime(DateUtil.getNow());
+ streamPush.setMediaServerId(mediaServerService.getDefaultMediaServer().getId());
+ streamPushItemForSave.add(streamPush);
+ allGBId.put(streamPush.getGbDeviceId(), streamPush);
} else {
- if (allGBId.containsKey(streamPushItem.getGbId())
- && (!allGBId.get(streamPushItem.getGbId()).getApp().equals(streamPushItem.getApp()) || !allGBId.get(streamPushItem.getGbId()).getStream().equals(streamPushItem.getStream()))) {
- GbStream gbStream = allGBId.get(streamPushItem.getGbId());
+ if (allGBId.containsKey(streamPush.getGbDeviceId())
+ && (!allGBId.get(streamPush.getGbDeviceId()).getApp().equals(streamPush.getApp())
+ || !allGBId.get(streamPush.getGbDeviceId()).getStream().equals(streamPush.getStream()))) {
+ StreamPush streamPushInDb = allGBId.get(streamPush.getGbDeviceId());
logger.warn("[REDIS消息-推流设备列表更新-UPDATE] 国标编号重复: {}, 已分配给{}/{}",
- streamPushItem.getGbId(), gbStream.getApp(), gbStream.getStream());
+ streamPush.getGbDeviceId(), streamPushInDb.getApp(), streamPushInDb.getStream());
continue;
}
//存在就只修改 name和gbId
- streamPushItemForUpdate.add(streamPushItem);
+ streamPushItemForUpdate.add(streamPush);
}
}
if (!streamPushItemForSave.isEmpty()) {
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
index a0746dc5..6c6f93d0 100755
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
@@ -204,4 +204,10 @@ public interface StreamPushMapper {
Map getAllAppAndStreamMap();
+ @MapKey("gb_id")
+ @Select("SELECT wgs.gb_id, wsp.app, wsp.stream, wgs.gb_id, wgs.name " +
+ " from wvp_stream_push wsp " +
+ " left join wvp_gb_stream wgs on wgs.app = wsp.app and wgs.stream = wsp.stream")
+ Map getAllGBId();
+
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 3f478442..ddb05dee 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -2,4 +2,4 @@ spring:
application:
name: wvp
profiles:
- active: local
\ No newline at end of file
+ active: local271
\ No newline at end of file
From 7255e5a8875f83b597ad26ef7705afcd5f0e15f8 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Tue, 25 Jun 2024 16:59:22 +0800
Subject: [PATCH 10/12] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../iot/vmp/service/IStreamPushService.java | 3 +
.../service/impl/StreamPushServiceImpl.java | 63 +++++++++----------
.../streamPush/StreamPushController.java | 19 ------
3 files changed, 31 insertions(+), 54 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
index 8936c642..650908e7 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
@@ -100,6 +100,8 @@ public interface IStreamPushService {
*/
boolean add(StreamPush stream);
+ boolean update(StreamPush stream);
+
/**
* 获取全部的app+Streanm 用于判断推流列表是新增还是修改
* @return
@@ -119,4 +121,5 @@ public interface IStreamPushService {
Map getAllGBId();
+ void updateStatus(StreamPush push);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
index 15285dd7..aa7296ed 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -19,7 +19,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPush;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType;
-import com.genersoft.iot.vmp.service.IGbStreamService;
import com.genersoft.iot.vmp.service.IStreamPushService;
import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -116,10 +115,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
StreamPush pushInDb = getPush(event.getApp(), event.getStream());
if (pushInDb == null) {
transform.setCreateTime(DateUtil.getNow());
- streamPushMapper.add(transform);
+ add(transform);
}else {
- streamPushMapper.update(transform);
- gbStreamMapper.updateMediaServer(event.getApp(), event.getStream(), event.getMediaServer().getId());
+ update(transform);
}
// 冗余数据,自己系统中自用
if (!"broadcast".equals(event.getApp()) && !"talk".equals(event.getApp())) {
@@ -166,14 +164,17 @@ public class StreamPushServiceImpl implements IStreamPushService {
redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
}
}
- GbStream gbStream = gbStreamMapper.selectOne(event.getApp(), event.getStream());
- if (gbStream != null) {
+ StreamPush push = getPush(event.getApp(), event.getStream());
+ push.setPushIng(false);
+ if (push.getGbDeviceId() != null) {
if (userSetting.isUsePushingAsStatus()) {
- streamPushMapper.updatePushStatus(event.getApp(), event.getStream(), false);
- eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
+ push.setGbStatus(false);
+ updateStatus(push);
+// streamPushMapper.updatePushStatus(event.getApp(), event.getStream(), false);
+// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
}
}else {
- streamPushMapper.del(event.getApp(), event.getStream());
+ deleteByAppAndStream(event.getApp(), event.getStream());
}
}
@@ -222,31 +223,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
return streamPushMapper.selectAllByMediaServerIdWithOutGbID(mediaServerId);
}
- @Override
- public boolean saveToGB(GbStream stream) {
- stream.setStreamType("push");
- stream.setStatus(true);
- stream.setCreateTime(DateUtil.getNow());
- stream.setStreamType("push");
- stream.setMediaServerId(mediaConfig.getId());
- int add = gbStreamMapper.add(stream);
- return add > 0;
- }
-
- @Override
- public boolean removeFromGB(GbStream stream) {
- // 判断是否需要发送事件
- gbStreamService.sendCatalogMsg(stream, CatalogEvent.DEL);
- platformGbStreamMapper.delByAppAndStream(stream.getApp(), stream.getStream());
- int del = gbStreamMapper.del(stream.getApp(), stream.getStream());
- MediaServer mediaInfo = mediaServerService.getOne(stream.getMediaServerId());
- List mediaList = mediaServerService.getMediaList(mediaInfo, stream.getApp(), stream.getStream(), null);
- if (mediaList != null && mediaList.isEmpty()) {
- streamPushMapper.del(stream.getApp(), stream.getStream());
- }
- return del > 0;
- }
-
@Override
public StreamPush getPush(String app, String streamId) {
@@ -255,7 +231,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Override
public boolean stop(String app, String stream) {
- logger.info("[推流 ] 停止流: {}/{}", app, stream);
+ logger.info("[推流] 停止流: {}/{}", app, stream);
StreamPush streamPushItem = streamPushMapper.selectOne(app, stream);
if (streamPushItem != null) {
gbStreamService.sendCatalogMsg(streamPushItem, CatalogEvent.DEL);
@@ -595,6 +571,11 @@ public class StreamPushServiceImpl implements IStreamPushService {
return result;
}
+ @Override
+ public boolean update(StreamPush stream) {
+
+ }
+
@Override
public List getAllAppAndStream() {
@@ -635,4 +616,16 @@ public class StreamPushServiceImpl implements IStreamPushService {
gbStreamMapper.updateMediaServer(param.getApp(), param.getStream(), param.getMediaServerId());
}
}
+
+ @Override
+ public void updateStatus(StreamPush push) {
+
+ }
+
+ @Override
+ public void deleteByAppAndStream(String app, String stream) {
+
+ }
+
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
index 41f12419..34ba4b0e 100755
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
@@ -88,25 +88,6 @@ public class StreamPushController {
return pushList;
}
- @PostMapping(value = "/save_to_gb")
- @ResponseBody
- @Operation(summary = "将推流添加到国标", security = @SecurityRequirement(name = JwtUtils.HEADER))
- public void saveToGB(@RequestBody GbStream stream){
- if (!streamPushService.saveToGB(stream)){
- throw new ControllerException(ErrorCode.ERROR100);
- }
- }
-
-
- @DeleteMapping(value = "/remove_form_gb")
- @ResponseBody
- @Operation(summary = "将推流移出到国标", security = @SecurityRequirement(name = JwtUtils.HEADER))
- public void removeFormGB(@RequestBody GbStream stream){
- if (!streamPushService.removeFromGB(stream)){
- throw new ControllerException(ErrorCode.ERROR100);
- }
- }
-
@PostMapping(value = "/stop")
@ResponseBody
From 81049b5a9ec89eb8e3ec2eacd051bc68a162ced4 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Tue, 25 Jun 2024 17:46:33 +0800
Subject: [PATCH 11/12] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../iot/vmp/service/impl/StreamPushServiceImpl.java | 2 +-
.../redisMsg/RedisCloseStreamMsgListener.java | 13 +++++--------
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
index aa7296ed..2f159336 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -231,7 +231,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Override
public boolean stop(String app, String stream) {
- logger.info("[推流] 停止流: {}/{}", app, stream);
+ logger.info("[推流] 停止推流: {}/{}", app, stream);
StreamPush streamPushItem = streamPushMapper.selectOne(app, stream);
if (streamPushItem != null) {
gbStreamService.sendCatalogMsg(streamPushItem, CatalogEvent.DEL);
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java
index d0104756..38eb5344 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java
@@ -3,9 +3,8 @@ package com.genersoft.iot.vmp.service.redisMsg;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.service.IStreamPushService;
+import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.Message;
@@ -17,14 +16,13 @@ import java.util.concurrent.ConcurrentLinkedQueue;
/**
* 接收来自redis的关闭流更新通知
+ * 消息举例: PUBLISH VM_MSG_STREAM_PUSH_CLOSE "{'app': 'live', 'stream': 'stream'}"
* @author lin
*/
+@Slf4j
@Component
public class RedisCloseStreamMsgListener implements MessageListener {
- private final static Logger logger = LoggerFactory.getLogger(RedisCloseStreamMsgListener.class);
-
-
@Autowired
private IStreamPushService pushService;
@@ -47,10 +45,9 @@ public class RedisCloseStreamMsgListener implements MessageListener {
String app = jsonObject.getString("app");
String stream = jsonObject.getString("stream");
pushService.stop(app, stream);
-
}catch (Exception e) {
- logger.warn("[REDIS的关闭推流通知] 发现未处理的异常, \r\n{}", JSON.toJSONString(message));
- logger.error("[REDIS的关闭推流通知] 异常内容: ", e);
+ log.warn("[REDIS的关闭推流通知] 发现未处理的异常, \r\n{}", JSON.toJSONString(message));
+ log.error("[REDIS的关闭推流通知] 异常内容: ", e);
}
}
});
From f32eb14125f6f5c2a38a4ded11286f20d96caaef Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: Wed, 26 Jun 2024 18:36:32 +0800
Subject: [PATCH 12/12] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../iot/vmp/gb28181/bean/CommonGBChannel.java | 3 +
.../gb28181/service/IGbChannelService.java | 25 ++
.../service/impl/GbChannelServiceImpl.java | 10 +
.../MediaServerStatusEventListener.java | 6 -
.../iot/vmp/media/zlm/dto/StreamPush.java | 11 +
.../iot/vmp/service/IStreamPushService.java | 8 +-
.../service/impl/StreamPushServiceImpl.java | 380 ++++++++++--------
.../redisMsg/RedisCloseStreamMsgListener.java | 2 +-
.../vmp/storager/dao/StreamPushMapper.java | 2 +-
.../streamPush/StreamPushController.java | 3 +-
10 files changed, 269 insertions(+), 181 deletions(-)
create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java
create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java
index a9842123..816917d4 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CommonGBChannel.java
@@ -7,6 +7,9 @@ import lombok.Data;
@Schema(description = "国标通道")
public class CommonGBChannel {
+ @Schema(description = "国标-数据库自增ID")
+ private int gbId;
+
@Schema(description = "国标-编码")
private String gbDeviceId;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java
new file mode 100644
index 00000000..4858bc5a
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelService.java
@@ -0,0 +1,25 @@
+package com.genersoft.iot.vmp.gb28181.service;
+
+import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
+
+import java.util.List;
+
+public interface IGbChannelService {
+
+ CommonGBChannel queryByDeviceId(String gbDeviceId);
+
+ int add(CommonGBChannel commonGBChannel);
+
+ int delete(int gbId);
+
+ int update(CommonGBChannel commonGBChannel);
+
+ int offline(CommonGBChannel commonGBChannel);
+
+ int online(CommonGBChannel commonGBChannel);
+
+ void closeSend(CommonGBChannel commonGBChannel);
+
+ void batchAdd(List commonGBChannels);
+
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java
new file mode 100644
index 00000000..adf5251c
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java
@@ -0,0 +1,10 @@
+package com.genersoft.iot.vmp.gb28181.service.impl;
+
+import com.genersoft.iot.vmp.gb28181.service.IGbChannelService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class GbChannelServiceImpl implements IGbChannelService {
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java
index 2413f567..1e1fcca1 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java
@@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.media.event.mediaServer;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.IStreamProxyService;
-import com.genersoft.iot.vmp.service.IStreamPushService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -23,9 +22,6 @@ public class MediaServerStatusEventListener {
private final static Logger logger = LoggerFactory.getLogger(MediaServerStatusEventListener.class);
- @Autowired
- private IStreamPushService streamPushService;
-
@Autowired
private IStreamProxyService streamProxyService;
@@ -36,7 +32,6 @@ public class MediaServerStatusEventListener {
@EventListener
public void onApplicationEvent(MediaServerOnlineEvent event) {
logger.info("[媒体节点] 上线 ID:" + event.getMediaServerId());
- streamPushService.zlmServerOnline(event.getMediaServerId());
streamProxyService.zlmServerOnline(event.getMediaServerId());
playService.zlmServerOnline(event.getMediaServerId());
}
@@ -48,7 +43,6 @@ public class MediaServerStatusEventListener {
logger.info("[媒体节点] 离线,ID:" + event.getMediaServerId());
// 处理ZLM离线
streamProxyService.zlmServerOffline(event.getMediaServerId());
- streamPushService.zlmServerOffline(event.getMediaServerId());
playService.zlmServerOffline(event.getMediaServerId());
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPush.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPush.java
index 41d4af96..eeb444dc 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPush.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPush.java
@@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.jetbrains.annotations.NotNull;
+import org.springframework.util.ObjectUtils;
@Data
@@ -102,6 +103,16 @@ public class StreamPush extends CommonGBChannel implements Comparable getAllGBId();
void updateStatus(StreamPush push);
+
+ void deleteByAppAndStream(String app, String stream);
+
+ void updatePushStatus(Integer streamPushId, boolean pushIng);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
index 2f159336..31dfe4cc 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -5,19 +5,22 @@ import com.baomidou.dynamic.datasource.annotation.DS;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
+import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
+import com.genersoft.iot.vmp.gb28181.service.IGbChannelService;
import com.genersoft.iot.vmp.media.bean.MediaInfo;
+import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOfflineEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOnlineEvent;
import com.genersoft.iot.vmp.media.service.IMediaServerService;
-import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPush;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType;
import com.genersoft.iot.vmp.service.IStreamPushService;
import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
@@ -28,6 +31,7 @@ import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
+import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -36,18 +40,17 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import java.util.*;
import java.util.stream.Collectors;
@Service
+@Slf4j
@DS("master")
public class StreamPushServiceImpl implements IStreamPushService {
- private final static Logger logger = LoggerFactory.getLogger(StreamPushServiceImpl.class);
-
@Autowired
private StreamPushMapper streamPushMapper;
@@ -84,6 +87,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Autowired
private MediaConfig mediaConfig;
+ @Autowired
+ private IGbChannelService gbChannelService;
+
/**
* 流到来的处理
*/
@@ -107,17 +113,17 @@ public class StreamPushServiceImpl implements IStreamPushService {
streamAuthorityInfo.setOriginType(mediaInfo.getOriginType());
}
redisCatchStorage.updateStreamAuthorityInfo(event.getApp(), event.getStream(), streamAuthorityInfo);
- StreamPush transform = StreamPush.getInstance(event, userSetting.getServerId());
- transform.setPushIng(true);
- transform.setUpdateTime(DateUtil.getNow());
- transform.setPushTime(DateUtil.getNow());
- transform.setSelf(true);
- StreamPush pushInDb = getPush(event.getApp(), event.getStream());
- if (pushInDb == null) {
- transform.setCreateTime(DateUtil.getNow());
- add(transform);
+
+ StreamPush streamPushInDb = getPush(event.getApp(), event.getStream());
+ if (streamPushInDb == null) {
+ StreamPush streamPush = StreamPush.getInstance(event, userSetting.getServerId());
+ streamPush.setPushIng(true);
+ streamPush.setUpdateTime(DateUtil.getNow());
+ streamPush.setPushTime(DateUtil.getNow());
+ streamPush.setSelf(true);
+ add(streamPush);
}else {
- update(transform);
+ updatePushStatus(streamPushInDb.getId(), true);
}
// 冗余数据,自己系统中自用
if (!"broadcast".equals(event.getApp()) && !"talk".equals(event.getApp())) {
@@ -143,6 +149,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Async("taskExecutor")
@EventListener
public void onApplicationEvent(MediaDepartureEvent event) {
+
// 兼容流注销时类型从redis记录获取
MediaInfo mediaInfo = redisCatchStorage.getStreamInfo(
event.getApp(), event.getStream(), event.getMediaServer().getId());
@@ -178,37 +185,22 @@ public class StreamPushServiceImpl implements IStreamPushService {
}
}
-
- private List handleJSON(List streamInfoList) {
- if (streamInfoList == null || streamInfoList.isEmpty()) {
- return null;
- }
- Map result = new HashMap<>();
- for (StreamInfo streamInfo : streamInfoList) {
- // 不保存国标推理以及拉流代理的流
- if (streamInfo.getOriginType() == OriginType.RTSP_PUSH.ordinal()
- || streamInfo.getOriginType() == OriginType.RTMP_PUSH.ordinal()
- || streamInfo.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
- String key = streamInfo.getApp() + "_" + streamInfo.getStream();
- StreamPush streamPushItem = result.get(key);
- if (streamPushItem == null) {
- streamPushItem = streamPushItem.getInstance(streamInfo);
- result.put(key, streamPushItem);
- }
- }
- }
- return new ArrayList<>(result.values());
+ /**
+ * 流媒体节点上线
+ */
+ @Async("taskExecutor")
+ @EventListener
+ public void onApplicationEvent(MediaServerOnlineEvent event) {
+ zlmServerOnline(event.getMediaServerId());
}
- @Override
- public StreamPush transform(OnStreamChangedHookParam item) {
- StreamPush streamPushItem = new StreamPush();
- streamPushItem.setApp(item.getApp());
- streamPushItem.setMediaServerId(item.getMediaServerId());
- streamPushItem.setStream(item.getStream());
- streamPushItem.setCreateTime(DateUtil.getNow());
- streamPushItem.setServerId(item.getSeverId());
- return streamPushItem;
+ /**
+ * 流媒体节点离线
+ */
+ @Async("taskExecutor")
+ @EventListener
+ public void onApplicationEvent(MediaServerOfflineEvent event) {
+ zlmServerOffline(event.getMediaServerId());
}
@Override
@@ -225,29 +217,113 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Override
- public StreamPush getPush(String app, String streamId) {
- return streamPushMapper.selectOne(app, streamId);
+ public StreamPush getPush(String app, String stream) {
+ return streamPushMapper.selectByAppAndStream(app, stream);
}
@Override
- public boolean stop(String app, String stream) {
- logger.info("[推流] 停止推流: {}/{}", app, stream);
- StreamPush streamPushItem = streamPushMapper.selectOne(app, stream);
- if (streamPushItem != null) {
- gbStreamService.sendCatalogMsg(streamPushItem, CatalogEvent.DEL);
+ @Transactional
+ public boolean add(StreamPush stream) {
+ log.info("[添加推流] app: {}, stream: {}, 国标编号: {}", stream.getApp(), stream.getStream(), stream.getGbDeviceId());
+ stream.setUpdateTime(DateUtil.getNow());
+ stream.setCreateTime(DateUtil.getNow());
+ int addResult = streamPushMapper.add(stream);
+ if (addResult <= 0) {
+ return false;
}
+ if (ObjectUtils.isEmpty(stream.getGbDeviceId())) {
+ return true;
+ }
+ CommonGBChannel channel = gbChannelService.queryByDeviceId(stream.getGbDeviceId());
+ if (channel != null) {
+ log.info("[添加推流]失败,国标编号已存在: {} app: {}, stream: {}, ", stream.getGbDeviceId(), stream.getApp(), stream.getStream());
+ }
+ int addChannelResult = gbChannelService.add(stream.getCommonGBChannel());
+ return addChannelResult > 0;
+ }
- platformGbStreamMapper.delByAppAndStream(app, stream);
- gbStreamMapper.del(app, stream);
- int delStream = streamPushMapper.del(app, stream);
- if (delStream > 0) {
- MediaServer mediaServerItem = mediaServerService.getOne(streamPushItem.getMediaServerId());
- mediaServerService.closeStreams(mediaServerItem,app, stream);
+ @Override
+ @Transactional
+ public void deleteByAppAndStream(String app, String stream) {
+ log.info("[删除推流] app: {}, stream: {}, ", app, stream);
+ StreamPush streamPush = streamPushMapper.selectByAppAndStream(app, stream);
+ if (streamPush == null) {
+ log.info("[删除推流]失败, 不存在 app: {}, stream: {}, ", app, stream);
+ return;
+ }
+ if (streamPush.isPushIng()) {
+ stop(streamPush);
+ }
+ if (streamPush.getGbId() > 0) {
+ gbChannelService.delete(streamPush.getGbId());
+ }
+ }
+ @Override
+ @Transactional
+ public boolean update(StreamPush streamPush) {
+ log.info("[更新推流]:id: {}, app: {}, stream: {}, ", streamPush.getId(), streamPush.getApp(), streamPush.getStream());
+ assert streamPush.getId() != null;
+ streamPush.setUpdateTime(DateUtil.getNow());
+ streamPushMapper.update(streamPush);
+ if (streamPush.getGbId() > 0) {
+ gbChannelService.update(streamPush.getCommonGBChannel());
+ }
+ return true;
+ }
+
+
+ @Override
+ @Transactional
+ public boolean stop(StreamPush streamPush) {
+ log.info("[主动停止推流] id: {}, app: {}, stream: {}, ", streamPush.getId(), streamPush.getApp(), streamPush.getStream());
+ MediaServer mediaServer = null;
+ if (streamPush.getMediaServerId() == null) {
+ log.info("[主动停止推流]未找到使用MediaServer,开始自动检索 id: {}, app: {}, stream: {}, ", streamPush.getId(), streamPush.getApp(), streamPush.getStream());
+ mediaServer = mediaServerService.getMediaServerByAppAndStream(streamPush.getApp(), streamPush.getStream());
+ if (mediaServer != null) {
+ log.info("[主动停止推流] 检索到MediaServer为{}, id: {}, app: {}, stream: {}, ", mediaServer.getId(), streamPush.getId(), streamPush.getApp(), streamPush.getStream());
+ }else {
+ log.info("[主动停止推流]未找到使用MediaServer id: {}, app: {}, stream: {}, ", streamPush.getId(), streamPush.getApp(), streamPush.getStream());
+ }
+ }else {
+ mediaServer = mediaServerService.getOne(streamPush.getMediaServerId());
+ if (mediaServer == null) {
+ log.info("[主动停止推流]未找到使用的MediaServer: {},开始自动检索 id: {}, app: {}, stream: {}, ",streamPush.getMediaServerId(), streamPush.getId(), streamPush.getApp(), streamPush.getStream());
+ mediaServer = mediaServerService.getMediaServerByAppAndStream(streamPush.getApp(), streamPush.getStream());
+ if (mediaServer != null) {
+ log.info("[主动停止推流] 检索到MediaServer为{}, id: {}, app: {}, stream: {}, ", mediaServer.getId(), streamPush.getId(), streamPush.getApp(), streamPush.getStream());
+ }else {
+ log.info("[主动停止推流]未找到使用MediaServer id: {}, app: {}, stream: {}, ", streamPush.getId(), streamPush.getApp(), streamPush.getStream());
+ }
+ }
+ }
+ if (mediaServer != null) {
+ mediaServerService.closeStreams(mediaServer, streamPush.getApp(), streamPush.getStream());
+ }
+ streamPush.setPushIng(false);
+ if (userSetting.isUsePushingAsStatus()) {
+ streamPush.setGbStatus(false);
+ gbChannelService.offline(streamPush.getCommonGBChannel());
+ }
+ gbChannelService.closeSend(streamPush.getCommonGBChannel());
+ streamPush.setUpdateTime(DateUtil.getNow());
+ streamPushMapper.update(streamPush);
+ return true;
+ }
+
+ @Override
+ @Transactional
+ public boolean stopByAppAndStream(String app, String stream) {
+ log.info("[主动停止推流] : app: {}, stream: {}, ", app, stream);
+ StreamPush streamPushItem = streamPushMapper.selectByAppAndStream(app, stream);
+ if (streamPushItem != null) {
+ stop(streamPushItem);
}
return true;
}
@Override
+ @Transactional
public void zlmServerOnline(String mediaServerId) {
// 同步zlm推流信息
MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId);
@@ -260,14 +336,14 @@ public class StreamPushServiceImpl implements IStreamPushService {
// redis记录
List mediaInfoList = redisCatchStorage.getStreams(mediaServerId, "PUSH");
Map streamInfoPushItemMap = new HashMap<>();
- if (pushList.size() > 0) {
+ if (!pushList.isEmpty()) {
for (StreamPush streamPushItem : pushList) {
if (ObjectUtils.isEmpty(streamPushItem.getGbId())) {
pushItemMap.put(streamPushItem.getApp() + streamPushItem.getStream(), streamPushItem);
}
}
}
- if (mediaInfoList.size() > 0) {
+ if (!mediaInfoList.isEmpty()) {
for (MediaInfo mediaInfo : mediaInfoList) {
streamInfoPushItemMap.put(mediaInfo.getApp() + mediaInfo.getStream(), mediaInfo);
}
@@ -290,26 +366,33 @@ public class StreamPushServiceImpl implements IStreamPushService {
streamAuthorityInfoInfoMap.remove(streamPushItem.getApp() + streamPushItem.getStream());
}
}
- List offlinePushItems = new ArrayList<>(pushItemMap.values());
- if (offlinePushItems.size() > 0) {
- String type = "PUSH";
- int runLimit = 300;
- if (offlinePushItems.size() > runLimit) {
- for (int i = 0; i < offlinePushItems.size(); i += runLimit) {
- int toIndex = i + runLimit;
- if (i + runLimit > offlinePushItems.size()) {
- toIndex = offlinePushItems.size();
- }
- List streamPushItemsSub = offlinePushItems.subList(i, toIndex);
- streamPushMapper.delAll(streamPushItemsSub);
- }
- }else {
- streamPushMapper.delAll(offlinePushItems);
+ List changedStreamPushList = new ArrayList<>(pushItemMap.values());
+ if (!changedStreamPushList.isEmpty()) {
+ for (StreamPush streamPush : changedStreamPushList) {
+ stop(streamPush);
}
-
}
+
+
+// if (!changedStreamPushList.isEmpty()) {
+// String type = "PUSH";
+// int runLimit = 300;
+// if (changedStreamPushList.size() > runLimit) {
+// for (int i = 0; i < changedStreamPushList.size(); i += runLimit) {
+// int toIndex = i + runLimit;
+// if (i + runLimit > changedStreamPushList.size()) {
+// toIndex = changedStreamPushList.size();
+// }
+// List streamPushItemsSub = changedStreamPushList.subList(i, toIndex);
+// streamPushMapper.delAll(streamPushItemsSub);
+// }
+// }else {
+// streamPushMapper.delAll(changedStreamPushList);
+// }
+//
+// }
Collection mediaInfos = streamInfoPushItemMap.values();
- if (mediaInfos.size() > 0) {
+ if (!mediaInfos.isEmpty()) {
String type = "PUSH";
for (MediaInfo mediaInfo : mediaInfos) {
JSONObject jsonObject = new JSONObject();
@@ -327,7 +410,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
}
Collection streamAuthorityInfos = streamAuthorityInfoInfoMap.values();
- if (streamAuthorityInfos.size() > 0) {
+ if (!streamAuthorityInfos.isEmpty()) {
for (StreamAuthorityInfo streamAuthorityInfo : streamAuthorityInfos) {
// 移除redis内流的信息
redisCatchStorage.removeStreamAuthorityInfo(streamAuthorityInfo.getApp(), streamAuthorityInfo.getStream());
@@ -336,19 +419,24 @@ public class StreamPushServiceImpl implements IStreamPushService {
}
@Override
+ @Transactional
public void zlmServerOffline(String mediaServerId) {
- List streamPushItems = streamPushMapper.selectAllByMediaServerIdWithOutGbID(mediaServerId);
- // 移除没有GBId的推流
- streamPushMapper.deleteWithoutGBId(mediaServerId);
- gbStreamMapper.deleteWithoutGBId("push", mediaServerId);
- // 其他的流设置未启用
- streamPushMapper.updateStatusByMediaServerId(mediaServerId, false);
- streamProxyMapper.updateStatusByMediaServerId(mediaServerId, false);
+ List streamPushItems = streamPushMapper.selectAllByMediaServerId(mediaServerId);
+ if (!streamPushItems.isEmpty()) {
+ for (StreamPush streamPushItem : streamPushItems) {
+ stop(streamPushItem);
+ }
+ }
+// // 移除没有GBId的推流
+// streamPushMapper.deleteWithoutGBId(mediaServerId);
+// // 其他的流设置未启用
+// streamPushMapper.updateStatusByMediaServerId(mediaServerId, false);
+// streamProxyMapper.updateStatusByMediaServerId(mediaServerId, false);
// 发送流停止消息
String type = "PUSH";
// 发送redis消息
List mediaInfoList = redisCatchStorage.getStreams(mediaServerId, type);
- if (mediaInfoList.size() > 0) {
+ if (!mediaInfoList.isEmpty()) {
for (MediaInfo mediaInfo : mediaInfoList) {
// 移除redis内流的信息
redisCatchStorage.removeStream(mediaServerId, type, mediaInfo.getApp(), mediaInfo.getStream());
@@ -367,41 +455,16 @@ public class StreamPushServiceImpl implements IStreamPushService {
}
@Override
- public void clean() {
-
- }
-
- @Override
- public boolean saveToRandomGB() {
- List streamPushItems = streamPushMapper.selectAll();
- long gbId = 100001;
- for (StreamPush streamPushItem : streamPushItems) {
- streamPushItem.setStreamType("push");
- streamPushItem.setStatus(true);
- streamPushItem.setGbId("34020000004111" + gbId);
- streamPushItem.setCreateTime(DateUtil.getNow());
- gbId ++;
- }
- int limitCount = 30;
-
- if (streamPushItems.size() > limitCount) {
- for (int i = 0; i < streamPushItems.size(); i += limitCount) {
- int toIndex = i + limitCount;
- if (i + limitCount > streamPushItems.size()) {
- toIndex = streamPushItems.size();
- }
- gbStreamMapper.batchAdd(streamPushItems.subList(i, toIndex));
- }
- }else {
- gbStreamMapper.batchAdd(streamPushItems);
- }
- return true;
- }
-
- @Override
+ @Transactional
public void batchAdd(List streamPushItems) {
streamPushMapper.addAll(streamPushItems);
- gbStreamMapper.batchAdd(streamPushItems);
+ List commonGBChannels = new ArrayList<>();
+ for (StreamPush streamPush : streamPushItems) {
+ if (ObjectUtils.isEmpty(streamPush.getGbDeviceId())) {
+ commonGBChannels.add(streamPush.getCommonGBChannel());
+ }
+ }
+ gbChannelService.batchAdd(commonGBChannels);
}
@@ -459,7 +522,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
// 不存在这个平台,则忽略导入此关联关系
if (platformInfoMap.get(platFormInfoArray[0]) == null
|| platformInfoMap.get(platFormInfoArray[0]).get(platFormInfoArray[1]) == null) {
- logger.info("导入数据时不存在平台或目录{}/{},已导入未分配", platFormInfoArray[0], platFormInfoArray[1] );
+ log.info("导入数据时不存在平台或目录{}/{},已导入未分配", platFormInfoArray[0], platFormInfoArray[1] );
continue;
}
streamPushItemForPlatform.setPlatformId(platFormInfoArray[0]);
@@ -544,38 +607,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
eventPublisher.catalogEventPublishForStream(null, onlinePushers, CatalogEvent.ON);
}
- @Override
- public boolean add(StreamPush stream) {
- stream.setUpdateTime(DateUtil.getNow());
- stream.setCreateTime(DateUtil.getNow());
- stream.setServerId(userSetting.getServerId());
- stream.setMediaServerId(mediaConfig.getId());
- stream.setSelf(true);
- stream.setPushIng(true);
-
- // 放在事务内执行
- boolean result = false;
- TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
- try {
- int addStreamResult = streamPushMapper.add(stream);
- if (!ObjectUtils.isEmpty(stream.getGbId())) {
- stream.setStreamType("push");
- gbStreamMapper.add(stream);
- }
- dataSourceTransactionManager.commit(transactionStatus);
- result = true;
- }catch (Exception e) {
- logger.error("批量移除流与平台的关系时错误", e);
- dataSourceTransactionManager.rollback(transactionStatus);
- }
- return result;
- }
-
- @Override
- public boolean update(StreamPush stream) {
-
- }
-
@Override
public List getAllAppAndStream() {
@@ -600,32 +631,41 @@ public class StreamPushServiceImpl implements IStreamPushService {
return streamPushMapper.getAllGBId();
}
- @Override
- public void updatePush(OnStreamChangedHookParam param) {
- StreamPush transform = transform(param);
- StreamPush pushInDb = getPush(param.getApp(), param.getStream());
- transform.setPushIng(param.isRegist());
- transform.setUpdateTime(DateUtil.getNow());
- transform.setPushTime(DateUtil.getNow());
- transform.setSelf(userSetting.getServerId().equals(param.getSeverId()));
- if (pushInDb == null) {
- transform.setCreateTime(DateUtil.getNow());
- streamPushMapper.add(transform);
- }else {
- streamPushMapper.update(transform);
- gbStreamMapper.updateMediaServer(param.getApp(), param.getStream(), param.getMediaServerId());
- }
- }
-
@Override
public void updateStatus(StreamPush push) {
}
- @Override
- public void deleteByAppAndStream(String app, String stream) {
+
+ @Override
+ public void updatePushStatus(Integer streamPushId, boolean pushIng) {
+ streamPushInDb.setPushIng(true);
+ if (userSetting.isUsePushingAsStatus()) {
+ streamPushInDb.setGbStatus(true);
+ }
+ streamPushInDb.setPushTime(DateUtil.getNow());
}
+ private List handleJSON(List streamInfoList) {
+ if (streamInfoList == null || streamInfoList.isEmpty()) {
+ return null;
+ }
+ Map result = new HashMap<>();
+ for (StreamInfo streamInfo : streamInfoList) {
+ // 不保存国标推理以及拉流代理的流
+ if (streamInfo.getOriginType() == OriginType.RTSP_PUSH.ordinal()
+ || streamInfo.getOriginType() == OriginType.RTMP_PUSH.ordinal()
+ || streamInfo.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
+ String key = streamInfo.getApp() + "_" + streamInfo.getStream();
+ StreamPush streamPushItem = result.get(key);
+ if (streamPushItem == null) {
+ streamPushItem = streamPushItem.getInstance(streamInfo);
+ result.put(key, streamPushItem);
+ }
+ }
+ }
+ return new ArrayList<>(result.values());
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java
index 38eb5344..d9c35e27 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisCloseStreamMsgListener.java
@@ -44,7 +44,7 @@ public class RedisCloseStreamMsgListener implements MessageListener {
JSONObject jsonObject = JSON.parseObject(msg.getBody());
String app = jsonObject.getString("app");
String stream = jsonObject.getString("stream");
- pushService.stop(app, stream);
+ pushService.stopByAppAndStream(app, stream);
}catch (Exception e) {
log.warn("[REDIS的关闭推流通知] 发现未处理的异常, \r\n{}", JSON.toJSONString(message));
log.error("[REDIS的关闭推流通知] 异常内容: ", e);
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
index 6c6f93d0..10372851 100755
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
@@ -87,7 +87,7 @@ public interface StreamPushMapper {
List selectAll();
@Select("SELECT st.*, gs.gb_id, gs.name, gs.longitude, gs.latitude FROM wvp_stream_push st LEFT join wvp_gb_stream gs on st.app = gs.app AND st.stream = gs.stream WHERE st.app=#{app} AND st.stream=#{stream}")
- StreamPush selectOne(@Param("app") String app, @Param("stream") String stream);
+ StreamPush selectByAppAndStream(@Param("app") String app, @Param("stream") String stream);
@Insert("