From 720231d33f387c6d1bf13bdef653314c5c450809 Mon Sep 17 00:00:00 2001
From: 648540858 <18010473990@163.com>
Date: 星期六, 25 九月 2021 22:12:15 +0800
Subject: [PATCH] 添加发送媒体流, 添加媒体服务器节点管理ui,修复修改密码
---
web_src/src/components/service/MediaServer.js | 55 +++
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java | 26 +
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java | 29 +
web_src/src/components/CloudRecord.vue | 2
web_src/src/components/dialog/MediaServerEdit.vue | 368 +++++++++++++++++++++++
web_src/static/images/zlm-logo.png | 0
web_src/src/components/dialog/deviceEdit.vue | 2
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java | 13
sql/mysql.sql | 1
web_src/src/components/MediaServerManger.vue | 159 +++++++++
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java | 166 ++++++++-
src/main/resources/application-dev.yml | 2
web_src/src/components/UiHeader.vue | 1
web_src/src/components/dialog/StreamProxyEdit.vue | 2
web_src/src/components/DeviceList.vue | 2
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java | 6
web_src/src/components/dialog/changePassword.vue | 2
src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java | 3
web_src/static/css/iconfont.css | 10
src/main/resources/wvp.sqlite | 0
web_src/build/webpack.base.conf.js | 1
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java | 7
src/main/resources/all-application.yml | 2
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java | 60 +++
web_src/src/assets/zlm-log.png | 0
web_src/static/css/iconfont.woff2 | 0
src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java | 3
web_src/src/components/control.vue | 2
web_src/src/router/index.js | 6
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java | 7
30 files changed, 890 insertions(+), 47 deletions(-)
diff --git a/sql/mysql.sql b/sql/mysql.sql
index 90393e6..6f44ce8 100644
--- a/sql/mysql.sql
+++ b/sql/mysql.sql
@@ -140,6 +140,7 @@
streamNoneReaderDelayMS int not null,
rtpEnable int not null,
rtpPortRange varchar(50) not null,
+ sendRtpPortRange varchar(50) not null,
recordAssistPort int not null,
defaultServer int not null,
createTime varchar(50) not null,
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 9831ddb..08d030a 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
@@ -18,6 +18,9 @@
import java.io.IOException;
import java.text.SimpleDateFormat;
+/**
+ * @author lin
+ */
@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/api/*", asyncSupported=true)
public class ApiAccessFilter extends OncePerRequestFilter {
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
index 72cefe1..e608361 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
@@ -68,6 +68,10 @@
@Value("${media.rtp.port-range}")
private String rtpPortRange;
+
+ @Value("${media.rtp.send-port-range}")
+ private String sendRtpPortRange;
+
@Value("${media.record-assist-port:0}")
private Integer recordAssistPort = 0;
@@ -165,6 +169,14 @@
}
}
+ public String getSipDomain() {
+ return sipDomain;
+ }
+
+ public String getSendRtpPortRange() {
+ return sendRtpPortRange;
+ }
+
public MediaServerItem getMediaSerItem(){
MediaServerItem mediaServerItem = new MediaServerItem();
mediaServerItem.setId(id);
@@ -185,6 +197,7 @@
mediaServerItem.setStreamNoneReaderDelayMS(streamNoneReaderDelayMS);
mediaServerItem.setRtpEnable(rtpEnable);
mediaServerItem.setRtpPortRange(rtpPortRange);
+ mediaServerItem.setSendRtpPortRange(sendRtpPortRange);
mediaServerItem.setRecordAssistPort(recordAssistPort);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
index 907e30d..5d8acce 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
@@ -21,6 +21,9 @@
import java.io.IOException;
import java.net.ConnectException;
+/**
+ * @author lin
+ */
@SuppressWarnings(value = {"rawtypes", "unchecked"})
@Configuration
public class ProxyServletConfig {
@@ -35,7 +38,7 @@
@Bean
public ServletRegistrationBean zlmServletRegistrationBean(){
- ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ZLMProxySerlet(),"/zlm/*");
+ ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ZlmProxyServlet(),"/zlm/*");
servletRegistrationBean.setName("zlm_Proxy");
servletRegistrationBean.addInitParameter("targetUri", "http://127.0.0.1:6080");
servletRegistrationBean.addUrlMappings();
@@ -45,7 +48,7 @@
return servletRegistrationBean;
}
- class ZLMProxySerlet extends ProxyServlet{
+ class ZlmProxyServlet extends ProxyServlet{
@Override
protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
index bd56401..b4d1048 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
@@ -8,6 +8,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
@@ -44,8 +45,15 @@
Map<String, Object> param = new HashMap<>();
int result = -1;
- int newPort = getPortFromportRange(mediaServerItem);
- param.put("port", newPort);
+ /**
+ * 涓嶈缃帹娴佺鍙g鍒欎娇鐢ㄩ殢鏈虹鍙�
+ */
+ if (StringUtils.isEmpty(mediaServerItem.getSendRtpPortRange())){
+ param.put("port", 0);
+ }else {
+ int newPort = getPortFromportRange(mediaServerItem);
+ param.put("port", newPort);
+ }
param.put("enable_tcp", 1);
param.put("stream_id", streamId);
JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
@@ -53,24 +61,24 @@
if (openRtpServerResultJson != null) {
switch (openRtpServerResultJson.getInteger("code")){
case 0:
- result= newPort;
+ result= openRtpServerResultJson.getInteger("port");
break;
case -300: // id宸茬粡瀛樺湪, 鍙兘宸茬粡鍦ㄥ叾浠栫鍙f帹娴�
Map<String, Object> closeRtpServerParam = new HashMap<>();
closeRtpServerParam.put("stream_id", streamId);
zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam);
- result = newPort;
+ result = createRTPServer(mediaServerItem, streamId);;
break;
case -400: // 绔彛鍗犵敤
result= createRTPServer(mediaServerItem, streamId);
break;
default:
- logger.error("鍒涘缓RTP Server 澶辫触 {}: " + openRtpServerResultJson.getString("msg"), newPort);
+ logger.error("鍒涘缓RTP Server 澶辫触 {}: " + openRtpServerResultJson.getString("msg"), param.get("port"));
break;
}
}else {
// 妫�鏌LM鐘舵��
- logger.error("鍒涘缓RTP Server 澶辫触 {}: 璇锋鏌LM鏈嶅姟", newPort);
+ logger.error("鍒涘缓RTP Server 澶辫触 {}: 璇锋鏌LM鏈嶅姟", param.get("port"));
}
return result;
}
@@ -98,7 +106,7 @@
private int getPortFromportRange(MediaServerItem mediaServerItem) {
int currentPort = mediaServerItem.getCurrentPort();
if (currentPort == 0) {
- String[] portRangeStrArray = mediaServerItem.getRtpPortRange().split(",");
+ String[] portRangeStrArray = mediaServerItem.getSendRtpPortRange().split(",");
portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]);
portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]);
}
@@ -229,7 +237,9 @@
*/
public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) {
JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
- if (mediaInfo == null) return 0;
+ if (mediaInfo == null) {
+ return 0;
+ }
return mediaInfo.getInteger("totalReaderCount");
}
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 187cbc1..7faebfa 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
@@ -108,8 +108,10 @@
}
public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) {
- if (startGetMedia == null) return null;
- if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) return null;
+ if (startGetMedia == null) { return null;}
+ if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) {
+ return null;
+ }
JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
ZLMServerConfig ZLMServerConfig = null;
if (responseJSON != null) {
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
index d1578d1..087c10a 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
@@ -41,13 +41,19 @@
private boolean rtpEnable;
+ private boolean status;
+
private String rtpPortRange;
+
+ private String sendRtpPortRange;
private int recordAssistPort;
private String createTime;
private String updateTime;
+
+ private String lastKeepaliveTime;
private boolean defaultServer;
@@ -82,6 +88,7 @@
secret = zlmServerConfig.getApiSecret();
streamNoneReaderDelayMS = zlmServerConfig.getGeneralStreamNoneReaderDelayMS();
rtpEnable = false; // 榛樿浣跨敤鍗曠鍙�;鐩村埌鐢ㄦ埛鑷繁璁剧疆寮�鍚绔彛
+ rtpPortRange = "30000,30500"; // 榛樿浣跨敤30000,30500浣滀负绾ц仈鏃跺彂閫佹祦鐨勭鍙e彿
recordAssistPort = 0; // 榛樿鍏抽棴
}
@@ -278,5 +285,27 @@
this.currentPort = currentPort;
}
+ public boolean isStatus() {
+ return status;
+ }
+ public void setStatus(boolean status) {
+ this.status = status;
+ }
+
+ public String getLastKeepaliveTime() {
+ return lastKeepaliveTime;
+ }
+
+ public void setLastKeepaliveTime(String lastKeepaliveTime) {
+ this.lastKeepaliveTime = lastKeepaliveTime;
+ }
+
+ public String getSendRtpPortRange() {
+ return sendRtpPortRange;
+ }
+
+ public void setSendRtpPortRange(String sendRtpPortRange) {
+ this.sendRtpPortRange = sendRtpPortRange;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
index f65a155..81cf8f1 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -4,6 +4,7 @@
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
+import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import java.util.List;
@@ -49,7 +50,11 @@
void clearMediaServerForOnline();
- void add(MediaServerItem mediaSerItem);
+ WVPResult<String> add(MediaServerItem mediaSerItem);
void resetOnlineServerItem(MediaServerItem serverItem);
+
+ WVPResult<MediaServerItem> checkMediaServer(String ip, int port, String secret);
+
+ boolean checkMediaRecordServer(String ip, int port);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
index 33c0051..18c1b93 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.service.impl;
+import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
@@ -14,10 +15,11 @@
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.MediaServerMapper;
import com.genersoft.iot.vmp.utils.redis.JedisUtil;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
+import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
+import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -57,9 +59,6 @@
private MediaServerMapper mediaServerMapper;
@Autowired
- private IRedisCatchStorage redisCatchStorage;
-
- @Autowired
private VideoStreamSessionManager streamSession;
@Autowired
@@ -97,7 +96,9 @@
@Override
public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId) {
- if (mediaServerItem == null || mediaServerItem.getId() == null) return null;
+ if (mediaServerItem == null || mediaServerItem.getId() == null) {
+ return null;
+ }
// 鑾峰彇mediaServer鍙敤鐨剆src
String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId();
@@ -107,7 +108,9 @@
return null;
}else {
String ssrc = ssrcConfig.getPlaySsrc();
- if (streamId == null) streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
+ if (streamId == null) {
+ streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
+ }
int rtpServerPort = mediaServerItem.getRtpProxyPort();
if (mediaServerItem.isRtpEnable()) {
rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId);
@@ -131,7 +134,9 @@
@Override
public void releaseSsrc(MediaServerItem mediaServerItem, String ssrc) {
- if (mediaServerItem == null || ssrc == null) return;
+ if (mediaServerItem == null || ssrc == null) {
+ return;
+ }
SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig();
ssrcConfig.releaseSsrc(ssrc);
mediaServerItem.setSsrcConfig(ssrcConfig);
@@ -141,7 +146,6 @@
/**
* zlm 閲嶅惎鍚庨噸缃粬鐨勬帹娴佷俊鎭紝 TODO 缁欐鍦ㄤ娇鐢ㄧ殑璁惧鍙戦�佸仠姝㈠懡浠�
- * @param mediaServerItem
*/
@Override
public void clearRTPServer(MediaServerItem mediaServerItem) {
@@ -174,9 +178,15 @@
public List<MediaServerItem> getAll() {
List<MediaServerItem> result = new ArrayList<>();
List<Object> mediaServerKeys = redisUtil.scan(String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX));
- for (int i = 0; i < mediaServerKeys.size(); i++) {
- String key = (String) mediaServerKeys.get(i);
- result.add((MediaServerItem)redisUtil.get(key));
+ String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX;
+ for (Object mediaServerKey : mediaServerKeys) {
+ String key = (String) mediaServerKey;
+ MediaServerItem mediaServerItem = (MediaServerItem) redisUtil.get(key);
+ // 妫�鏌ョ姸鎬�
+ if (redisUtil.zScore(onlineKey, mediaServerItem.getId()) != null) {
+ mediaServerItem.setStatus(true);
+ }
+ result.add(mediaServerItem);
}
return result;
}
@@ -208,7 +218,9 @@
*/
@Override
public MediaServerItem getOne(String mediaServerId) {
- if (mediaServerId == null) return null;
+ if (mediaServerId == null) {
+ return null;
+ }
String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerId;
return (MediaServerItem)redisUtil.get(key);
}
@@ -225,8 +237,34 @@
}
@Override
- public void add(MediaServerItem mediaSerItem) {
- mediaServerMapper.add(mediaSerItem);
+ public WVPResult<String> add(MediaServerItem mediaServerItem) {
+ WVPResult<String> result = new WVPResult<>();
+ mediaServerItem.setCreateTime(this.format.format(System.currentTimeMillis()));
+ mediaServerItem.setUpdateTime(this.format.format(System.currentTimeMillis()));
+ JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
+ if (responseJSON != null) {
+ JSONArray data = responseJSON.getJSONArray("data");
+ if (data != null && data.size() > 0) {
+ ZLMServerConfig zlmServerConfig= JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
+ if (mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()) != null) {
+ result.setCode(-1);
+ result.setMsg("淇濆瓨澶辫触锛屽獟浣撴湇鍔D [ " + zlmServerConfig.getGeneralMediaServerId() + " ] 宸插瓨鍦紝璇蜂慨鏀瑰獟浣撴湇鍔″櫒閰嶇疆");
+ return result;
+ }
+ zlmServerConfig.setIp(mediaServerItem.getIp());
+ handLeZLMServerConfig(zlmServerConfig);
+ result.setCode(0);
+ result.setMsg("success");
+ }else {
+ result.setCode(-1);
+ result.setMsg("杩炴帴澶辫触");
+ }
+
+ }else {
+ result.setCode(-1);
+ result.setMsg("杩炴帴澶辫触");
+ }
+ return result;
}
/**
@@ -249,13 +287,27 @@
// docker閮ㄧ讲涓嶄細浣跨敤zlm閰嶇疆鐨勭鍙e彿涓嶆槸榛樿鐨勫垯涓嶅仛鏇存柊锛� 閰嶇疆淇敼闇�瑕佽嚜琛屼慨鏀箂erver閰嶇疆;
MediaServerItem serverItemFromConfig = mediaConfig.getMediaSerItem();
serverItemFromConfig.setId(zlmServerConfig.getGeneralMediaServerId());
- if (mediaConfig.getHttpPort() == 0) serverItemFromConfig.setHttpPort(zlmServerConfig.getHttpPort());
- if (mediaConfig.getHttpSSlPort() == 0) serverItemFromConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport());
- if (mediaConfig.getRtmpPort() == 0) serverItemFromConfig.setRtmpPort(zlmServerConfig.getRtmpPort());
- if (mediaConfig.getRtmpSSlPort() == 0) serverItemFromConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
- if (mediaConfig.getRtspPort() == 0) serverItemFromConfig.setRtspPort(zlmServerConfig.getRtspPort());
- if (mediaConfig.getRtspSSLPort() == 0) serverItemFromConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport());
- if (mediaConfig.getRtpProxyPort() == 0) serverItemFromConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
+ if (mediaConfig.getHttpPort() == 0) {
+ serverItemFromConfig.setHttpPort(zlmServerConfig.getHttpPort());
+ }
+ if (mediaConfig.getHttpSSlPort() == 0) {
+ serverItemFromConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport());
+ }
+ if (mediaConfig.getRtmpPort() == 0) {
+ serverItemFromConfig.setRtmpPort(zlmServerConfig.getRtmpPort());
+ }
+ if (mediaConfig.getRtmpSSlPort() == 0) {
+ serverItemFromConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
+ }
+ if (mediaConfig.getRtspPort() == 0) {
+ serverItemFromConfig.setRtspPort(zlmServerConfig.getRtspPort());
+ }
+ if (mediaConfig.getRtspSSLPort() == 0) {
+ serverItemFromConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport());
+ }
+ if (mediaConfig.getRtpProxyPort() == 0) {
+ serverItemFromConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
+ }
if (serverItem != null){
mediaServerMapper.delDefault();
mediaServerMapper.add(serverItemFromConfig);
@@ -319,9 +371,10 @@
@Override
public void addCount(String mediaServerId) {
- if (mediaServerId == null) return;
+ if (mediaServerId == null) {
+ return;
+ }
String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX;
- Double aDouble = redisUtil.zScore(key, mediaServerId);
redisUtil.zIncrScore(key, mediaServerId, 1);
}
@@ -399,4 +452,71 @@
}
+ @Override
+ public WVPResult<MediaServerItem> checkMediaServer(String ip, int port, String secret) {
+ WVPResult<MediaServerItem> result = new WVPResult<>();
+ if (mediaServerMapper.queryOneByHostAndPort(ip, port) != null) {
+ result.setCode(-1);
+ result.setMsg("姝よ繛鎺ュ凡瀛樺湪");
+ return result;
+ }
+ MediaServerItem mediaServerItem = new MediaServerItem();
+ mediaServerItem.setIp(ip);
+ mediaServerItem.setHttpPort(port);
+ mediaServerItem.setSecret(secret);
+ JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
+ if (responseJSON == null) {
+ result.setCode(-1);
+ result.setMsg("杩炴帴澶辫触");
+ return result;
+ }
+ JSONArray data = responseJSON.getJSONArray("data");
+ ZLMServerConfig zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
+ if (zlmServerConfig == null) {
+ result.setCode(-1);
+ result.setMsg("璇诲彇閰嶇疆澶辫触");
+ return result;
+ }
+ if (mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()) != null) {
+ result.setCode(-1);
+ result.setMsg("濯掍綋鏈嶅姟ID [" + zlmServerConfig.getGeneralMediaServerId() + " ] 宸插瓨鍦紝璇蜂慨鏀瑰獟浣撴湇鍔″櫒閰嶇疆");
+ return result;
+ }
+ mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpPort());
+ mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort());
+ mediaServerItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
+ mediaServerItem.setRtspPort(zlmServerConfig.getRtspPort());
+ mediaServerItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport());
+ mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
+ mediaServerItem.setStreamIp(ip);
+ mediaServerItem.setHookIp(sipConfig.getIp());
+ mediaServerItem.setSdpIp(ip);
+ mediaServerItem.setStreamNoneReaderDelayMS(zlmServerConfig.getGeneralStreamNoneReaderDelayMS());
+ result.setCode(0);
+ result.setMsg("鎴愬姛");
+ result.setData(mediaServerItem);
+ return result;
+ }
+
+ @Override
+ public boolean checkMediaRecordServer(String ip, int port) {
+ boolean result = false;
+ OkHttpClient client = new OkHttpClient();
+ String url = String.format("http://%s:%s/index/api/record", ip, port);
+
+ FormBody.Builder builder = new FormBody.Builder();
+
+ Request request = new Request.Builder()
+ .get()
+ .url(url)
+ .build();
+ try {
+ Response response = client.newCall(request).execute();
+ if (response != null) {
+ result = true;
+ }
+ } catch (Exception e) {}
+
+ return result;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
index 2167c55..8d45b05 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
@@ -32,6 +32,7 @@
"streamNoneReaderDelayMS, " +
"rtpEnable, " +
"rtpPortRange, " +
+ "sendRtpPortRange, " +
"recordAssistPort, " +
"defaultServer, " +
"createTime, " +
@@ -55,6 +56,7 @@
"${streamNoneReaderDelayMS}, " +
"${rtpEnable}, " +
"'${rtpPortRange}', " +
+ "'${sendRtpPortRange}', " +
"${recordAssistPort}, " +
"${defaultServer}, " +
"'${createTime}', " +
@@ -79,6 +81,7 @@
"<if test=\"streamNoneReaderDelayMS != null\">, streamNoneReaderDelayMS=${streamNoneReaderDelayMS}</if>" +
"<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" +
"<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" +
+ "<if test=\"sendRtpPortRange != null\">, sendRtpPortRange='${sendRtpPortRange}'</if>" +
"<if test=\"secret != null\">, secret='${secret}'</if>" +
"<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +
"WHERE id='${id}'"+
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
index 3bfa595..881a20a 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
@@ -57,7 +57,9 @@
@ApiOperation("娴佸獟浣撴湇鍔″垪琛�")
@GetMapping(value = "/media_server/list")
@ResponseBody
- public WVPResult<List<MediaServerItem>> getMediaServerList(){
+ public WVPResult<List<MediaServerItem>> getMediaServerList(boolean detail){
+ List<MediaServerItem> all = mediaServerService.getAll();
+
WVPResult<List<MediaServerItem>> result = new WVPResult<>();
result.setCode(0);
result.setMsg("success");
@@ -86,6 +88,60 @@
result.setData(mediaServerService.getOne(id));
return result;
}
+
+ @ApiOperation("娴嬭瘯娴佸獟浣撴湇鍔�")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name="ip", value = "娴佸獟浣撴湇鍔P", dataTypeClass = String.class),
+ @ApiImplicitParam(name="port", value = "娴佸獟浣撴湇鍔TT绔彛", dataTypeClass = Integer.class),
+ @ApiImplicitParam(name="secret", value = "娴佸獟浣撴湇鍔ecret", dataTypeClass = String.class),
+ })
+ @GetMapping(value = "/media_server/check")
+ @ResponseBody
+ public WVPResult<MediaServerItem> checkMediaServer(@RequestParam String ip, @RequestParam int port, @RequestParam String secret){
+ return mediaServerService.checkMediaServer(ip, port, secret);
+ }
+
+ @ApiOperation("娴嬭瘯娴佸獟浣撳綍鍍忕鐞嗘湇鍔�")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name="ip", value = "娴佸獟浣撴湇鍔P", dataTypeClass = String.class),
+ @ApiImplicitParam(name="port", value = "娴佸獟浣撴湇鍔TT绔彛", dataTypeClass = Integer.class),
+ @ApiImplicitParam(name="secret", value = "娴佸獟浣撴湇鍔ecret", dataTypeClass = String.class),
+ })
+ @GetMapping(value = "/media_server/record/check")
+ @ResponseBody
+ public WVPResult<String> checkMediaRecordServer(@RequestParam String ip, @RequestParam int port){
+ boolean checkResult = mediaServerService.checkMediaRecordServer(ip, port);
+ WVPResult<String> result = new WVPResult<>();
+ if (checkResult) {
+ result.setCode(0);
+ result.setMsg("success");
+
+ }else {
+ result.setCode(-1);
+ result.setMsg("杩炴帴澶辫触");
+ }
+ return result;
+ }
+
+ @ApiOperation("淇濆瓨娴佸獟浣撴湇鍔�")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name="mediaServerItem", value = "娴佸獟浣撲俊鎭�", dataTypeClass = MediaServerItem.class)
+ })
+ @PostMapping(value = "/media_server/save")
+ @ResponseBody
+ public WVPResult<String> checkMediaServer(@RequestBody MediaServerItem mediaServerItem){
+ if (mediaServerService.getOne(mediaServerItem.getId()) != null) {
+ mediaServerService.update(mediaServerItem);
+ }else {
+ return mediaServerService.add(mediaServerItem);
+ }
+ WVPResult<String> result = new WVPResult<>();
+ result.setCode(0);
+ result.setMsg("success");
+ return result;
+ }
+
+
@ApiOperation("閲嶅惎鏈嶅姟")
@GetMapping(value = "/restart")
@@ -155,6 +211,8 @@
case "base":
jsonObject.put("base", userSetup);
break;
+ default:
+ break;
}
}
result.setData(jsonObject);
diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml
index 856d6c5..f2d85ec 100644
--- a/src/main/resources/all-application.yml
+++ b/src/main/resources/all-application.yml
@@ -119,6 +119,8 @@
enable: true
# [鍙�塢 鍦ㄦ鑼冨洿鍐呴�夋嫨绔彛鐢ㄤ簬濯掍綋娴佷紶杈�,
port-range: 30000,30500 # 绔彛鑼冨洿
+ # [鍙�塢 鍥芥爣绾ц仈鍦ㄦ鑼冨洿鍐呴�夋嫨绔彛鍙戦�佸獟浣撴祦,
+ send-port-range: 30000,30500 # 绔彛鑼冨洿
# 褰曞儚杈呭姪鏈嶅姟锛� 閮ㄧ讲姝ゆ湇鍔″彲浠ュ疄鐜皕lm褰曞儚鐨勭鐞嗕笌涓嬭浇锛� 0 琛ㄧず涓嶄娇鐢�
record-assist-port: 0
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index 062f70e..44f70e6 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -63,6 +63,8 @@
enable: true
# [鍙�塢 鍦ㄦ鑼冨洿鍐呴�夋嫨绔彛鐢ㄤ簬濯掍綋娴佷紶杈�,
port-range: 30000,30500 # 绔彛鑼冨洿
+ # [鍙�塢 鍥芥爣绾ц仈鍦ㄦ鑼冨洿鍐呴�夋嫨绔彛鍙戦�佸獟浣撴祦,
+ send-port-range: 30000,30500 # 绔彛鑼冨洿
# 褰曞儚杈呭姪鏈嶅姟锛� 閮ㄧ讲姝ゆ湇鍔″彲浠ュ疄鐜皕lm褰曞儚鐨勭鐞嗕笌涓嬭浇锛� 0 琛ㄧず涓嶄娇鐢�
record-assist-port: 0
diff --git a/src/main/resources/wvp.sqlite b/src/main/resources/wvp.sqlite
index b95368d..40bdad8 100644
--- a/src/main/resources/wvp.sqlite
+++ b/src/main/resources/wvp.sqlite
Binary files differ
diff --git a/web_src/build/webpack.base.conf.js b/web_src/build/webpack.base.conf.js
index a07e683..72539e3 100644
--- a/web_src/build/webpack.base.conf.js
+++ b/web_src/build/webpack.base.conf.js
@@ -27,6 +27,7 @@
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
+ '@static': resolve('static'),
}
},
module: {
diff --git a/web_src/src/assets/zlm-log.png b/web_src/src/assets/zlm-log.png
new file mode 100644
index 0000000..5f492dc
--- /dev/null
+++ b/web_src/src/assets/zlm-log.png
Binary files differ
diff --git a/web_src/src/components/CloudRecord.vue b/web_src/src/components/CloudRecord.vue
index e39cd5b..f5d052a 100644
--- a/web_src/src/components/CloudRecord.vue
+++ b/web_src/src/components/CloudRecord.vue
@@ -111,7 +111,7 @@
},
getMediaServerList: function (){
let that = this;
- that.mediaServerObj.getMediaServerList((data)=>{
+ that.mediaServerObj.getOnlineMediaServerList((data)=>{
that.mediaServerList = data.data;
if (that.mediaServerList.length > 0) {
that.mediaServerId = that.mediaServerList[0].id
diff --git a/web_src/src/components/DeviceList.vue b/web_src/src/components/DeviceList.vue
index 7644a96..8d97833 100644
--- a/web_src/src/components/DeviceList.vue
+++ b/web_src/src/components/DeviceList.vue
@@ -60,7 +60,7 @@
<el-button-group>
<el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" type="primary" @click="showChannelList(scope.row)">閫氶亾</el-button>
<el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" @click="showDevicePosition(scope.row)">瀹氫綅</el-button>
- <el-button size="mini" icon="el-icon-delete" type="primary" @click="edit(scope.row)">缂栬緫</el-button>
+ <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">缂栬緫</el-button>
<el-button size="mini" icon="el-icon-delete" type="danger" v-if="scope.row.online==0" @click="deleteDevice(scope.row)">鍒犻櫎</el-button>
</el-button-group>
</template>
diff --git a/web_src/src/components/MediaServerManger.vue b/web_src/src/components/MediaServerManger.vue
new file mode 100644
index 0000000..19674d1
--- /dev/null
+++ b/web_src/src/components/MediaServerManger.vue
@@ -0,0 +1,159 @@
+<template>
+ <div id="mediaServerManger">
+ <el-container>
+ <el-header>
+ <uiHeader></uiHeader>
+ </el-header>
+ <el-main id="msMain">
+ <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>
+ <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="add">娣诲姞鑺傜偣</el-button>
+ </div>
+
+ <el-row :gutter="12">
+ <el-col :span="num" v-for="item in mediaServerList" :key="item.id">
+ <el-card shadow="hover" :body-style="{ padding: '0px'}" class="server-card">
+ <div class="card-img-zlm"></div>
+ <div style="padding: 14px;text-align: left">
+ <span style="font-size: 16px">{{item.id}}</span>
+ <div style="margin-top: 13px; line-height: 12px; ">
+ <span style="font-size: 14px; color: #999; margin-top: 5px">鍒涘缓鏃堕棿锛� {{item.createTime}}</span>
+ <el-button icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">缂栬緫</el-button>
+ </div>
+ </div>
+ <i v-if="item.status" class="iconfont icon-online server-card-status-online" title="鍦ㄧ嚎"></i>
+ <i v-if="!item.status" class="iconfont icon-online server-card-status-offline" title="绂荤嚎"></i>
+ </el-card>
+ </el-col>
+ </el-row>
+ <mediaServerEdit ref="mediaServerEdit" ></mediaServerEdit>
+ </el-main>
+ </el-container>
+ </div>
+</template>
+
+<script>
+ import uiHeader from './UiHeader.vue'
+ import MediaServer from './service/MediaServer'
+ import mediaServerEdit from './dialog/MediaServerEdit'
+ export default {
+ name: 'mediaServerManger',
+ components: {
+ uiHeader,mediaServerEdit
+ },
+ data() {
+ return {
+ mediaServerObj : new MediaServer(),
+ mediaServerList: [], //璁惧鍒楄〃
+ winHeight: window.innerHeight - 200,
+ updateLooper: false,
+ currentPage:1,
+ count:15,
+ num: this.getNumberByWidth(),
+ total:0,
+ };
+ },
+ computed: {
+
+ },
+ mounted() {
+ this.initData();
+ this.updateLooper = setInterval(this.initData, 2000);
+ },
+ destroyed() {
+ clearTimeout(this.updateLooper);
+ },
+ methods: {
+ initData: function() {
+ this.getServerList()
+ },
+ currentChange: function(val){
+ this.currentPage = val;
+ this.getServerList();
+ },
+ handleSizeChange: function(val){
+ this.count = val;
+ this.getServerList();
+ },
+ getServerList: function(){
+ this.mediaServerObj.getMediaServerList((data)=>{
+ this.mediaServerList = data.data;
+ })
+ },
+ add: function (){
+ this.$refs.mediaServerEdit.openDialog(null, this.initData)
+ },
+ edit: function (row){
+ this.$refs.mediaServerEdit.openDialog(row, this.initData)
+ },
+ getNumberByWidth(){
+ let candidateNums = [1, 2, 3, 4, 6, 8, 12, 24]
+ let clientWidth = window.innerWidth - 30;
+ let interval = 20;
+ let itemWidth = 360;
+ let num = (clientWidth + interval)/(itemWidth + interval)
+ let result = Math.ceil(24/num);
+ let resultVal = 24;
+ for (let i = 0; i < candidateNums.length; i++) {
+ let value = candidateNums[i]
+ if (i + 1 >= candidateNums.length) {
+ return 24;
+ }
+ if (value <= result && candidateNums[i + 1] > result ) {
+ return value;
+ }
+ }
+
+ console.log("aadada: "+ resultVal)
+ return resultVal;
+ },
+ dateFormat: function(/** timestamp=0 **/) {
+ var ts = arguments[0] || 0;
+ var t,y,m,d,h,i,s;
+ t = ts ? new Date(ts*1000) : new Date();
+ y = t.getFullYear();
+ m = t.getMonth()+1;
+ d = t.getDate();
+ h = t.getHours();
+ i = t.getMinutes();
+ s = t.getSeconds();
+ // 鍙牴鎹渶瑕佸湪杩欓噷瀹氫箟鏃堕棿鏍煎紡
+ return y+'-'+(m<10?'0'+m:m)+'-'+(d<10?'0'+d:d)+' '+(h<10?'0'+h:h)+':'+(i<10?'0'+i:i)+':'+(s<10?'0'+s:s);
+ }
+
+ }
+ };
+</script>
+
+<style>
+ .server-card{
+ position: relative;
+ margin-bottom: 20px;
+ }
+ .card-img-zlm{
+ width: 200px; height: 200px;
+ background: url('~@static/images/zlm-logo.png') no-repeat center;
+ background-position: center;
+ background-size: contain;
+ margin: 0 auto;
+ }
+ .server-card-status-online{
+ position: absolute;
+ right: 20px;
+ top: 20px;
+ color: #3caf36;
+ font-size: 18px;
+ }
+ .server-card-status-offline{
+ position: absolute;
+ right: 20px;
+ top: 20px;
+ color: #808080;
+ font-size: 18px;
+ }
+ .server-card:hover {
+ border: 1px solid #adadad;
+ }
+</style>
diff --git a/web_src/src/components/UiHeader.vue b/web_src/src/components/UiHeader.vue
index 4ab4642..b2e9bbb 100644
--- a/web_src/src/components/UiHeader.vue
+++ b/web_src/src/components/UiHeader.vue
@@ -6,6 +6,7 @@
<el-menu-item index="/pushVideoList">鎺ㄦ祦鍒楄〃</el-menu-item>
<el-menu-item index="/streamProxyList">鎷夋祦浠g悊</el-menu-item>
<el-menu-item index="/cloudRecord">浜戠褰曞儚</el-menu-item>
+ <el-menu-item index="/mediaServerManger">鑺傜偣绠$悊</el-menu-item>
<el-menu-item index="/parentPlatformList/15/1">鍥芥爣绾ц仈</el-menu-item>
<el-menu-item @click="openDoc">鍦ㄧ嚎鏂囨。</el-menu-item>
<!-- <el-submenu index="/setting">-->
diff --git a/web_src/src/components/control.vue b/web_src/src/components/control.vue
index 6326712..a8ee8d4 100644
--- a/web_src/src/components/control.vue
+++ b/web_src/src/components/control.vue
@@ -139,7 +139,7 @@
this.initTable();
this.updateData();
this.chartInterval = setInterval(this.updateData, 3000);
- this.mediaServer.getMediaServerList((data)=>{
+ this.mediaServer.getOnlineMediaServerList((data)=>{
this.mediaServerList = data.data;
if (this.mediaServerList && this.mediaServerList.length > 0) {
this.mediaServerChoose = this.mediaServerList[0].id
diff --git a/web_src/src/components/dialog/MediaServerEdit.vue b/web_src/src/components/dialog/MediaServerEdit.vue
new file mode 100644
index 0000000..b67daf8
--- /dev/null
+++ b/web_src/src/components/dialog/MediaServerEdit.vue
@@ -0,0 +1,368 @@
+<template>
+ <div id="mediaServerEdit" v-loading="isLoging">
+ <el-dialog
+ title="濯掍綋鑺傜偣"
+ :width="dialogWidth"
+ top="2rem"
+ :close-on-click-modal="false"
+ :visible.sync="showDialog"
+ :destroy-on-close="true"
+ @close="close()"
+ >
+ <div id="formStep" style="margin-top: 1rem; margin-right: 20px;">
+ <el-form v-if="currentStep == 1" ref="mediaServerForm" :rules="rules" :model="mediaServerForm" label-width="140px" >
+ <el-form-item label="IP" prop="ip">
+ <el-input v-model="mediaServerForm.ip" placeholder="濯掍綋鏈嶅姟IP" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="HTTP绔彛" prop="port">
+ <el-input v-model="mediaServerForm.httpPort" placeholder="濯掍綋鏈嶅姟HTTP绔彛" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="SECRET" prop="secret">
+ <el-input v-model="mediaServerForm.secret" placeholder="濯掍綋鏈嶅姟SECRET" clearable></el-input>
+ </el-form-item>
+ <el-form-item>
+ <div style="float: right;">
+ <el-button type="primary" v-if="currentStep === 1 && serverCheck === 1" @click="next" >涓嬩竴姝�</el-button>
+ <el-button @click="close">鍙栨秷</el-button>
+ <el-button type="primary" @click="checkServer" >娴嬭瘯</el-button>
+ <i v-if="serverCheck === 1" class="el-icon-success" style="color: #3caf36"></i>
+ <i v-if="serverCheck === -1" class="el-icon-error" style="color: #c80000"></i>
+ </div>
+ </el-form-item>
+ </el-form>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form v-if="currentStep === 2 || currentStep === 3" ref="mediaServerForm1" :rules="rules" :model="mediaServerForm" label-width="140px" >
+ <el-form-item label="IP" prop="ip">
+ <el-input v-if="currentStep === 2" v-model="mediaServerForm.ip" disabled></el-input>
+ <el-input v-if="currentStep === 3" v-model="mediaServerForm.ip"></el-input>
+ </el-form-item>
+ <el-form-item label="HTTP绔彛" prop="port">
+ <el-input v-if="currentStep === 2" v-model="mediaServerForm.httpPort" disabled></el-input>
+ <el-input v-if="currentStep === 3" v-model="mediaServerForm.httpPort"></el-input>
+ </el-form-item>
+ <el-form-item label="SECRET" prop="secret">
+ <el-input v-if="currentStep === 2" v-model="mediaServerForm.secret" disabled></el-input>
+ <el-input v-if="currentStep === 3" v-model="mediaServerForm.secret"></el-input>
+ </el-form-item>
+ <el-form-item label="HOOK IP" prop="ip">
+ <el-input v-model="mediaServerForm.hookIp" placeholder="濯掍綋鏈嶅姟HOOK_IP" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="SDP IP" prop="ip">
+ <el-input v-model="mediaServerForm.sdpIp" placeholder="濯掍綋鏈嶅姟SDP_IP" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="娴両P" prop="ip">
+ <el-input v-model="mediaServerForm.streamIp" placeholder="濯掍綋鏈嶅姟娴両P" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="HTTPS PORT" prop="port">
+ <el-input v-model="mediaServerForm.httpSSlPort" placeholder="濯掍綋鏈嶅姟HTTPS_PORT" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="RTSP PORT" prop="port">
+ <el-input v-model="mediaServerForm.rtspPort" placeholder="濯掍綋鏈嶅姟RTSP_PORT" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="RTSPS PORT" prop="port">
+ <el-input v-model="mediaServerForm.rtspSSLPort" placeholder="濯掍綋鏈嶅姟RTSPS_PORT" clearable></el-input>
+ </el-form-item>
+
+ </el-form>
+ </el-col>
+ <el-col :span="12">
+ <el-form v-if="currentStep === 2 || currentStep === 3" ref="mediaServerForm2" :rules="rules" :model="mediaServerForm" label-width="180px" >
+ <el-form-item label="RTMP PORT" prop="port">
+ <el-input v-model="mediaServerForm.rtmpPort" placeholder="濯掍綋鏈嶅姟RTMP_PORT" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="RTMPS PORT" prop="port">
+ <el-input v-model="mediaServerForm.rtmpSSlPort" placeholder="濯掍綋鏈嶅姟RTMPS_PORT" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="鑷姩閰嶇疆濯掍綋鏈嶅姟" >
+ <el-switch v-model="mediaServerForm.autoConfig"></el-switch>
+ </el-form-item>
+ <el-form-item label="鏀舵祦绔彛妯″紡" >
+ <el-switch active-text="澶氱鍙�" inactive-text="鍗曠鍙�" v-model="mediaServerForm.rtpEnable"></el-switch>
+ </el-form-item>
+
+ <el-form-item v-if="!mediaServerForm.rtpEnable" label="鏀舵祦绔彛" prop="port">
+ <el-input v-model.number="mediaServerForm.rtpProxyPort" clearable></el-input>
+ </el-form-item>
+ <el-form-item v-if="mediaServerForm.rtpEnable" label="鏀舵祦绔彛" prop="port">
+ <el-input v-model="mediaServerForm.rtpPortRange1" placeholder="璧峰" clearable style="width: 100px" prop="port"></el-input>
+ -
+ <el-input v-model="mediaServerForm.rtpPortRange2" placeholder="缁堟" clearable style="width: 100px" prop="port"></el-input>
+ </el-form-item>
+ <el-form-item label="鎺ㄦ祦绔彛" prop="port">
+ <el-input v-model="mediaServerForm.sendRtpPortRange1" placeholder="璧峰" clearable style="width: 100px" prop="port"></el-input>
+ -
+ <el-input v-model="mediaServerForm.sendRtpPortRange2" placeholder="缁堟" clearable style="width: 100px" prop="port"></el-input>
+ </el-form-item>
+ <el-form-item label="鏃犱汉瑙傜湅澶氫箙鍚庡仠姝㈡媺娴�" >
+ <el-input v-model.number="mediaServerForm.streamNoneReaderDelayMS" clearable></el-input>
+ </el-form-item>
+ <el-form-item label="褰曞儚绠$悊鏈嶅姟绔彛" prop="port">
+ <el-input v-model.number="mediaServerForm.recordAssistPort">
+<!-- <el-button v-if="mediaServerForm.recordAssistPort > 0" slot="append" type="primary" @click="checkRecordServer">娴嬭瘯</el-button>-->
+ <el-button v-if="mediaServerForm.recordAssistPort > 0" class="el-icon-check" slot="append" type="primary" @click="checkRecordServer"></el-button>
+ </el-input>
+ <i v-if="recordServerCheck == 1" class="el-icon-success" style="color: #3caf36; position: absolute;top: 14px;"></i>
+ <i v-if="recordServerCheck == 2" class="el-icon-loading" style="color: #3caf36; position: absolute;top: 14px;"></i>
+ <i v-if="recordServerCheck === -1" class="el-icon-error" style="color: #c80000; position: absolute;top: 14px;"></i>
+ </el-form-item>
+ <el-form-item>
+ <div style="float: right;">
+ <el-button type="primary" @click="onSubmit" >鎻愪氦</el-button>
+ <el-button @click="close">鍙栨秷</el-button>
+ </div>
+ </el-form-item>
+ </el-form>
+ </el-col>
+ </el-row>
+
+ </div>
+ </el-dialog>
+ </div>
+</template>
+
+<script>
+import MediaServer from './../service/MediaServer'
+
+export default {
+ name: "streamProxyEdit",
+ props: {},
+ computed: {},
+ created() {
+ this.setDialogWidth()
+ },
+ data() {
+ const isValidIp = (rule, value, callback) => { // 鏍¢獙IP鏄惁绗﹀悎瑙勫垯
+ var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
+ console.log(this.mediaServerForm.ip)
+ if (!reg.test(this.mediaServerForm.ip)) {
+ return callback(new Error('璇疯緭鍏ユ湁鏁堢殑IP鍦板潃'))
+ } else {
+ callback()
+ }
+ return true
+ }
+ const isValidPort = (rule, value, callback) => { // 鏍¢獙IP鏄惁绗﹀悎瑙勫垯
+ var reg = /^(([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5]))$/
+ if (!reg.test(this.mediaServerForm.httpPort)) {
+ return callback(new Error('璇疯緭鍏ユ湁鏁堢殑绔彛鍙�'))
+ } else {
+ callback()
+ }
+ return true
+ }
+ return {
+ dialogWidth: 0,
+ defaultWidth: 1000,
+ listChangeCallback: null,
+ showDialog: false,
+ isLoging: false,
+ dialogLoading: false,
+
+ currentStep: 1,
+ platformList: [],
+ mediaServer: new MediaServer(),
+ serverCheck: 0,
+ recordServerCheck: 0,
+ mediaServerForm: {
+ id: "",
+ ip: "",
+ autoConfig: true,
+ hookIp: "",
+ sdpIp: "",
+ streamIp: "",
+ streamNoneReaderDelayMS: "",
+ secret: "035c73f7-bb6b-4889-a715-d9eb2d1925cc",
+ httpPort: "",
+ httpSSlPort: "",
+ recordAssistPort: "",
+ rtmpPort: "",
+ rtmpSSlPort: "",
+ rtpEnable: false,
+ rtpPortRange: "",
+ sendRtpPortRange: "",
+ rtpPortRange1: "",
+ rtpPortRange2: "",
+ sendRtpPortRange1: "",
+ sendRtpPortRange2: "",
+ rtpProxyPort: "",
+ rtspPort: "",
+ rtspSSLPort: "",
+ },
+
+ rules: {
+ ip: [{ required: true, validator: isValidIp, message: '璇疯緭鍏ユ湁鏁堢殑IP鍦板潃', trigger: 'blur' }],
+ port: [{ required: true, validator: isValidPort, message: '璇疯緭鍏ユ湁鏁堢殑绔彛鍙�', trigger: 'blur' }],
+ secret: [{ required: true, message: "璇疯緭鍏ecret", trigger: "blur" }],
+ timeout_ms: [{ required: true, message: "璇疯緭鍏Fmpeg鎺ㄦ祦鎴愬姛瓒呮椂鏃堕棿", trigger: "blur" }],
+ ffmpeg_cmd_key: [{ required: false, message: "璇疯緭鍏Fmpeg鍛戒护鍙傛暟妯℃澘锛堝彲閫夛級", trigger: "blur" }],
+ },
+ };
+ },
+ methods: {
+ setDialogWidth() {
+ let val = document.body.clientWidth
+ if (val < this.defaultWidth) {
+ this.dialogWidth = '100%'
+ } else {
+ this.dialogWidth = this.defaultWidth + 'px'
+ }
+ },
+ openDialog: function (param, callback) {
+ this.showDialog = true;
+ this.listChangeCallback = callback;
+ if (param != null) {
+ this.mediaServerForm = param;
+ this.currentStep = 3;
+ if (param.rtpPortRange) {
+ let rtpPortRange = this.mediaServerForm.rtpPortRange.split(",");
+ if (rtpPortRange.length > 0) {
+ this.mediaServerForm["rtpPortRange1"] = rtpPortRange[0]
+ this.mediaServerForm["rtpPortRange2"] = rtpPortRange[1]
+ }
+ }
+ let sendRtpPortRange = this.mediaServerForm.sendRtpPortRange.split(",");
+ this.mediaServerForm["sendRtpPortRange1"] = sendRtpPortRange[0]
+ this.mediaServerForm["sendRtpPortRange2"] = sendRtpPortRange[1]
+ }
+ },
+ checkServer: function() {
+ let that = this;
+ that.serverCheck = 0;
+ that.mediaServer.checkServer(that.mediaServerForm, data =>{
+ if (data.code === 0) {
+ if (parseInt(that.mediaServerForm.httpPort) !== parseInt(data.data.httpPort)) {
+ that.$message({
+ showClose: true,
+ message: '濡傛灉浣犳鍦ㄤ娇鐢╠ocker閮ㄧ讲浣犵殑濯掍綋鏈嶅姟锛岃娉ㄦ剰鐨勭鍙f槧灏勩��',
+ type: 'warning',
+ duration: 0
+ });
+ }
+ let httpPort = that.mediaServerForm.httpPort;
+ that.mediaServerForm = data.data;
+ that.mediaServerForm.httpPort = httpPort;
+ that.mediaServerForm.autoConfig = true;
+ that.mediaServerForm.sendRtpPortRange1 = 30000
+ that.mediaServerForm.sendRtpPortRange2 = 30500
+ that.mediaServerForm.rtpPortRange1 = 30000
+ that.mediaServerForm.rtpPortRange2 = 30500
+ that.serverCheck = 1;
+ }else {
+ that.serverCheck = -1;
+ that.$message({
+ showClose: true,
+ message: data.msg,
+ type: "error",
+ });
+ }
+
+ })
+ },
+ next: function (){
+ this.currentStep = 2;
+ this.defaultWidth = 900;
+ this.setDialogWidth();
+ },
+ checkRecordServer: function (){
+ let that = this;
+ that.recordServerCheck = 2;
+ if (that.mediaServerForm.recordAssistPort <= 0 || that.mediaServerForm.recordAssistPort > 65535 ) {
+ that.recordServerCheck = -1;
+ that.$message({
+ showClose: true,
+ message: "绔彛鍙峰簲璇ュ湪-65535涔嬮棿",
+ type: "error",
+ });
+ return;
+ }
+ that.mediaServer.checkRecordServer(that.mediaServerForm, data =>{
+ if (data.code === 0) {
+ that.recordServerCheck = 1;
+ }else {
+ that.recordServerCheck = -1;
+ that.$message({
+ showClose: true,
+ message: data.msg,
+ type: "error",
+ });
+ }
+ })
+ },
+ onSubmit: function () {
+ this.dialogLoading = true;
+ let that = this;
+ if (this.mediaServerForm.rtpEnable) {
+ this.mediaServerForm.rtpPortRange = this.mediaServerForm.rtpPortRange1 + "," + this.mediaServerForm.rtpPortRange2;
+ }
+ this.mediaServerForm.sendRtpPortRange = this.mediaServerForm.sendRtpPortRange1 + "," + this.mediaServerForm.sendRtpPortRange2;
+ that.mediaServer.addServer(this.mediaServerForm, data => {
+ if (data.code === 0) {
+ that.$message({
+ showClose: true,
+ message: "淇濆瓨鎴愬姛",
+ type: "success",
+ });
+ if (this.listChangeCallback) this.listChangeCallback();
+ that.close()
+ }else {
+ that.$message({
+ showClose: true,
+ message: data.msg,
+ type: "error",
+ });
+ }
+ })
+ },
+ close: function () {
+ this.showDialog = false;
+ this.dialogLoading = false;
+ this.mediaServerForm = {
+ id: "",
+ ip: "",
+ autoConfig: true,
+ hookIp: "",
+ sdpIp: "",
+ streamIp: "",
+ streamNoneReaderDelayMS: "",
+ secret: "035c73f7-bb6b-4889-a715-d9eb2d1925cc",
+ httpPort: "",
+ httpSSlPort: "",
+ recordAssistPort: "",
+ rtmpPort: "",
+ rtmpSSlPort: "",
+ rtpEnable: false,
+ rtpPortRange: "",
+ sendRtpPortRange: "",
+ rtpPortRange1: "",
+ rtpPortRange2: "",
+ sendRtpPortRange1: "",
+ sendRtpPortRange2: "",
+ rtpProxyPort: "",
+ rtspPort: "",
+ rtspSSLPort: "",
+ };
+ this.listChangeCallback = null
+ this.currentStep = 1;
+ },
+ deviceGBIdExit: async function (deviceGbId) {
+ var result = false;
+ var that = this;
+ await that.$axios({
+ method: 'post',
+ url:`/api/platform/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/dialog/StreamProxyEdit.vue b/web_src/src/components/dialog/StreamProxyEdit.vue
index 3310d9c..ea3a64f 100644
--- a/web_src/src/components/dialog/StreamProxyEdit.vue
+++ b/web_src/src/components/dialog/StreamProxyEdit.vue
@@ -203,7 +203,7 @@
}).catch(function (error) {
console.log(error);
});
- this.mediaServer.getMediaServerList((data)=>{
+ this.mediaServer.getOnlineMediaServerList((data)=>{
this.mediaServerList = data;
})
},
diff --git a/web_src/src/components/dialog/changePassword.vue b/web_src/src/components/dialog/changePassword.vue
index 39aba8d..eade6a8 100644
--- a/web_src/src/components/dialog/changePassword.vue
+++ b/web_src/src/components/dialog/changePassword.vue
@@ -89,7 +89,7 @@
method: 'post',
url:"/api/user/changePassword",
params: {
- oldpassword: crypto.createHash('md5').update(this.oldPassword, "utf8").digest('hex'),
+ oldPassword: crypto.createHash('md5').update(this.oldPassword, "utf8").digest('hex'),
password: this.newPassword
}
}).then((res)=> {
diff --git a/web_src/src/components/dialog/deviceEdit.vue b/web_src/src/components/dialog/deviceEdit.vue
index 464de02..5d2ffa5 100644
--- a/web_src/src/components/dialog/deviceEdit.vue
+++ b/web_src/src/components/dialog/deviceEdit.vue
@@ -82,7 +82,7 @@
},
getMediaServerList: function (){
let that = this;
- that.mediaServerObj.getMediaServerList((data)=>{
+ that.mediaServerObj.getOnlineMediaServerList((data)=>{
that.mediaServerList = data.data;
})
},
diff --git a/web_src/src/components/service/MediaServer.js b/web_src/src/components/service/MediaServer.js
index b905352..e9de603 100644
--- a/web_src/src/components/service/MediaServer.js
+++ b/web_src/src/components/service/MediaServer.js
@@ -6,10 +6,20 @@
this.$axios = axios;
}
- getMediaServerList(callback){
+ getOnlineMediaServerList(callback){
this.$axios({
method: 'get',
url:`/api/server/media_server/online/list`,
+ }).then(function (res) {
+ if (typeof (callback) == "function") callback(res.data)
+ }).catch(function (error) {
+ console.log(error);
+ });
+ }
+ getMediaServerList(callback){
+ this.$axios({
+ method: 'get',
+ url:`/api/server/media_server/list`,
}).then(function (res) {
if (typeof (callback) == "function") callback(res.data)
}).catch(function (error) {
@@ -27,6 +37,49 @@
console.log(error);
});
}
+
+ checkServer(param, callback){
+ this.$axios({
+ method: 'get',
+ url:`/api/server/media_server/check`,
+ params: {
+ ip: param.ip,
+ port: param.httpPort,
+ secret: param.secret
+ }
+ }).then(function (res) {
+ if (typeof (callback) == "function") callback(res.data)
+ }).catch(function (error) {
+ console.log(error);
+ });
+ }
+
+ checkRecordServer(param, callback){
+ this.$axios({
+ method: 'get',
+ url:`/api/server/media_server/record/check`,
+ params: {
+ ip: param.ip,
+ port: param.recordAssistPort
+ }
+ }).then(function (res) {
+ if (typeof (callback) == "function") callback(res.data)
+ }).catch(function (error) {
+ console.log(error);
+ });
+ }
+
+ addServer(param, callback){
+ this.$axios({
+ method: 'post',
+ url:`/api/server/media_server/save`,
+ data: param
+ }).then(function (res) {
+ if (typeof (callback) == "function") callback(res.data)
+ }).catch(function (error) {
+ console.log(error);
+ });
+ }
}
export default MediaServer;
diff --git a/web_src/src/router/index.js b/web_src/src/router/index.js
index 4b0810d..59bbb23 100644
--- a/web_src/src/router/index.js
+++ b/web_src/src/router/index.js
@@ -10,6 +10,7 @@
import login from '../components/Login.vue'
import parentPlatformList from '../components/ParentPlatformList.vue'
import cloudRecord from '../components/CloudRecord.vue'
+import mediaServerManger from '../components/MediaServerManger.vue'
import test from '../components/test.vue'
import web from '../components/setting/Web.vue'
import sip from '../components/setting/Sip.vue'
@@ -71,6 +72,11 @@
component: cloudRecord,
},
{
+ path: '/mediaServerManger',
+ name: 'mediaServerManger',
+ component: mediaServerManger,
+ },
+ {
path: '/setting/web',
name: 'web',
component: web,
diff --git a/web_src/static/css/iconfont.css b/web_src/static/css/iconfont.css
index 972cf6b..0f9b608 100644
--- a/web_src/static/css/iconfont.css
+++ b/web_src/static/css/iconfont.css
@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 1291092 */
- src: url('iconfont.woff2?t=1626163621710') format('woff2'),
- url('iconfont.woff?t=1626163621710') format('woff'),
- url('iconfont.ttf?t=1626163621710') format('truetype');
+ src: url('iconfont.woff2?t=1631767887536') format('woff2'),
+ url('iconfont.woff?t=1631767887536') format('woff'),
+ url('iconfont.ttf?t=1631767887536') format('truetype');
}
.iconfont {
@@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale;
}
+.icon-online:before {
+ content: "\e600";
+}
+
.icon-xiangqing2:before {
content: "\e798";
}
diff --git a/web_src/static/css/iconfont.woff2 b/web_src/static/css/iconfont.woff2
index c8d7e3d..42e2eca 100644
--- a/web_src/static/css/iconfont.woff2
+++ b/web_src/static/css/iconfont.woff2
Binary files differ
diff --git a/web_src/static/images/zlm-logo.png b/web_src/static/images/zlm-logo.png
new file mode 100644
index 0000000..5f492dc
--- /dev/null
+++ b/web_src/static/images/zlm-logo.png
Binary files differ
--
Gitblit v1.8.0