添加发送媒体流, 添加媒体服务器节点管理ui,修复修改密码
| | |
| | | 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, |
| | |
| | | import java.io.IOException; |
| | | import java.text.SimpleDateFormat; |
| | | |
| | | /** |
| | | * @author lin |
| | | */ |
| | | @WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/api/*", asyncSupported=true) |
| | | public class ApiAccessFilter extends OncePerRequestFilter { |
| | | |
| | |
| | | @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; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | public String getSipDomain() { |
| | | return sipDomain; |
| | | } |
| | | |
| | | public String getSendRtpPortRange() { |
| | | return sendRtpPortRange; |
| | | } |
| | | |
| | | public MediaServerItem getMediaSerItem(){ |
| | | MediaServerItem mediaServerItem = new MediaServerItem(); |
| | | mediaServerItem.setId(id); |
| | |
| | | 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"); |
| | |
| | | import java.io.IOException; |
| | | import java.net.ConnectException; |
| | | |
| | | /** |
| | | * @author lin |
| | | */ |
| | | @SuppressWarnings(value = {"rawtypes", "unchecked"}) |
| | | @Configuration |
| | | public class ProxyServletConfig { |
| | |
| | | |
| | | @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(); |
| | |
| | | return servletRegistrationBean; |
| | | } |
| | | |
| | | class ZLMProxySerlet extends ProxyServlet{ |
| | | class ZlmProxyServlet extends ProxyServlet{ |
| | | @Override |
| | | protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { |
| | | String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); |
| | |
| | | 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; |
| | |
| | | |
| | | Map<String, Object> param = new HashMap<>(); |
| | | int result = -1; |
| | | int newPort = getPortFromportRange(mediaServerItem); |
| | | param.put("port", newPort); |
| | | /** |
| | | * 不设置推流端口端则使用随机端口 |
| | | */ |
| | | 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); |
| | |
| | | if (openRtpServerResultJson != null) { |
| | | switch (openRtpServerResultJson.getInteger("code")){ |
| | | case 0: |
| | | result= newPort; |
| | | result= openRtpServerResultJson.getInteger("port"); |
| | | break; |
| | | case -300: // id已经存在, 可能已经在其他端口推流 |
| | | 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 { |
| | | // 检查ZLM状态 |
| | | logger.error("创建RTP Server 失败 {}: 请检查ZLM服务", newPort); |
| | | logger.error("创建RTP Server 失败 {}: 请检查ZLM服务", param.get("port")); |
| | | } |
| | | return result; |
| | | } |
| | |
| | | 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]); |
| | | } |
| | |
| | | */ |
| | | 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"); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | 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) { |
| | |
| | | |
| | | 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; |
| | | |
| | |
| | | secret = zlmServerConfig.getApiSecret(); |
| | | streamNoneReaderDelayMS = zlmServerConfig.getGeneralStreamNoneReaderDelayMS(); |
| | | rtpEnable = false; // 默认使用单端口;直到用户自己设置开启多端口 |
| | | rtpPortRange = "30000,30500"; // 默认使用30000,30500作为级联时发送流的端口号 |
| | | recordAssistPort = 0; // 默认关闭 |
| | | |
| | | } |
| | |
| | | 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; |
| | | } |
| | | } |
| | |
| | | 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; |
| | | |
| | |
| | | |
| | | 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); |
| | | } |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | private MediaServerMapper mediaServerMapper; |
| | | |
| | | @Autowired |
| | | private IRedisCatchStorage redisCatchStorage; |
| | | |
| | | @Autowired |
| | | private VideoStreamSessionManager streamSession; |
| | | |
| | | @Autowired |
| | |
| | | |
| | | @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可用的ssrc |
| | | String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(); |
| | | |
| | |
| | | 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); |
| | |
| | | |
| | | @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); |
| | |
| | | |
| | | /** |
| | | * zlm 重启后重置他的推流信息, TODO 给正在使用的设备发送停止命令 |
| | | * @param mediaServerItem |
| | | */ |
| | | @Override |
| | | public void clearRTPServer(MediaServerItem mediaServerItem) { |
| | |
| | | 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; |
| | | } |
| | |
| | | */ |
| | | @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); |
| | | } |
| | |
| | | } |
| | | |
| | | @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("保存失败,媒体服务ID [ " + 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; |
| | | } |
| | | |
| | | /** |
| | |
| | | // docker部署不会使用zlm配置的端口号不是默认的则不做更新, 配置修改需要自行修改server配置; |
| | | 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); |
| | |
| | | |
| | | @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); |
| | | |
| | | } |
| | |
| | | } |
| | | |
| | | |
| | | @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; |
| | | } |
| | | } |
| | |
| | | "streamNoneReaderDelayMS, " + |
| | | "rtpEnable, " + |
| | | "rtpPortRange, " + |
| | | "sendRtpPortRange, " + |
| | | "recordAssistPort, " + |
| | | "defaultServer, " + |
| | | "createTime, " + |
| | |
| | | "${streamNoneReaderDelayMS}, " + |
| | | "${rtpEnable}, " + |
| | | "'${rtpPortRange}', " + |
| | | "'${sendRtpPortRange}', " + |
| | | "${recordAssistPort}, " + |
| | | "${defaultServer}, " + |
| | | "'${createTime}', " + |
| | |
| | | "<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}'"+ |
| | |
| | | @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"); |
| | |
| | | result.setData(mediaServerService.getOne(id)); |
| | | return result; |
| | | } |
| | | |
| | | @ApiOperation("测试流媒体服务") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name="ip", value = "流媒体服务IP", dataTypeClass = String.class), |
| | | @ApiImplicitParam(name="port", value = "流媒体服务HTT端口", dataTypeClass = Integer.class), |
| | | @ApiImplicitParam(name="secret", value = "流媒体服务secret", 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 = "流媒体服务IP", dataTypeClass = String.class), |
| | | @ApiImplicitParam(name="port", value = "流媒体服务HTT端口", dataTypeClass = Integer.class), |
| | | @ApiImplicitParam(name="secret", value = "流媒体服务secret", 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") |
| | |
| | | case "base": |
| | | jsonObject.put("base", userSetup); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | result.setData(jsonObject); |
| | |
| | | enable: true |
| | | # [可选] 在此范围内选择端口用于媒体流传输, |
| | | port-range: 30000,30500 # 端口范围 |
| | | # [可选] 国标级联在此范围内选择端口发送媒体流, |
| | | send-port-range: 30000,30500 # 端口范围 |
| | | # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 |
| | | record-assist-port: 0 |
| | | |
| | |
| | | enable: true |
| | | # [可选] 在此范围内选择端口用于媒体流传输, |
| | | port-range: 30000,30500 # 端口范围 |
| | | # [可选] 国标级联在此范围内选择端口发送媒体流, |
| | | send-port-range: 30000,30500 # 端口范围 |
| | | # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 |
| | | record-assist-port: 0 |
| | | |
| | |
| | | alias: { |
| | | 'vue$': 'vue/dist/vue.esm.js', |
| | | '@': resolve('src'), |
| | | '@static': resolve('static'), |
| | | } |
| | | }, |
| | | module: { |
| | |
| | | }, |
| | | 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 |
| | |
| | | <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> |
New file |
| | |
| | | <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> |
| | |
| | | <el-menu-item index="/pushVideoList">推流列表</el-menu-item> |
| | | <el-menu-item index="/streamProxyList">拉流代理</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">--> |
| | |
| | | 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 |
New file |
| | |
| | | <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="流IP" prop="ip"> |
| | | <el-input v-model="mediaServerForm.streamIp" placeholder="媒体服务流IP" 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: "请输入secret", trigger: "blur" }], |
| | | timeout_ms: [{ required: true, message: "请输入FFmpeg推流成功超时时间", trigger: "blur" }], |
| | | ffmpeg_cmd_key: [{ required: false, message: "请输入FFmpeg命令参数模板(可选)", 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: '如果你正在使用docker部署你的媒体服务,请注意的端口映射。', |
| | | 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> |
| | |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | | this.mediaServer.getMediaServerList((data)=>{ |
| | | this.mediaServer.getOnlineMediaServerList((data)=>{ |
| | | this.mediaServerList = data; |
| | | }) |
| | | }, |
| | |
| | | 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)=> { |
| | |
| | | }, |
| | | getMediaServerList: function (){ |
| | | let that = this; |
| | | that.mediaServerObj.getMediaServerList((data)=>{ |
| | | that.mediaServerObj.getOnlineMediaServerList((data)=>{ |
| | | that.mediaServerList = data.data; |
| | | }) |
| | | }, |
| | |
| | | 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) { |
| | |
| | | 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; |
| | |
| | | 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' |
| | |
| | | component: cloudRecord, |
| | | }, |
| | | { |
| | | path: '/mediaServerManger', |
| | | name: 'mediaServerManger', |
| | | component: mediaServerManger, |
| | | }, |
| | | { |
| | | path: '/setting/web', |
| | | name: 'web', |
| | | component: web, |
| | |
| | | @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 { |
| | |
| | | -moz-osx-font-smoothing: grayscale; |
| | | } |
| | | |
| | | .icon-online:before { |
| | | content: "\e600"; |
| | | } |
| | | |
| | | .icon-xiangqing2:before { |
| | | content: "\e798"; |
| | | } |