优化集群方案, 每个zlm一套ssrc;

优化集群下的docker接入逻辑;
更正sql脚本;
支持重启不设置设备离线。重启SIP事务不丢失
This commit is contained in:
64850858
2021-07-26 11:40:32 +08:00
parent 379830f7eb
commit 3469271ec2
57 changed files with 1318 additions and 1076 deletions

View File

@@ -3,15 +3,14 @@ package com.genersoft.iot.vmp.media.zlm;
import java.util.List;
import java.util.UUID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.conf.UserSetup;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
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.IVideoManagerStorager;
import com.genersoft.iot.vmp.service.IPlayService;
@@ -42,7 +41,6 @@ public class ZLMHttpHookListener {
private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class);
@Autowired
private SIPCommander cmder;
@@ -125,7 +123,7 @@ public class ZLMHttpHookListener {
String mediaServerId = json.getString("mediaServerId");
ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json);
if (subscribe != null ) {
IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
if (mediaInfo != null) {
subscribe.response(mediaInfo, json);
}
@@ -150,7 +148,7 @@ public class ZLMHttpHookListener {
String mediaServerId = json.getString("mediaServerId");
ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json);
if (subscribe != null) {
IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
if (mediaInfo != null) {
subscribe.response(mediaInfo, json);
}
@@ -237,7 +235,7 @@ public class ZLMHttpHookListener {
String mediaServerId = json.getString("mediaServerId");
ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json);
if (subscribe != null ) {
IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
if (mediaInfo != null) {
subscribe.response(mediaInfo, json);
}
@@ -264,7 +262,7 @@ public class ZLMHttpHookListener {
String mediaServerId = json.getString("mediaServerId");
ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json);
if (subscribe != null ) {
IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
if (mediaInfo != null) {
subscribe.response(mediaInfo, json);
}
@@ -297,7 +295,7 @@ public class ZLMHttpHookListener {
}
}else {
if (!"rtp".equals(app) ){
IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
if (regist) {
zlmMediaListManager.addMedia(mediaServerItem, app, streamId);
}else {
@@ -369,7 +367,7 @@ public class ZLMHttpHookListener {
logger.debug("ZLM HOOK on_stream_not_found API调用参数" + json.toString());
}
String mediaServerId = json.getString("mediaServerId");
IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
if (userSetup.isAutoApplyPlay() && mediaInfo != null) {
String app = json.getString("app");
String streamId = json.getString("stream");
@@ -381,7 +379,13 @@ public class ZLMHttpHookListener {
Device device = storager.queryVideoDevice(deviceId);
if (device != null) {
UUID uuid = UUID.randomUUID();
cmder.playStreamCmd(mediaInfo, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> {
SSRCInfo ssrcInfo;
String streamId2 = null;
if (mediaInfo.isRtpEnable()) {
streamId2 = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
}
ssrcInfo = mediaServerService.openRTPServer(mediaInfo, streamId2);
cmder.playStreamCmd(mediaInfo, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
logger.info("收到订阅消息: " + response.toJSONString());
playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString());
}, null);

View File

@@ -1,7 +1,6 @@
package com.genersoft.iot.vmp.media.zlm;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import org.springframework.stereotype.Component;
@@ -32,7 +31,7 @@ public class ZLMHttpHookSubscribe {
}
public interface Event{
void response(IMediaServerItem mediaServerItem, JSONObject response);
void response(MediaServerItem mediaServerItem, JSONObject response);
}
private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>();
@@ -58,6 +57,9 @@ public class ZLMHttpHookSubscribe {
if (result == null) {
result = key.getString(s).equals(hookResponse.getString(s));
}else {
if (key.getString(s) == null) {
continue;
}
result = result && key.getString(s).equals(hookResponse.getString(s));
}
@@ -83,9 +85,9 @@ public class ZLMHttpHookSubscribe {
if (result == null) {
result = key.getString(s).equals(hookResponse.getString(s));
}else {
if (key.getString(s) == null) continue;
result = result && key.getString(s).equals(hookResponse.getString(s));
}
}
if (null != result && result){
iterator.remove();

View File

@@ -1,12 +1,9 @@
package com.genersoft.iot.vmp.media.zlm;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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.StreamProxyItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.service.IStreamPushService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
@@ -76,7 +73,7 @@ public class ZLMMediaListManager {
jsonObject.put("stream", streamPushItem.getStream());
jsonObject.put("mediaServerId", mediaServerItem.getId());
subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject,
(IMediaServerItem mediaServerItemInuse, JSONObject response)->{
(MediaServerItem mediaServerItemInuse, JSONObject response)->{
updateMedia(mediaServerItem, response.getString("app"), response.getString("stream"));
}
);
@@ -86,13 +83,13 @@ public class ZLMMediaListManager {
}
public void addMedia(IMediaServerItem mediaServerItem, String app, String streamId) {
public void addMedia(MediaServerItem mediaServerItem, String app, String streamId) {
//使用异步更新推流
updateMedia(mediaServerItem, app, streamId);
}
public void updateMedia(IMediaServerItem mediaServerItem, String app, String streamId) {
public void updateMedia(MediaServerItem mediaServerItem, String app, String streamId) {
//使用异步更新推流
zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{

View File

@@ -2,14 +2,11 @@ package com.genersoft.iot.vmp.media.zlm;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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 okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.*;
@@ -27,7 +24,7 @@ public class ZLMRESTfulUtils {
void run(JSONObject response);
}
public JSONObject sendPost(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) {
public JSONObject sendPost(MediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) {
OkHttpClient client = new OkHttpClient();
String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
JSONObject responseJSON = null;
@@ -93,7 +90,7 @@ public class ZLMRESTfulUtils {
}
public void sendPostForImg(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) {
public void sendPostForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) {
OkHttpClient client = new OkHttpClient();
String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
JSONObject responseJSON = null;
@@ -139,7 +136,7 @@ public class ZLMRESTfulUtils {
}
public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream, String schema, RequestCallback callback){
public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream, String schema, RequestCallback callback){
Map<String, Object> param = new HashMap<>();
if (app != null) param.put("app",app);
if (stream != null) param.put("stream",stream);
@@ -148,15 +145,15 @@ public class ZLMRESTfulUtils {
return sendPost(mediaServerItem, "getMediaList",param, callback);
}
public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream){
public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream){
return getMediaList(mediaServerItem, app, stream,null, null);
}
public JSONObject getMediaList(IMediaServerItem mediaServerItem,RequestCallback callback){
public JSONObject getMediaList(MediaServerItem mediaServerItem, RequestCallback callback){
return sendPost(mediaServerItem, "getMediaList",null, callback);
}
public JSONObject getMediaInfo(IMediaServerItem mediaServerItem,String app, String schema, String stream){
public JSONObject getMediaInfo(MediaServerItem mediaServerItem, String app, String schema, String stream){
Map<String, Object> param = new HashMap<>();
param.put("app",app);
param.put("schema",schema);
@@ -165,13 +162,13 @@ public class ZLMRESTfulUtils {
return sendPost(mediaServerItem, "getMediaInfo",param, null);
}
public JSONObject getRtpInfo(IMediaServerItem mediaServerItem,String stream_id){
public JSONObject getRtpInfo(MediaServerItem mediaServerItem, String stream_id){
Map<String, Object> param = new HashMap<>();
param.put("stream_id",stream_id);
return sendPost(mediaServerItem, "getRtpInfo",param, null);
}
public JSONObject addFFmpegSource(IMediaServerItem mediaServerItem,String src_url, String dst_url, String timeout_ms,
public JSONObject addFFmpegSource(MediaServerItem mediaServerItem, String src_url, String dst_url, String timeout_ms,
boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){
logger.info(src_url);
logger.info(dst_url);
@@ -185,41 +182,41 @@ public class ZLMRESTfulUtils {
return sendPost(mediaServerItem, "addFFmpegSource",param, null);
}
public JSONObject delFFmpegSource(IMediaServerItem mediaServerItem,String key){
public JSONObject delFFmpegSource(MediaServerItem mediaServerItem, String key){
Map<String, Object> param = new HashMap<>();
param.put("key", key);
return sendPost(mediaServerItem, "delFFmpegSource",param, null);
}
public JSONObject getMediaServerConfig(IMediaServerItem mediaServerItem){
public JSONObject getMediaServerConfig(MediaServerItem mediaServerItem){
return sendPost(mediaServerItem, "getServerConfig",null, null);
}
public JSONObject setServerConfig(IMediaServerItem mediaServerItem, Map<String, Object> param){
public JSONObject setServerConfig(MediaServerItem mediaServerItem, Map<String, Object> param){
return sendPost(mediaServerItem,"setServerConfig",param, null);
}
public JSONObject openRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param){
public JSONObject openRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param){
return sendPost(mediaServerItem, "openRtpServer",param, null);
}
public JSONObject closeRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param) {
public JSONObject closeRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param) {
return sendPost(mediaServerItem, "closeRtpServer",param, null);
}
public JSONObject listRtpServer(IMediaServerItem mediaServerItem) {
public JSONObject listRtpServer(MediaServerItem mediaServerItem) {
return sendPost(mediaServerItem, "listRtpServer",null, null);
}
public JSONObject startSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) {
public JSONObject startSendRtp(MediaServerItem mediaServerItem, Map<String, Object> param) {
return sendPost(mediaServerItem, "startSendRtp",param, null);
}
public JSONObject stopSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) {
public JSONObject stopSendRtp(MediaServerItem mediaServerItem, Map<String, Object> param) {
return sendPost(mediaServerItem, "stopSendRtp",param, null);
}
public JSONObject addStreamProxy(IMediaServerItem mediaServerItem,String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) {
public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) {
Map<String, Object> param = new HashMap<>();
param.put("vhost", "__defaultVhost__");
param.put("app", app);
@@ -231,7 +228,7 @@ public class ZLMRESTfulUtils {
return sendPost(mediaServerItem, "addStreamProxy",param, null);
}
public JSONObject closeStreams(IMediaServerItem mediaServerItem,String app, String stream) {
public JSONObject closeStreams(MediaServerItem mediaServerItem, String app, String stream) {
Map<String, Object> param = new HashMap<>();
param.put("vhost", "__defaultVhost__");
param.put("app", app);
@@ -240,17 +237,17 @@ public class ZLMRESTfulUtils {
return sendPost(mediaServerItem, "close_streams",param, null);
}
public JSONObject getAllSession(IMediaServerItem mediaServerItem) {
public JSONObject getAllSession(MediaServerItem mediaServerItem) {
return sendPost(mediaServerItem, "getAllSession",null, null);
}
public void kickSessions(IMediaServerItem mediaServerItem, String localPortSStr) {
public void kickSessions(MediaServerItem mediaServerItem, String localPortSStr) {
Map<String, Object> param = new HashMap<>();
param.put("local_port", localPortSStr);
sendPost(mediaServerItem, "kick_sessions",param, null);
}
public void getSnap(IMediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) {
public void getSnap(MediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) {
Map<String, Object> param = new HashMap<>();
param.put("url", flvUrl);
param.put("timeout_sec", timeout_sec);

View File

@@ -2,10 +2,7 @@ package com.genersoft.iot.vmp.media.zlm;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.session.SsrcUtil;
import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,29 +17,20 @@ public class ZLMRTPServerFactory {
private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory");
@Autowired
private MediaConfig mediaConfig;
@Autowired
private ZLMRESTfulUtils zlmresTfulUtils;
private int[] portRangeArray = new int[2];
private int currentPort = 0;
private Map<String, Integer> currentStreams = null;
public int createRTPServer(IMediaServerItem mediaServerItem, String streamId) {
if (currentStreams == null) {
currentStreams = new HashMap<>();
JSONObject jsonObject = zlmresTfulUtils.listRtpServer(mediaServerItem);
if (jsonObject != null) {
JSONArray data = jsonObject.getJSONArray("data");
if (data != null) {
for (int i = 0; i < data.size(); i++) {
JSONObject dataItem = data.getJSONObject(i);
currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port"));
}
public int createRTPServer(MediaServerItem mediaServerItem, String streamId) {
Map<String, Integer> currentStreams = new HashMap<>();
JSONObject listRtpServerJsonResult = zlmresTfulUtils.listRtpServer(mediaServerItem);
if (listRtpServerJsonResult != null) {
JSONArray data = listRtpServerJsonResult.getJSONArray("data");
if (data != null) {
for (int i = 0; i < data.size(); i++) {
JSONObject dataItem = data.getJSONObject(i);
currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port"));
}
}
}
@@ -56,18 +44,18 @@ public class ZLMRTPServerFactory {
Map<String, Object> param = new HashMap<>();
int result = -1;
int newPort = getPortFromportRange();
int newPort = getPortFromportRange(mediaServerItem);
param.put("port", newPort);
param.put("enable_tcp", 1);
param.put("stream_id", streamId);
JSONObject jsonObject = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
if (jsonObject != null) {
switch (jsonObject.getInteger("code")){
if (openRtpServerResultJson != null) {
switch (openRtpServerResultJson.getInteger("code")){
case 0:
result= newPort;
break;
case -300: // id已经存在, 可能已经在其他端口推流
case -300: // id已经存在, 可能已经在其他端口推流, TODO 也可能是设备不等ack就直接推流了, 需要查询与设置的推流ip端口是否一致
Map<String, Object> closeRtpServerParam = new HashMap<>();
closeRtpServerParam.put("stream_id", streamId);
zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam);
@@ -77,7 +65,7 @@ public class ZLMRTPServerFactory {
result= createRTPServer(mediaServerItem, streamId);
break;
default:
logger.error("创建RTP Server 失败 {}: " + jsonObject.getString("msg"), newPort);
logger.error("创建RTP Server 失败 {}: " + openRtpServerResultJson.getString("msg"), newPort);
break;
}
}else {
@@ -87,7 +75,7 @@ public class ZLMRTPServerFactory {
return result;
}
public boolean closeRTPServer(IMediaServerItem serverItem, String streamId) {
public boolean closeRTPServer(MediaServerItem serverItem, String streamId) {
boolean result = false;
if (serverItem !=null){
Map<String, Object> param = new HashMap<>();
@@ -107,21 +95,25 @@ public class ZLMRTPServerFactory {
return result;
}
private int getPortFromportRange() {
private int getPortFromportRange(MediaServerItem mediaServerItem) {
int currentPort = mediaServerItem.getCurrentPort();
if (currentPort == 0) {
String[] portRangeStrArray = mediaConfig.getRtpPortRange().split(",");
String[] portRangeStrArray = mediaServerItem.getRtpPortRange().split(",");
portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]);
portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]);
}
if (currentPort == 0 || currentPort++ > portRangeArray[1]) {
currentPort = portRangeArray[0];
mediaServerItem.setCurrentPort(currentPort);
return portRangeArray[0];
} else {
if (currentPort % 2 == 1) {
currentPort++;
}
return currentPort++;
currentPort++;
mediaServerItem.setCurrentPort(currentPort);
return currentPort;
}
}
@@ -135,10 +127,14 @@ public class ZLMRTPServerFactory {
* @param tcp 是否为tcp
* @return SendRtpItem
*/
public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){
String playSsrc = SsrcUtil.getPlaySsrc();
int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc());
public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){
// 使用RTPServer 功能找一个可用的端口
String playSsrc = serverItem.getSsrcConfig().getPlaySsrc();
int localPort = createRTPServer(serverItem, playSsrc);
if (localPort != -1) {
// TODO 高并发时可能因为未放入缓存而ssrc冲突
serverItem.getSsrcConfig().releaseSsrc(playSsrc);
closeRTPServer(serverItem, playSsrc);
}else {
logger.error("没有可用的端口");
@@ -168,10 +164,12 @@ public class ZLMRTPServerFactory {
* @param tcp 是否为tcp
* @return SendRtpItem
*/
public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
String playSsrc = SsrcUtil.getPlaySsrc();
int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc());
public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
String playSsrc = serverItem.getSsrcConfig().getPlaySsrc();
int localPort = createRTPServer(serverItem, playSsrc);
if (localPort != -1) {
// TODO 高并发时可能因为未放入缓存而ssrc冲突
serverItem.getSsrcConfig().releaseSsrc(ssrc);
closeRTPServer(serverItem, playSsrc);
}else {
logger.error("没有可用的端口");
@@ -194,7 +192,7 @@ public class ZLMRTPServerFactory {
/**
* 调用zlm RESTful API —— startSendRtp
*/
public Boolean startSendRtpStream(IMediaServerItem mediaServerItem, Map<String, Object>param) {
public Boolean startSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) {
Boolean result = false;
JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param);
if (jsonObject == null) {
@@ -219,7 +217,7 @@ public class ZLMRTPServerFactory {
/**
* 查询待转推的流是否就绪
*/
public Boolean isStreamReady(IMediaServerItem mediaServerItem, String app, String streamId) {
public Boolean isStreamReady(MediaServerItem mediaServerItem, String app, String streamId) {
JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
}
@@ -229,7 +227,7 @@ public class ZLMRTPServerFactory {
* @param streamId
* @return
*/
public int totalReaderCount(IMediaServerItem mediaServerItem, String app, String streamId) {
public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) {
JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
return mediaInfo.getInteger("totalReaderCount");
}
@@ -237,7 +235,7 @@ public class ZLMRTPServerFactory {
/**
* 调用zlm RESTful API —— stopSendRtp
*/
public Boolean stopSendRtpStream(IMediaServerItem mediaServerItem,Map<String, Object>param) {
public Boolean stopSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) {
Boolean result = false;
JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param);
if (jsonObject == null) {

View File

@@ -4,22 +4,16 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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 com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.service.IStreamProxyService;
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.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.print.attribute.standard.Media;
import java.util.*;
@Component
@@ -47,16 +41,26 @@ public class ZLMRunner implements CommandLineRunner {
@Override
public void run(String... strings) throws Exception {
IMediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort(
// 清楚redis缓存的在线zlm信息
mediaServerService.clearMediaServerForOnline();
// 将配置文件的meida配置写入数据库
MediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort(
mediaConfig.getIp(), mediaConfig.getHttpPort());
if (presetMediaServer != null) {
mediaConfig.setId(presetMediaServer.getId());
mediaServerService.update(mediaConfig);
MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem();
mediaSerItem.setId(presetMediaServer.getId());
mediaServerService.update(mediaSerItem);
}else {
if (mediaConfig.getId() != null) {
MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem();
mediaServerService.add(mediaSerItem);
}
}
// 订阅 zlm启动事件, 新的zlm也会从这里进入系统
hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null,
(IMediaServerItem mediaServerItem, JSONObject response)->{
(MediaServerItem mediaServerItem, JSONObject response)->{
ZLMServerConfig zlmServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class);
if (zlmServerConfig !=null ) {
startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId());
@@ -69,23 +73,25 @@ public class ZLMRunner implements CommandLineRunner {
logger.info("等待默认zlm接入...");
// 获取所有的zlm 并开启主动连接
List<IMediaServerItem> all = mediaServerService.getAll();
List<MediaServerItem> all = mediaServerService.getAll();
if (presetMediaServer == null) {
all.add(mediaConfig.getMediaSerItem());
}
for (IMediaServerItem mediaServerItem : all) {
for (MediaServerItem mediaServerItem : all) {
if (startGetMedia == null) startGetMedia = new HashMap<>();
startGetMedia.put(mediaServerItem.getId(), true);
new Thread(() -> {
ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem);
if (zlmServerConfig != null) {
zlmServerConfig.setIp(mediaServerItem.getIp());
zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort());
startGetMedia.remove(mediaServerItem.getId());
mediaServerService.handLeZLMServerConfig(zlmServerConfig);
}
}).start();
}
Timer timer = new Timer();
// 1分钟后未连接到则不再去主动连接
// 2分钟后未连接到则不再去主动连接, TODO 并对重启前使用此在zlm的通道发送bye
timer.schedule(new TimerTask() {
@Override
public void run() {
@@ -100,7 +106,7 @@ public class ZLMRunner implements CommandLineRunner {
}, 60 * 1000 * 2);
}
public ZLMServerConfig getMediaServerConfig(IMediaServerItem mediaServerItem) {
public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) {
if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) return null;
JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
ZLMServerConfig ZLMServerConfig = null;

View File

@@ -1,92 +0,0 @@
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);
}

View File

@@ -1,10 +1,13 @@
package com.genersoft.iot.vmp.media.zlm.dto;
import com.genersoft.iot.vmp.gb28181.session.SsrcConfig;
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import org.springframework.util.StringUtils;
public class MediaServerItem implements IMediaServerItem{
import java.util.HashMap;
public class MediaServerItem{
private String id;
@@ -46,9 +49,18 @@ public class MediaServerItem implements IMediaServerItem{
private String updateTime;
private boolean docker;
private boolean defaultServer;
private int count;
private SsrcConfig ssrcConfig;
private int currentPort;
/**
* 每一台ZLM都有一套独立的SSRC列表
* 在ApplicationCheckRunner里对mediaServerSsrcMap进行初始化
*/
private HashMap<String, SsrcConfig> mediaServerSsrcMap;
public MediaServerItem() {
}
@@ -218,14 +230,12 @@ public class MediaServerItem implements IMediaServerItem{
this.recordAssistPort = recordAssistPort;
}
@Override
public boolean isDocker() {
return docker;
public boolean isDefaultServer() {
return defaultServer;
}
@Override
public void setDocker(boolean docker) {
this.docker = docker;
public void setDefaultServer(boolean defaultServer) {
this.defaultServer = defaultServer;
}
public String getCreateTime() {
@@ -244,11 +254,29 @@ public class MediaServerItem implements IMediaServerItem{
this.updateTime = updateTime;
}
public int getCount() {
return count;
public HashMap<String, SsrcConfig> getMediaServerSsrcMap() {
return mediaServerSsrcMap;
}
public void setCount(int count) {
this.count = count;
public void setMediaServerSsrcMap(HashMap<String, SsrcConfig> mediaServerSsrcMap) {
this.mediaServerSsrcMap = mediaServerSsrcMap;
}
public SsrcConfig getSsrcConfig() {
return ssrcConfig;
}
public void setSsrcConfig(SsrcConfig ssrcConfig) {
this.ssrcConfig = ssrcConfig;
}
public int getCurrentPort() {
return currentPort;
}
public void setCurrentPort(int currentPort) {
this.currentPort = currentPort;
}
}