README.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
doc/README.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
doc/_media/1372762149.jpg | 补丁 | 查看 | 原始文档 | blame | 历史 | |
doc/_media/903207146.jpg | 补丁 | 查看 | 原始文档 | blame | 历史 | |
pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
README.md
@@ -27,7 +27,7 @@ ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) > wvp文档由gitee提供服务,如果遇到打不开请多刷新几次。 # 社群地址 # 付费社群 [](https://t.zsxq.com/0d8VAD3Dm) > 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 @@ -105,6 +105,7 @@ - [X] 支持打包可执行jar和war - [X] 支持跨域请求,支持前后端分离部署 - [X] 支持Mysql,Postgresql,金仓等数据库 - [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取) # 授权协议 本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议 doc/README.md
@@ -14,7 +14,7 @@ - 完全开源,且使用MIT许可协议。保留版权的情况下可以用于商业项目。 - 支持多流媒体节点负载均衡。 # 社群 # 付费社群 [](https://t.zsxq.com/0d8VAD3Dm) > 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 @@ -62,16 +62,16 @@ - [X] 注册 - [X] 注销 - [X] 实时视音频点播 - [ ] 设备控制 - [ ] 云台控制 - [X] 设备控制 - [X] 云台控制 - [ ] 远程启动 - [ ] 录像控制 - [ ] 报警布防/撤防 - [ ] 报警复位 - [ ] 强制关键帧 - [ ] 拉框放大 - [ ] 拉框缩小 - [ ] 看守位控制 - [X] 录像控制 - [X] 报警布防/撤防 - [X] 报警复位 - [X] 强制关键帧 - [X] 拉框放大 - [X] 拉框缩小 - [X] 看守位控制 - [ ] 设备配置 - [ ] 报警事件通知和分发 - [X] 设备目录订阅 @@ -79,7 +79,7 @@ - [X] 设备目录查询 - [X] 设备状态查询 - [ ] 设备配置查询 - [ ] 设备预置位查询 - [X] 设备预置位查询 - [X] 状态信息报送 - [X] 设备视音频文件检索 - [X] 历史视音频的回放 @@ -87,7 +87,7 @@ - [x] 暂停 - [x] 进/退 - [x] 停止 - [ ] 视音频文件下载 - [X] 视音频文件下载 - [ ] ~~校时~~ - [X] 订阅和通知 - [X] 事件订阅 doc/_media/1372762149.jpg
doc/_media/903207146.jpg
pom.xml
@@ -11,7 +11,7 @@ <groupId>com.genersoft</groupId> <artifactId>wvp-pro</artifactId> <version>2.6.8</version> <version>2.6.9</version> <name>web video platform</name> <description>国标28181视频平台</description> <packaging>${project.packaging}</packaging> src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java
@@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.gb28181.session; import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.UserSetting; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; @@ -31,10 +32,13 @@ @Autowired private SipConfig sipConfig; @Autowired private UserSetting userSetting; public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) { String ssrcPrefix = sipConfig.getDomain().substring(3, 8); String redisKey = SSRC_INFO_KEY + mediaServerId; String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; List<String> ssrcList = new ArrayList<>(); for (int i = 1; i < MAX_STREAM_COUNT; i++) { String ssrc = String.format("%s%04d", ssrcPrefix, i); @@ -77,7 +81,7 @@ return; } String sn = ssrc.substring(1); String redisKey = SSRC_INFO_KEY + mediaServerId; String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; redisTemplate.opsForSet().add(redisKey, sn); } @@ -86,7 +90,7 @@ */ private String getSN(String mediaServerId) { String sn = null; String redisKey = SSRC_INFO_KEY + mediaServerId; String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; Long size = redisTemplate.opsForSet().size(redisKey); if (size == null || size == 0) { throw new RuntimeException("ssrc已经用完"); @@ -113,7 +117,7 @@ * @param mediaServerId 流媒体服务ID */ public boolean hasMediaServerSSRC(String mediaServerId) { String redisKey = SSRC_INFO_KEY + mediaServerId; String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; return redisTemplate.opsForSet().members(redisKey) != null; } @@ -126,7 +130,7 @@ */ public boolean checkSsrc(String mediaServerId, String ssrc) { String sn = ssrc.substring(1); String redisKey = SSRC_INFO_KEY + mediaServerId; String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; return redisTemplate.opsForSet().isMember(redisKey, sn) != null; } } src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -188,7 +188,20 @@ null); return; } logger.info("[点播开始] deviceId: {}, channelId: {},收流端口:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck()); logger.info("\r\n" + " [点播开始] \r\n" + "deviceId : {}, \r\n" + "channelId : {},\r\n" + "收流端口 : {}, \r\n" + "收流模式 : {}, \r\n" + "SSRC : {}, \r\n" + "SSRC校验 :{}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck()); //端口获取失败的ssrcInfo 没有必要发送点播指令 if (ssrcInfo.getPort() <= 0) { @@ -329,23 +342,13 @@ return; } logger.info("[点播消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse); if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) { logger.info("[点播消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); if (!ssrcFactory.checkSsrc(mediaServerItem.getId(),ssrcInResponse)) { // ssrc 不可用 logger.info("[点播消息] SSRC修正时发现ssrc不可使用 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); // 释放ssrc ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); callback.run(InviteErrorCode.ERROR_FOR_SSRC_UNAVAILABLE.getCode(), InviteErrorCode.ERROR_FOR_SSRC_UNAVAILABLE.getMsg(), null); inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, InviteErrorCode.ERROR_FOR_SSRC_UNAVAILABLE.getCode(), InviteErrorCode.ERROR_FOR_SSRC_UNAVAILABLE.getMsg(), null); // 释放ssrc mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); return; } // 单端口模式streamId也有变化,重新设置监听即可 if (!mediaServerItem.isRtpEnable()) { // 添加订阅 @@ -388,8 +391,6 @@ } dynamicTask.stop(timeOutTaskKey); // 释放ssrc mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); @@ -654,17 +655,8 @@ if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) { logger.info("[录像回放] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); if (!ssrcFactory.checkSsrc(mediaServerItem.getId(),ssrcInResponse)) { // ssrc 不可用 logger.info("[录像回放] SSRC修正时发现ssrc不可使用 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); // 释放ssrc dynamicTask.stop(playBackTimeOutTaskKey); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); callback.run(InviteErrorCode.ERROR_FOR_SSRC_UNAVAILABLE.getCode(), InviteErrorCode.ERROR_FOR_SSRC_UNAVAILABLE.getMsg(), null); return; } // 释放ssrc mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); // 单端口模式streamId也有变化,需要重新设置监听 if (!mediaServerItem.isRtpEnable()) { @@ -693,8 +685,6 @@ } dynamicTask.stop(playBackTimeOutTaskKey); // 释放ssrc mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); @@ -858,15 +848,8 @@ if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) { logger.info("[录像下载] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); if (!ssrcFactory.checkSsrc(mediaServerItem.getId(),ssrcInResponse)) { // ssrc 不可用 // 释放ssrc mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); callback.run(InviteErrorCode.ERROR_FOR_SSRC_UNAVAILABLE.getCode(), InviteErrorCode.ERROR_FOR_SSRC_UNAVAILABLE.getMsg(), null); return; } // 释放ssrc mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); // 单端口模式streamId也有变化,需要重新设置监听 if (!mediaServerItem.isRtpEnable()) { @@ -892,8 +875,6 @@ } dynamicTask.stop(downLoadTimeOutTaskKey); // 释放ssrc mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());