From 56859d09df8d4226882d43934acf32d60a3b51d7 Mon Sep 17 00:00:00 2001
From: panlinlin <648540858@qq.com>
Date: 星期二, 30 三月 2021 18:46:34 +0800
Subject: [PATCH] 添加推流列表和拉流代理,下一步与国标关联
---
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java | 28
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java | 21
web_src/src/components/PushVideoList.vue | 157 +---
web_src/package-lock.json | 20
web_src/src/components/dialog/chooseChannelForGb.vue | 0
web_src/src/main.js | 3
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java | 17
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java | 10
web_src/src/components/dialog/devicePlayer.vue | 15
src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java | 37
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyDto.java | 112 ++++
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java | 3
web_src/src/components/UiHeader.vue | 1
web_src/src/components/dialog/StreamProxyEdit.vue | 186 ++++++
src/main/java/com/genersoft/iot/vmp/vmanager/service/IStreamProxyService.java | 60 ++
web_src/src/components/dialog/player.vue | 0
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java | 55 +
web_src/src/components/dialog/platformEdit.vue | 0
src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java | 10
web_src/src/components/StreamProxyList.vue | 297 ++++++++++
web_src/src/components/ParentPlatformList.vue | 4
src/main/java/com/genersoft/iot/vmp/vmanager/media/MediaController.java | 52 +
src/main/resources/wvp.sqlite | 0
web_src/package.json | 1
src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java | 73 ++
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java | 76 ++
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java | 46 +
/dev/null | 45 -
web_src/src/components/dialog/chooseChannel.vue | 2
web_src/src/components/channelList.vue | 2
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 49 +
src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/StreamProxyServiceImpl.java | 123 ++++
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java | 46 +
src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/MediaServiceImpl.java | 52 +
web_src/src/router/index.js | 5
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java | 1
src/main/java/com/genersoft/iot/vmp/vmanager/service/IMediaService.java | 25
37 files changed, 1,417 insertions(+), 217 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java
index 76390e4..eba9a5e 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaServerConfig.java
@@ -35,6 +35,8 @@
private String wanIp;
+ private long updateTime;
+
@JSONField(name = "hls.fileBufSize")
private String hlsFileBufSize;
@@ -728,4 +730,12 @@
public void setWanIp(String wanIp) {
this.wanIp = wanIp;
}
+
+ public long getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(long updateTime) {
+ this.updateTime = updateTime;
+ }
}
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 51c6e1b..b2c1597 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
@@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.media.zlm;
+import java.util.List;
import java.util.UUID;
import com.alibaba.fastjson.JSON;
@@ -272,26 +273,35 @@
}
String streamId = json.getString("stream");
+ String app = json.getString("app");
StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
- JSONObject ret = new JSONObject();
- ret.put("code", 0);
- ret.put("close", true);
- if (streamInfo != null) {
- if (redisCatchStorage.isChannelSendingRTP(streamInfo.getChannelId())) {
- ret.put("close", false);
- } else {
+ if ("rtp".equals(app)){
+ JSONObject ret = new JSONObject();
+ ret.put("code", 0);
+ ret.put("close", true);
+ if (streamInfo != null) {
+ if (redisCatchStorage.isChannelSendingRTP(streamInfo.getChannelId())) {
+ ret.put("close", false);
+ } else {
+ cmder.streamByeCmd(streamId);
+ redisCatchStorage.stopPlay(streamInfo);
+ storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
+ }
+ }else{
cmder.streamByeCmd(streamId);
- redisCatchStorage.stopPlay(streamInfo);
- storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
+ streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId);
+ redisCatchStorage.stopPlayback(streamInfo);
}
- }else{
- cmder.streamByeCmd(streamId);
- streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId);
- redisCatchStorage.stopPlayback(streamInfo);
+ return new ResponseEntity<String>(ret.toString(),HttpStatus.OK);
+ }else {
+ JSONObject ret = new JSONObject();
+ ret.put("code", 0);
+ ret.put("close", false);
+ return new ResponseEntity<String>(ret.toString(),HttpStatus.OK);
}
- return new ResponseEntity<String>(ret.toString(),HttpStatus.OK);
+
}
/**
@@ -350,10 +360,21 @@
// String data = json.getString("data");
// List<MediaServerConfig> mediaServerConfigs = JSON.parseArray(JSON.toJSONString(json), MediaServerConfig.class);
// MediaServerConfig mediaServerConfig = mediaServerConfigs.get(0);
+
+ List<ZLMHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(ZLMHttpHookSubscribe.HookType.on_server_started);
+ if (subscribes != null && subscribes.size() > 0) {
+ for (ZLMHttpHookSubscribe.Event subscribe : subscribes) {
+ subscribe.response(json);
+ }
+ }
+
MediaServerConfig mediaServerConfig = JSON.toJavaObject(json, MediaServerConfig.class);
mediaServerConfig.setWanIp(StringUtils.isEmpty(mediaWanIp)? mediaIp: mediaWanIp);
mediaServerConfig.setLocalIP(mediaIp);
redisCatchStorage.updateMediaInfo(mediaServerConfig);
+
+ // 閲嶆柊鍙戣捣浠g悊
+
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("msg", "success");
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
index 995f916..129f8a3 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
@@ -3,7 +3,9 @@
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -67,4 +69,19 @@
}
return event;
}
+
+ public List<ZLMHttpHookSubscribe.Event> getSubscribes(HookType type) {
+ ZLMHttpHookSubscribe.Event event= null;
+ Map<JSONObject, Event> eventMap = allSubscribes.get(type);
+ if (eventMap == null) {
+ return null;
+ }
+ List<ZLMHttpHookSubscribe.Event> result = new ArrayList<>();
+ for (JSONObject key : eventMap.keySet()) {
+ result.add(eventMap.get(key));
+ }
+ return result;
+ }
+
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
index b17151a..5ffa467 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
@@ -32,6 +32,7 @@
public void updateMediaList() {
JSONObject mediaList = zlmresTfulUtils.getMediaList();
+ if (mediaList == null) return;
String dataStr = mediaList.getString("data");
Integer code = mediaList.getInteger("code");
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 ad17fee..21752a0 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
@@ -131,4 +131,25 @@
public JSONObject stopSendRtp(Map<String, Object> param) {
return sendPost("stopSendRtp",param);
}
+
+ public JSONObject addStreamProxy(String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) {
+ Map<String, Object> param = new HashMap<>();
+ param.put("vhost", "__defaultVhost__");
+ param.put("app", app);
+ param.put("stream", stream);
+ param.put("url", url);
+ param.put("enable_hls", enable_hls?1:0);
+ param.put("enable_mp4", enable_mp4?1:0);
+ param.put("rtp_type", rtp_type);
+ return sendPost("addStreamProxy",param);
+ }
+
+ public JSONObject closeStreams(String app, String stream) {
+ Map<String, Object> param = new HashMap<>();
+ param.put("vhost", "__defaultVhost__");
+ param.put("app", app);
+ param.put("stream", stream);
+ param.put("force", 1);
+ return sendPost("close_streams",param);
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
index e65fae0..15fa957 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -4,8 +4,11 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.conf.MediaServerConfig;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
//import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+import com.genersoft.iot.vmp.vmanager.service.IStreamProxyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -16,6 +19,7 @@
import org.springframework.util.StringUtils;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
@Component
@@ -24,8 +28,8 @@
private final static Logger logger = LoggerFactory.getLogger(ZLMRunner.class);
- // @Autowired
- // private IVideoManagerStorager storager;
+ @Autowired
+ private IVideoManagerStorager storager;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@@ -63,18 +67,27 @@
@Autowired
private ZLMMediaListManager zlmMediaListManager;
+ @Autowired
+ private ZLMHttpHookSubscribe hookSubscribe;
+
+ @Autowired
+ private IStreamProxyService streamProxyService;
+
@Override
public void run(String... strings) throws Exception {
+ JSONObject subscribeKey = new JSONObject();
+ // 璁㈤槄 zlm鍚姩浜嬩欢
+ hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,subscribeKey,(response)->{
+ MediaServerConfig mediaServerConfig = JSONObject.toJavaObject(response, MediaServerConfig.class);
+ zLmRunning(mediaServerConfig);
+ });
+
// 鑾峰彇zlm淇℃伅
logger.info("绛夊緟zlm鎺ュ叆...");
MediaServerConfig mediaServerConfig = getMediaServerConfig();
+
if (mediaServerConfig != null) {
- logger.info("zlm鎺ュ叆鎴愬姛...");
- if (autoConfig) saveZLMConfig();
- mediaServerConfig = getMediaServerConfig();
- redisCatchStorage.updateMediaInfo(mediaServerConfig);
- // 鏇存柊娴佸垪琛�
- zlmMediaListManager.updateMediaList();
+ zLmRunning(mediaServerConfig);
}
}
@@ -85,8 +98,7 @@
JSONArray data = responseJSON.getJSONArray("data");
if (data != null && data.size() > 0) {
mediaServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), MediaServerConfig.class);
- mediaServerConfig.setLocalIP(mediaIp);
- mediaServerConfig.setWanIp(StringUtils.isEmpty(mediaWanIp)? mediaIp: mediaWanIp);
+
}
} else {
logger.error("getMediaServerConfig澶辫触, 1s鍚庨噸璇�");
@@ -136,4 +148,27 @@
}
}
+ /**
+ * zlm 杩炴帴鎴愬姛鎴栬�厇lm閲嶅惎鍚�
+ */
+ private void zLmRunning(MediaServerConfig mediaServerConfig){
+ logger.info("zlm鎺ュ叆鎴愬姛...");
+ if (autoConfig) saveZLMConfig();
+ MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
+ if (System.currentTimeMillis() - mediaInfo.getUpdateTime() < 50){
+ logger.info("zlm鍒氬垰鏇存柊锛屽拷鐣ヨ繖娆℃洿鏂�");
+ return;
+ }
+ mediaServerConfig.setLocalIP(mediaIp);
+ mediaServerConfig.setWanIp(StringUtils.isEmpty(mediaWanIp)? mediaIp: mediaWanIp);
+ redisCatchStorage.updateMediaInfo(mediaServerConfig);
+ // 鏇存柊娴佸垪琛�
+ zlmMediaListManager.updateMediaList();
+ // 鎭㈠娴佷唬鐞�
+ List<StreamProxyDto> streamProxyListForEnable = storager.getStreamProxyListForEnable(true);
+ for (StreamProxyDto streamProxyDto : streamProxyListForEnable) {
+ logger.info("鎭㈠娴佷唬鐞嗭紝" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
+ streamProxyService.addStreamProxyToZlm(streamProxyDto);
+ }
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyDto.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyDto.java
new file mode 100644
index 0000000..8f03602
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyDto.java
@@ -0,0 +1,112 @@
+package com.genersoft.iot.vmp.media.zlm.dto;
+
+public class StreamProxyDto {
+ private String type;
+ private String app;
+ private String stream;
+ private String url;
+ private String src_url;
+ private String dst_url;
+ private int timeout_ms;
+ private String ffmpeg_cmd_key;
+ private String rtp_type;
+ private boolean enable;
+ private boolean enable_hls;
+ private boolean enable_mp4;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ 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 getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getSrc_url() {
+ return src_url;
+ }
+
+ public void setSrc_url(String src_url) {
+ this.src_url = src_url;
+ }
+
+ public String getDst_url() {
+ return dst_url;
+ }
+
+ public void setDst_url(String dst_url) {
+ this.dst_url = dst_url;
+ }
+
+ public int getTimeout_ms() {
+ return timeout_ms;
+ }
+
+ public void setTimeout_ms(int timeout_ms) {
+ this.timeout_ms = timeout_ms;
+ }
+
+ public String getFfmpeg_cmd_key() {
+ return ffmpeg_cmd_key;
+ }
+
+ public void setFfmpeg_cmd_key(String ffmpeg_cmd_key) {
+ this.ffmpeg_cmd_key = ffmpeg_cmd_key;
+ }
+
+ public String getRtp_type() {
+ return rtp_type;
+ }
+
+ public void setRtp_type(String rtp_type) {
+ this.rtp_type = rtp_type;
+ }
+
+ public boolean isEnable() {
+ return enable;
+ }
+
+ public void setEnable(boolean enable) {
+ this.enable = enable;
+ }
+
+ public boolean isEnable_hls() {
+ return enable_hls;
+ }
+
+ public void setEnable_hls(boolean enable_hls) {
+ this.enable_hls = enable_hls;
+ }
+
+ public boolean isEnable_mp4() {
+ return enable_mp4;
+ }
+
+ public void setEnable_mp4(boolean enable_mp4) {
+ this.enable_mp4 = enable_mp4;
+ }
+}
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 2866611..ca4ebae 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.storager;
+import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.RealVideo;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaServerConfig;
@@ -116,5 +117,5 @@
* 鑾峰彇褰撳墠濯掍綋娴佸垪琛�
* @return List<RealVideo>
*/
- List<Object> getMediaList(int start, int end);
+ JSONObject getMediaList(int start, int end);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
index 10360b0..7656898 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -5,6 +5,7 @@
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
import com.github.pagehelper.PageInfo;
@@ -261,4 +262,49 @@
* @param deviceId
*/
public int clearMobilePositionsByDeviceId(String deviceId);
+
+ /**
+ * 鏂板浠g悊娴�
+ * @param streamProxyDto
+ * @return
+ */
+ public int addStreamProxy(StreamProxyDto streamProxyDto);
+
+ /**
+ * 鏇存柊浠g悊娴�
+ * @param streamProxyDto
+ * @return
+ */
+ public int updateStreamProxy(StreamProxyDto streamProxyDto);
+
+ /**
+ * 绉婚櫎浠g悊娴�
+ * @param app
+ * @param stream
+ * @return
+ */
+ public int deleteStreamProxy(String app, String stream);
+
+ /**
+ * 鎸夌収鏄惁鍚敤鑾峰彇浠g悊娴�
+ * @param enable
+ * @return
+ */
+ public List<StreamProxyDto> getStreamProxyListForEnable(boolean enable);
+
+ /**
+ * 鎸夌収鏄痑pp鍜宻tream鑾峰彇浠g悊娴�
+ * @param app
+ * @param stream
+ * @return
+ */
+ public StreamProxyDto queryStreamProxy(String app, String stream);
+
+ /**
+ * 鑾峰彇浠g悊娴�
+ * @param page
+ * @param count
+ * @return
+ */
+ PageInfo<StreamProxyDto> queryStreamProxyList(Integer page, Integer count);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
new file mode 100644
index 0000000..414125b
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
@@ -0,0 +1,46 @@
+package com.genersoft.iot.vmp.storager.dao;
+
+import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
+import org.apache.ibatis.annotations.*;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Mapper
+@Repository
+public interface StreamProxyMapper {
+
+ @Insert("INSERT INTO stream_proxy (type, app, stream, url, src_url, dst_url, " +
+ "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable) VALUES" +
+ "('${type}','${app}', '${stream}', '${url}', '${src_url}', '${dst_url}', " +
+ "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable} )")
+ int add(StreamProxyDto streamProxyDto);
+
+ @Update("UPDATE stream_proxy " +
+ "SET type=#{type}, " +
+ "app=#{app}," +
+ "stream=#{stream}," +
+ "url=#{url}, " +
+ "src_url=#{src_url}," +
+ "dst_url=#{dst_url}, " +
+ "timeout_ms=#{timeout_ms}, " +
+ "ffmpeg_cmd_key=#{ffmpeg_cmd_key}, " +
+ "rtp_type=#{rtp_type}, " +
+ "enable_hls=#{enable_hls}, " +
+ "enable=#{enable}, " +
+ "enable_mp4=#{enable_mp4} " +
+ "WHERE app=#{app} AND stream=#{stream}")
+ int update(StreamProxyDto streamProxyDto);
+
+ @Delete("DELETE FROM stream_proxy WHERE app=#{app} AND stream=#{stream}")
+ int del(String app, String stream);
+
+ @Select("SELECT * FROM stream_proxy")
+ List<StreamProxyDto> selectAll();
+
+ @Select("SELECT * FROM stream_proxy WHERE enable=${enable}")
+ List<StreamProxyDto> selectForEnable(boolean enable);
+
+ @Select("SELECT * FROM stream_proxy WHERE app=#{app} AND stream=#{stream}")
+ StreamProxyDto selectOne(String app, String stream);
+}
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 9871083..7b7f599 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.storager.impl;
+import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.RealVideo;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
@@ -92,6 +93,7 @@
*/
@Override
public boolean updateMediaInfo(MediaServerConfig mediaServerConfig) {
+ mediaServerConfig.setUpdateTime(System.currentTimeMillis());
return redis.set(VideoManagerConstants.MEDIA_SERVER_PREFIX,mediaServerConfig);
}
@@ -280,9 +282,13 @@
* @return List<RealVideo>
*/
@Override
- public List<Object> getMediaList(int start, int end) {
+ public JSONObject getMediaList(int start, int end) {
String key = VideoManagerConstants.MEDIA_STREAM_PREFIX;
Set<Object> realVideos = redis.ZRange(key, start, end);
- return new ArrayList(realVideos);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("list", new ArrayList(realVideos));
+ jsonObject.put("total", redis.zSize(key));
+
+ return jsonObject;
}
}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
index ac2ed5b..071bf68 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -5,14 +5,11 @@
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
-import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
-import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
-import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
-import com.genersoft.iot.vmp.storager.dao.PatformChannelMapper;
+import com.genersoft.iot.vmp.storager.dao.*;
import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
-import com.genersoft.iot.vmp.storager.dao.DeviceMobilePositionMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
@@ -48,6 +45,9 @@
@Autowired
private PatformChannelMapper patformChannelMapper;
+
+ @Autowired
+ private StreamProxyMapper streamProxyMapper;
@@ -233,7 +233,7 @@
/**
* 娣诲姞Mobile Position璁惧绉诲姩浣嶇疆
- * @param MobilePosition
+ * @param mobilePosition
*/
@Override
public synchronized boolean insertMobilePosition(MobilePosition mobilePosition) {
@@ -388,4 +388,68 @@
return deviceMobilePositionMapper.clearMobilePositionsByDeviceId(deviceId);
}
+ /**
+ * 鏂板浠g悊娴�
+ * @param streamProxyDto
+ * @return
+ */
+ @Override
+ public int addStreamProxy(StreamProxyDto streamProxyDto) {
+ return streamProxyMapper.add(streamProxyDto);
+ }
+
+ /**
+ * 鏇存柊浠g悊娴�
+ * @param streamProxyDto
+ * @return
+ */
+ @Override
+ public int updateStreamProxy(StreamProxyDto streamProxyDto) {
+ return streamProxyMapper.update(streamProxyDto);
+ }
+
+ /**
+ * 绉婚櫎浠g悊娴�
+ * @param id
+ * @return
+ */
+ @Override
+ public int deleteStreamProxy(String app, String stream) {
+ return streamProxyMapper.del(app, stream);
+ }
+
+ /**
+ * 鏍规嵁鏄惁鍚敤鑾峰彇浠g悊娴佸垪琛�
+ * @param enable
+ * @return
+ */
+ @Override
+ public List<StreamProxyDto> getStreamProxyListForEnable(boolean enable) {
+ return streamProxyMapper.selectForEnable(enable);
+ }
+
+ /**
+ * 鍒嗛〉鏌ヨ浠g悊娴佸垪琛�
+ * @param page
+ * @param count
+ * @return
+ */
+ @Override
+ public PageInfo<StreamProxyDto> queryStreamProxyList(Integer page, Integer count) {
+ PageHelper.startPage(page, count);
+ List<StreamProxyDto> all = streamProxyMapper.selectAll();
+ return new PageInfo<>(all);
+ }
+
+
+ /**
+ * 鎸夌収鏄痑pp鍜宻tream鑾峰彇浠g悊娴�
+ * @param app
+ * @param stream
+ * @return
+ */
+ @Override
+ public StreamProxyDto queryStreamProxy(String app, String stream){
+ return streamProxyMapper.selectOne(app, stream);
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/media/MediaController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/media/MediaController.java
new file mode 100644
index 0000000..115e840
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/media/MediaController.java
@@ -0,0 +1,52 @@
+package com.genersoft.iot.vmp.vmanager.media;
+
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.vmanager.service.IMediaService;
+import com.genersoft.iot.vmp.vmanager.service.IStreamProxyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/api/media")
+public class MediaController {
+
+ private final static Logger logger = LoggerFactory.getLogger(MediaController.class);
+
+ @Autowired
+ private IRedisCatchStorage redisCatchStorage;
+
+ @Autowired
+ private IStreamProxyService streamProxyService;
+
+ @Autowired
+ private IMediaService mediaService;
+
+
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public JSONObject list( @RequestParam(required = false)Integer page,
+ @RequestParam(required = false)Integer count,
+ @RequestParam(required = false)String q,
+ @RequestParam(required = false)Boolean online ){
+
+ JSONObject jsonObject = redisCatchStorage.getMediaList(page - 1, page - 1 + count);
+ return jsonObject;
+ }
+
+ @RequestMapping(value = "/getStreamInfoByAppAndStream")
+ @ResponseBody
+ public StreamInfo getStreamInfoByAppAndStream(String app, String stream){
+ return mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream);
+ }
+
+
+
+
+}
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 0c773e6..67045b4 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
@@ -8,6 +8,7 @@
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult;
+import com.genersoft.iot.vmp.vmanager.service.IMediaService;
import com.genersoft.iot.vmp.vmanager.service.IPlayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,6 +55,9 @@
@Autowired
private IPlayService playService;
+
+ @Autowired
+ private IMediaService mediaService;
@GetMapping("/play/{deviceId}/{channelId}")
public DeferredResult<ResponseEntity<String>> play(@PathVariable String deviceId,
@@ -159,18 +163,20 @@
JSONObject data = jsonObject.getJSONObject("data");
if (data != null) {
result.put("key", data.getString("key"));
- StreamInfo streamInfoResult = new StreamInfo();
- streamInfoResult.setRtmp(dstUrl);
- streamInfoResult.setRtsp(String.format("rtsp://%s:%s/convert/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), streamId));
+// StreamInfo streamInfoResult = new StreamInfo();
+// streamInfoResult.setRtmp(dstUrl);
+// streamInfoResult.setRtsp(String.format("rtsp://%s:%s/convert/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), streamId));
+// streamInfoResult.setStreamId(streamId);
+// streamInfoResult.setFlv(String.format("http://%s:%s/convert/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
+// streamInfoResult.setWs_flv(String.format("ws://%s:%s/convert/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
+// streamInfoResult.setHls(String.format("http://%s:%s/convert/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
+// streamInfoResult.setWs_hls(String.format("ws://%s:%s/convert/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
+// streamInfoResult.setFmp4(String.format("http://%s:%s/convert/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
+// streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/convert/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
+// streamInfoResult.setTs(String.format("http://%s:%s/convert/%s.live.ts", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
+// streamInfoResult.setWs_ts(String.format("ws://%s:%s/convert/%s.live.ts", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
+ StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStream("convert", streamId);
streamInfoResult.setStreamId(streamId);
- streamInfoResult.setFlv(String.format("http://%s:%s/convert/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
- streamInfoResult.setWs_flv(String.format("ws://%s:%s/convert/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
- streamInfoResult.setHls(String.format("http://%s:%s/convert/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
- streamInfoResult.setWs_hls(String.format("ws://%s:%s/convert/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
- streamInfoResult.setFmp4(String.format("http://%s:%s/convert/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
- streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/convert/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
- streamInfoResult.setTs(String.format("http://%s:%s/convert/%s.live.ts", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
- streamInfoResult.setWs_ts(String.format("ws://%s:%s/convert/%s.live.ts", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
result.put("data", streamInfoResult);
}
}else {
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/IMediaService.java
new file mode 100644
index 0000000..757a7ac
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/IMediaService.java
@@ -0,0 +1,25 @@
+package com.genersoft.iot.vmp.vmanager.service;
+
+import com.genersoft.iot.vmp.common.StreamInfo;
+
+/**
+ * 濯掍綋淇℃伅涓氬姟
+ */
+public interface IMediaService {
+
+ /**
+ * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 閫氳繃zlm鎺ュ彛妫�鏌ユ槸鍚﹀瓨鍦�
+ * @param app
+ * @param stream
+ * @return
+ */
+ StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream);
+
+ /**
+ * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 鍙槸鍦板潃鎷兼帴
+ * @param app
+ * @param stream
+ * @return
+ */
+ StreamInfo getStreamInfoByAppAndStream(String app, String stream);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/IStreamProxyService.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/IStreamProxyService.java
new file mode 100644
index 0000000..4a93cd2
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/IStreamProxyService.java
@@ -0,0 +1,60 @@
+package com.genersoft.iot.vmp.vmanager.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
+import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController;
+import com.github.pagehelper.PageInfo;
+
+public interface IStreamProxyService {
+
+ /**
+ * 淇濆瓨瑙嗛浠g悊
+ * @param param
+ */
+ void save(StreamProxyDto param);
+
+ /**
+ * 娣诲姞瑙嗛浠g悊鍒皕lm
+ * @param param
+ * @return
+ */
+ JSONObject addStreamProxyToZlm(StreamProxyDto param);
+
+ /**
+ * 浠巣lm绉婚櫎瑙嗛浠g悊
+ * @param param
+ * @return
+ */
+ JSONObject removeStreamProxyFromZlm(StreamProxyDto param);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ * @param page
+ * @param count
+ * @return
+ */
+ PageInfo<StreamProxyDto> getAll(Integer page, Integer count);
+
+ /**
+ * 鍒犻櫎瑙嗛浠g悊
+ * @param app
+ * @param stream
+ */
+ void del(String app, String stream);
+
+ /**
+ * 鍚敤瑙嗛浠g悊
+ * @param app
+ * @param stream
+ * @return
+ */
+ boolean start(String app, String stream);
+
+ /**
+ * 鍋滅敤鐢ㄨ棰戜唬鐞�
+ * @param app
+ * @param stream
+ * @return
+ */
+ boolean stop(String app, String stream);
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/MediaServiceImpl.java
new file mode 100644
index 0000000..afd6cc9
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/MediaServiceImpl.java
@@ -0,0 +1,52 @@
+package com.genersoft.iot.vmp.vmanager.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.conf.MediaServerConfig;
+import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+import com.genersoft.iot.vmp.vmanager.service.IMediaService;
+import com.genersoft.iot.vmp.vmanager.service.IStreamProxyService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class MediaServiceImpl implements IMediaService {
+
+ @Autowired
+ private IRedisCatchStorage redisCatchStorage;
+
+ @Autowired
+ private IVideoManagerStorager storager;
+
+ @Autowired
+ private ZLMRESTfulUtils zlmresTfulUtils;
+
+ @Override
+ public StreamInfo getStreamInfoByAppAndStream(String app, String stream) {
+ MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
+ StreamInfo streamInfoResult = new StreamInfo();
+ streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s", mediaInfo.getWanIp(), mediaInfo.getRtmpPort(), app, stream));
+ streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), app, stream));
+ streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
+ streamInfoResult.setWs_flv(String.format("ws://%s:%s/%s/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
+ streamInfoResult.setHls(String.format("http://%s:%s/%s/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
+ streamInfoResult.setWs_hls(String.format("ws://%s:%s/%s/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
+ streamInfoResult.setFmp4(String.format("http://%s:%s/%s/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
+ streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/%s/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
+ streamInfoResult.setTs(String.format("http://%s:%s/%s/%s.live.ts", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
+ streamInfoResult.setWs_ts(String.format("ws://%s:%s/%s/%s.live.ts", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
+ return streamInfoResult;
+ }
+
+ @Override
+ public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream) {
+ StreamInfo streamInfo = null;
+ JSONObject mediaList = zlmresTfulUtils.getMediaList(app, stream);
+ if (mediaList != null) {
+ streamInfo = getStreamInfoByAppAndStream(app, stream);
+ }
+ return streamInfo;
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
index 376040a..edd8710 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
@@ -15,6 +15,7 @@
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult;
+import com.genersoft.iot.vmp.vmanager.service.IMediaService;
import com.genersoft.iot.vmp.vmanager.service.IPlayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,6 +46,9 @@
@Autowired
private ZLMRESTfulUtils zlmresTfulUtils;
+
+ @Autowired
+ private IMediaService mediaService;
@Override
@@ -148,26 +152,27 @@
public StreamInfo onPublishHandler(JSONObject resonse, String deviceId, String channelId, String uuid) {
String streamId = resonse.getString("id");
- StreamInfo streamInfo = new StreamInfo();
+ StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream("rtp", streamId);
+// StreamInfo streamInfo = new StreamInfo();
streamInfo.setStreamId(streamId);
streamInfo.setDeviceID(deviceId);
streamInfo.setChannelId(channelId);
- MediaServerConfig mediaServerConfig = redisCatchStorage.getMediaInfo();
+// MediaServerConfig mediaServerConfig = redisCatchStorage.getMediaInfo();
- streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
- streamInfo.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
-
- streamInfo.setFmp4(String.format("http://%s:%s/rtp/%s.live.mp4", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
- streamInfo.setWs_fmp4(String.format("ws://%s:%s/rtp/%s.live.mp4", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
-
- streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
- streamInfo.setWs_hls(String.format("ws://%s:%s/rtp/%s/hls.m3u8", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
-
- streamInfo.setTs(String.format("http://%s:%s/rtp/%s.live.ts", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
- streamInfo.setWs_ts(String.format("ws://%s:%s/rtp/%s.live.ts", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
-
- streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaServerConfig.getWanIp(), mediaServerConfig.getRtmpPort(), streamId));
- streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaServerConfig.getWanIp(), mediaServerConfig.getRtspPort(), streamId));
+// streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
+// streamInfo.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
+//
+// streamInfo.setFmp4(String.format("http://%s:%s/rtp/%s.live.mp4", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
+// streamInfo.setWs_fmp4(String.format("ws://%s:%s/rtp/%s.live.mp4", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
+//
+// streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
+// streamInfo.setWs_hls(String.format("ws://%s:%s/rtp/%s/hls.m3u8", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
+//
+// streamInfo.setTs(String.format("http://%s:%s/rtp/%s.live.ts", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
+// streamInfo.setWs_ts(String.format("ws://%s:%s/rtp/%s.live.ts", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
+//
+// streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaServerConfig.getWanIp(), mediaServerConfig.getRtmpPort(), streamId));
+// streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaServerConfig.getWanIp(), mediaServerConfig.getRtspPort(), streamId));
return streamInfo;
}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/StreamProxyServiceImpl.java
new file mode 100644
index 0000000..0655980
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/StreamProxyServiceImpl.java
@@ -0,0 +1,123 @@
+package com.genersoft.iot.vmp.vmanager.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.conf.MediaServerConfig;
+import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
+import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
+import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper;
+import com.genersoft.iot.vmp.vmanager.service.IStreamProxyService;
+import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 瑙嗛浠g悊涓氬姟
+ */
+@Service
+public class StreamProxyServiceImpl implements IStreamProxyService {
+
+ @Autowired
+ private IVideoManagerStorager videoManagerStorager;
+
+ @Autowired
+ private IRedisCatchStorage redisCatchStorage;
+
+ @Autowired
+ private ZLMRESTfulUtils zlmresTfulUtils;
+
+ @Autowired
+ private StreamProxyMapper streamProxyMapper;
+
+
+ @Override
+ public void save(StreamProxyDto param) {
+ MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
+ String dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(),
+ param.getStream() );
+ param.setDst_url(dstUrl);
+ // 鏇存柊
+ if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) {
+ int result = videoManagerStorager.updateStreamProxy(param);
+ if (result > 0 && param.isEnable()) {
+ addStreamProxyToZlm(param);
+ }
+ }else { // 鏂板
+ int result = videoManagerStorager.addStreamProxy(param);
+ if (result > 0 && param.isEnable()) {
+ addStreamProxyToZlm(param);
+ }
+ }
+ }
+
+ @Override
+ public JSONObject addStreamProxyToZlm(StreamProxyDto param) {
+ JSONObject result = null;
+ if ("default".equals(param.getType())){
+ result = zlmresTfulUtils.addStreamProxy(param.getApp(), param.getStream(), param.getUrl(),
+ param.isEnable_hls(), param.isEnable_mp4(), param.getRtp_type());
+ }else if ("ffmpeg".equals(param.getType())) {
+ result = zlmresTfulUtils.addFFmpegSource(param.getSrc_url(), param.getDst_url(),
+ param.getTimeout_ms() + "");
+ }
+ return result;
+ }
+
+ @Override
+ public JSONObject removeStreamProxyFromZlm(StreamProxyDto param) {
+ JSONObject result = zlmresTfulUtils.closeStreams(param.getApp(), param.getStream());
+ return result;
+ }
+
+ @Override
+ public PageInfo<StreamProxyDto> getAll(Integer page, Integer count) {
+ return videoManagerStorager.queryStreamProxyList(page, count);
+ }
+
+ @Override
+ public void del(String app, String stream) {
+ StreamProxyDto streamProxyDto = new StreamProxyDto();
+ streamProxyDto.setApp(app);
+ streamProxyDto.setStream(stream);
+ JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyDto);
+ if (jsonObject.getInteger("code") == 0) {
+ videoManagerStorager.deleteStreamProxy(app, stream);
+ }
+ }
+
+ @Override
+ public boolean start(String app, String stream) {
+ boolean result = false;
+ StreamProxyDto streamProxyDto = videoManagerStorager.queryStreamProxy(app, stream);
+ if (!streamProxyDto.isEnable() && streamProxyDto != null) {
+ JSONObject jsonObject = addStreamProxyToZlm(streamProxyDto);
+ if (jsonObject.getInteger("code") == 0) {
+ result = true;
+ streamProxyDto.setEnable(true);
+ videoManagerStorager.updateStreamProxy(streamProxyDto);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean stop(String app, String stream) {
+ boolean result = false;
+ StreamProxyDto streamProxyDto = videoManagerStorager.queryStreamProxy(app, stream);
+ if (streamProxyDto.isEnable() && streamProxyDto != null) {
+ JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyDto);
+ if (jsonObject.getInteger("code") == 0) {
+ result = true;
+ streamProxyDto.setEnable(false);
+ videoManagerStorager.updateStreamProxy(streamProxyDto);
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
new file mode 100644
index 0000000..09d4174
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
@@ -0,0 +1,73 @@
+package com.genersoft.iot.vmp.vmanager.streamProxy;
+
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
+import com.genersoft.iot.vmp.vmanager.service.IStreamProxyService;
+import com.github.pagehelper.PageInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 鎷夋祦浠g悊鎺ュ彛
+ */
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/api/proxy")
+public class StreamProxyController {
+
+ private final static Logger logger = LoggerFactory.getLogger(StreamProxyController.class);
+
+ @Autowired
+ private IRedisCatchStorage redisCatchStorage;
+
+ @Autowired
+ private IStreamProxyService streamProxyService;
+
+
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public PageInfo<StreamProxyDto> list(@RequestParam(required = false)Integer page,
+ @RequestParam(required = false)Integer count,
+ @RequestParam(required = false)String q,
+ @RequestParam(required = false)Boolean online ){
+
+ return streamProxyService.getAll(page, count);
+ }
+
+ @RequestMapping(value = "/save")
+ @ResponseBody
+ public Object save(@RequestBody StreamProxyDto param){
+ logger.info("娣诲姞浠g悊锛� " + JSONObject.toJSONString(param));
+ streamProxyService.save(param);
+ return "success";
+ }
+
+ @RequestMapping(value = "/del")
+ @ResponseBody
+ public Object del(String app, String stream){
+ logger.info("绉婚櫎浠g悊锛� " + app + "/" + stream);
+ streamProxyService.del(app, stream);
+ return "success";
+ }
+
+ @RequestMapping(value = "/start")
+ @ResponseBody
+ public Object start(String app, String stream){
+ logger.info("鍚敤浠g悊锛� " + app + "/" + stream);
+ boolean result = streamProxyService.start(app, stream);
+ return "success";
+ }
+
+ @RequestMapping(value = "/stop")
+ @ResponseBody
+ public Object stop(String app, String stream){
+ logger.info("鍋滅敤浠g悊锛� " + app + "/" + stream);
+ boolean result = streamProxyService.stop(app, stream);
+ return "success";
+ }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiMediaController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiMediaController.java
deleted file mode 100644
index 84910c5..0000000
--- a/src/main/java/com/genersoft/iot/vmp/web/ApiMediaController.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.genersoft.iot.vmp.web;
-
-import com.alibaba.fastjson.JSONObject;
-import com.genersoft.iot.vmp.common.RealVideo;
-import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-import java.util.List;
-
-/**
- * 鍏煎LiveGBS鐨凙PI锛氱郴缁熸帴鍙�
- */
-@Controller
-@CrossOrigin
-@RequestMapping(value = "/api/v1/media")
-public class ApiMediaController {
-
- private final static Logger logger = LoggerFactory.getLogger(ApiMediaController.class);
-
- @Autowired
- private IRedisCatchStorage redisCatchStorage;
-
-
- @RequestMapping(value = "/list")
- @ResponseBody
- public JSONObject list( @RequestParam(required = false)Integer start,
- @RequestParam(required = false)Integer limit,
- @RequestParam(required = false)String q,
- @RequestParam(required = false)Boolean online ){
-
- List<Object> mediaList = redisCatchStorage.getMediaList(start - 1, start - 1 + limit);
- JSONObject jsonObject = new JSONObject();
- jsonObject.put("code", 0);
- jsonObject.put("data", mediaList);
- return jsonObject;
- }
-}
diff --git a/src/main/resources/wvp.sqlite b/src/main/resources/wvp.sqlite
index d50f18c..9147e22 100644
--- a/src/main/resources/wvp.sqlite
+++ b/src/main/resources/wvp.sqlite
Binary files differ
diff --git a/web_src/package-lock.json b/web_src/package-lock.json
index e4ed934..9e734e5 100644
--- a/web_src/package-lock.json
+++ b/web_src/package-lock.json
@@ -10924,6 +10924,26 @@
"clipboard": "^2.0.0"
}
},
+ "vue-clipboards": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/vue-clipboards/-/vue-clipboards-1.3.0.tgz",
+ "integrity": "sha512-VMDYHpLQH0EUmqfk9b5XMrkvSu/HjNsLW2EBR4OS6JZHcv/PxmWYdoTBPVlp5eYrhWy07La8nWpRwAh09Mgufw==",
+ "requires": {
+ "clipboard": "^1.7.1"
+ },
+ "dependencies": {
+ "clipboard": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.7.1.tgz",
+ "integrity": "sha1-Ng1taUbpmnof7zleQrqStem1oWs=",
+ "requires": {
+ "good-listener": "^1.2.2",
+ "select": "^1.1.2",
+ "tiny-emitter": "^2.0.0"
+ }
+ }
+ }
+ },
"vue-cookies": {
"version": "1.7.4",
"resolved": "https://registry.npm.taobao.org/vue-cookies/download/vue-cookies-1.7.4.tgz?cache=0&sync_timestamp=1598941352058&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-cookies%2Fdownload%2Fvue-cookies-1.7.4.tgz",
diff --git a/web_src/package.json b/web_src/package.json
index 4a9f766..b7a947c 100644
--- a/web_src/package.json
+++ b/web_src/package.json
@@ -21,6 +21,7 @@
"vue": "^2.6.11",
"vue-baidu-map": "^0.21.22",
"vue-clipboard2": "^0.3.1",
+ "vue-clipboards": "^1.3.0",
"vue-cookies": "^1.7.4",
"vue-router": "^3.1.6"
},
diff --git a/web_src/src/components/ParentPlatformList.vue b/web_src/src/components/ParentPlatformList.vue
index 298504b..32c999d 100644
--- a/web_src/src/components/ParentPlatformList.vue
+++ b/web_src/src/components/ParentPlatformList.vue
@@ -68,9 +68,9 @@
</template>
<script>
-import platformEdit from './platformEdit.vue'
+import platformEdit from './dialog/platformEdit.vue'
import uiHeader from './UiHeader.vue'
-import chooseChannelDialog from './gb28181/chooseChannel.vue'
+import chooseChannelDialog from './dialog/chooseChannel.vue'
export default {
name: 'app',
components: {
diff --git a/web_src/src/components/PushVideoList.vue b/web_src/src/components/PushVideoList.vue
index 60a5c9e..4a93d7a 100644
--- a/web_src/src/components/PushVideoList.vue
+++ b/web_src/src/components/PushVideoList.vue
@@ -1,5 +1,5 @@
<template>
- <div id="app">
+ <div id="pushVideoList">
<el-container>
<el-header>
<uiHeader></uiHeader>
@@ -7,28 +7,27 @@
<el-main>
<div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;">
<span style="font-size: 1rem; font-weight: bold;">鎺ㄦ祦鍒楄〃</span>
- <div style="position: absolute; right: 1rem; top: 0.3rem;">
- <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button>
- </div>
</div>
- <!-- <devicePlayer ref="devicePlayer"></devicePlayer> -->
- <el-table :data="deviceList" border style="width: 100%" :height="winHeight">
- <el-table-column prop="schema" label="鍗忚" width="180" align="center">
+ <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
+ <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">娣诲姞浠g悊</el-button>
+ </div>
+ <devicePlayer ref="devicePlayer"></devicePlayer>
+ <el-table :data="pushList" border style="width: 100%" :height="winHeight">
+ <el-table-column prop="app" label="APP" width="180" align="center">
</el-table-column>
- <el-table-column prop="streamUrl" label="娴佸湴鍧�" width="240" align="center">
+ <el-table-column prop="stream" label="娴両D" width="240" align="center">
</el-table-column>
- <el-table-column prop="online" label="鍦ㄧ嚎浜烘暟" width="240" align="center">
+ <el-table-column prop="totalReaderCount" label="鍦ㄧ嚎浜烘暟" width="240" align="center">
</el-table-column>
- <el-table-column prop="startTime" label="寮�濮嬫椂闂�" align="center">
+ <el-table-column prop="createStamp" label="寮�濮嬫椂闂�" align="center">
</el-table-column>
<el-table-column label="鎿嶄綔" width="360" align="center" fixed="right">
<template slot-scope="scope">
- <el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " icon="el-icon-refresh" @click="refDevice(scope.row)">鍒锋柊</el-button>
<el-button-group>
- <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">鎾斁</el-button>
- <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" @click="stopDevicePush(scope.row)">鍋滄</el-button>
+ <el-button size="mini" icon="el-icon-video-play" @click="playPuhsh(scope.row)">鎾斁</el-button>
+ <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" @click="stopPuhsh(scope.row)">鍋滄</el-button>
</el-button-group>
</template>
</el-table-column>
@@ -43,25 +42,27 @@
layout="total, sizes, prev, pager, next"
:total="total">
</el-pagination>
-
+ <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit>
</el-main>
</el-container>
</div>
</template>
<script>
+ import streamProxyEdit from './dialog/StreamProxyEdit.vue'
+ import devicePlayer from './dialog/devicePlayer.vue'
import uiHeader from './UiHeader.vue'
export default {
- name: 'app',
+ name: 'pushVideoList',
components: {
+ devicePlayer,
+ streamProxyEdit,
uiHeader
},
data() {
return {
- deviceList: [], //璁惧鍒楄〃
- currentDevice: {}, //褰撳墠鎿嶄綔璁惧瀵硅薄
-
- videoComponentList: [],
+ pushList: [], //璁惧鍒楄〃
+ currentPusher: {}, //褰撳墠鎿嶄綔璁惧瀵硅薄
updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織
currentDeviceChannelsLenth:0,
winHeight: window.innerHeight - 200,
@@ -72,23 +73,10 @@
};
},
computed: {
- getcurrentDeviceChannels: function() {
- let data = this.currentDevice['channelMap'];
- let channels = null;
- if (data) {
- channels = Object.keys(data).map(key => {
- return data[key];
- });
- this.currentDeviceChannelsLenth = channels.length;
- }
-
- console.log("鏁版嵁锛�" + JSON.stringify(channels));
- return channels;
- }
},
mounted() {
this.initData();
- this.updateLooper = setInterval(this.initData, 10000);
+ // this.updateLooper = setInterval(this.initData, 10000);
},
destroyed() {
this.$destroy('videojs');
@@ -96,20 +84,20 @@
},
methods: {
initData: function() {
- this.getDeviceList();
+ this.getPushList();
},
currentChange: function(val){
this.currentPage = val;
- this.getDeviceList();
+ this.getPushList();
},
handleSizeChange: function(val){
this.count = val;
- this.getDeviceList();
+ this.getPushList();
},
- getDeviceList: function() {
+ getPushList: function() {
let that = this;
this.getDeviceListLoading = true;
- this.$axios.get(`/api/devices`,{
+ this.$axios.get(`/api/media/list`,{
params: {
page: that.currentPage,
count: that.count
@@ -119,83 +107,44 @@
console.log(res);
console.log(res.data.list);
that.total = res.data.total;
- that.deviceList = res.data.list;
+ that.pushList = res.data.list;
that.getDeviceListLoading = false;
})
.catch(function (error) {
console.log(error);
that.getDeviceListLoading = false;
});
-
},
- showChannelList: function(row) {
- console.log(JSON.stringify(row))
- this.$router.push(`/channelList/${row.deviceId}/0/15/1`);
+ addStreamProxy: function(){
+ console.log(2222)
+ this.$refs.streamProxyEdit.openDialog(null, this.initData)
},
- showDevicePosition: function(row) {
- console.log(JSON.stringify(row))
- this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`);
+ saveStreamProxy: function(){
},
-
- //gb28181骞冲彴瀵规帴
- //鍒锋柊璁惧淇℃伅
- refDevice: function(itemData) {
- ///api/devices/{deviceId}/sync
- console.log("鍒锋柊瀵瑰簲璁惧:" + itemData.deviceId);
- var that = this;
- that.$refs[itemData.deviceId + 'refbtn' ].loading = true;
- this.$axios({
- method: 'post',
- url: '/api/devices/' + itemData.deviceId + '/sync'
- }).then(function(res) {
- console.log("鍒锋柊璁惧缁撴灉锛�"+JSON.stringify(res));
- if (!res.data.deviceId) {
- that.$message({
- showClose: true,
- message: res.data,
- type: 'error'
- });
- }else{
- that.$message({
- showClose: true,
- message: '璇锋眰鎴愬姛',
- type: 'success'
- });
+ playPuhsh: function(row){
+ let that = this;
+ this.getListLoading = true;
+ this.$axios.get(`/api/media/getStreamInfoByAppAndStream`,{
+ params: {
+ app: row.app,
+ stream: row.stream
}
- that.initData()
- that.$refs[itemData.deviceId + 'refbtn' ].loading = false;
- }).catch(function(e) {
- console.error(e)
- that.$refs[itemData.deviceId + 'refbtn' ].loading = false;
- });;
+ })
+ .then(function (res) {
+ that.getListLoading = false;
+ that.$refs.devicePlayer.openDialog("streamPlay", null, null, {
+ streamInfo: res.data,
+ hasAudio: true
+ });
+ })
+ .catch(function (error) {
+ console.log(error);
+ that.getListLoading = false;
+ });
},
- //閫氱煡璁惧涓婁紶濯掍綋娴�
- sendDevicePush: function(itemData) {
- // let deviceId = this.currentDevice.deviceId;
- // let channelId = itemData.channelId;
- // console.log("閫氱煡璁惧鎺ㄦ祦1锛�" + deviceId + " : " + channelId);
- // let that = this;
- // this.$axios({
- // method: 'get',
- // url: '/api/play/' + deviceId + '/' + channelId
- // }).then(function(res) {
- // let ssrc = res.data.ssrc;
- // that.$refs.devicePlayer.play(ssrc,deviceId,channelId);
- // }).catch(function(e) {
- // });
- },
- transportChange: function (row) {
- console.log(row);
- console.log(`淇敼浼犺緭鏂瑰紡涓� ${row.streamMode}锛�${row.deviceId} `);
- let that = this;
- this.$axios({
- method: 'get',
- url: '/api/devices/' + row.deviceId + '/transport/' + row.streamMode
- }).then(function(res) {
-
- }).catch(function(e) {
- });
- }
+ stopPuhsh: function(row){
+ console.log(row)
+ }
}
};
diff --git a/web_src/src/components/StreamProxyList.vue b/web_src/src/components/StreamProxyList.vue
new file mode 100644
index 0000000..0a1e03d
--- /dev/null
+++ b/web_src/src/components/StreamProxyList.vue
@@ -0,0 +1,297 @@
+<template>
+ <div id="streamProxyList">
+ <el-container>
+ <el-header>
+ <uiHeader></uiHeader>
+ </el-header>
+ <el-main>
+ <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;">
+ <span style="font-size: 1rem; font-weight: bold;">鎷夋祦浠g悊鍒楄〃</span>
+ </div>
+ <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
+ <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">娣诲姞浠g悊</el-button>
+ </div>
+ <devicePlayer ref="devicePlayer"></devicePlayer>
+ <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight">
+ <el-table-column prop="app" label="搴旂敤鍚�" align="center" show-overflow-tooltip/>
+ <el-table-column prop="stream" label="娴両D" align="center" show-overflow-tooltip/>
+ <el-table-column label="娴佸湴鍧�" width="400" align="center" show-overflow-tooltip >
+ <template slot-scope="scope">
+ <div slot="reference" class="name-wrapper">
+
+ <el-tag size="medium" v-if="scope.row.type == 'default'">
+ <i class="cpoy-btn el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="scope.row.url" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></i>
+ {{scope.row.url}}
+ </el-tag>
+ <el-tag size="medium" v-if="scope.row.type != 'default'">
+ <i class="cpoy-btn el-icon-document-copy" title="鐐瑰嚮鎷疯礉" v-clipboard="scope.row.src_url" @success="$message({type:'success', message:'鎴愬姛鎷疯礉鍒扮矘璐存澘'})"></i>
+ {{scope.row.src_url}}
+ </el-tag>
+ </div>
+ </template>
+ </el-table-column>
+
+ <el-table-column label="杞琀LS" width="120" align="center">
+ <template slot-scope="scope">
+ <div slot="reference" class="name-wrapper">
+ <el-tag size="medium" v-if="scope.row.enable_hls">宸插惎鐢�</el-tag>
+ <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">鏈惎鐢�</el-tag>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column label="MP4褰曞埗" width="120" align="center">
+ <template slot-scope="scope">
+ <div slot="reference" class="name-wrapper">
+ <el-tag size="medium" v-if="scope.row.enable_mp4">宸插惎鐢�</el-tag>
+ <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">鏈惎鐢�</el-tag>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍚敤" width="120" align="center">
+ <template slot-scope="scope">
+ <div slot="reference" class="name-wrapper">
+ <el-tag size="medium" v-if="scope.row.enable">宸插惎鐢�</el-tag>
+ <el-tag size="medium" type="info" v-if="!scope.row.enable">鏈惎鐢�</el-tag>
+ </div>
+ </template>
+ </el-table-column>
+
+
+ <el-table-column label="鎿嶄綔" width="360" align="center" fixed="right">
+ <template slot-scope="scope">
+ <el-button-group>
+ <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.enable" @click="play(scope.row)">鎾斁</el-button>
+ <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">鍋滅敤</el-button>
+ <el-button size="mini" icon="el-icon-check" type="primary" v-if="!scope.row.enable" @click="start(scope.row)">鍚敤</el-button>
+ <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">鍒犻櫎</el-button>
+ </el-button-group>
+ </template>
+ </el-table-column>
+ </el-table>
+ <el-pagination
+ style="float: right"
+ @size-change="handleSizeChange"
+ @current-change="currentChange"
+ :current-page="currentPage"
+ :page-size="count"
+ :page-sizes="[15, 25, 35, 50]"
+ layout="total, sizes, prev, pager, next"
+ :total="total">
+ </el-pagination>
+ <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit>
+ </el-main>
+ </el-container>
+ </div>
+</template>
+
+<script>
+ import streamProxyEdit from './dialog/StreamProxyEdit.vue'
+ import devicePlayer from './dialog/devicePlayer.vue'
+ import uiHeader from './UiHeader.vue'
+ export default {
+ name: 'streamProxyList',
+ components: {
+ devicePlayer,
+ streamProxyEdit,
+ uiHeader
+ },
+ data() {
+ return {
+ streamProxyList: [],
+ currentPusher: {}, //褰撳墠鎿嶄綔璁惧瀵硅薄
+ updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織
+ currentDeviceChannelsLenth:0,
+ winHeight: window.innerHeight - 200,
+ currentPage:1,
+ count:15,
+ total:0,
+ getListLoading: false
+ };
+ },
+ computed: {
+ },
+ mounted() {
+ this.initData();
+ // this.updateLooper = setInterval(this.initData, 10000);
+ },
+ destroyed() {
+ this.$destroy('videojs');
+ clearTimeout(this.updateLooper);
+ },
+ methods: {
+ initData: function() {
+ this.getStreamProxyList();
+ },
+ currentChange: function(val){
+ this.currentPage = val;
+ this.getStreamProxyList();
+ },
+ handleSizeChange: function(val){
+ this.count = val;
+ this.getStreamProxyList();
+ },
+ getStreamProxyList: function() {
+ let that = this;
+ this.getListLoading = true;
+ this.$axios.get(`/api/proxy/list`,{
+ params: {
+ page: that.currentPage,
+ count: that.count
+ }
+ } )
+ .then(function (res) {
+ console.log(res);
+ console.log(res.data.list);
+ that.total = res.data.total;
+ that.streamProxyList = res.data.list;
+ that.getListLoading = false;
+ })
+ .catch(function (error) {
+ console.log(error);
+ that.getListLoading = false;
+ });
+ },
+ addStreamProxy: function(){
+ this.$refs.streamProxyEdit.openDialog(null, this.initData)
+ },
+ saveStreamProxy: function(){
+ },
+ play: function(row){
+ let that = this;
+ this.getListLoading = true;
+ this.$axios.get(`/api/media/getStreamInfoByAppAndStream`,{
+ params: {
+ app: row.app,
+ stream: row.stream
+ }
+ })
+ .then(function (res) {
+ that.getListLoading = false;
+ that.$refs.devicePlayer.openDialog("streamPlay", null, null, {
+ streamInfo: res.data,
+ hasAudio: true
+ });
+ })
+ .catch(function (error) {
+ console.log(error);
+ that.getListLoading = false;
+ });
+
+ },
+ deleteStreamProxy: function(row){
+ console.log(1111)
+ let that = this;
+ this.getListLoading = true;
+ this.$axios.get(`/api/proxy/del`,{
+ params: {
+ app: row.app,
+ stream: row.stream
+ }
+ })
+ .then(function (res) {
+ that.getListLoading = false;
+ that.initData()
+ })
+ .catch(function (error) {
+ console.log(error);
+ that.getListLoading = false;
+ });
+ },
+ start: function(row){
+ let that = this;
+ this.getListLoading = true;
+ this.$axios.get(`/api/proxy/start`,{
+ params: {
+ app: row.app,
+ stream: row.stream
+ }
+ })
+ .then(function (res) {
+ that.getListLoading = false;
+ that.initData()
+ })
+ .catch(function (error) {
+ console.log(error);
+ that.getListLoading = false;
+ });
+ },
+ stop: function(row){
+ let that = this;
+ this.getListLoading = true;
+ this.$axios.get(`/api/proxy/stop`,{
+ params: {
+ app: row.app,
+ stream: row.stream
+ }
+ })
+ .then(function (res) {
+ that.getListLoading = false;
+ that.initData()
+ })
+ .catch(function (error) {
+ console.log(error);
+ that.getListLoading = false;
+ });
+ }
+
+ }
+ };
+</script>
+
+<style>
+ .videoList {
+ display: flex;
+ flex-wrap: wrap;
+ align-content: flex-start;
+ }
+
+ .video-item {
+ position: relative;
+ width: 15rem;
+ height: 10rem;
+ margin-right: 1rem;
+ background-color: #000000;
+ }
+
+ .video-item-img {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ margin: auto;
+ width: 100%;
+ height: 100%;
+ }
+
+ .video-item-img:after {
+ content: "";
+ display: inline-block;
+ position: absolute;
+ z-index: 2;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ margin: auto;
+ width: 3rem;
+ height: 3rem;
+ background-image: url("../assets/loading.png");
+ background-size: cover;
+ background-color: #000000;
+ }
+
+ .video-item-title {
+ position: absolute;
+ bottom: 0;
+ color: #000000;
+ background-color: #ffffff;
+ line-height: 1.5rem;
+ padding: 0.3rem;
+ width: 14.4rem;
+ }
+ .cpoy-btn {
+ cursor: pointer;
+ margin-right: 10px;
+ }
+</style>
diff --git a/web_src/src/components/UiHeader.vue b/web_src/src/components/UiHeader.vue
index fa1c442..ae0780b 100644
--- a/web_src/src/components/UiHeader.vue
+++ b/web_src/src/components/UiHeader.vue
@@ -4,6 +4,7 @@
<el-menu-item index="/">鎺у埗鍙�</el-menu-item>
<el-menu-item index="/deviceList">璁惧鍒楄〃</el-menu-item>
<el-menu-item index="/pushVideoList">鎺ㄦ祦鍒楄〃</el-menu-item>
+ <el-menu-item index="/streamProxyList">鎷夋祦浠g悊</el-menu-item>
<el-menu-item index="/parentPlatformList/15/1">鍥芥爣绾ц仈</el-menu-item>
<el-switch v-model="alarmNotify" active-text="鎶ヨ淇℃伅鎺ㄩ��" style="display: block float: right" @change="sseControl"></el-switch>
<el-menu-item style="float: right;" @click="loginout">閫�鍑�</el-menu-item>
diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue
index 6d893ce..b06ce25 100644
--- a/web_src/src/components/channelList.vue
+++ b/web_src/src/components/channelList.vue
@@ -75,7 +75,7 @@
</template>
<script>
-import devicePlayer from './gb28181/devicePlayer.vue'
+import devicePlayer from './dialog/devicePlayer.vue'
import uiHeader from './UiHeader.vue'
import moment from "moment";
export default {
diff --git a/web_src/src/components/dialog/StreamProxyEdit.vue b/web_src/src/components/dialog/StreamProxyEdit.vue
new file mode 100644
index 0000000..a2b3c9e
--- /dev/null
+++ b/web_src/src/components/dialog/StreamProxyEdit.vue
@@ -0,0 +1,186 @@
+<template>
+ <div id="addStreamProxy" v-loading="isLoging">
+ <el-dialog
+ title="娣诲姞浠g悊"
+ width="40%"
+ top="2rem"
+ :close-on-click-modal="false"
+ :visible.sync="showDialog"
+ :destroy-on-close="true"
+ @close="close()"
+ >
+ <div id="shared" style="margin-top: 1rem;margin-right: 100px;">
+ <el-form ref="streamProxy" :rules="rules" :model="proxyParam" label-width="140px">
+ <el-form-item label="绫诲瀷" prop="type">
+ <el-select
+ v-model="proxyParam.type"
+ style="width: 100%"
+ placeholder="璇烽�夋嫨浠g悊绫诲瀷"
+ >
+ <el-option label="榛樿" value="default"></el-option>
+ <el-option label="FFmpeg" value="ffmpeg"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="搴旂敤鍚�" prop="app">
+ <el-input v-model="proxyParam.app" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="娴両D" prop="stream">
+ <el-input v-model="proxyParam.stream" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="鎷夋祦鍦板潃" prop="url" v-if="proxyParam.type=='default'">
+ <el-input v-model="proxyParam.url" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="鎷夋祦鍦板潃" prop="src_url" v-if="proxyParam.type=='ffmpeg'">
+ <el-input v-model="proxyParam.src_url" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="瓒呮椂鏃堕棿" prop="timeout_ms" v-if="proxyParam.type=='ffmpeg'">
+ <el-input v-model="proxyParam.timeout_ms" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="FFmpeg鍛戒护妯℃澘" prop="ffmpeg_cmd_key" v-if="proxyParam.type=='ffmpeg'">
+ <el-input v-model="proxyParam.ffmpeg_cmd_key" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="鎷夋祦鏂瑰紡" prop="rtp_type" v-if="proxyParam.type=='default'">
+ <el-select
+ v-model="proxyParam.rtp_type"
+ style="width: 100%"
+ placeholder="璇烽�夋嫨鎷夋祦鏂瑰紡"
+ >
+ <el-option label="TCP" value="0"></el-option>
+ <el-option label="UDP" value="1"></el-option>
+ <el-option label="缁勬挱" value="2"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍏朵粬閫夐」">
+ <div style="float: left;">
+ <el-checkbox label="鍚敤" v-model="proxyParam.enable" ></el-checkbox>
+ <el-checkbox label="杞琀LS" v-model="proxyParam.enable_hls" ></el-checkbox>
+ <el-checkbox label="MP4褰曞埗" v-model="proxyParam.enable_mp4" ></el-checkbox>
+ </div>
+
+ </el-form-item>
+ <el-form-item>
+ <div style="float: right;">
+ <el-button type="primary" @click="onSubmit">{{onSubmit_text}}</el-button>
+ <el-button @click="close">鍙栨秷</el-button>
+ </div>
+
+ </el-form-item>
+ </el-form>
+ </div>
+ </el-dialog>
+ </div>
+</template>
+
+<script>
+export default {
+ name: "streamProxyEdit",
+ props: {},
+ computed: {},
+ created() {},
+ data() {
+ // var deviceGBIdRules = async (rule, value, callback) => {
+ // console.log(value);
+ // if (value === "") {
+ // callback(new Error("璇疯緭鍏ヨ澶囧浗鏍囩紪鍙�"));
+ // } else {
+ // var exit = await this.deviceGBIdExit(value);
+ // console.log(exit);
+ // console.log(exit == "true");
+ // console.log(exit === "true");
+ // if (exit) {
+ // callback(new Error("璁惧鍥芥爣缂栧彿宸插瓨鍦�"));
+ // } else {
+ // callback();
+ // }
+ // }
+ // };
+ return {
+ listChangeCallback: null,
+ showDialog: false,
+ isLoging: false,
+ onSubmit_text: "绔嬪嵆鍒涘缓",
+ proxyParam: {
+ type: "default",
+ app: null,
+ stream: null,
+ url: "rtmp://58.200.131.2:1935/livetv/hunantv",
+ src_url: null,
+ timeout_ms: null,
+ ffmpeg_cmd_key: null,
+ rtp_type: null,
+ enable: true,
+ enable_hls: true,
+ enable_mp4: false,
+ },
+
+ rules: {
+ app: [{ required: true, message: "璇疯緭鍏ュ簲鐢ㄥ悕", trigger: "blur" }],
+ stream: [{ required: true, message: "璇疯緭鍏ユ祦ID", trigger: "blur" }],
+ url: [{ required: true, message: "璇疯緭鍏ヨ浠g悊鐨勬祦", trigger: "blur" }],
+ src_url: [{ required: true, message: "璇疯緭鍏ヨ浠g悊鐨勬祦", trigger: "blur" }],
+ timeout_ms: [{ required: true, message: "璇疯緭鍏Fmpeg鎺ㄦ祦鎴愬姛瓒呮椂鏃堕棿", trigger: "blur" }],
+ ffmpeg_cmd_key: [{ required: false, message: "璇疯緭鍏Fmpeg鍛戒护鍙傛暟妯℃澘锛堝彲閫夛級", trigger: "blur" }],
+ },
+ };
+ },
+ methods: {
+ openDialog: function (proxyParam, callback) {
+ this.showDialog = true;
+ this.listChangeCallback = callback;
+ if (proxyParam != null) {
+ this.proxyParam = proxyParam;
+ this.onSubmit_text = "淇濆瓨";
+ } else {
+ this.onSubmit_text = "绔嬪嵆鍒涘缓";
+ }
+ },
+ onSubmit: function () {
+ console.log("onSubmit");
+ var that = this;
+ that.$axios
+ .post(`/api/proxy/save`, that.proxyParam)
+ .then(function (res) {
+ console.log(res);
+ console.log(res.data == "success");
+ if (res.data == "success") {
+ that.$message({
+ showClose: true,
+ message: "淇濆瓨鎴愬姛",
+ type: "success",
+ });
+ that.showDialog = false;
+ if (that.listChangeCallback != null) {
+ that.listChangeCallback();
+ }
+ }
+ })
+ .catch(function (error) {
+ console.log(error);
+ });
+ },
+ close: function () {
+ console.log("鍏抽棴娣诲姞瑙嗛骞冲彴");
+ this.showDialog = false;
+ this.$refs.streamProxy.resetFields();
+ },
+ deviceGBIdExit: async function (deviceGbId) {
+ var result = false;
+ var that = this;
+ await that.$axios
+ .post(`/api/platforms/exit/${deviceGbId}`)
+ .then(function (res) {
+ result = res.data;
+ })
+ .catch(function (error) {
+ console.log(error);
+ });
+ return result;
+ },
+ checkExpires: function() {
+ if (this.platform.enable && this.platform.expires == "0") {
+ this.platform.expires = "300";
+ }
+ }
+ },
+};
+</script>
diff --git a/web_src/src/components/gb28181/chooseChannel.vue b/web_src/src/components/dialog/chooseChannel.vue
similarity index 97%
rename from web_src/src/components/gb28181/chooseChannel.vue
rename to web_src/src/components/dialog/chooseChannel.vue
index 810ebd3..219036c 100644
--- a/web_src/src/components/gb28181/chooseChannel.vue
+++ b/web_src/src/components/dialog/chooseChannel.vue
@@ -21,7 +21,7 @@
</template>
<script>
-import chooseChannelForGb from './chooseChannelForGb.vue'
+import chooseChannelForGb from '../dialog/chooseChannelForGb.vue'
export default {
name: 'chooseChannel',
props: {},
diff --git a/web_src/src/components/gb28181/chooseChannelForGb.vue b/web_src/src/components/dialog/chooseChannelForGb.vue
similarity index 100%
rename from web_src/src/components/gb28181/chooseChannelForGb.vue
rename to web_src/src/components/dialog/chooseChannelForGb.vue
diff --git a/web_src/src/components/gb28181/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue
similarity index 98%
rename from web_src/src/components/gb28181/devicePlayer.vue
rename to web_src/src/components/dialog/devicePlayer.vue
index 2341831..48d295a 100644
--- a/web_src/src/components/gb28181/devicePlayer.vue
+++ b/web_src/src/components/dialog/devicePlayer.vue
@@ -26,7 +26,7 @@
</div>
</el-tab-pane>
<!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
- <el-tab-pane label="褰曞儚鏌ヨ" name="record">
+ <el-tab-pane label="褰曞儚鏌ヨ" name="record" v-if="showRrecord">
<el-date-picker size="mini" v-model="videoHistory.date" type="date" value-format="yyyy-MM-dd" placeholder="鏃ユ湡" @change="queryRecords()"></el-date-picker>
<el-table :data="videoHistory.searchHistoryResult" height="150" v-loading="recordsLoading">
<el-table-column label="鍚嶇О" prop="name"></el-table-column>
@@ -42,7 +42,7 @@
</el-table>
</el-tab-pane>
<!--閬ユ帶鐣岄潰-->
- <el-tab-pane label="浜戝彴鎺у埗" name="control">
+ <el-tab-pane label="浜戝彴鎺у埗" name="control" v-if="showPtz">
<div style="display: flex; justify-content: left;">
<div class="control-wrapper">
<div class="control-btn control-top" @mousedown="ptzCamera(0, 2, 0)" @mouseup="ptzCamera(0, 0, 0)">
@@ -136,7 +136,7 @@
</template>
<script>
-import player from './player.vue'
+import player from '../dialog/player.vue'
export default {
name: 'devicePlayer',
props: {},
@@ -184,7 +184,9 @@
tracks: [],
coverPlaying:false,
tracksLoading: false,
- recordPlay: ""
+ recordPlay: "",
+ showPtz: true,
+ showRrecord: true,
};
},
methods: {
@@ -230,6 +232,11 @@
this.videoHistory.date = param.date;
this.queryRecords()
break;
+ case "streamPlay":
+ this.showRrecord = false,
+ this.showPtz = false,
+ this.play(param.streamInfo, param.hasAudio)
+ break;
case "control":
break;
}
diff --git a/web_src/src/components/platformEdit.vue b/web_src/src/components/dialog/platformEdit.vue
similarity index 100%
rename from web_src/src/components/platformEdit.vue
rename to web_src/src/components/dialog/platformEdit.vue
diff --git a/web_src/src/components/gb28181/player.vue b/web_src/src/components/dialog/player.vue
similarity index 100%
rename from web_src/src/components/gb28181/player.vue
rename to web_src/src/components/dialog/player.vue
diff --git a/web_src/src/main.js b/web_src/src/main.js
index 197fa17..ed1f36c 100644
--- a/web_src/src/main.js
+++ b/web_src/src/main.js
@@ -11,6 +11,8 @@
import VueClipboard from 'vue-clipboard2';
import { Notification } from 'element-ui';
import Fingerprint2 from 'fingerprintjs2';
+import VueClipboards from 'vue-clipboards';
+
// 鐢熸垚鍞竴ID
Fingerprint2.get(function(components) {
@@ -32,6 +34,7 @@
Vue.use(VueClipboard);
Vue.use(ElementUI);
Vue.use(VueCookies);
+Vue.use(VueClipboards);
Vue.prototype.$axios = axios;
Vue.prototype.$notify = Notification;
diff --git a/web_src/src/router/index.js b/web_src/src/router/index.js
index fc55dd5..4735e62 100644
--- a/web_src/src/router/index.js
+++ b/web_src/src/router/index.js
@@ -5,6 +5,7 @@
import deviceList from '../components/DeviceList.vue'
import channelList from '../components/channelList.vue'
import pushVideoList from '../components/PushVideoList.vue'
+import streamProxyList from '../components/StreamProxyList.vue'
import devicePosition from '../components/devicePosition.vue'
import login from '../components/Login.vue'
import parentPlatformList from '../components/ParentPlatformList.vue'
@@ -33,6 +34,10 @@
component: pushVideoList,
},
{
+ path: '/streamProxyList',
+ component: streamProxyList,
+ },
+ {
path: '/login',
name: '鐧诲綍',
component: login,
--
Gitblit v1.8.0