From 676a722241116fd53e9f6063484a966dcabe5b48 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 16 Aug 2023 01:56:34 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=EF=BC=8C=E6=94=AF=E6=8C=81=E9=80=9A=E9=81=93?= =?UTF-8?q?=E5=88=97=E8=A1=A8=EF=BC=8C=E6=8E=A8=E6=B5=81=E5=88=97=E8=A1=A8?= =?UTF-8?q?=EF=BC=8C=E6=8B=89=E6=B5=81=E4=BB=A3=E7=90=86=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E6=9F=A5=E7=9C=8B=E5=AF=B9=E5=BA=94=E7=9A=84?= =?UTF-8?q?=E4=BA=91=E7=AB=AF=E5=BD=95=E5=83=8F=EF=BC=8C=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E5=A4=A7=E4=BA=8EINT=E7=9A=84ssrc=E7=9A=84=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/vmanager/bean/PageInfo.java | 99 ++++++++++++ .../iot/vmp/vmanager/bean/RecordFile.java | 53 +++++++ .../cloudRecord/CloudRecordController.java | 145 ++++++++++++++++++ 3 files changed, 297 insertions(+) create mode 100755 src/main/java/com/genersoft/iot/vmp/vmanager/bean/PageInfo.java create mode 100755 src/main/java/com/genersoft/iot/vmp/vmanager/bean/RecordFile.java create mode 100755 src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/PageInfo.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/PageInfo.java new file mode 100755 index 000000000..8894191ab --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/PageInfo.java @@ -0,0 +1,99 @@ +package com.genersoft.iot.vmp.vmanager.bean; + +import java.util.ArrayList; +import java.util.List; + +public class PageInfo { + //当前页 + private int pageNum; + //每页的数量 + private int pageSize; + //当前页的数量 + private int size; + //总页数 + private int pages; + //总数 + private int total; + + private List resultData; + + private List list; + + public PageInfo(List resultData) { + this.resultData = resultData; + } + + public PageInfo() { + } + + public void startPage(int page, int count) { + if (count <= 0) count = 10; + if (page <= 0) page = 1; + this.pageNum = page; + this.pageSize = count; + this.total = resultData.size(); + + this.pages = total % count == 0 ? total / count : total / count + 1; + int fromIndx = (page - 1) * count; + if (fromIndx > this.total - 1) { + this.list = new ArrayList<>(); + this.size = 0; + return; + } + + int toIndx = page * count; + if (toIndx > this.total) { + toIndx = this.total; + } + this.list = this.resultData.subList(fromIndx, toIndx); + this.size = this.list.size(); + } + + public int getPageNum() { + return pageNum; + } + + public void setPageNum(int pageNum) { + this.pageNum = pageNum; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public int getPages() { + return pages; + } + + public void setPages(int pages) { + this.pages = pages; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/RecordFile.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/RecordFile.java new file mode 100755 index 000000000..72d6561f2 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/RecordFile.java @@ -0,0 +1,53 @@ +package com.genersoft.iot.vmp.vmanager.bean; + +public class RecordFile { + private String app; + private String stream; + + private String fileName; + + private String mediaServerId; + + private String date; + + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java new file mode 100755 index 000000000..0f37a7dea --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -0,0 +1,145 @@ +package com.genersoft.iot.vmp.vmanager.cloudRecord; + +import com.genersoft.iot.vmp.conf.DynamicTask; +import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.conf.exception.ControllerException; +import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; +import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.PageInfo; +import com.genersoft.iot.vmp.vmanager.bean.RecordFile; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.commons.lang3.ObjectUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +@SuppressWarnings("rawtypes") +@Tag(name = "云端录像接口") + +@RestController +@RequestMapping("/api/cloud/record") +public class CloudRecordController { + + @Autowired + private ZLMServerFactory zlmServerFactory; + + @Autowired + private SendRtpPortManager sendRtpPortManager; + + private final static Logger logger = LoggerFactory.getLogger(CloudRecordController.class); + + @Autowired + private ZlmHttpHookSubscribe hookSubscribe; + + @Autowired + private IMediaServerService mediaServerService; + + @Autowired + private UserSetting userSetting; + + @Autowired + private DynamicTask dynamicTask; + + @Autowired + private RedisTemplate redisTemplate; + + @ResponseBody + @GetMapping("/date/list") + @Operation(summary = "查询存在云端录像的日期") + @Parameter(name = "app", description = "应用名", required = true) + @Parameter(name = "stream", description = "流ID", required = true) + @Parameter(name = "year", description = "年,置空则查询当年", required = false) + @Parameter(name = "month", description = "月,置空则查询当月", required = false) + @Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部", required = false) + public List openRtpServer( + @RequestParam String app, + @RequestParam String stream, + @RequestParam(required = false) int year, + @RequestParam(required = false) int month, + @RequestParam(required = false) String mediaServerId + + ) { + logger.info("[云端录像] 查询存在云端录像的日期 app->{}, stream->{}, mediaServerId->{}, year->{}, month->{}", + app, stream, mediaServerId, year, month); + Calendar calendar = Calendar.getInstance(); + if (ObjectUtils.isEmpty(year)) { + year = calendar.get(Calendar.YEAR); + } + if (ObjectUtils.isEmpty(month)) { + month = calendar.get(Calendar.MONTH) + 1; + } + List mediaServerItems; + if (!ObjectUtils.isEmpty(mediaServerId)) { + mediaServerItems = new ArrayList<>(); + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + if (mediaServerItem == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId); + } + mediaServerItems.add(mediaServerItem); + } else { + mediaServerItems = mediaServerService.getAll(); + } + if (mediaServerItems.isEmpty()) { + return new ArrayList<>(); + } + + return mediaServerService.getRecordDates(app, stream, year, month, mediaServerItems); + } + + @ResponseBody + @GetMapping("/list") + @Operation(summary = "分页查询云端录像") + @Parameter(name = "app", description = "应用名", required = true) + @Parameter(name = "stream", description = "流ID", required = true) + @Parameter(name = "page", description = "当前页", required = false) + @Parameter(name = "count", description = "每页查询数量", required = false) + @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = true) + @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = true) + @Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部流媒体", required = false) + public PageInfo openRtpServer( + @RequestParam String app, + @RequestParam String stream, + @RequestParam int page, + @RequestParam int count, + @RequestParam String startTime, + @RequestParam String endTime, + @RequestParam(required = false) String mediaServerId + + ) { + logger.info("[云端录像] 查询 app->{}, stream->{}, mediaServerId->{}, page->{}, count->{}, startTime->{}, endTime->{}", + app, stream, mediaServerId, page, count, startTime, endTime); + + List mediaServerItems; + if (!ObjectUtils.isEmpty(mediaServerId)) { + mediaServerItems = new ArrayList<>(); + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + if (mediaServerItem == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId); + } + mediaServerItems.add(mediaServerItem); + } else { + mediaServerItems = mediaServerService.getAll(); + } + if (mediaServerItems.isEmpty()) { + return new PageInfo<>(); + } + List records = mediaServerService.getRecords(app, stream, startTime, endTime, mediaServerItems); + PageInfo pageInfo = new PageInfo<>(records); + pageInfo.startPage(page, count); + return pageInfo; + } + + +} From 985082d33930868c3cc1723f28fd9aaae9013a8f Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Wed, 16 Aug 2023 09:11:22 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BC=BA=E5=B0=91?= =?UTF-8?q?=E7=9A=84=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/zlm/AssistRESTfulUtils.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java index 863ff32cb..cf71bf1d7 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java @@ -21,6 +21,7 @@ public class AssistRESTfulUtils { private final static Logger logger = LoggerFactory.getLogger(AssistRESTfulUtils.class); + public interface RequestCallback{ void run(JSONObject response); } @@ -145,4 +146,25 @@ public class AssistRESTfulUtils { return sendGet(mediaServerItem, "api/record/addStreamCallInfo",param, callback); } + public JSONObject getDateList(MediaServerItem mediaServerItem, String app, String stream, int year, int month) { + Map param = new HashMap<>(); + param.put("app", app); + param.put("stream", stream); + param.put("year", year); + param.put("month", month); + return sendGet(mediaServerItem, "api/record/date/list", param, null); + } + + public JSONObject getFileList(MediaServerItem mediaServerItem, int page, int count, String app, String stream, + String startTime, String endTime) { + Map param = new HashMap<>(); + param.put("app", app); + param.put("stream", stream); + param.put("page", page); + param.put("count", count); + param.put("startTime", startTime); + param.put("endTime", endTime); + return sendGet(mediaServerItem, "api/record/file/listWithDate", param, null); + } + } From b63a89a0a83dfddab0d714bb9aad90114ab9d514 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 18 Aug 2023 14:06:39 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=91=E6=B5=81?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/genersoft/iot/vmp/vmanager/ps/PsController.java | 2 -- .../java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java index 045480ac5..bed8f9ce8 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java @@ -221,8 +221,6 @@ public class PsController { String is_Udp = isUdp ? "1" : "0"; param.put("is_udp", is_Udp); param.put("src_port", sendInfo.getSendLocalPort()); - param.put("use_ps", "0"); - param.put("only_audio", "1"); Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, app, stream); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index ba4473f85..3b4fa3bfc 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -246,7 +246,6 @@ public class RtpController { String is_Udp = isUdp ? "1" : "0"; paramForAudio.put("is_udp", is_Udp); paramForAudio.put("src_port", sendInfo.getSendLocalPortForAudio()); - paramForAudio.put("use_ps", "0"); paramForAudio.put("only_audio", "1"); if (ptForAudio != null) { paramForAudio.put("pt", ptForAudio); @@ -267,7 +266,6 @@ public class RtpController { String is_Udp = isUdp ? "1" : "0"; paramForVideo.put("is_udp", is_Udp); paramForVideo.put("src_port", sendInfo.getSendLocalPortForVideo()); - paramForVideo.put("use_ps", "0"); paramForVideo.put("only_audio", "0"); if (ptForVideo != null) { paramForVideo.put("pt", ptForVideo); From b5ccb1636fc0efb0ea9d87c38995fee14cfd45d3 Mon Sep 17 00:00:00 2001 From: AlphaWu Date: Sun, 20 Aug 2023 15:50:24 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E4=BF=AE=E6=AD=A3Database=E6=8B=BC?= =?UTF-8?q?=E5=86=99=E9=94=99=E8=AF=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/_content/introduction/config.md | 2 +- .../com/genersoft/iot/vmp/conf/ApiAccessFilter.java | 2 +- .../java/com/genersoft/iot/vmp/conf/UserSetting.java | 10 +++++----- .../genersoft/iot/vmp/vmanager/log/LogController.java | 2 +- src/main/resources/all-application.yml | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/_content/introduction/config.md b/doc/_content/introduction/config.md index ad88140e9..29f00a4b8 100644 --- a/doc/_content/introduction/config.md +++ b/doc/_content/introduction/config.md @@ -153,7 +153,7 @@ user-settings: # 国标是否录制 record-sip: true # 是否将日志存储进数据库 - logInDatebase: true + logInDatabase: true # 第三方匹配,用于从stream钟获取有效信息 thirdPartyGBIdReg: [\s\S]* ``` diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java index 4d885e86c..b449b1b7e 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java @@ -51,7 +51,7 @@ public class ApiAccessFilter extends OncePerRequestFilter { filterChain.doFilter(servletRequest, servletResponse); - if (uriName != null && userSetting != null && userSetting.getLogInDatebase() != null && userSetting.getLogInDatebase()) { + if (uriName != null && userSetting != null && userSetting.getLogInDatabase() != null && userSetting.getLogInDatabase()) { LogDto logDto = new LogDto(); logDto.setName(uriName); 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 540072903..aaeff0a2a 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java @@ -31,7 +31,7 @@ public class UserSetting { private Boolean recordSip = Boolean.TRUE; - private Boolean logInDatebase = Boolean.TRUE; + private Boolean logInDatabase = Boolean.TRUE; private Boolean usePushingAsStatus = Boolean.TRUE; @@ -132,12 +132,12 @@ public class UserSetting { this.interfaceAuthenticationExcludes = interfaceAuthenticationExcludes; } - public Boolean getLogInDatebase() { - return logInDatebase; + public Boolean getLogInDatabase() { + return logInDatabase; } - public void setLogInDatebase(Boolean logInDatebase) { - this.logInDatebase = logInDatebase; + public void setLogInDatabase(Boolean logInDatabase) { + this.logInDatabase = logInDatabase; } public String getServerId() { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java index 3aabd9248..937bc08bf 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java @@ -61,7 +61,7 @@ public class LogController { query = null; } - if (!userSetting.getLogInDatebase()) { + if (!userSetting.getLogInDatabase()) { logger.warn("自动记录日志功能已关闭,查询结果可能不完整。"); } diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index 695bc748f..595f629cc 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -178,7 +178,7 @@ user-settings: # 国标是否录制 record-sip: true # 是否将日志存储进数据库 - logInDatebase: true + logInDatabase: true # 使用推流状态作为推流通道状态 use-pushing-as-status: true # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 From 49a8a08c94cbde6c255037892484f4405b92a878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E4=BF=8A=E6=9D=B0?= <502612493@qq.com> Date: Thu, 24 Aug 2023 17:12:39 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E6=8D=95=E8=8E=B7=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E4=B8=AD=E5=8F=91=E9=80=81sip=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=AF=BC=E8=87=B4=E7=9A=84=E5=90=AF=E5=8A=A8=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/conf/SipPlatformRunner.java | 17 ++++++++++++++--- .../iot/vmp/gb28181/task/SipRunner.java | 14 +++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java index eb1b157a3..b58b91c55 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java @@ -4,13 +4,19 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.service.IPlatformService; +import com.genersoft.iot.vmp.service.impl.PlatformServiceImpl; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import java.text.ParseException; import java.util.List; /** @@ -33,6 +39,7 @@ public class SipPlatformRunner implements CommandLineRunner { @Autowired private ISIPCommanderForPlatform sipCommanderForPlatform; + private final static Logger logger = LoggerFactory.getLogger(PlatformServiceImpl.class); @Override public void run(String... args) throws Exception { @@ -50,9 +57,13 @@ public class SipPlatformRunner implements CommandLineRunner { redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); if (parentPlatformCatchOld != null) { // 取消订阅 - sipCommanderForPlatform.unregister(parentPlatform, parentPlatformCatchOld.getSipTransactionInfo(), null, (eventResult)->{ - platformService.login(parentPlatform); - }); + try { + sipCommanderForPlatform.unregister(parentPlatform, parentPlatformCatchOld.getSipTransactionInfo(), null, (eventResult)->{ + platformService.login(parentPlatform); + }); + } catch (InvalidArgumentException | ParseException | SipException e) { + logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage()); + } } // 设置所有平台离线 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java index 17c23a00d..73cb9eaa2 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java @@ -12,13 +12,19 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IPlatformService; +import com.genersoft.iot.vmp.service.impl.PlatformServiceImpl; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import java.text.ParseException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -59,6 +65,8 @@ public class SipRunner implements CommandLineRunner { @Autowired private ISIPCommanderForPlatform commanderForPlatform; + private final static Logger logger = LoggerFactory.getLogger(PlatformServiceImpl.class); + @Override public void run(String... args) throws Exception { List deviceList = deviceService.getAllOnlineDevice(); @@ -110,7 +118,11 @@ public class SipRunner implements CommandLineRunner { if (jsonObject != null && jsonObject.getInteger("code") == 0) { ParentPlatform platform = platformService.queryPlatformByServerGBId(sendRtpItem.getPlatformId()); if (platform != null) { - commanderForPlatform.streamByeCmd(platform, sendRtpItem.getCallId()); + try { + commanderForPlatform.streamByeCmd(platform, sendRtpItem.getCallId()); + } catch (InvalidArgumentException | ParseException | SipException e) { + logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); + } } } } From 23ce55260fdb9277cd72987c1e6a3d4e058f3bb4 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 25 Aug 2023 08:51:06 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BA=A7=E8=81=94?= =?UTF-8?q?=E7=82=B9=E6=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/impl/InviteRequestProcessor.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 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 073720aa8..89381d90f 100644 --- 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 @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.*; @@ -454,21 +455,17 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements }); } else { sendRtpItem.setPlayType(InviteStreamType.PLAY); - SsrcTransaction playTransaction = sessionManager.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); - if (playTransaction != null) { - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, "rtp", playTransaction.getStream()); +// SsrcTransaction playTransaction = sessionManager.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); + if (streamInfo != null) { + Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, streamInfo.getApp(), streamInfo.getStream()); if (!streamReady) { - boolean hasRtpServer = mediaServerService.checkRtpServer(mediaServerItem, "rtp", playTransaction.getStream()); - if (hasRtpServer) { - logger.info("[上级点播]已经开启rtpServer但是尚未收到流,开启监听流的到来"); - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", playTransaction.getStream(), true, "rtsp", mediaServerItem.getId()); - zlmHttpHookSubscribe.addSubscribe(hookSubscribe, hookEvent); - }else { - playTransaction = null; - } + redisCatchStorage.stopPlay(streamInfo); + storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); + streamInfo = null; } } - if (playTransaction == null) { + if (streamInfo == null) { String streamId = null; if (mediaServerItem.isRtpEnable()) { streamId = String.format("%s_%s", device.getDeviceId(), channelId); @@ -488,7 +485,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements } else { // 当前系统作为下级平台使用,当上级平台点播时不携带ssrc时,并且设备在当前系统中已经点播了。这个时候需要重新给生成一个ssrc,不使用默认的"0000000000"。 sendRtpItem.setSsrc(ssrc); - sendRtpItem.setStreamId(playTransaction.getStream()); + sendRtpItem.setStreamId(streamInfo.getStream()); // 写入redis, 超时时回复 redisCatchStorage.updateSendRTPSever(sendRtpItem); JSONObject jsonObject = new JSONObject(); From 760b14eaaaf86884960a355e77f1586119f0afa9 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 25 Aug 2023 09:14:38 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E7=BA=A7=E8=81=94?= =?UTF-8?q?=E7=82=B9=E6=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/impl/InviteRequestProcessor.java | 90 ++++++++++--------- 1 file changed, 49 insertions(+), 41 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 57217964a..a4f3b5e7e 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 @@ -18,10 +18,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.service.IMediaServerService; -import com.genersoft.iot.vmp.service.IPlayService; -import com.genersoft.iot.vmp.service.IStreamProxyService; -import com.genersoft.iot.vmp.service.IStreamPushService; +import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; @@ -79,6 +76,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @Autowired private IRedisCatchStorage redisCatchStorage; + @Autowired + private IInviteStreamService inviteStreamService; + @Autowired private SSRCFactory ssrcFactory; @@ -479,47 +479,55 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements errorEvent.run(code, msg, data); } }); - } else { - sendRtpItem.setPlayType(InviteStreamType.PLAY); - sendRtpItem.setPlayType(InviteStreamType.PLAY); -// SsrcTransaction playTransaction = sessionManager.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); - if (streamInfo != null) { - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, streamInfo.getApp(), streamInfo.getStream()); - if (!streamReady) { - redisCatchStorage.stopPlay(streamInfo); - storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); - streamInfo = null; - } + } else if ("Download".equalsIgnoreCase(sessionName)) { + // 获取指定的下载速度 + Vector sdpMediaDescriptions = sdp.getMediaDescriptions(true); + MediaDescription mediaDescription = null; + String downloadSpeed = "1"; + if (sdpMediaDescriptions.size() > 0) { + mediaDescription = (MediaDescription) sdpMediaDescriptions.get(0); + } + if (mediaDescription != null) { + downloadSpeed = mediaDescription.getAttribute("downloadspeed"); } - if (streamInfo == null) { - String streamId = null; - if (mediaServerItem.isRtpEnable()) { - streamId = String.format("%s_%s", device.getDeviceId(), channelId); - } - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam()); - logger.info(JSONObject.toJSONString(ssrcInfo)); - sendRtpItem.setStreamId(ssrcInfo.getStream()); - sendRtpItem.setSsrc(ssrc); - // 写入redis, 超时时回复 - redisCatchStorage.updateSendRTPSever(sendRtpItem); - MediaServerItem finalMediaServerItem = mediaServerItem; - playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> { + sendRtpItem.setPlayType(InviteStreamType.DOWNLOAD); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam()); + sendRtpItem.setStreamId(ssrcInfo.getStream()); + // 写入redis, 超时时回复 + redisCatchStorage.updateSendRTPSever(sendRtpItem); + playService.download(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start), + DateUtil.formatter.format(end), Integer.parseInt(downloadSpeed), + (code, msg, data) -> { + if (code == InviteErrorCode.SUCCESS.getCode()) { + hookEvent.run(code, msg, data); + } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) { + logger.info("[录像下载]超时, 用户:{}, 通道:{}", username, channelId); + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); + errorEvent.run(code, msg, data); + } else { + errorEvent.run(code, msg, data); + } + }); + } else { + + SSRCInfo ssrcInfo = playService.play(mediaServerItem, device.getDeviceId(), channelId, ssrc, ((code, msg, data) -> { + if (code == InviteErrorCode.SUCCESS.getCode()) { + hookEvent.run(code, msg, data); + } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) { logger.info("[上级点播]超时, 用户:{}, 通道:{}", username, channelId); redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); - }); - } else { - // 当前系统作为下级平台使用,当上级平台点播时不携带ssrc时,并且设备在当前系统中已经点播了。这个时候需要重新给生成一个ssrc,不使用默认的"0000000000"。 - sendRtpItem.setSsrc(ssrc); - sendRtpItem.setStreamId(playTransaction.getStream()); - // 写入redis, 超时时回复 - redisCatchStorage.updateSendRTPSever(sendRtpItem); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("app", sendRtpItem.getApp()); - jsonObject.put("stream", sendRtpItem.getStreamId()); - hookEvent.response(mediaServerItem, jsonObject); - } + errorEvent.run(code, msg, data); + } else { + errorEvent.run(code, msg, data); + } + })); + sendRtpItem.setPlayType(InviteStreamType.PLAY); + String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + sendRtpItem.setStreamId(streamId); + sendRtpItem.setSsrc(ssrcInfo.getSsrc()); + redisCatchStorage.updateSendRTPSever(sendRtpItem); + } } else if (gbStream != null) { From d739017678ec63398a863bf58e06c05d230aa0a4 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Thu, 31 Aug 2023 16:41:44 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E9=80=82=E9=85=8Dassist=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web_src/src/components/CloudRecordDetail.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/web_src/src/components/CloudRecordDetail.vue b/web_src/src/components/CloudRecordDetail.vue index 1e1599096..4dbd06e0e 100755 --- a/web_src/src/components/CloudRecordDetail.vue +++ b/web_src/src/components/CloudRecordDetail.vue @@ -39,11 +39,11 @@
  • - {{ item.fileName.substring(0, 17) }} + {{ getFileShowName(item.fileName) }} - {{ item.fileName.substring(0, 17) }} + {{ getFileShowName(item.fileName) }}