
75 changed files with 2415 additions and 898 deletions
@ -1,54 +0,0 @@ |
|||||
//package com.genersoft.iot.vmp.media.zlm;
|
|
||||
//
|
|
||||
//import com.genersoft.iot.vmp.conf.MediaConfig;
|
|
||||
//import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
|
||||
//import org.springframework.beans.factory.annotation.Value;
|
|
||||
//import org.springframework.web.bind.annotation.*;
|
|
||||
//import org.springframework.web.client.HttpClientErrorException;
|
|
||||
//import org.springframework.web.client.RestTemplate;
|
|
||||
//
|
|
||||
//import javax.servlet.http.HttpServletRequest;
|
|
||||
//import javax.servlet.http.HttpServletResponse;
|
|
||||
//
|
|
||||
//@RestController
|
|
||||
//@RequestMapping("/zlm")
|
|
||||
//public class ZLMHTTPProxyController {
|
|
||||
//
|
|
||||
//
|
|
||||
// // private final static Logger logger = LoggerFactory.getLogger(ZLMHTTPProxyController.class);
|
|
||||
//
|
|
||||
// @Autowired
|
|
||||
// private IRedisCatchStorage redisCatchStorage;
|
|
||||
//
|
|
||||
// @Autowired
|
|
||||
// private MediaConfig mediaConfig;
|
|
||||
//
|
|
||||
// @ResponseBody
|
|
||||
// @RequestMapping(value = "/**/**/**", produces = "application/json;charset=UTF-8")
|
|
||||
// public Object proxy(HttpServletRequest request, HttpServletResponse response){
|
|
||||
//
|
|
||||
// if (redisCatchStorage.getMediaInfo() == null) {
|
|
||||
// return "未接入流媒体";
|
|
||||
// }
|
|
||||
// ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
|
|
||||
// String requestURI = String.format("http://%s:%s%s?%s&%s",
|
|
||||
// mediaInfo.getLocalIP(),
|
|
||||
// mediaConfig.getHttpPort(),
|
|
||||
// request.getRequestURI().replace("/zlm",""),
|
|
||||
// mediaInfo.getHookAdminParams(),
|
|
||||
// request.getQueryString()
|
|
||||
// );
|
|
||||
// // 发送请求
|
|
||||
// RestTemplate restTemplate = new RestTemplate();
|
|
||||
// //将指定的url返回的参数自动封装到自定义好的对应类对象中
|
|
||||
// Object result = null;
|
|
||||
// try {
|
|
||||
// result = restTemplate.getForObject(requestURI,Object.class);
|
|
||||
//
|
|
||||
// }catch (HttpClientErrorException httpClientErrorException) {
|
|
||||
// response.setStatus(httpClientErrorException.getStatusCode().value());
|
|
||||
// }
|
|
||||
// return result;
|
|
||||
// }
|
|
||||
//}
|
|
@ -1,45 +0,0 @@ |
|||||
package com.genersoft.iot.vmp.media.zlm; |
|
||||
|
|
||||
import com.genersoft.iot.vmp.conf.MediaConfig; |
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.stereotype.Component; |
|
||||
import org.springframework.util.StringUtils; |
|
||||
|
|
||||
@Component |
|
||||
public class ZLMServerManger { |
|
||||
|
|
||||
@Autowired |
|
||||
private IRedisCatchStorage redisCatchStorage; |
|
||||
|
|
||||
@Autowired |
|
||||
private MediaConfig mediaConfig; |
|
||||
|
|
||||
public void updateServerCatch(ZLMServerConfig zlmServerConfig) { |
|
||||
|
|
||||
zlmServerConfig.setIp(mediaConfig.getIp()); |
|
||||
zlmServerConfig.setStreamIp(mediaConfig.getStreamIp()); |
|
||||
zlmServerConfig.setSdpIp(mediaConfig.getSdpIp()); |
|
||||
zlmServerConfig.setHttpPort(mediaConfig.getHttpPort()); |
|
||||
|
|
||||
if(!StringUtils.isEmpty(mediaConfig.getHttpSSlPort())) |
|
||||
zlmServerConfig.setHttpSSLport(mediaConfig.getHttpSSlPort()); |
|
||||
|
|
||||
if(!StringUtils.isEmpty(mediaConfig.getRtspPort())) |
|
||||
zlmServerConfig.setRtspPort(mediaConfig.getRtspPort()); |
|
||||
|
|
||||
if(!StringUtils.isEmpty(mediaConfig.getRtspSSLPort())) |
|
||||
zlmServerConfig.setRtspSSlport(mediaConfig.getRtspSSLPort()); |
|
||||
|
|
||||
if(!StringUtils.isEmpty(mediaConfig.getRtmpPort())) |
|
||||
zlmServerConfig.setRtmpPort(mediaConfig.getRtmpPort()); |
|
||||
|
|
||||
if(!StringUtils.isEmpty(mediaConfig.getRtmpSSlPort())) |
|
||||
zlmServerConfig.setRtmpSslPort(mediaConfig.getRtmpSSlPort()); |
|
||||
|
|
||||
if(!StringUtils.isEmpty(mediaConfig.getRtpProxyPort())) |
|
||||
zlmServerConfig.setRtpProxyPort(mediaConfig.getRtpProxyPort()); |
|
||||
|
|
||||
redisCatchStorage.updateMediaInfo(zlmServerConfig); |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,92 @@ |
|||||
|
package com.genersoft.iot.vmp.media.zlm.dto; |
||||
|
|
||||
|
public interface IMediaServerItem { |
||||
|
|
||||
|
String getId(); |
||||
|
|
||||
|
void setId(String id); |
||||
|
|
||||
|
String getIp(); |
||||
|
|
||||
|
void setIp(String ip); |
||||
|
|
||||
|
String getHookIp(); |
||||
|
|
||||
|
void setHookIp(String hookIp); |
||||
|
|
||||
|
String getSdpIp(); |
||||
|
|
||||
|
void setSdpIp(String sdpIp); |
||||
|
|
||||
|
String getStreamIp(); |
||||
|
|
||||
|
void setStreamIp(String streamIp); |
||||
|
|
||||
|
int getHttpPort(); |
||||
|
|
||||
|
void setHttpPort(int httpPort); |
||||
|
|
||||
|
int getHttpSSlPort(); |
||||
|
|
||||
|
void setHttpSSlPort(int httpSSlPort); |
||||
|
|
||||
|
int getRtmpPort(); |
||||
|
|
||||
|
void setRtmpPort(int rtmpPort); |
||||
|
|
||||
|
int getRtmpSSlPort(); |
||||
|
|
||||
|
void setRtmpSSlPort(int rtmpSSlPort); |
||||
|
|
||||
|
int getRtpProxyPort(); |
||||
|
|
||||
|
void setRtpProxyPort(int rtpProxyPort); |
||||
|
|
||||
|
int getRtspPort(); |
||||
|
|
||||
|
void setRtspPort(int rtspPort); |
||||
|
|
||||
|
int getRtspSSLPort(); |
||||
|
|
||||
|
void setRtspSSLPort(int rtspSSLPort); |
||||
|
|
||||
|
boolean isAutoConfig(); |
||||
|
|
||||
|
void setAutoConfig(boolean autoConfig); |
||||
|
|
||||
|
String getSecret(); |
||||
|
|
||||
|
void setSecret(String secret); |
||||
|
|
||||
|
String getStreamNoneReaderDelayMS(); |
||||
|
|
||||
|
void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS); |
||||
|
|
||||
|
boolean isRtpEnable(); |
||||
|
|
||||
|
void setRtpEnable(boolean rtpEnable); |
||||
|
|
||||
|
String getRtpPortRange(); |
||||
|
|
||||
|
void setRtpPortRange(String rtpPortRange); |
||||
|
|
||||
|
int getRecordAssistPort(); |
||||
|
|
||||
|
void setRecordAssistPort(int recordAssistPort); |
||||
|
|
||||
|
boolean isDocker(); |
||||
|
|
||||
|
void setDocker(boolean docker); |
||||
|
|
||||
|
String getUpdateTime(); |
||||
|
|
||||
|
void setUpdateTime(String updateTime); |
||||
|
|
||||
|
String getCreateTime(); |
||||
|
|
||||
|
void setCreateTime(String createTime); |
||||
|
|
||||
|
int getCount(); |
||||
|
|
||||
|
void setCount(int count); |
||||
|
} |
@ -0,0 +1,254 @@ |
|||||
|
package com.genersoft.iot.vmp.media.zlm.dto; |
||||
|
|
||||
|
|
||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
|
||||
|
public class MediaServerItem implements IMediaServerItem{ |
||||
|
|
||||
|
private String id; |
||||
|
|
||||
|
private String ip; |
||||
|
|
||||
|
private String hookIp; |
||||
|
|
||||
|
private String sdpIp; |
||||
|
|
||||
|
private String streamIp; |
||||
|
|
||||
|
private int httpPort; |
||||
|
|
||||
|
private int httpSSlPort; |
||||
|
|
||||
|
private int rtmpPort; |
||||
|
|
||||
|
private int rtmpSSlPort; |
||||
|
|
||||
|
private int rtpProxyPort; |
||||
|
|
||||
|
private int rtspPort; |
||||
|
|
||||
|
private int rtspSSLPort; |
||||
|
|
||||
|
private boolean autoConfig; |
||||
|
|
||||
|
private String secret; |
||||
|
|
||||
|
private String streamNoneReaderDelayMS; |
||||
|
|
||||
|
private boolean rtpEnable; |
||||
|
|
||||
|
private String rtpPortRange; |
||||
|
|
||||
|
private int recordAssistPort; |
||||
|
|
||||
|
private String createTime; |
||||
|
|
||||
|
private String updateTime; |
||||
|
|
||||
|
private boolean docker; |
||||
|
|
||||
|
private int count; |
||||
|
|
||||
|
public MediaServerItem() { |
||||
|
} |
||||
|
|
||||
|
public MediaServerItem(ZLMServerConfig zlmServerConfig, String sipIp) { |
||||
|
id = zlmServerConfig.getGeneralMediaServerId(); |
||||
|
ip = zlmServerConfig.getIp(); |
||||
|
hookIp = StringUtils.isEmpty(zlmServerConfig.getHookIp())? sipIp: zlmServerConfig.getHookIp(); |
||||
|
sdpIp = StringUtils.isEmpty(zlmServerConfig.getSdpIp())? zlmServerConfig.getIp(): zlmServerConfig.getSdpIp(); |
||||
|
streamIp = StringUtils.isEmpty(zlmServerConfig.getStreamIp())? zlmServerConfig.getIp(): zlmServerConfig.getStreamIp(); |
||||
|
httpPort = zlmServerConfig.getHttpPort(); |
||||
|
httpSSlPort = zlmServerConfig.getHttpSSLport(); |
||||
|
rtmpPort = zlmServerConfig.getRtmpPort(); |
||||
|
rtmpSSlPort = zlmServerConfig.getRtmpSslPort(); |
||||
|
rtpProxyPort = zlmServerConfig.getRtpProxyPort(); |
||||
|
rtspPort = zlmServerConfig.getRtspPort(); |
||||
|
rtspSSLPort = zlmServerConfig.getRtspSSlport(); |
||||
|
autoConfig = true; // 默认值true;
|
||||
|
secret = zlmServerConfig.getApiSecret(); |
||||
|
streamNoneReaderDelayMS = zlmServerConfig.getGeneralStreamNoneReaderDelayMS(); |
||||
|
rtpEnable = false; // 默认使用单端口;直到用户自己设置开启多端口
|
||||
|
recordAssistPort = 0; // 默认关闭
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getIp() { |
||||
|
return ip; |
||||
|
} |
||||
|
|
||||
|
public void setIp(String ip) { |
||||
|
this.ip = ip; |
||||
|
} |
||||
|
|
||||
|
public String getHookIp() { |
||||
|
return hookIp; |
||||
|
} |
||||
|
|
||||
|
public void setHookIp(String hookIp) { |
||||
|
this.hookIp = hookIp; |
||||
|
} |
||||
|
|
||||
|
public String getSdpIp() { |
||||
|
return sdpIp; |
||||
|
} |
||||
|
|
||||
|
public void setSdpIp(String sdpIp) { |
||||
|
this.sdpIp = sdpIp; |
||||
|
} |
||||
|
|
||||
|
public String getStreamIp() { |
||||
|
return streamIp; |
||||
|
} |
||||
|
|
||||
|
public void setStreamIp(String streamIp) { |
||||
|
this.streamIp = streamIp; |
||||
|
} |
||||
|
|
||||
|
public int getHttpPort() { |
||||
|
return httpPort; |
||||
|
} |
||||
|
|
||||
|
public void setHttpPort(int httpPort) { |
||||
|
this.httpPort = httpPort; |
||||
|
} |
||||
|
|
||||
|
public int getHttpSSlPort() { |
||||
|
return httpSSlPort; |
||||
|
} |
||||
|
|
||||
|
public void setHttpSSlPort(int httpSSlPort) { |
||||
|
this.httpSSlPort = httpSSlPort; |
||||
|
} |
||||
|
|
||||
|
public int getRtmpPort() { |
||||
|
return rtmpPort; |
||||
|
} |
||||
|
|
||||
|
public void setRtmpPort(int rtmpPort) { |
||||
|
this.rtmpPort = rtmpPort; |
||||
|
} |
||||
|
|
||||
|
public int getRtmpSSlPort() { |
||||
|
return rtmpSSlPort; |
||||
|
} |
||||
|
|
||||
|
public void setRtmpSSlPort(int rtmpSSlPort) { |
||||
|
this.rtmpSSlPort = rtmpSSlPort; |
||||
|
} |
||||
|
|
||||
|
public int getRtpProxyPort() { |
||||
|
return rtpProxyPort; |
||||
|
} |
||||
|
|
||||
|
public void setRtpProxyPort(int rtpProxyPort) { |
||||
|
this.rtpProxyPort = rtpProxyPort; |
||||
|
} |
||||
|
|
||||
|
public int getRtspPort() { |
||||
|
return rtspPort; |
||||
|
} |
||||
|
|
||||
|
public void setRtspPort(int rtspPort) { |
||||
|
this.rtspPort = rtspPort; |
||||
|
} |
||||
|
|
||||
|
public int getRtspSSLPort() { |
||||
|
return rtspSSLPort; |
||||
|
} |
||||
|
|
||||
|
public void setRtspSSLPort(int rtspSSLPort) { |
||||
|
this.rtspSSLPort = rtspSSLPort; |
||||
|
} |
||||
|
|
||||
|
public boolean isAutoConfig() { |
||||
|
return autoConfig; |
||||
|
} |
||||
|
|
||||
|
public void setAutoConfig(boolean autoConfig) { |
||||
|
this.autoConfig = autoConfig; |
||||
|
} |
||||
|
|
||||
|
public String getSecret() { |
||||
|
return secret; |
||||
|
} |
||||
|
|
||||
|
public void setSecret(String secret) { |
||||
|
this.secret = secret; |
||||
|
} |
||||
|
|
||||
|
public String getStreamNoneReaderDelayMS() { |
||||
|
return streamNoneReaderDelayMS; |
||||
|
} |
||||
|
|
||||
|
public void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS) { |
||||
|
this.streamNoneReaderDelayMS = streamNoneReaderDelayMS; |
||||
|
} |
||||
|
|
||||
|
public boolean isRtpEnable() { |
||||
|
return rtpEnable; |
||||
|
} |
||||
|
|
||||
|
public void setRtpEnable(boolean rtpEnable) { |
||||
|
this.rtpEnable = rtpEnable; |
||||
|
} |
||||
|
|
||||
|
public String getRtpPortRange() { |
||||
|
return rtpPortRange; |
||||
|
} |
||||
|
|
||||
|
public void setRtpPortRange(String rtpPortRange) { |
||||
|
this.rtpPortRange = rtpPortRange; |
||||
|
} |
||||
|
|
||||
|
public int getRecordAssistPort() { |
||||
|
return recordAssistPort; |
||||
|
} |
||||
|
|
||||
|
public void setRecordAssistPort(int recordAssistPort) { |
||||
|
this.recordAssistPort = recordAssistPort; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isDocker() { |
||||
|
return docker; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void setDocker(boolean docker) { |
||||
|
this.docker = docker; |
||||
|
} |
||||
|
|
||||
|
public String getCreateTime() { |
||||
|
return createTime; |
||||
|
} |
||||
|
|
||||
|
public void setCreateTime(String createTime) { |
||||
|
this.createTime = createTime; |
||||
|
} |
||||
|
|
||||
|
public String getUpdateTime() { |
||||
|
return updateTime; |
||||
|
} |
||||
|
|
||||
|
public void setUpdateTime(String updateTime) { |
||||
|
this.updateTime = updateTime; |
||||
|
} |
||||
|
|
||||
|
public int getCount() { |
||||
|
return count; |
||||
|
} |
||||
|
|
||||
|
public void setCount(int count) { |
||||
|
this.count = count; |
||||
|
} |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
package com.genersoft.iot.vmp.media.zlm.dto; |
||||
|
|
||||
|
/** |
||||
|
* 记录zlm运行中一些参数 |
||||
|
*/ |
||||
|
public class ZLMRunInfo { |
||||
|
|
||||
|
/** |
||||
|
* zlm当前流数量 |
||||
|
*/ |
||||
|
private int mediaCount; |
||||
|
|
||||
|
/** |
||||
|
* 在线状态 |
||||
|
*/ |
||||
|
private boolean online; |
||||
|
|
||||
|
public int getMediaCount() { |
||||
|
return mediaCount; |
||||
|
} |
||||
|
|
||||
|
public void setMediaCount(int mediaCount) { |
||||
|
this.mediaCount = mediaCount; |
||||
|
} |
||||
|
|
||||
|
public boolean isOnline() { |
||||
|
return online; |
||||
|
} |
||||
|
|
||||
|
public void setOnline(boolean online) { |
||||
|
this.online = online; |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
package com.genersoft.iot.vmp.service; |
||||
|
|
||||
|
import com.genersoft.iot.vmp.conf.MediaConfig; |
||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device; |
||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; |
||||
|
import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; |
||||
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 媒体服务节点 |
||||
|
*/ |
||||
|
public interface IMediaServerService { |
||||
|
|
||||
|
List<IMediaServerItem> getAll(); |
||||
|
|
||||
|
IMediaServerItem getOne(String generalMediaServerId); |
||||
|
|
||||
|
IMediaServerItem getOneByHostAndPort(String host, int port); |
||||
|
|
||||
|
/** |
||||
|
* 新的节点加入 |
||||
|
* @param zlmServerConfig |
||||
|
* @return |
||||
|
*/ |
||||
|
void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig); |
||||
|
|
||||
|
void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean b); |
||||
|
|
||||
|
IMediaServerItem getMediaServerForMinimumLoad(); |
||||
|
|
||||
|
void setZLMConfig(IMediaServerItem mediaServerItem); |
||||
|
|
||||
|
void init(); |
||||
|
|
||||
|
void closeRTPServer(Device device, String channelId); |
||||
|
|
||||
|
void update(MediaConfig mediaConfig); |
||||
|
|
||||
|
void addCount(String mediaServerId); |
||||
|
|
||||
|
void removeCount(String mediaServerId); |
||||
|
} |
@ -0,0 +1,340 @@ |
|||||
|
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.StreamInfo; |
||||
|
import com.genersoft.iot.vmp.conf.MediaConfig; |
||||
|
import com.genersoft.iot.vmp.conf.ProxyServletConfig; |
||||
|
import com.genersoft.iot.vmp.gb28181.bean.Device; |
||||
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; |
||||
|
import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; |
||||
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
||||
|
import com.genersoft.iot.vmp.media.zlm.dto.ZLMRunInfo; |
||||
|
import com.genersoft.iot.vmp.service.IMediaServerService; |
||||
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
||||
|
import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; |
||||
|
import org.mitre.dsmiley.httpproxy.ProxyServlet; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.text.SimpleDateFormat; |
||||
|
import java.util.*; |
||||
|
|
||||
|
/** |
||||
|
* 媒体服务器节点管理 |
||||
|
*/ |
||||
|
@Service |
||||
|
public class MediaServerServiceImpl implements IMediaServerService { |
||||
|
|
||||
|
private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); |
||||
|
|
||||
|
private Map<String, IMediaServerItem> zlmServers = new HashMap<>(); // 所有数据库的zlm的缓存
|
||||
|
private Map<String, Integer> zlmServerStatus = new LinkedHashMap<>(); // 所有上线的zlm的缓存以及负载
|
||||
|
|
||||
|
@Value("${sip.ip}") |
||||
|
private String sipIp; |
||||
|
|
||||
|
@Value("${server.ssl.enabled:false}") |
||||
|
private boolean sslEnabled; |
||||
|
|
||||
|
@Value("${server.port}") |
||||
|
private String serverPort; |
||||
|
|
||||
|
@Autowired |
||||
|
private MediaConfig mediaConfig; |
||||
|
|
||||
|
@Autowired |
||||
|
private ZLMRESTfulUtils zlmresTfulUtils; |
||||
|
|
||||
|
@Autowired |
||||
|
private MediaServerMapper mediaServerMapper; |
||||
|
|
||||
|
|
||||
|
@Autowired |
||||
|
private IRedisCatchStorage redisCatchStorage; |
||||
|
|
||||
|
@Autowired |
||||
|
private VideoStreamSessionManager streamSession; |
||||
|
|
||||
|
@Autowired |
||||
|
private ZLMRTPServerFactory zlmrtpServerFactory; |
||||
|
|
||||
|
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
||||
|
|
||||
|
/** |
||||
|
* 初始化 |
||||
|
*/ |
||||
|
@Override |
||||
|
public void init() { |
||||
|
zlmServers.clear(); |
||||
|
zlmServerStatus.clear(); |
||||
|
List<MediaServerItem> mediaServerItemList = mediaServerMapper.queryAll(); |
||||
|
for (IMediaServerItem mediaServerItem : mediaServerItemList) { |
||||
|
zlmServers.put(mediaServerItem.getId(), mediaServerItem); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void closeRTPServer(Device device, String channelId) { |
||||
|
StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); |
||||
|
IMediaServerItem mediaServerItem = null; |
||||
|
if (streamInfo != null) { |
||||
|
mediaServerItem = this.getOne (streamInfo.getMediaServerId()); |
||||
|
} |
||||
|
String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); |
||||
|
zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId); |
||||
|
streamSession.remove(device.getDeviceId(), channelId); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void update(MediaConfig mediaConfig) { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<IMediaServerItem> getAll() { |
||||
|
if (zlmServers.size() == 0) { |
||||
|
init(); |
||||
|
} |
||||
|
List<IMediaServerItem> result = new ArrayList<>(); |
||||
|
for (String id : zlmServers.keySet()) { |
||||
|
IMediaServerItem mediaServerItem = zlmServers.get(id); |
||||
|
mediaServerItem.setCount(zlmServerStatus.get(id) == null ? 0 : zlmServerStatus.get(id)); |
||||
|
result.add(mediaServerItem); |
||||
|
} |
||||
|
return result; |
||||
|
|
||||
|
|
||||
|
// return mediaServerMapper.queryAll();
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取单个zlm服务器 |
||||
|
* @param mediaServerId 服务id |
||||
|
* @return MediaServerItem |
||||
|
*/ |
||||
|
@Override |
||||
|
public IMediaServerItem getOne(String mediaServerId) { |
||||
|
if (mediaServerId ==null) return null; |
||||
|
IMediaServerItem mediaServerItem = zlmServers.get(mediaServerId); |
||||
|
if (mediaServerItem != null) { |
||||
|
mediaServerItem.setCount(zlmServerStatus.get(mediaServerId) == null ? 0 : zlmServerStatus.get(mediaServerId)); |
||||
|
return mediaServerItem; |
||||
|
}else { |
||||
|
IMediaServerItem item = mediaServerMapper.queryOne(mediaServerId); |
||||
|
if (item != null) { |
||||
|
zlmServers.put(item.getId(), item); |
||||
|
} |
||||
|
return item; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public IMediaServerItem getOneByHostAndPort(String host, int port) { |
||||
|
return mediaServerMapper.queryOneByHostAndPort(host, port); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 处理zlm上线 |
||||
|
* @param zlmServerConfig zlm上线携带的参数 |
||||
|
*/ |
||||
|
@Override |
||||
|
public void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig) { |
||||
|
logger.info("[ {} ]-[ {}:{} ]已连接", |
||||
|
zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); |
||||
|
|
||||
|
IMediaServerItem serverItem = getOne(zlmServerConfig.getGeneralMediaServerId()); |
||||
|
String now = this.format.format(new Date(System.currentTimeMillis())); |
||||
|
if (serverItem != null) { |
||||
|
serverItem.setSecret(zlmServerConfig.getApiSecret()); |
||||
|
serverItem.setIp(zlmServerConfig.getIp()); |
||||
|
// 如果是配置文件中的zlm。 也就是默认zlm。 一切以配置文件内容为准
|
||||
|
// docker部署不会使用zlm配置的端口号;
|
||||
|
// 直接编译部署的使用配置文件的端口号,如果zlm修改配改了配置,wvp自动修改
|
||||
|
|
||||
|
if (serverItem.getId().equals(mediaConfig.getId()) |
||||
|
|| (serverItem.getIp().equals(mediaConfig.getIp()) && serverItem.getHttpPort() == mediaConfig.getHttpPort())) { |
||||
|
// 配置文件的zlm
|
||||
|
mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId()); |
||||
|
mediaConfig.setUpdateTime(now); |
||||
|
if (mediaConfig.getHttpPort() == 0) mediaConfig.setHttpPort(zlmServerConfig.getHttpPort()); |
||||
|
if (mediaConfig.getHttpSSlPort() == 0) mediaConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); |
||||
|
if (mediaConfig.getRtmpPort() == 0) mediaConfig.setRtmpPort(zlmServerConfig.getRtmpPort()); |
||||
|
if (mediaConfig.getRtmpSSlPort() == 0) mediaConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); |
||||
|
if (mediaConfig.getRtspPort() == 0) mediaConfig.setRtspPort(zlmServerConfig.getRtspPort()); |
||||
|
if (mediaConfig.getRtspSSLPort() == 0) mediaConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); |
||||
|
if (mediaConfig.getRtpProxyPort() == 0) mediaConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); |
||||
|
mediaServerMapper.update(mediaConfig); |
||||
|
serverItem = mediaConfig.getMediaSerItem(); |
||||
|
setZLMConfig(mediaConfig); |
||||
|
}else { |
||||
|
if (!serverItem.isDocker()) { |
||||
|
serverItem.setHttpPort(zlmServerConfig.getHttpPort()); |
||||
|
serverItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); |
||||
|
serverItem.setRtmpPort(zlmServerConfig.getRtmpPort()); |
||||
|
serverItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); |
||||
|
serverItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); |
||||
|
serverItem.setRtspPort(zlmServerConfig.getRtspPort()); |
||||
|
|
||||
|
} |
||||
|
serverItem.setUpdateTime(now); |
||||
|
mediaServerMapper.update(serverItem); |
||||
|
setZLMConfig(serverItem); |
||||
|
} |
||||
|
}else { |
||||
|
if (zlmServerConfig.getGeneralMediaServerId().equals(mediaConfig.getId()) |
||||
|
|| (zlmServerConfig.getIp().equals(mediaConfig.getIp()) && zlmServerConfig.getHttpPort() == mediaConfig.getHttpPort())) { |
||||
|
mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId()); |
||||
|
mediaConfig.setCreateTime(now); |
||||
|
mediaConfig.setUpdateTime(now); |
||||
|
serverItem = mediaConfig; |
||||
|
mediaServerMapper.add(mediaConfig); |
||||
|
}else { |
||||
|
// 一个新的zlm接入wvp
|
||||
|
serverItem = new MediaServerItem(zlmServerConfig, sipIp); |
||||
|
serverItem.setCreateTime(now); |
||||
|
serverItem.setUpdateTime(now); |
||||
|
mediaServerMapper.add(serverItem); |
||||
|
} |
||||
|
} |
||||
|
// 更新缓存
|
||||
|
if (zlmServerStatus.get(serverItem.getId()) == null) { |
||||
|
zlmServers.put(serverItem.getId(), serverItem); |
||||
|
zlmServerStatus.put(serverItem.getId(),0); |
||||
|
} |
||||
|
// 查询服务流数量
|
||||
|
IMediaServerItem finalServerItem = serverItem; |
||||
|
zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{ |
||||
|
Integer code = mediaList.getInteger("code"); |
||||
|
if (code == 0) { |
||||
|
JSONArray data = mediaList.getJSONArray("data"); |
||||
|
if (data != null) { |
||||
|
zlmServerStatus.put(finalServerItem.getId(),data.size()); |
||||
|
}else { |
||||
|
zlmServerStatus.put(finalServerItem.getId(),0); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
})); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新缓存 |
||||
|
* @param mediaServerItem zlm服务 |
||||
|
* @param count 在线数 |
||||
|
* @param online 在线状态 |
||||
|
*/ |
||||
|
@Override |
||||
|
public void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean online) { |
||||
|
if (mediaServerItem != null) { |
||||
|
zlmServers.put(mediaServerItem.getId(), mediaServerItem); |
||||
|
Collection<Integer> values = zlmServerStatus.values(); |
||||
|
if (online != null && count != null) { |
||||
|
zlmServerStatus.put(mediaServerItem.getId(), count); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void addCount(String mediaServerId) { |
||||
|
if (zlmServerStatus.get(mediaServerId) != null) { |
||||
|
zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) + 1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void removeCount(String mediaServerId) { |
||||
|
if (zlmServerStatus.get(mediaServerId) != null) { |
||||
|
zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) - 1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取负载最低的节点 |
||||
|
* @return MediaServerItem |
||||
|
*/ |
||||
|
@Override |
||||
|
public IMediaServerItem getMediaServerForMinimumLoad() { |
||||
|
int mediaCount = -1; |
||||
|
String key = null; |
||||
|
System.out.println(JSON.toJSONString(zlmServerStatus)); |
||||
|
if (zlmServerStatus.size() == 1) { |
||||
|
Map.Entry entry = zlmServerStatus.entrySet().iterator().next(); |
||||
|
key= (String) entry.getKey(); |
||||
|
}else { |
||||
|
for (String id : zlmServerStatus.keySet()) { |
||||
|
if (key == null) { |
||||
|
key = id; |
||||
|
mediaCount = zlmServerStatus.get(id); |
||||
|
} |
||||
|
if (zlmServerStatus.get(id) == 0) { |
||||
|
key = id; |
||||
|
break; |
||||
|
}else if (mediaCount >= zlmServerStatus.get(id)){ |
||||
|
mediaCount = zlmServerStatus.get(id); |
||||
|
key = id; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (key == null) { |
||||
|
logger.info("获取负载最低的节点时无在线节点"); |
||||
|
return null; |
||||
|
}else{ |
||||
|
return zlmServers.get(key); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 对zlm服务器进行基础配置 |
||||
|
* @param mediaServerItem 服务ID |
||||
|
*/ |
||||
|
@Override |
||||
|
public void setZLMConfig(IMediaServerItem mediaServerItem) { |
||||
|
logger.info("[ {} ]-[ {}:{} ]设置zlm", |
||||
|
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); |
||||
|
String protocol = sslEnabled ? "https" : "http"; |
||||
|
String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort); |
||||
|
String recordHookPrex = null; |
||||
|
if (mediaServerItem.getRecordAssistPort() != 0) { |
||||
|
recordHookPrex = String.format("http://127.0.0.1:%s/api/record", mediaServerItem.getRecordAssistPort()); |
||||
|
} |
||||
|
Map<String, Object> param = new HashMap<>(); |
||||
|
param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline
|
||||
|
param.put("ffmpeg.cmd","%s -fflags nobuffer -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s"); |
||||
|
param.put("hook.enable","1"); |
||||
|
param.put("hook.on_flow_report",""); |
||||
|
param.put("hook.on_play",String.format("%s/on_play", hookPrex)); |
||||
|
param.put("hook.on_http_access",""); |
||||
|
param.put("hook.on_publish", String.format("%s/on_publish", hookPrex)); |
||||
|
param.put("hook.on_record_mp4",recordHookPrex != null? String.format("%s/on_record_mp4", recordHookPrex): ""); |
||||
|
param.put("hook.on_record_ts",""); |
||||
|
param.put("hook.on_rtsp_auth",""); |
||||
|
param.put("hook.on_rtsp_realm",""); |
||||
|
param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrex)); |
||||
|
param.put("hook.on_shell_login",String.format("%s/on_shell_login", hookPrex)); |
||||
|
param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrex)); |
||||
|
param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex)); |
||||
|
param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex)); |
||||
|
param.put("hook.timeoutSec","20"); |
||||
|
param.put("general.streamNoneReaderDelayMS",mediaServerItem.getStreamNoneReaderDelayMS()); |
||||
|
|
||||
|
JSONObject responseJSON = zlmresTfulUtils.setServerConfig(mediaServerItem, param); |
||||
|
|
||||
|
if (responseJSON != null && responseJSON.getInteger("code") == 0) { |
||||
|
logger.info("[ {} ]-[ {}:{} ]设置zlm成功", |
||||
|
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); |
||||
|
}else { |
||||
|
logger.info("[ {} ]-[ {}:{} ]设置zlm失败" + responseJSON.getString("msg"), |
||||
|
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,99 @@ |
|||||
|
package com.genersoft.iot.vmp.storager.dao; |
||||
|
|
||||
|
import com.genersoft.iot.vmp.conf.MediaConfig; |
||||
|
import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; |
||||
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
||||
|
import org.apache.ibatis.annotations.Insert; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
import org.apache.ibatis.annotations.Select; |
||||
|
import org.apache.ibatis.annotations.Update; |
||||
|
import org.springframework.stereotype.Repository; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
|
||||
|
@Mapper |
||||
|
@Repository |
||||
|
public interface MediaServerMapper { |
||||
|
|
||||
|
@Insert("INSERT INTO media_server (" + |
||||
|
"id, " + |
||||
|
"ip, " + |
||||
|
"hookIp, " + |
||||
|
"sdpIp, " + |
||||
|
"streamIp, " + |
||||
|
"httpPort, " + |
||||
|
"httpSSlPort, " + |
||||
|
"rtmpPort, " + |
||||
|
"rtmpSSlPort, " + |
||||
|
"rtpProxyPort, " + |
||||
|
"rtspPort, " + |
||||
|
"rtspSSLPort, " + |
||||
|
"autoConfig, " + |
||||
|
"secret, " + |
||||
|
"streamNoneReaderDelayMS, " + |
||||
|
"rtpEnable, " + |
||||
|
"rtpPortRange, " + |
||||
|
"recordAssistPort, " + |
||||
|
"createTime, " + |
||||
|
"updateTime" + |
||||
|
") VALUES " + |
||||
|
"(" + |
||||
|
"'${id}', " + |
||||
|
"'${ip}', " + |
||||
|
"'${hookIp}', " + |
||||
|
"'${sdpIp}', " + |
||||
|
"'${streamIp}', " + |
||||
|
"${httpPort}, " + |
||||
|
"${httpSSlPort}, " + |
||||
|
"${rtmpPort}, " + |
||||
|
"${rtmpSSlPort}, " + |
||||
|
"${rtpProxyPort}, " + |
||||
|
"${rtspPort}, " + |
||||
|
"${rtspSSLPort}, " + |
||||
|
"${autoConfig}, " + |
||||
|
"'${secret}', " + |
||||
|
"${streamNoneReaderDelayMS}, " + |
||||
|
"${rtpEnable}, " + |
||||
|
"'${rtpPortRange}', " + |
||||
|
"${recordAssistPort}, " + |
||||
|
"'${createTime}', " + |
||||
|
"'${updateTime}')") |
||||
|
int add(IMediaServerItem mediaServerItem); |
||||
|
|
||||
|
@Update(value = {" <script>" + |
||||
|
"UPDATE media_server " + |
||||
|
"SET updateTime='${updateTime}'" + |
||||
|
"<if test=\"ip != null\">, ip='${ip}'</if>" + |
||||
|
"<if test=\"hookIp != null\">, hookIp='${hookIp}'</if>" + |
||||
|
"<if test=\"sdpIp != null\">, sdpIp='${sdpIp}'</if>" + |
||||
|
"<if test=\"streamIp != null\">, streamIp='${streamIp}'</if>" + |
||||
|
"<if test=\"httpPort != null\">, httpPort=${httpPort}</if>" + |
||||
|
"<if test=\"httpSSlPort != null\">, httpSSlPort=${httpSSlPort}</if>" + |
||||
|
"<if test=\"rtmpPort != null\">, rtmpPort=${rtmpPort}</if>" + |
||||
|
"<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=${rtmpSSlPort}</if>" + |
||||
|
"<if test=\"rtpProxyPort != null\">, rtpProxyPort=${rtpProxyPort}</if>" + |
||||
|
"<if test=\"rtspPort != null\">, rtspPort=${rtspPort}</if>" + |
||||
|
"<if test=\"rtspSSLPort != null\">, rtspSSLPort=${rtspSSLPort}</if>" + |
||||
|
"<if test=\"autoConfig != null\">, autoConfig=${autoConfig}</if>" + |
||||
|
"<if test=\"streamNoneReaderDelayMS != null\">, streamNoneReaderDelayMS=${streamNoneReaderDelayMS}</if>" + |
||||
|
"<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" + |
||||
|
"<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" + |
||||
|
"<if test=\"secret != null\">, secret='${secret}'</if>" + |
||||
|
"<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" + |
||||
|
"WHERE id='${id}'"+ |
||||
|
" </script>"}) |
||||
|
int update(IMediaServerItem mediaServerItem); |
||||
|
|
||||
|
@Select("SELECT * FROM media_server WHERE id='${id}'") |
||||
|
MediaServerItem queryOne(String id); |
||||
|
|
||||
|
@Select("SELECT * FROM media_server") |
||||
|
List<MediaServerItem> queryAll(); |
||||
|
|
||||
|
@Select("DELETE FROM media_server WHERE id='${id}'") |
||||
|
int delOne(String secret); |
||||
|
|
||||
|
@Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}") |
||||
|
MediaServerItem queryOneByHostAndPort(String host, int port); |
||||
|
} |
Binary file not shown.
@ -0,0 +1,32 @@ |
|||||
|
import axios from 'axios'; |
||||
|
|
||||
|
class MediaServer{ |
||||
|
|
||||
|
constructor() { |
||||
|
this.$axios = axios; |
||||
|
} |
||||
|
|
||||
|
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); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
getMediaServer(id, callback){ |
||||
|
this.$axios({ |
||||
|
method: 'get', |
||||
|
url:`/api/server/media_server/one/` + id, |
||||
|
}).then(function (res) { |
||||
|
if (typeof (callback) == "function") callback(res.data) |
||||
|
}).catch(function (error) { |
||||
|
console.log(error); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default MediaServer; |
Loading…
Reference in new issue