diff --git a/README.md b/README.md index 97ad0f16..69f77eb7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # wvp WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的网络视频平台,负责实现核心信令与设备管理后台部分,支持NAT穿透,支持海康、大华、宇视等品牌的IPC、NVR、DVR接入。 -流媒体服务基于ZLMediaKit-https://github.com/xiongziliang/ZLMediaKit +流媒体服务基于ZLMediaKit-https://github.com/xiongziliang/ZLMediaKit 前段页面基于MediaServerUI进行修改. # 应用场景: @@ -16,24 +16,25 @@ WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的网络视频平台 ![build_1.png](https://github.com/648540858/wiki/blob/master/images/Screenshot_20201012_151606.png) # 原版特性: -1. 视频预览 -2. 云台控制(方向、缩放控制) -3. 视频设备信息同步 -4. 离在线监控 -5. 录像查询与回放(基于NVR\DVR,暂不支持快进、seek操作) -6. 无人观看自动断流 - - -# 新支持特性 -1. 集成web界面, 不需要单独部署前端服务, 直接利用wvp内置文件服务部署. -2. 支持平台接入, 针对大平台大量设备的情况进行优化. -3. 支持检索,通道筛选. -4. 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题. -5. 支持启用udp多端口模式, 提高udp模式下媒体传输性能. -6. 支持通道是否含有音频的设置 -7. 支持通道子目录查询 -8. 支持udp/tcp,两种模式传输视频流 +1. 视频预览; +2. 云台控制(方向、缩放控制); +3. 视频设备信息同步; +4. 离在线监控; +5. 录像查询与回放(基于NVR\DVR,暂不支持快进、seek操作); +6. 无人观看自动断流; +7. 支持UDP和TCP两种国标信令传输模式; +# 新支持特性 +1. 集成web界面, 不需要单独部署前端服务, 直接利用wvp内置文件服务部署, 随wvp一起部署; +2. 支持平台接入, 针对大平台大量设备的情况进行优化; +3. 支持检索,通道筛选; +4. 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题; +5. 支持启用udp多端口模式, 提高udp模式下媒体传输性能; +6. 支持通道是否含有音频的设置; +7. 支持通道子目录查询; +8. 支持udp/tcp国标流传输模式; +9. 支持直接输出RTSP、RTMP、HTTP-FLV、Websocket-FLV、HLS多种协议流地址 +10. # 待实现: 上级级联 推流列表 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 9af409f0..e2c11cb6 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -538,7 +538,7 @@ public class SIPCommander implements ISIPCommander { recordInfoXml.append("" + channelId + "\r\n"); recordInfoXml.append("" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(startTime) + "\r\n"); recordInfoXml.append("" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(endTime) + "\r\n"); - recordInfoXml.append("0\\r\n"); + recordInfoXml.append("0\r\n"); // 大华NVR要求必须增加一个值为all的文本元素节点Type recordInfoXml.append("all\r\n"); recordInfoXml.append("\r\n"); 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 4c9f6fdc..96b4af21 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -140,8 +140,6 @@ public class ZLMHttpHookListener { streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId)); streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId)); - - storager.startPlay(streamInfo); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 775cb0f0..86f05da4 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -74,6 +74,15 @@ public class ZLMRESTfulUtils { return sendPost("getMediaList",param); } + public JSONObject getMediaInfo(String app, String schema, String stream){ + Map param = new HashMap<>(); + param.put("app",app); + param.put("schema",schema); + param.put("stream",stream); + param.put("vhost","__defaultVhost__"); + return sendPost("getMediaInfo",param); + } + public JSONObject getRtpInfo(String stream_id){ Map param = new HashMap<>(); param.put("stream_id",stream_id); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java index 93e6a24d..f88d59c6 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java @@ -37,7 +37,7 @@ public class ZLMUtils { System.out.println(jsonObject.toJSONString()); return newPort; }else { - return getNewRTPPort(streamId); + return getNewRTPPort(ssrc); } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java index 99f19ee2..1e68095c 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java @@ -165,7 +165,7 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { @Override public void updateCatch() { - + System.out.println("##################"); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java index ad0ff0c0..3827fc7c 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java @@ -64,18 +64,25 @@ public class PlayController { while (lockFlag) { try { - if (System.currentTimeMillis() - startTime > 15 * 1000) { storager.stopPlay(streamInfo); return new ResponseEntity("timeout",HttpStatus.OK); }else { + streamInfo = storager.queryPlayByDevice(deviceId, channelId); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); - if (rtpInfo == null || !rtpInfo.getBoolean("exist") || storager.queryPlayByDevice(deviceId, channelId).getFlv() == null){ + if (rtpInfo != null && rtpInfo.getBoolean("exist") && streamInfo.getFlv() != null){ + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId); + if (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")) { + lockFlag = false; + JSONArray tracks = mediaInfo.getJSONArray("tracks"); + streamInfo.setTracks(tracks); + storager.startPlay(streamInfo); + }else { + + } + }else { Thread.sleep(2000); continue; - }else { - lockFlag = false; - streamInfo = storager.queryPlay(streamInfo); }; } } catch (InterruptedException e) { diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue index b3980c32..8e6638a8 100644 --- a/web_src/src/components/channelList.vue +++ b/web_src/src/components/channelList.vue @@ -54,12 +54,15 @@ - + diff --git a/web_src/src/components/gb28181/devicePlayer.vue b/web_src/src/components/gb28181/devicePlayer.vue index 2f2cfc00..18a8d51b 100644 --- a/web_src/src/components/gb28181/devicePlayer.vue +++ b/web_src/src/components/gb28181/devicePlayer.vue @@ -1,8 +1,7 @@