调整节点管理代码结构

pull/1411/head
648540858 2024-03-22 16:45:18 +08:00
parent 08696a57d3
commit 150e7a3199
14 changed files with 644 additions and 493 deletions

View File

@ -84,6 +84,9 @@ public class StreamInfo implements Serializable, Cloneable{
@Schema(description = "是否暂停(录像回放使用)") @Schema(description = "是否暂停(录像回放使用)")
private boolean pause; private boolean pause;
@Schema(description = "产生源类型,包括 unknown = 0,rtmp_push=1,rtsp_push=2,rtp_push=3,pull=4,ffmpeg_pull=5,mp4_vod=6,device_chn=7")
private int originType;
public void setFlv(StreamURL flv) { public void setFlv(StreamURL flv) {
this.flv = flv; this.flv = flv;
} }
@ -616,4 +619,12 @@ public class StreamInfo implements Serializable, Cloneable{
public void setDownLoadFilePath(DownloadFileInfo downLoadFilePath) { public void setDownLoadFilePath(DownloadFileInfo downLoadFilePath) {
this.downLoadFilePath = downLoadFilePath; this.downLoadFilePath = downLoadFilePath;
} }
public int getOriginType() {
return originType;
}
public void setOriginType(int originType) {
this.originType = originType;
}
} }

View File

@ -28,13 +28,37 @@ public class MediaInfo {
private Integer audioSampleRate; private Integer audioSampleRate;
@Schema(description = "音频采样率") @Schema(description = "音频采样率")
private Long duration; private Long duration;
@Schema(description = "在线")
private Boolean online;
@Schema(description = "unknown = 0,rtmp_push=1,rtsp_push=2,rtp_push=3,pull=4,ffmpeg_pull=5,mp4_vod=6,device_chn=7")
private Integer originType;
@Schema(description = "存活时间,单位秒")
private Long aliveSecond;
@Schema(description = "数据产生速度单位byte/s")
private Long bytesSpeed;
public static MediaInfo getInstance(JSONObject jsonObject) { public static MediaInfo getInstance(JSONObject jsonObject) {
MediaInfo mediaInfo = new MediaInfo(); MediaInfo mediaInfo = new MediaInfo();
Integer totalReaderCount = jsonObject.getInteger("totalReaderCount"); Integer totalReaderCount = jsonObject.getInteger("totalReaderCount");
Boolean online = jsonObject.getBoolean("online");
Integer originType = jsonObject.getInteger("originType");
Long aliveSecond = jsonObject.getLong("aliveSecond");
Long bytesSpeed = jsonObject.getLong("bytesSpeed");
if (totalReaderCount != null) { if (totalReaderCount != null) {
mediaInfo.setReaderCount(totalReaderCount); mediaInfo.setReaderCount(totalReaderCount);
} }
if (online != null) {
mediaInfo.setOnline(online);
}
if (originType != null) {
mediaInfo.setOriginType(originType);
}
if (aliveSecond != null) {
mediaInfo.setAliveSecond(aliveSecond);
}
if (bytesSpeed != null) {
mediaInfo.setBytesSpeed(bytesSpeed);
}
JSONArray jsonArray = jsonObject.getJSONArray("tracks"); JSONArray jsonArray = jsonObject.getJSONArray("tracks");
if (jsonArray.isEmpty()) { if (jsonArray.isEmpty()) {
return null; return null;
@ -90,6 +114,10 @@ public class MediaInfo {
List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks(); List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
MediaInfo mediaInfo = new MediaInfo(); MediaInfo mediaInfo = new MediaInfo();
mediaInfo.setReaderCount(param.getTotalReaderCount()); mediaInfo.setReaderCount(param.getTotalReaderCount());
mediaInfo.setOnline(param.isRegist());
mediaInfo.setOriginType(param.getOriginType());
mediaInfo.setAliveSecond(param.getAliveSecond());
mediaInfo.setBytesSpeed(param.getBytesSpeed());
for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) { for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) {
switch (mediaTrack.getCodec_id()) { switch (mediaTrack.getCodec_id()) {
case 0: case 0:
@ -187,4 +215,36 @@ public class MediaInfo {
public void setDuration(Long duration) { public void setDuration(Long duration) {
this.duration = duration; this.duration = duration;
} }
public Boolean getOnline() {
return online;
}
public void setOnline(Boolean online) {
this.online = online;
}
public Integer getOriginType() {
return originType;
}
public void setOriginType(Integer originType) {
this.originType = originType;
}
public Long getAliveSecond() {
return aliveSecond;
}
public void setAliveSecond(Long aliveSecond) {
this.aliveSecond = aliveSecond;
}
public Long getBytesSpeed() {
return bytesSpeed;
}
public void setBytesSpeed(Long bytesSpeed) {
this.bytesSpeed = bytesSpeed;
}
} }

View File

@ -4,39 +4,53 @@ import com.genersoft.iot.vmp.common.CommonCallback;
import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import java.util.List; import java.util.List;
import java.util.Map;
public interface IMediaNodeServerService { public interface IMediaNodeServerService {
int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode); int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode);
void closeRtpServer(MediaServer mediaServerItem, String streamId); void closeRtpServer(MediaServer mediaServer, String streamId);
void closeRtpServer(MediaServer mediaServerItem, String streamId, CommonCallback<Boolean> callback); void closeRtpServer(MediaServer mediaServer, String streamId, CommonCallback<Boolean> callback);
void closeStreams(MediaServer mediaServerItem, String app, String stream); void closeStreams(MediaServer mediaServer, String app, String stream);
Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String stream, String ssrc); Boolean updateRtpServerSSRC(MediaServer mediaServer, String stream, String ssrc);
boolean checkNodeId(MediaServer mediaServerItem); boolean checkNodeId(MediaServer mediaServer);
void online(MediaServer mediaServerItem); void online(MediaServer mediaServer);
MediaServer checkMediaServer(String ip, int port, String secret); MediaServer checkMediaServer(String ip, int port, String secret);
boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc); boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc);
boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName); boolean deleteRecordDirectory(MediaServer mediaServer, String app, String stream, String date, String fileName);
List<StreamInfo> getMediaList(MediaServer mediaServerItem, String app, String stream, String callId); List<StreamInfo> getMediaList(MediaServer mediaServer, String app, String stream, String callId);
Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream); Boolean connectRtpServer(MediaServer mediaServer, String address, int port, String stream);
void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName); void getSnap(MediaServer mediaServer, String streamUrl, int timeoutSec, int expireSec, String path, String fileName);
MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream); MediaInfo getMediaInfo(MediaServer mediaServer, String app, String stream);
Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey); Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey);
Boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey); Boolean resumeRtpCheck(MediaServer mediaServer, String streamKey);
String getFfmpegCmd(MediaServer mediaServer, String cmdKey);
WVPResult<String> addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey);
WVPResult<String> addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType);
Boolean delFFmpegSource(MediaServer mediaServer, String streamKey);
Boolean delStreamProxy(MediaServer mediaServer, String streamKey);
Map<String, String> getFFmpegCMDs(MediaServer mediaServer);
} }

View File

@ -6,8 +6,10 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* *
@ -87,4 +89,19 @@ public interface IMediaServerService {
Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey); Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey);
boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey); boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey);
String getFfmpegCmd(MediaServer mediaServer, String cmdKey);
void closeStreams(MediaServer mediaServerItem, String app, String stream);
WVPResult<String> addFFmpegSource(MediaServer mediaServerItem, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey);
WVPResult<String> addStreamProxy(MediaServer mediaServerItem, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType);
Boolean delFFmpegSource(MediaServer mediaServerItem, String streamKey);
Boolean delStreamProxy(MediaServer mediaServerItem, String streamKey);
Map<String, String> getFFmpegCMDs(MediaServer mediaServer);
} }

View File

@ -22,6 +22,7 @@ import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.utils.JsonUtil; import com.genersoft.iot.vmp.utils.JsonUtil;
import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@ -74,31 +75,31 @@ public class MediaServerServiceImpl implements IMediaServerService {
* *
*/ */
@Override @Override
public void updateVmServer(List<MediaServer> mediaServerItemList) { public void updateVmServer(List<MediaServer> mediaServerList) {
logger.info("[媒体服务节点] 缓存初始化 "); logger.info("[媒体服务节点] 缓存初始化 ");
for (MediaServer mediaServerItem : mediaServerItemList) { for (MediaServer mediaServer : mediaServerList) {
if (ObjectUtils.isEmpty(mediaServerItem.getId())) { if (ObjectUtils.isEmpty(mediaServer.getId())) {
continue; continue;
} }
// 更新 // 更新
if (!ssrcFactory.hasMediaServerSSRC(mediaServerItem.getId())) { if (!ssrcFactory.hasMediaServerSSRC(mediaServer.getId())) {
ssrcFactory.initMediaServerSSRC(mediaServerItem.getId(), null); ssrcFactory.initMediaServerSSRC(mediaServer.getId(), null);
} }
// 查询redis是否存在此mediaServer // 查询redis是否存在此mediaServer
String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(); String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServer.getId();
Boolean hasKey = redisTemplate.hasKey(key); Boolean hasKey = redisTemplate.hasKey(key);
if (hasKey != null && ! hasKey) { if (hasKey != null && ! hasKey) {
redisTemplate.opsForValue().set(key, mediaServerItem); redisTemplate.opsForValue().set(key, mediaServer);
} }
} }
} }
@Override @Override
public SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String presetSsrc, boolean ssrcCheck, public SSRCInfo openRTPServer(MediaServer mediaServer, String streamId, String presetSsrc, boolean ssrcCheck,
boolean isPlayback, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { boolean isPlayback, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) {
if (mediaServerItem == null || mediaServerItem.getId() == null) { if (mediaServer == null || mediaServer.getId() == null) {
logger.info("[openRTPServer] 失败, mediaServerItem == null || mediaServerItem.getId() == null"); logger.info("[openRTPServer] 失败, mediaServer == null || mediaServer.getId() == null");
return null; return null;
} }
// 获取mediaServer可用的ssrc // 获取mediaServer可用的ssrc
@ -107,9 +108,9 @@ public class MediaServerServiceImpl implements IMediaServerService {
ssrc = presetSsrc; ssrc = presetSsrc;
}else { }else {
if (isPlayback) { if (isPlayback) {
ssrc = ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); ssrc = ssrcFactory.getPlayBackSsrc(mediaServer.getId());
}else { }else {
ssrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId()); ssrc = ssrcFactory.getPlaySsrc(mediaServer.getId());
} }
} }
@ -121,97 +122,97 @@ public class MediaServerServiceImpl implements IMediaServerService {
logger.warn("[openRTPServer] 平台对接时下级可能自定义ssrc但是tcp模式zlm收流目前无法更新ssrc可能收流超时此时请使用udp收流或者关闭ssrc校验"); logger.warn("[openRTPServer] 平台对接时下级可能自定义ssrc但是tcp模式zlm收流目前无法更新ssrc可能收流超时此时请使用udp收流或者关闭ssrc校验");
} }
int rtpServerPort; int rtpServerPort;
if (mediaServerItem.isRtpEnable()) { if (mediaServer.isRtpEnable()) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[openRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[openRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return null; return null;
} }
rtpServerPort = mediaNodeServerService.createRTPServer(mediaServerItem, streamId, ssrcCheck ? Long.parseLong(ssrc) : 0, port, onlyAuto, reUsePort, tcpMode); rtpServerPort = mediaNodeServerService.createRTPServer(mediaServer, streamId, ssrcCheck ? Long.parseLong(ssrc) : 0, port, onlyAuto, reUsePort, tcpMode);
} else { } else {
rtpServerPort = mediaServerItem.getRtpProxyPort(); rtpServerPort = mediaServer.getRtpProxyPort();
} }
return new SSRCInfo(rtpServerPort, ssrc, streamId); return new SSRCInfo(rtpServerPort, ssrc, streamId);
} }
@Override @Override
public SSRCInfo openRTPServer(MediaServer mediaServerItem, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto) { public SSRCInfo openRTPServer(MediaServer mediaServer, String streamId, String ssrc, boolean ssrcCheck, boolean isPlayback, Integer port, Boolean onlyAuto) {
return openRTPServer(mediaServerItem, streamId, ssrc, ssrcCheck, isPlayback, port, onlyAuto, null, 0); return openRTPServer(mediaServer, streamId, ssrc, ssrcCheck, isPlayback, port, onlyAuto, null, 0);
} }
@Override @Override
public void closeRTPServer(MediaServer mediaServerItem, String streamId) { public void closeRTPServer(MediaServer mediaServer, String streamId) {
if (mediaServerItem == null) { if (mediaServer == null) {
return; return;
} }
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[closeRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return; return;
} }
mediaNodeServerService.closeRtpServer(mediaServerItem, streamId); mediaNodeServerService.closeRtpServer(mediaServer, streamId);
} }
@Override @Override
public void closeRTPServer(MediaServer mediaServerItem, String streamId, CommonCallback<Boolean> callback) { public void closeRTPServer(MediaServer mediaServer, String streamId, CommonCallback<Boolean> callback) {
if (mediaServerItem == null) { if (mediaServer == null) {
callback.run(false); callback.run(false);
return; return;
} }
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[closeRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return; return;
} }
mediaNodeServerService.closeRtpServer(mediaServerItem, streamId, callback); mediaNodeServerService.closeRtpServer(mediaServer, streamId, callback);
} }
@Override @Override
public void closeRTPServer(String mediaServerId, String streamId) { public void closeRTPServer(String mediaServerId, String streamId) {
MediaServer mediaServerItem = this.getOne(mediaServerId); MediaServer mediaServer = this.getOne(mediaServerId);
if (mediaServerItem == null) { if (mediaServer == null) {
return; return;
} }
if (mediaServerItem.isRtpEnable()) { if (mediaServer.isRtpEnable()) {
closeRTPServer(mediaServerItem, streamId); closeRTPServer(mediaServer, streamId);
} }
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[closeRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return; return;
} }
mediaNodeServerService.closeStreams(mediaServerItem, "rtp", streamId); mediaNodeServerService.closeStreams(mediaServer, "rtp", streamId);
} }
@Override @Override
public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { public Boolean updateRtpServerSSRC(MediaServer mediaServer, String streamId, String ssrc) {
if (mediaServerItem == null) { if (mediaServer == null) {
return false; return false;
} }
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[updateRtpServerSSRC] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[updateRtpServerSSRC] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return false; return false;
} }
return mediaNodeServerService.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); return mediaNodeServerService.updateRtpServerSSRC(mediaServer, streamId, ssrc);
} }
@Override @Override
public void releaseSsrc(String mediaServerItemId, String ssrc) { public void releaseSsrc(String mediaServerId, String ssrc) {
MediaServer mediaServerItem = getOne(mediaServerItemId); MediaServer mediaServer = getOne(mediaServerId);
if (mediaServerItem == null || ssrc == null) { if (mediaServer == null || ssrc == null) {
return; return;
} }
ssrcFactory.releaseSsrc(mediaServerItemId, ssrc); ssrcFactory.releaseSsrc(mediaServerId, ssrc);
} }
/** /**
* TODO 使 * TODO 使
*/ */
@Override @Override
public void clearRTPServer(MediaServer mediaServerItem) { public void clearRTPServer(MediaServer mediaServer) {
ssrcFactory.reset(mediaServerItem.getId()); ssrcFactory.reset(mediaServer.getId());
} }
@ -219,22 +220,22 @@ public class MediaServerServiceImpl implements IMediaServerService {
public void update(MediaServer mediaSerItem) { public void update(MediaServer mediaSerItem) {
mediaServerMapper.update(mediaSerItem); mediaServerMapper.update(mediaSerItem);
MediaServer mediaServerInRedis = getOne(mediaSerItem.getId()); MediaServer mediaServerInRedis = getOne(mediaSerItem.getId());
MediaServer mediaServerItemInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId()); MediaServer mediaServerInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId());
if (mediaServerItemInDataBase == null) { if (mediaServerInDataBase == null) {
return; return;
} }
mediaServerItemInDataBase.setStatus(mediaSerItem.isStatus()); mediaServerInDataBase.setStatus(mediaSerItem.isStatus());
if (mediaServerInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerItemInDataBase.getId())) { if (mediaServerInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerInDataBase.getId())) {
ssrcFactory.initMediaServerSSRC(mediaServerItemInDataBase.getId(),null); ssrcFactory.initMediaServerSSRC(mediaServerInDataBase.getId(),null);
} }
String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItemInDataBase.getId(); String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerInDataBase.getId();
redisTemplate.opsForValue().set(key, mediaServerItemInDataBase); redisTemplate.opsForValue().set(key, mediaServerInDataBase);
if (mediaServerItemInDataBase.isStatus()) { if (mediaServerInDataBase.isStatus()) {
resetOnlineServerItem(mediaServerItemInDataBase); resetOnlineServerItem(mediaServerInDataBase);
}else { }else {
// 发送事件 // 发送事件
MediaServerChangeEvent event = new MediaServerChangeEvent(this); MediaServerChangeEvent event = new MediaServerChangeEvent(this);
event.setMediaServerItemList(mediaServerItemInDataBase); event.setMediaServerItemList(mediaServerInDataBase);
applicationEventPublisher.publishEvent(event); applicationEventPublisher.publishEvent(event);
} }
} }
@ -247,16 +248,16 @@ public class MediaServerServiceImpl implements IMediaServerService {
String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
for (Object mediaServerKey : mediaServerKeys) { for (Object mediaServerKey : mediaServerKeys) {
String key = (String) mediaServerKey; String key = (String) mediaServerKey;
MediaServer mediaServerItem = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServer.class); MediaServer mediaServer = JsonUtil.redisJsonToObject(redisTemplate, key, MediaServer.class);
if (Objects.isNull(mediaServerItem)) { if (Objects.isNull(mediaServer)) {
continue; continue;
} }
// 检查状态 // 检查状态
Double aDouble = redisTemplate.opsForZSet().score(onlineKey, mediaServerItem.getId()); Double aDouble = redisTemplate.opsForZSet().score(onlineKey, mediaServer.getId());
if (aDouble != null) { if (aDouble != null) {
mediaServerItem.setStatus(true); mediaServer.setStatus(true);
} }
result.add(mediaServerItem); result.add(mediaServer);
} }
result.sort((serverItem1, serverItem2)->{ result.sort((serverItem1, serverItem2)->{
int sortResult = 0; int sortResult = 0;
@ -275,10 +276,10 @@ public class MediaServerServiceImpl implements IMediaServerService {
if (mediaServerList.isEmpty()) { if (mediaServerList.isEmpty()) {
return new ArrayList<>(); return new ArrayList<>();
} }
for (MediaServer mediaServerItem : mediaServerList) { for (MediaServer mediaServer : mediaServerList) {
MediaServer mediaServerItemInRedis = getOne(mediaServerItem.getId()); MediaServer mediaServerInRedis = getOne(mediaServer.getId());
if (mediaServerItemInRedis != null) { if (mediaServerInRedis != null) {
mediaServerItem.setStatus(mediaServerItemInRedis.isStatus()); mediaServer.setStatus(mediaServerInRedis.isStatus());
} }
} }
return mediaServerList; return mediaServerList;
@ -310,7 +311,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
/** /**
* *
* @param mediaServerId id * @param mediaServerId id
* @return MediaServerItem * @return mediaServer
*/ */
@Override @Override
public MediaServer getOne(String mediaServerId) { public MediaServer getOne(String mediaServerId) {
@ -334,32 +335,32 @@ public class MediaServerServiceImpl implements IMediaServerService {
} }
@Override @Override
public void add(MediaServer mediaServerItem) { public void add(MediaServer mediaServer) {
mediaServerItem.setCreateTime(DateUtil.getNow()); mediaServer.setCreateTime(DateUtil.getNow());
mediaServerItem.setUpdateTime(DateUtil.getNow()); mediaServer.setUpdateTime(DateUtil.getNow());
if (mediaServerItem.getHookAliveInterval() == null || mediaServerItem.getHookAliveInterval() == 0F) { if (mediaServer.getHookAliveInterval() == null || mediaServer.getHookAliveInterval() == 0F) {
mediaServerItem.setHookAliveInterval(10F); mediaServer.setHookAliveInterval(10F);
} }
if (mediaServerItem.getType() == null) { if (mediaServer.getType() == null) {
logger.info("[添加媒体节点] 失败, mediaServerItem的类型:为空"); logger.info("[添加媒体节点] 失败, mediaServer的类型:为空");
return; return;
} }
if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) { if (mediaServerMapper.queryOne(mediaServer.getId()) != null) {
logger.info("[添加媒体节点] 失败, 媒体服务ID已存在请修改媒体服务器配置, {}", mediaServerItem.getId()); logger.info("[添加媒体节点] 失败, 媒体服务ID已存在请修改媒体服务器配置, {}", mediaServer.getId());
throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败媒体服务ID [ " + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); throw new ControllerException(ErrorCode.ERROR100.getCode(),"保存失败媒体服务ID [ " + mediaServer.getId() + " ] 已存在,请修改媒体服务器配置");
} }
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[添加媒体节点] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[添加媒体节点] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return; return;
} }
mediaServerMapper.add(mediaServerItem); mediaServerMapper.add(mediaServer);
if (mediaServerItem.isStatus()) { if (mediaServer.isStatus()) {
mediaNodeServerService.online(mediaServerItem); mediaNodeServerService.online(mediaServer);
}else { }else {
// 发送事件 // 发送事件
MediaServerChangeEvent event = new MediaServerChangeEvent(this); MediaServerChangeEvent event = new MediaServerChangeEvent(this);
event.setMediaServerItemList(mediaServerItem); event.setMediaServerItemList(mediaServer);
applicationEventPublisher.publishEvent(event); applicationEventPublisher.publishEvent(event);
} }
} }
@ -403,7 +404,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
/** /**
* *
* @return MediaServerItem * @return mediaServer
*/ */
@Override @Override
public MediaServer getMediaServerForMinimumLoad(Boolean hasAssist) { public MediaServer getMediaServerForMinimumLoad(Boolean hasAssist) {
@ -417,16 +418,16 @@ public class MediaServerServiceImpl implements IMediaServerService {
// 获取分数最低的,及并发最低的 // 获取分数最低的,及并发最低的
Set<Object> objects = redisTemplate.opsForZSet().range(key, 0, -1); Set<Object> objects = redisTemplate.opsForZSet().range(key, 0, -1);
ArrayList<Object> mediaServerObjectS = new ArrayList<>(objects); ArrayList<Object> mediaServerObjectS = new ArrayList<>(objects);
MediaServer mediaServerItem = null; MediaServer mediaServer = null;
if (hasAssist == null) { if (hasAssist == null) {
String mediaServerId = (String)mediaServerObjectS.get(0); String mediaServerId = (String)mediaServerObjectS.get(0);
mediaServerItem = getOne(mediaServerId); mediaServer = getOne(mediaServerId);
}else if (hasAssist) { }else if (hasAssist) {
for (Object mediaServerObject : mediaServerObjectS) { for (Object mediaServerObject : mediaServerObjectS) {
String mediaServerId = (String)mediaServerObject; String mediaServerId = (String)mediaServerObject;
MediaServer serverItem = getOne(mediaServerId); MediaServer serverItem = getOne(mediaServerId);
if (serverItem.getRecordAssistPort() > 0) { if (serverItem.getRecordAssistPort() > 0) {
mediaServerItem = serverItem; mediaServer = serverItem;
break; break;
} }
} }
@ -435,13 +436,13 @@ public class MediaServerServiceImpl implements IMediaServerService {
String mediaServerId = (String)mediaServerObject; String mediaServerId = (String)mediaServerObject;
MediaServer serverItem = getOne(mediaServerId); MediaServer serverItem = getOne(mediaServerId);
if (serverItem.getRecordAssistPort() == 0) { if (serverItem.getRecordAssistPort() == 0) {
mediaServerItem = serverItem; mediaServer = serverItem;
break; break;
} }
} }
} }
return mediaServerItem; return mediaServer;
} }
@Override @Override
@ -452,16 +453,16 @@ public class MediaServerServiceImpl implements IMediaServerService {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(type); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(type);
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[closeRTPServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", type); logger.info("[closeRTPServer] 失败, mediaServer的类型: {},未找到对应的实现类", type);
return null; return null;
} }
MediaServer mediaServerItem = mediaNodeServerService.checkMediaServer(ip, port, secret); MediaServer mediaServer = mediaNodeServerService.checkMediaServer(ip, port, secret);
if (mediaServerItem != null) { if (mediaServer != null) {
if (mediaServerMapper.queryOne(mediaServerItem.getId()) != null) { if (mediaServerMapper.queryOne(mediaServer.getId()) != null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体服务ID [" + mediaServerItem.getId() + " ] 已存在,请修改媒体服务器配置"); throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体服务ID [" + mediaServer.getId() + " ] 已存在,请修改媒体服务器配置");
} }
} }
return mediaServerItem; return mediaServer;
} }
@Override @Override
@ -504,28 +505,28 @@ public class MediaServerServiceImpl implements IMediaServerService {
public void syncCatchFromDatabase() { public void syncCatchFromDatabase() {
List<MediaServer> allInCatch = getAllOnlineList(); List<MediaServer> allInCatch = getAllOnlineList();
List<MediaServer> allInDatabase = mediaServerMapper.queryAll(); List<MediaServer> allInDatabase = mediaServerMapper.queryAll();
Map<String, MediaServer> mediaServerItemMap = new HashMap<>(); Map<String, MediaServer> mediaServerMap = new HashMap<>();
for (MediaServer mediaServerItem : allInDatabase) { for (MediaServer mediaServer : allInDatabase) {
mediaServerItemMap.put(mediaServerItem.getId(), mediaServerItem); mediaServerMap.put(mediaServer.getId(), mediaServer);
} }
for (MediaServer mediaServerItem : allInCatch) { for (MediaServer mediaServer : allInCatch) {
// 清除数据中不存在但redis缓存数据 // 清除数据中不存在但redis缓存数据
if (!mediaServerItemMap.containsKey(mediaServerItem.getId())) { if (!mediaServerMap.containsKey(mediaServer.getId())) {
delete(mediaServerItem.getId()); delete(mediaServer.getId());
} }
} }
} }
@Override @Override
public MediaServerLoad getLoad(MediaServer mediaServerItem) { public MediaServerLoad getLoad(MediaServer mediaServer) {
MediaServerLoad result = new MediaServerLoad(); MediaServerLoad result = new MediaServerLoad();
result.setId(mediaServerItem.getId()); result.setId(mediaServer.getId());
result.setPush(redisCatchStorage.getPushStreamCount(mediaServerItem.getId())); result.setPush(redisCatchStorage.getPushStreamCount(mediaServer.getId()));
result.setProxy(redisCatchStorage.getProxyStreamCount(mediaServerItem.getId())); result.setProxy(redisCatchStorage.getProxyStreamCount(mediaServer.getId()));
result.setGbReceive(inviteStreamService.getStreamInfoCount(mediaServerItem.getId())); result.setGbReceive(inviteStreamService.getStreamInfoCount(mediaServer.getId()));
result.setGbSend(redisCatchStorage.getGbSendCount(mediaServerItem.getId())); result.setGbSend(redisCatchStorage.getGbSendCount(mediaServer.getId()));
return result; return result;
} }
@ -539,79 +540,149 @@ public class MediaServerServiceImpl implements IMediaServerService {
public boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) { public boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaInfo.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaInfo.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaInfo.getType()); logger.info("[stopSendRtp] 失败, mediaServer的类型: {},未找到对应的实现类", mediaInfo.getType());
return false; return false;
} }
return mediaNodeServerService.stopSendRtp(mediaInfo, app, stream, ssrc); return mediaNodeServerService.stopSendRtp(mediaInfo, app, stream, ssrc);
} }
@Override @Override
public boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { public boolean deleteRecordDirectory(MediaServer mediaServer, String app, String stream, String date, String fileName) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[stopSendRtp] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return false; return false;
} }
return mediaNodeServerService.deleteRecordDirectory(mediaServerItem, app, stream, date, fileName); return mediaNodeServerService.deleteRecordDirectory(mediaServer, app, stream, date, fileName);
} }
@Override @Override
public List<StreamInfo> getMediaList(MediaServer mediaServerItem, String app, String stream, String callId) { public List<StreamInfo> getMediaList(MediaServer mediaServer, String app, String stream, String callId) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[getMediaList] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[getMediaList] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return new ArrayList<>(); return new ArrayList<>();
} }
return mediaNodeServerService.getMediaList(mediaServerItem, app, stream, callId); return mediaNodeServerService.getMediaList(mediaServer, app, stream, callId);
} }
@Override @Override
public Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream) { public Boolean connectRtpServer(MediaServer mediaServer, String address, int port, String stream) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[connectRtpServer] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[connectRtpServer] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return false; return false;
} }
return mediaNodeServerService.connectRtpServer(mediaServerItem, address, port, stream); return mediaNodeServerService.connectRtpServer(mediaServer, address, port, stream);
} }
@Override @Override
public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { public void getSnap(MediaServer mediaServer, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[getSnap] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[getSnap] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return; return;
} }
mediaNodeServerService.getSnap(mediaServerItem, streamUrl, timeoutSec, expireSec, path, fileName); mediaNodeServerService.getSnap(mediaServer, streamUrl, timeoutSec, expireSec, path, fileName);
} }
@Override @Override
public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { public MediaInfo getMediaInfo(MediaServer mediaServer, String app, String stream) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[getMediaInfo] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[getMediaInfo] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return null; return null;
} }
return mediaNodeServerService.getMediaInfo(mediaServerItem, app, stream); return mediaNodeServerService.getMediaInfo(mediaServer, app, stream);
} }
@Override @Override
public Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey) { public Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[pauseRtpCheck] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[pauseRtpCheck] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return false; return false;
} }
return mediaNodeServerService.pauseRtpCheck(mediaServerItem, streamKey); return mediaNodeServerService.pauseRtpCheck(mediaServer, streamKey);
} }
@Override @Override
public boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey) { public boolean resumeRtpCheck(MediaServer mediaServer, String streamKey) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType()); IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) { if (mediaNodeServerService == null) {
logger.info("[pauseRtpCheck] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType()); logger.info("[pauseRtpCheck] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
return false; return false;
} }
return mediaNodeServerService.resumeRtpCheck(mediaServerItem, streamKey); return mediaNodeServerService.resumeRtpCheck(mediaServer, streamKey);
}
@Override
public String getFfmpegCmd(MediaServer mediaServer, String cmdKey) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) {
logger.info("[getFfmpegCmd] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServer.getType());
return null;
}
return mediaNodeServerService.getFfmpegCmd(mediaServer, cmdKey);
}
@Override
public void closeStreams(MediaServer mediaServer, String app, String stream) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) {
logger.info("[closeStreams] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServer.getType());
return;
}
mediaNodeServerService.closeStreams(mediaServer, app, stream);
}
@Override
public WVPResult<String> addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) {
logger.info("[addFFmpegSource] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServer.getType());
return WVPResult.fail(ErrorCode.ERROR400);
}
return mediaNodeServerService.addFFmpegSource(mediaServer, srcUrl, dstUrl, timeoutMs, enableAudio, enableMp4, ffmpegCmdKey);
}
@Override
public WVPResult<String> addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) {
logger.info("[addStreamProxy] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServer.getType());
return WVPResult.fail(ErrorCode.ERROR400);
}
return mediaNodeServerService.addStreamProxy(mediaServer, app, stream, url, enableAudio, enableMp4, rtpType);
}
@Override
public Boolean delFFmpegSource(MediaServer mediaServer, String streamKey) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) {
logger.info("[delFFmpegSource] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServer.getType());
return false;
}
return mediaNodeServerService.delFFmpegSource(mediaServer, streamKey);
}
@Override
public Boolean delStreamProxy(MediaServer mediaServerItem, String streamKey) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType());
if (mediaNodeServerService == null) {
logger.info("[delStreamProxy] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServerItem.getType());
return false;
}
return mediaNodeServerService.delStreamProxy(mediaServerItem, streamKey);
}
@Override
public Map<String, String> getFFmpegCMDs(MediaServer mediaServer) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) {
logger.info("[getFFmpegCMDs] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServer.getType());
return new HashMap<>();
}
return mediaNodeServerService.getFFmpegCMDs(mediaServer);
} }
} }

View File

@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.media.service.IMediaNodeServerService;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -38,41 +39,41 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
private String sipIp; private String sipIp;
@Override @Override
public int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) { public int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode) {
return zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode); return zlmServerFactory.createRTPServer(mediaServer, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode);
} }
@Override @Override
public void closeRtpServer(MediaServer mediaServerItem, String streamId) { public void closeRtpServer(MediaServer mediaServer, String streamId) {
zlmresTfulUtils.closeStreams(mediaServerItem, "rtp", streamId); zlmresTfulUtils.closeStreams(mediaServer, "rtp", streamId);
} }
@Override @Override
public void closeRtpServer(MediaServer mediaServerItem, String streamId, CommonCallback<Boolean> callback) { public void closeRtpServer(MediaServer mediaServer, String streamId, CommonCallback<Boolean> callback) {
zlmServerFactory.closeRtpServer(mediaServerItem, streamId, callback); zlmServerFactory.closeRtpServer(mediaServer, streamId, callback);
} }
@Override @Override
public void closeStreams(MediaServer mediaServerItem, String app, String stream) { public void closeStreams(MediaServer mediaServer, String app, String stream) {
zlmresTfulUtils.closeStreams(mediaServerItem, app, stream); zlmresTfulUtils.closeStreams(mediaServer, app, stream);
} }
@Override @Override
public Boolean updateRtpServerSSRC(MediaServer mediaServerItem, String streamId, String ssrc) { public Boolean updateRtpServerSSRC(MediaServer mediaServer, String streamId, String ssrc) {
return zlmServerFactory.updateRtpServerSSRC(mediaServerItem, streamId, ssrc); return zlmServerFactory.updateRtpServerSSRC(mediaServer, streamId, ssrc);
} }
@Override @Override
public boolean checkNodeId(MediaServer mediaServerItem) { public boolean checkNodeId(MediaServer mediaServer) {
if (mediaServerItem == null) { if (mediaServer == null) {
return false; return false;
} }
JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServer);
if (responseJSON != null) { if (responseJSON != null) {
JSONArray data = responseJSON.getJSONArray("data"); JSONArray data = responseJSON.getJSONArray("data");
if (data != null && !data.isEmpty()) { if (data != null && !data.isEmpty()) {
ZLMServerConfig zlmServerConfig= JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class); ZLMServerConfig zlmServerConfig= JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
return zlmServerConfig.getGeneralMediaServerId().equals(mediaServerItem.getId()); return zlmServerConfig.getGeneralMediaServerId().equals(mediaServer.getId());
}else { }else {
return false; return false;
} }
@ -83,17 +84,17 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
} }
@Override @Override
public void online(MediaServer mediaServerItem) { public void online(MediaServer mediaServer) {
} }
@Override @Override
public MediaServer checkMediaServer(String ip, int port, String secret) { public MediaServer checkMediaServer(String ip, int port, String secret) {
MediaServer mediaServerItem = new MediaServer(); MediaServer mediaServer = new MediaServer();
mediaServerItem.setIp(ip); mediaServer.setIp(ip);
mediaServerItem.setHttpPort(port); mediaServer.setHttpPort(port);
mediaServerItem.setSecret(secret); mediaServer.setSecret(secret);
JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServer);
if (responseJSON == null) { if (responseJSON == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接失败"); throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接失败");
} }
@ -105,18 +106,18 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
if (zlmServerConfig == null) { if (zlmServerConfig == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败"); throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败");
} }
mediaServerItem.setId(zlmServerConfig.getGeneralMediaServerId()); mediaServer.setId(zlmServerConfig.getGeneralMediaServerId());
mediaServerItem.setHttpSSlPort(zlmServerConfig.getHttpPort()); mediaServer.setHttpSSlPort(zlmServerConfig.getHttpPort());
mediaServerItem.setRtmpPort(zlmServerConfig.getRtmpPort()); mediaServer.setRtmpPort(zlmServerConfig.getRtmpPort());
mediaServerItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); mediaServer.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
mediaServerItem.setRtspPort(zlmServerConfig.getRtspPort()); mediaServer.setRtspPort(zlmServerConfig.getRtspPort());
mediaServerItem.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); mediaServer.setRtspSSLPort(zlmServerConfig.getRtspSSlport());
mediaServerItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); mediaServer.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
mediaServerItem.setStreamIp(ip); mediaServer.setStreamIp(ip);
mediaServerItem.setHookIp(sipIp.split(",")[0]); mediaServer.setHookIp(sipIp.split(",")[0]);
mediaServerItem.setSdpIp(ip); mediaServer.setSdpIp(ip);
mediaServerItem.setType("zlm"); mediaServer.setType("zlm");
return mediaServerItem; return mediaServer;
} }
@Override @Override
@ -134,22 +135,22 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
} }
@Override @Override
public boolean deleteRecordDirectory(MediaServer mediaServerItem, String app, String stream, String date, String fileName) { public boolean deleteRecordDirectory(MediaServer mediaServer, String app, String stream, String date, String fileName) {
logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件, server: {} {}:{}->{}/{}", mediaServerItem.getId(), app, stream, date, fileName); logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件, server: {} {}:{}->{}/{}", mediaServer.getId(), app, stream, date, fileName);
JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServerItem, app, JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServer, app,
stream, date, fileName); stream, date, fileName);
if (jsonObject.getInteger("code") == 0) { if (jsonObject.getInteger("code") == 0) {
return true; return true;
}else { }else {
logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件错误, server: {} {}:{}->{}/{}, 结果: {}", mediaServerItem.getId(), app, stream, date, fileName, jsonObject); logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件错误, server: {} {}:{}->{}/{}, 结果: {}", mediaServer.getId(), app, stream, date, fileName, jsonObject);
return false; return false;
} }
} }
@Override @Override
public List<StreamInfo> getMediaList(MediaServer mediaServerItem, String app, String stream, String callId) { public List<StreamInfo> getMediaList(MediaServer mediaServer, String app, String stream, String callId) {
List<StreamInfo> streamInfoList = new ArrayList<>(); List<StreamInfo> streamInfoList = new ArrayList<>();
JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream); JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServer, app, stream);
if (mediaList != null) { if (mediaList != null) {
if (mediaList.getInteger("code") == 0) { if (mediaList.getInteger("code") == 0) {
JSONArray data = mediaList.getJSONArray("data"); JSONArray data = mediaList.getJSONArray("data");
@ -158,7 +159,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
} }
JSONObject mediaJSON = data.getJSONObject(0); JSONObject mediaJSON = data.getJSONObject(0);
MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON); MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON);
StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, mediaInfo, callId, true); StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, app, stream, mediaInfo, callId, true);
if (streamInfo != null) { if (streamInfo != null) {
streamInfoList.add(streamInfo); streamInfoList.add(streamInfo);
} }
@ -167,41 +168,42 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
return streamInfoList; return streamInfoList;
} }
public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId, boolean isPlay) { public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String callId, boolean isPlay) {
StreamInfo streamInfoResult = new StreamInfo(); StreamInfo streamInfoResult = new StreamInfo();
streamInfoResult.setStream(stream); streamInfoResult.setStream(stream);
streamInfoResult.setApp(app); streamInfoResult.setApp(app);
String addr = mediaServerItem.getStreamIp(); String addr = mediaServer.getStreamIp();
streamInfoResult.setIp(addr); streamInfoResult.setIp(addr);
streamInfoResult.setMediaServerId(mediaServerItem.getId()); streamInfoResult.setMediaServerId(mediaServer.getId());
String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId;
streamInfoResult.setRtmp(addr, mediaServerItem.getRtmpPort(),mediaServerItem.getRtmpSSlPort(), app, stream, callIdParam); streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam);
streamInfoResult.setRtsp(addr, mediaServerItem.getRtspPort(),mediaServerItem.getRtspSSLPort(), app, stream, callIdParam); streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam);
streamInfoResult.setFlv(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam);
streamInfoResult.setFmp4(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam);
streamInfoResult.setHls(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam);
streamInfoResult.setTs(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam); streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam);
streamInfoResult.setRtc(addr, mediaServerItem.getHttpPort(),mediaServerItem.getHttpSSlPort(), app, stream, callIdParam, isPlay); streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay);
streamInfoResult.setMediaInfo(mediaInfo); streamInfoResult.setMediaInfo(mediaInfo);
streamInfoResult.setOriginType(mediaInfo.getOriginType());
return streamInfoResult; return streamInfoResult;
} }
@Override @Override
public Boolean connectRtpServer(MediaServer mediaServerItem, String address, int port, String stream) { public Boolean connectRtpServer(MediaServer mediaServer, String address, int port, String stream) {
JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, address, port, stream); JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServer, address, port, stream);
logger.info("[TCP主动连接对方] 结果: {}", jsonObject); logger.info("[TCP主动连接对方] 结果: {}", jsonObject);
return jsonObject.getInteger("code") == 0; return jsonObject.getInteger("code") == 0;
} }
@Override @Override
public void getSnap(MediaServer mediaServerItem, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) { public void getSnap(MediaServer mediaServer, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) {
zlmresTfulUtils.getSnap(mediaServerItem, streamUrl, timeoutSec, expireSec, path, fileName); zlmresTfulUtils.getSnap(mediaServer, streamUrl, timeoutSec, expireSec, path, fileName);
} }
@Override @Override
public MediaInfo getMediaInfo(MediaServer mediaServerItem, String app, String stream) { public MediaInfo getMediaInfo(MediaServer mediaServer, String app, String stream) {
JSONObject jsonObject = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtsp", stream); JSONObject jsonObject = zlmresTfulUtils.getMediaInfo(mediaServer, app, "rtsp", stream);
if (jsonObject.getInteger("code") != 0) { if (jsonObject.getInteger("code") != 0) {
return null; return null;
} }
@ -209,14 +211,90 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
} }
@Override @Override
public Boolean pauseRtpCheck(MediaServer mediaServerItem, String streamKey) { public Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey) {
JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServerItem, streamKey); JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServer, streamKey);
return jsonObject.getInteger("code") == 0; return jsonObject.getInteger("code") == 0;
} }
@Override @Override
public Boolean resumeRtpCheck(MediaServer mediaServerItem, String streamKey) { public Boolean resumeRtpCheck(MediaServer mediaServer, String streamKey) {
JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServerItem, streamKey); JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServer, streamKey);
return jsonObject.getInteger("code") == 0; return jsonObject.getInteger("code") == 0;
} }
@Override
public String getFfmpegCmd(MediaServer mediaServer, String cmdKey) {
JSONObject jsonObject = zlmresTfulUtils.getMediaServerConfig(mediaServer);
if (jsonObject.getInteger("code") != 0) {
logger.warn("[getFfmpegCmd] 获取流媒体配置失败");
throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取流媒体配置失败");
}
JSONArray dataArray = jsonObject.getJSONArray("data");
JSONObject mediaServerConfig = dataArray.getJSONObject(0);
if (ObjectUtils.isEmpty(cmdKey)) {
cmdKey = "ffmpeg.cmd";
}
return mediaServerConfig.getString(cmdKey);
}
@Override
public WVPResult<String> addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey) {
JSONObject jsonObject = zlmresTfulUtils.addFFmpegSource(mediaServer, srcUrl, dstUrl, timeoutMs, enableAudio, enableMp4, ffmpegCmdKey);
if (jsonObject.getInteger("code") != 0) {
logger.warn("[getFfmpegCmd] 添加FFMPEG代理失败");
return WVPResult.fail(ErrorCode.ERROR100.getCode(), "添加FFMPEG代理失败");
}else {
JSONObject data = jsonObject.getJSONObject("data");
if (data == null) {
return WVPResult.fail(ErrorCode.ERROR100.getCode(), "代理结果异常: " + jsonObject);
}else {
return WVPResult.success(data.getString("key"));
}
}
}
@Override
public WVPResult<String> addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enableAudio, boolean enableMp4, String rtpType) {
JSONObject jsonObject = zlmresTfulUtils.addStreamProxy(mediaServer, app, stream, url, enableAudio, enableMp4, rtpType);
if (jsonObject.getInteger("code") != 0) {
logger.warn("[addStreamProxy] 添加代理失败");
return WVPResult.fail(ErrorCode.ERROR100.getCode(), "添加代理失败");
}else {
JSONObject data = jsonObject.getJSONObject("data");
if (data == null) {
return WVPResult.fail(ErrorCode.ERROR100.getCode(), "代理结果异常: " + jsonObject);
}else {
return WVPResult.success("");
}
}
}
@Override
public Boolean delFFmpegSource(MediaServer mediaServer, String streamKey) {
JSONObject jsonObject = zlmresTfulUtils.delFFmpegSource(mediaServer, streamKey);
return jsonObject.getInteger("code") == 0;
}
@Override
public Boolean delStreamProxy(MediaServer mediaServer, String streamKey) {
JSONObject jsonObject = zlmresTfulUtils.delStreamProxy(mediaServer, streamKey);
return jsonObject.getInteger("code") == 0;
}
@Override
public Map<String, String> getFFmpegCMDs(MediaServer mediaServer) {
Map<String, String> result = new HashMap<>();
JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServer);
if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0
&& mediaServerConfigResuly.getJSONArray("data").size() > 0){
JSONObject mediaServerConfig = mediaServerConfigResuly.getJSONArray("data").getJSONObject(0);
for (String key : mediaServerConfig.keySet()) {
if (key.startsWith("ffmpeg.cmd")){
result.put(key, mediaServerConfig.getString(key));
}
}
}
return result;
}
} }

View File

@ -269,7 +269,7 @@ public class ZLMRESTfulUtils {
return sendPost(mediaServerItem, "getRtpInfo",param, null); return sendPost(mediaServerItem, "getRtpInfo",param, null);
} }
public JSONObject addFFmpegSource(MediaServer mediaServerItem, String src_url, String dst_url, String timeout_ms, public JSONObject addFFmpegSource(MediaServer mediaServerItem, String src_url, String dst_url, Integer timeout_ms,
boolean enable_audio, boolean enable_mp4, String ffmpeg_cmd_key){ boolean enable_audio, boolean enable_mp4, String ffmpeg_cmd_key){
logger.info(src_url); logger.info(src_url);
logger.info(dst_url); logger.info(dst_url);

View File

@ -1,5 +1,6 @@
package com.genersoft.iot.vmp.media.zlm.dto; package com.genersoft.iot.vmp.media.zlm.dto;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.DateUtil;
@ -150,6 +151,27 @@ public class StreamPushItem extends GbStream implements Comparable<StreamPushIte
- DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(streamPushItem.getCreateTime())).intValue(); - DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(streamPushItem.getCreateTime())).intValue();
} }
public StreamPushItem instance(StreamInfo streamInfo) {
StreamPushItem streamPushItem = new StreamPushItem();
streamPushItem.setApp(streamInfo.getApp());
streamPushItem.setMediaServerId(streamInfo.getMediaServerId());
streamPushItem.setStream(streamInfo.getStream());
streamPushItem.setAliveSecond(streamInfo.getMediaInfo().getAliveSecond());
// streamPushItem.setOriginSock(streamInfo.getMediaInfo().getOriginSock());
streamPushItem.setTotalReaderCount(streamInfo.getMediaInfo().getReaderCount() + "");
streamPushItem.setOriginType(streamInfo.getOriginType());
// streamPushItem.setOriginTypeStr(streamInfo.getMediaInfo().getOriginTypeStr());
// streamPushItem.setOriginUrl(streamInfo.getMediaInfo().getOriginUrl());
streamPushItem.setCreateTime(DateUtil.getNow());
streamPushItem.setAliveSecond(streamInfo.getMediaInfo().getAliveSecond());
streamPushItem.setStatus(true);
streamPushItem.setStreamType("push");
// streamPushItem.setVhost(streamInfo.getVhost());
streamPushItem.setServerId(streamInfo.getMediaServerId());
return streamPushItem;
}
public static class MediaSchema { public static class MediaSchema {
private String schema; private String schema;
private Long bytesSpeed; private Long bytesSpeed;

View File

@ -1,13 +1,15 @@
package com.genersoft.iot.vmp.service; package com.genersoft.iot.vmp.service;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.common.GeneralCallback; import com.genersoft.iot.vmp.common.GeneralCallback;
import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import java.util.Map;
public interface IStreamProxyService { public interface IStreamProxyService {
/** /**
@ -18,17 +20,19 @@ public interface IStreamProxyService {
/** /**
* zlm * zlm
*
* @param param * @param param
* @return * @return
*/ */
JSONObject addStreamProxyToZlm(StreamProxyItem param); WVPResult<String> addStreamProxyToZlm(StreamProxyItem param);
/** /**
* zlm * zlm
*
* @param param * @param param
* @return * @return
*/ */
JSONObject removeStreamProxyFromZlm(StreamProxyItem param); Boolean removeStreamProxyFromZlm(StreamProxyItem param);
/** /**
* *
@ -73,9 +77,10 @@ public interface IStreamProxyService {
/** /**
* ffmpeg.cmd * ffmpeg.cmd
*
* @return * @return
*/ */
JSONObject getFFmpegCMDs(MediaServer mediaServerItem); Map<String, String> getFFmpegCMDs(MediaServer mediaServerItem);
/** /**
* appstreamstreamProxy * appstreamstreamProxy

View File

@ -1,9 +1,8 @@
package com.genersoft.iot.vmp.service; package com.genersoft.iot.vmp.service;
import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
@ -16,8 +15,6 @@ import java.util.Map;
*/ */
public interface IStreamPushService { public interface IStreamPushService {
List<StreamPushItem> handleJSON(String json, MediaServer mediaServerItem);
/** /**
* ID * ID
* @param stream * @param stream

View File

@ -1,6 +1,5 @@
package com.genersoft.iot.vmp.service.impl; package com.genersoft.iot.vmp.service.impl;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.annotation.DS;
import com.genersoft.iot.vmp.common.GeneralCallback; import com.genersoft.iot.vmp.common.GeneralCallback;
@ -9,7 +8,8 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.exception.ControllerException;
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.bean.MediaInfo;
import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
@ -18,7 +18,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.service.IGbStreamService;
import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IStreamProxyService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@ -29,6 +28,7 @@ import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper;
import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -63,9 +63,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
@Autowired @Autowired
private IMediaService mediaService; private IMediaService mediaService;
@Autowired
private ZLMRESTfulUtils zlmresTfulUtils;
@Autowired @Autowired
private ZLMServerFactory zlmServerFactory; private ZLMServerFactory zlmServerFactory;
@ -108,28 +105,21 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
@Override @Override
public void save(StreamProxyItem param, GeneralCallback<StreamInfo> callback) { public void save(StreamProxyItem param, GeneralCallback<StreamInfo> callback) {
MediaServer mediaInfo; MediaServer mediaServer;
if (ObjectUtils.isEmpty(param.getMediaServerId()) || "auto".equals(param.getMediaServerId())){ if (ObjectUtils.isEmpty(param.getMediaServerId()) || "auto".equals(param.getMediaServerId())){
mediaInfo = mediaServerService.getMediaServerForMinimumLoad(null); mediaServer = mediaServerService.getMediaServerForMinimumLoad(null);
}else { }else {
mediaInfo = mediaServerService.getOne(param.getMediaServerId()); mediaServer = mediaServerService.getOne(param.getMediaServerId());
} }
if (mediaInfo == null) { if (mediaServer == null) {
logger.warn("保存代理未找到在线的ZLM..."); logger.warn("保存代理未找到在线的ZLM...");
throw new ControllerException(ErrorCode.ERROR100.getCode(), "保存代理未找到在线的ZLM"); throw new ControllerException(ErrorCode.ERROR100.getCode(), "保存代理未找到在线的ZLM");
} }
String dstUrl; String dstUrl;
if ("ffmpeg".equalsIgnoreCase(param.getType())) { if ("ffmpeg".equalsIgnoreCase(param.getType())) {
JSONObject jsonObject = zlmresTfulUtils.getMediaServerConfig(mediaInfo);
if (jsonObject.getInteger("code") != 0) { String ffmpegCmd = mediaServerService.getFfmpegCmd(mediaServer, param.getFfmpegCmdKey());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取流媒体配置失败");
}
JSONArray dataArray = jsonObject.getJSONArray("data");
JSONObject mediaServerConfig = dataArray.getJSONObject(0);
if (ObjectUtils.isEmpty(param.getFfmpegCmdKey())) {
param.setFfmpegCmdKey("ffmpeg.cmd");
}
String ffmpegCmd = mediaServerConfig.getString(param.getFfmpegCmdKey());
if (ffmpegCmd == null) { if (ffmpegCmd == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg拉流代理无法获取ffmpeg cmd"); throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg拉流代理无法获取ffmpeg cmd");
} }
@ -140,25 +130,25 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
int port; int port;
String schemaForUri; String schemaForUri;
if (schema.equalsIgnoreCase("rtsp")) { if (schema.equalsIgnoreCase("rtsp")) {
port = mediaInfo.getRtspPort(); port = mediaServer.getRtspPort();
schemaForUri = schema; schemaForUri = schema;
}else if (schema.equalsIgnoreCase("flv")) { }else if (schema.equalsIgnoreCase("flv")) {
port = mediaInfo.getRtmpPort(); port = mediaServer.getRtmpPort();
schemaForUri = schema; schemaForUri = schema;
}else { }else {
port = mediaInfo.getRtmpPort(); port = mediaServer.getRtmpPort();
schemaForUri = schema; schemaForUri = schema;
} }
dstUrl = String.format("%s://%s:%s/%s/%s", schemaForUri, "127.0.0.1", port, param.getApp(), dstUrl = String.format("%s://%s:%s/%s/%s", schemaForUri, "127.0.0.1", port, param.getApp(),
param.getStream()); param.getStream());
}else { }else {
dstUrl = String.format("rtsp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtspPort(), param.getApp(), dstUrl = String.format("rtsp://%s:%s/%s/%s", "127.0.0.1", mediaServer.getRtspPort(), param.getApp(),
param.getStream()); param.getStream());
} }
param.setDstUrl(dstUrl); param.setDstUrl(dstUrl);
logger.info("[拉流代理] 输出地址为:{}", dstUrl); logger.info("[拉流代理] 输出地址为:{}", dstUrl);
param.setMediaServerId(mediaInfo.getId()); param.setMediaServerId(mediaServer.getId());
boolean saveResult; boolean saveResult;
// 更新 // 更新
if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) { if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) {
@ -170,17 +160,17 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
callback.run(ErrorCode.ERROR100.getCode(), "保存失败", null); callback.run(ErrorCode.ERROR100.getCode(), "保存失败", null);
return; return;
} }
HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(param.getApp(), param.getStream(), true, "rtsp", mediaInfo.getId()); HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(param.getApp(), param.getStream(), true, "rtsp", mediaServer.getId());
hookSubscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItem, response) -> { hookSubscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItem, response) -> {
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
mediaInfo, param.getApp(), param.getStream(), null, null); mediaServer, param.getApp(), param.getStream(), null, null);
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
}); });
if (param.isEnable()) { if (param.isEnable()) {
String talkKey = UUID.randomUUID().toString(); String talkKey = UUID.randomUUID().toString();
String delayTalkKey = UUID.randomUUID().toString(); String delayTalkKey = UUID.randomUUID().toString();
dynamicTask.startDelay(delayTalkKey, ()->{ dynamicTask.startDelay(delayTalkKey, ()->{
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaInfo.getId(), false); StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaServer.getId(), false);
if (streamInfo != null) { if (streamInfo != null) {
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
}else { }else {
@ -188,12 +178,12 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
callback.run(ErrorCode.ERROR100.getCode(), "超时", null); callback.run(ErrorCode.ERROR100.getCode(), "超时", null);
} }
}, 7000); }, 7000);
JSONObject jsonObject = addStreamProxyToZlm(param); WVPResult<String> result = addStreamProxyToZlm(param);
if (jsonObject != null && jsonObject.getInteger("code") == 0) { if (result != null && result.getCode() == 0) {
hookSubscribe.removeSubscribe(hookSubscribeForStreamChange); hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
dynamicTask.stop(talkKey); dynamicTask.stop(talkKey);
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
mediaInfo, param.getApp(), param.getStream(), null, null); mediaServer, param.getApp(), param.getStream(), null, null);
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
}else { }else {
param.setEnable(false); param.setEnable(false);
@ -203,16 +193,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
}else { }else {
updateStreamProxy(param); updateStreamProxy(param);
} }
if (jsonObject == null){ if (result == null){
callback.run(ErrorCode.ERROR100.getCode(), "记录已保存,启用失败", null); callback.run(ErrorCode.ERROR100.getCode(), "记录已保存,启用失败", null);
}else { }else {
callback.run(ErrorCode.ERROR100.getCode(), jsonObject.getString("msg"), null); callback.run(ErrorCode.ERROR100.getCode(), result.getMsg(), null);
} }
} }
} }
else{ else{
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
mediaInfo, param.getApp(), param.getStream(), null, null); mediaServer, param.getApp(), param.getStream(), null, null);
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
} }
} }
@ -308,40 +298,36 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
} }
@Override @Override
public JSONObject addStreamProxyToZlm(StreamProxyItem param) { public WVPResult<String> addStreamProxyToZlm(StreamProxyItem param) {
JSONObject result = null; WVPResult<String> result = null;
MediaServer mediaServerItem = null; MediaServer mediaServer = null;
if (param.getMediaServerId() == null) { if (param.getMediaServerId() == null) {
logger.warn("添加代理时MediaServerId 为null"); logger.warn("添加代理时MediaServerId 为null");
return null; return null;
}else { }else {
mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); mediaServer = mediaServerService.getOne(param.getMediaServerId());
} }
if (mediaServerItem == null) { if (mediaServer == null) {
return null; return null;
} }
if (zlmServerFactory.isStreamReady(mediaServerItem, param.getApp(), param.getStream())) { if (zlmServerFactory.isStreamReady(mediaServer, param.getApp(), param.getStream())) {
zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream()); mediaServerService.closeStreams(mediaServer, param.getApp(), param.getStream());
} }
String msgResult;
if ("ffmpeg".equalsIgnoreCase(param.getType())){ if ("ffmpeg".equalsIgnoreCase(param.getType())){
result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrcUrl().trim(), param.getDstUrl(), result = mediaServerService.addFFmpegSource(mediaServer, param.getSrcUrl().trim(), param.getDstUrl(),
param.getTimeoutMs() + "", param.isEnableAudio(), param.isEnableMp4(), param.getTimeoutMs(), param.isEnableAudio(), param.isEnableMp4(),
param.getFfmpegCmdKey()); param.getFfmpegCmdKey());
}else { }else {
result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl().trim(), result = mediaServerService.addStreamProxy(mediaServer, param.getApp(), param.getStream(), param.getUrl().trim(),
param.isEnableAudio(), param.isEnableMp4(), param.getRtpType()); param.isEnableAudio(), param.isEnableMp4(), param.getRtpType());
} }
System.out.println("addStreamProxyToZlm===="); System.out.println("addStreamProxyToZlm====");
System.out.println(result); System.out.println(result);
if (result != null && result.getInteger("code") == 0) { if (result != null && result.getCode() == 0) {
JSONObject data = result.getJSONObject("data"); String key = result.getData();
if (data == null) {
logger.warn("[获取拉流代理的结果数据Data] 失败: {}", result );
return result;
}
String key = data.getString("key");
if (key == null) { if (key == null) {
logger.warn("[获取拉流代理的结果数据Data中的KEY] 失败: {}", result ); logger.warn("[获取拉流代理的结果数据Data] 失败: {}", result );
return result; return result;
} }
param.setStreamKey(key); param.setStreamKey(key);
@ -351,16 +337,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
} }
@Override @Override
public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) { public Boolean removeStreamProxyFromZlm(StreamProxyItem param) {
if (param ==null) { if (param ==null) {
return null; return null;
} }
MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId());
JSONObject result = null; Boolean result = false;
if ("ffmpeg".equalsIgnoreCase(param.getType())){ if ("ffmpeg".equalsIgnoreCase(param.getType())){
result = zlmresTfulUtils.delFFmpegSource(mediaServerItem, param.getStreamKey()); result = mediaServerService.delFFmpegSource(mediaServer, param.getStreamKey());
}else { }else {
result = zlmresTfulUtils.delStreamProxy(mediaServerItem, param.getStreamKey()); result = mediaServerService.delStreamProxy(mediaServer, param.getStreamKey());
} }
return result; return result;
} }
@ -381,8 +367,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
gbStreamMapper.del(app, stream); gbStreamMapper.del(app, stream);
videoManagerStorager.deleteStreamProxy(app, stream); videoManagerStorager.deleteStreamProxy(app, stream);
redisCatchStorage.removeStream(streamProxyItem.getMediaServerId(), "PULL", app, stream); redisCatchStorage.removeStream(streamProxyItem.getMediaServerId(), "PULL", app, stream);
JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyItem); Boolean result = removeStreamProxyFromZlm(streamProxyItem);
if (jsonObject != null && jsonObject.getInteger("code") == 0) { if (result != null && result) {
logger.info("[移除代理] 代理: {}/{}, 从zlm移除成功", app, stream); logger.info("[移除代理] 代理: {}/{}, 从zlm移除成功", app, stream);
}else { }else {
logger.info("[移除代理] 代理: {}/{}, 从zlm移除失败", app, stream); logger.info("[移除代理] 代理: {}/{}, 从zlm移除失败", app, stream);
@ -395,16 +381,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
boolean result = false; boolean result = false;
StreamProxyItem streamProxy = videoManagerStorager.queryStreamProxy(app, stream); StreamProxyItem streamProxy = videoManagerStorager.queryStreamProxy(app, stream);
if (streamProxy != null && !streamProxy.isEnable() ) { if (streamProxy != null && !streamProxy.isEnable() ) {
JSONObject jsonObject = addStreamProxyToZlm(streamProxy); WVPResult<String> wvpResult = addStreamProxyToZlm(streamProxy);
if (jsonObject == null) { if (wvpResult == null) {
return false; return false;
} }
if (jsonObject.getInteger("code") == 0) { if (wvpResult.getCode() == 0) {
result = true; result = true;
streamProxy.setEnable(true); streamProxy.setEnable(true);
updateStreamProxy(streamProxy); updateStreamProxy(streamProxy);
}else { }else {
logger.info("启用代理失败: {}/{}->{}({})", app, stream, jsonObject.getString("msg"), logger.info("启用代理失败: {}/{}->{}({})", app, stream, wvpResult.getMsg(),
streamProxy.getSrcUrl() == null? streamProxy.getUrl():streamProxy.getSrcUrl()); streamProxy.getSrcUrl() == null? streamProxy.getUrl():streamProxy.getSrcUrl());
} }
} else if (streamProxy != null && streamProxy.isEnable()) { } else if (streamProxy != null && streamProxy.isEnable()) {
@ -418,8 +404,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
boolean result = false; boolean result = false;
StreamProxyItem streamProxyDto = videoManagerStorager.queryStreamProxy(app, stream); StreamProxyItem streamProxyDto = videoManagerStorager.queryStreamProxy(app, stream);
if (streamProxyDto != null && streamProxyDto.isEnable()) { if (streamProxyDto != null && streamProxyDto.isEnable()) {
JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyDto); Boolean removed = removeStreamProxyFromZlm(streamProxyDto);
if (jsonObject != null && jsonObject.getInteger("code") == 0) { if (removed != null && removed) {
streamProxyDto.setEnable(false); streamProxyDto.setEnable(false);
result = updateStreamProxy(streamProxyDto); result = updateStreamProxy(streamProxyDto);
} }
@ -428,20 +414,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
} }
@Override @Override
public JSONObject getFFmpegCMDs(MediaServer mediaServerItem) { public Map<String, String> getFFmpegCMDs(MediaServer mediaServer) {
JSONObject result = new JSONObject(); return mediaServerService.getFFmpegCMDs(mediaServer);
JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0
&& mediaServerConfigResuly.getJSONArray("data").size() > 0){
JSONObject mediaServerConfig = mediaServerConfigResuly.getJSONArray("data").getJSONObject(0);
for (String key : mediaServerConfig.keySet()) {
if (key.startsWith("ffmpeg.cmd")){
result.put(key, mediaServerConfig.getString(key));
}
}
}
return result;
} }
@ -467,8 +441,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
mediaServerId, true); mediaServerId, true);
for (StreamProxyItem streamProxyDto : streamProxyListForEnable) { for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {
logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream()); logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
JSONObject jsonObject = addStreamProxyToZlm(streamProxyDto); WVPResult<String> wvpResult = addStreamProxyToZlm(streamProxyDto);
if (jsonObject == null) { if (wvpResult == null) {
// 设置为离线 // 设置为离线
logger.info("恢复流代理失败" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream()); logger.info("恢复流代理失败" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
updateStatus(false, streamProxyDto.getApp(), streamProxyDto.getStream()); updateStatus(false, streamProxyDto.getApp(), streamProxyDto.getStream());
@ -521,41 +495,27 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
MediaServer mediaServer = mediaServerService.getOne(mediaServerId); MediaServer mediaServer = mediaServerService.getOne(mediaServerId);
if (mediaServer != null) { if (mediaServer != null) {
List<OnStreamChangedHookParam> allPullStream = redisCatchStorage.getStreams(mediaServerId, "PULL"); List<OnStreamChangedHookParam> allPullStream = redisCatchStorage.getStreams(mediaServerId, "PULL");
if (allPullStream.size() > 0) { if (!allPullStream.isEmpty()) {
zlmresTfulUtils.getMediaList(mediaServer, jsonObject->{ List<StreamInfo> mediaList = mediaServerService.getMediaList(mediaServer, null, null, null);
Map<String, StreamInfo> stringStreamInfoMap = new HashMap<>(); Map<String, StreamInfo> stringStreamInfoMap = new HashMap<>();
if (jsonObject.getInteger("code") == 0) { if (mediaList != null && !mediaList.isEmpty()) {
JSONArray data = jsonObject.getJSONArray("data"); for (StreamInfo streamInfo : mediaList) {
if(data != null && data.size() > 0) { stringStreamInfoMap.put(streamInfo.getApp() + streamInfo.getStream(), streamInfo);
for (int i = 0; i < data.size(); i++) { }
JSONObject streamJSONObj = data.getJSONObject(i); }
if ("rtsp".equals(streamJSONObj.getString("schema"))) { if (stringStreamInfoMap.isEmpty()) {
StreamInfo streamInfo = new StreamInfo(); redisCatchStorage.removeStream(mediaServerId, "PULL");
String app = streamJSONObj.getString("app"); }else {
String stream = streamJSONObj.getString("stream"); for (String key : stringStreamInfoMap.keySet()) {
streamInfo.setApp(app); StreamInfo streamInfo = stringStreamInfoMap.get(key);
streamInfo.setStream(stream); if (stringStreamInfoMap.get(streamInfo.getApp() + streamInfo.getStream()) == null) {
stringStreamInfoMap.put(app+stream, streamInfo); redisCatchStorage.removeStream(mediaServerId, "PULL", streamInfo.getApp(),
} streamInfo.getStream());
}
} }
} }
if (stringStreamInfoMap.size() == 0) { }
redisCatchStorage.removeStream(mediaServerId, "PULL");
}else {
for (String key : stringStreamInfoMap.keySet()) {
StreamInfo streamInfo = stringStreamInfoMap.get(key);
if (stringStreamInfoMap.get(streamInfo.getApp() + streamInfo.getStream()) == null) {
redisCatchStorage.removeStream(mediaServerId, "PULL", streamInfo.getApp(),
streamInfo.getStream());
}
}
}
});
} }
} }
} }
@Override @Override
@ -589,13 +549,12 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
MediaServer mediaServerItem = serverItemMap.get(streamProxyItem.getMediaServerId()); MediaServer mediaServerItem = serverItemMap.get(streamProxyItem.getMediaServerId());
// TODO 支持其他 schema MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServerItem, streamProxyItem.getApp(), streamProxyItem.getStream());
JSONObject mediaInfo = zlmresTfulUtils.isMediaOnline(mediaServerItem, streamProxyItem.getApp(), streamProxyItem.getStream(), "rtsp");
if (mediaInfo == null){ if (mediaInfo == null){
streamProxyItem.setStatus(false); streamProxyItem.setStatus(false);
} else { } else {
if (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")) { if (mediaInfo.getOnline() != null && mediaInfo.getOnline()) {
streamProxyItem.setStatus(true); streamProxyItem.setStatus(true);
} else { } else {
streamProxyItem.setStatus(false); streamProxyItem.setStatus(false);

View File

@ -1,21 +1,22 @@
package com.genersoft.iot.vmp.service.impl; package com.genersoft.iot.vmp.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.annotation.DS;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType;
import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.service.IGbStreamService;
import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.IStreamPushService;
import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@ -66,9 +67,6 @@ public class StreamPushServiceImpl implements IStreamPushService {
@Autowired @Autowired
private EventPublisher eventPublisher; private EventPublisher eventPublisher;
@Autowired
private ZLMRESTfulUtils zlmresTfulUtils;
@Autowired @Autowired
private IRedisCatchStorage redisCatchStorage; private IRedisCatchStorage redisCatchStorage;
@ -88,32 +86,27 @@ public class StreamPushServiceImpl implements IStreamPushService {
private MediaConfig mediaConfig; private MediaConfig mediaConfig;
@Override private List<StreamPushItem> handleJSON(List<StreamInfo> streamInfoList) {
public List<StreamPushItem> handleJSON(String jsonData, MediaServer mediaServerItem) { if (streamInfoList == null || streamInfoList.isEmpty()) {
if (jsonData == null) {
return null; return null;
} }
Map<String, StreamPushItem> result = new HashMap<>(); Map<String, StreamPushItem> result = new HashMap<>();
for (StreamInfo streamInfo : streamInfoList) {
List<OnStreamChangedHookParam> onStreamChangedHookParams = JSON.parseObject(jsonData, new TypeReference<List<OnStreamChangedHookParam>>() {});
for (OnStreamChangedHookParam item : onStreamChangedHookParams) {
// 不保存国标推理以及拉流代理的流 // 不保存国标推理以及拉流代理的流
if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal() if (streamInfo.getOriginType() == OriginType.RTSP_PUSH.ordinal()
|| item.getOriginType() == OriginType.RTMP_PUSH.ordinal() || streamInfo.getOriginType() == OriginType.RTMP_PUSH.ordinal()
|| item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) { || streamInfo.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
String key = item.getApp() + "_" + item.getStream(); String key = streamInfo.getApp() + "_" + streamInfo.getStream();
StreamPushItem streamPushItem = result.get(key); StreamPushItem streamPushItem = result.get(key);
if (streamPushItem == null) { if (streamPushItem == null) {
streamPushItem = transform(item); streamPushItem = streamPushItem.instance(streamInfo);
result.put(key, streamPushItem); result.put(key, streamPushItem);
} }
} }
} }
return new ArrayList<>(result.values()); return new ArrayList<>(result.values());
} }
@Override @Override
public StreamPushItem transform(OnStreamChangedHookParam item) { public StreamPushItem transform(OnStreamChangedHookParam item) {
StreamPushItem streamPushItem = new StreamPushItem(); StreamPushItem streamPushItem = new StreamPushItem();
@ -165,14 +158,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
platformGbStreamMapper.delByAppAndStream(stream.getApp(), stream.getStream()); platformGbStreamMapper.delByAppAndStream(stream.getApp(), stream.getStream());
int del = gbStreamMapper.del(stream.getApp(), stream.getStream()); int del = gbStreamMapper.del(stream.getApp(), stream.getStream());
MediaServer mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); MediaServer mediaInfo = mediaServerService.getOne(stream.getMediaServerId());
JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream()); List<StreamInfo> mediaList = mediaServerService.getMediaList(mediaInfo, stream.getApp(), stream.getStream(), null);
if (mediaList != null) { if (mediaList != null && mediaList.isEmpty()) {
if (mediaList.getInteger("code") == 0) { streamPushMapper.del(stream.getApp(), stream.getStream());
JSONArray data = mediaList.getJSONArray("data");
if (data == null) {
streamPushMapper.del(stream.getApp(), stream.getStream());
}
}
} }
return del > 0; return del > 0;
} }
@ -196,7 +184,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
int delStream = streamPushMapper.del(app, streamId); int delStream = streamPushMapper.del(app, streamId);
if (delStream > 0) { if (delStream > 0) {
MediaServer mediaServerItem = mediaServerService.getOne(streamPushItem.getMediaServerId()); MediaServer mediaServerItem = mediaServerService.getOne(streamPushItem.getMediaServerId());
zlmresTfulUtils.closeStreams(mediaServerItem,app, streamId); mediaServerService.closeStreams(mediaServerItem,app, streamId);
} }
return true; return true;
} }
@ -232,71 +220,61 @@ public class StreamPushServiceImpl implements IStreamPushService {
for (StreamAuthorityInfo streamAuthorityInfo : allStreamAuthorityInfo) { for (StreamAuthorityInfo streamAuthorityInfo : allStreamAuthorityInfo) {
streamAuthorityInfoInfoMap.put(streamAuthorityInfo.getApp() + streamAuthorityInfo.getStream(), streamAuthorityInfo); streamAuthorityInfoInfoMap.put(streamAuthorityInfo.getApp() + streamAuthorityInfo.getStream(), streamAuthorityInfo);
} }
zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{ List<StreamInfo> mediaList = mediaServerService.getMediaList(mediaServerItem, null, null, null);
if (mediaList == null) { if (mediaList == null) {
return; return;
}
List<StreamPushItem> streamPushItems = handleJSON(mediaList);
if (streamPushItems != null) {
for (StreamPushItem streamPushItem : streamPushItems) {
pushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream());
streamInfoPushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream());
streamAuthorityInfoInfoMap.remove(streamPushItem.getApp() + streamPushItem.getStream());
} }
String dataStr = mediaList.getString("data"); }
List<StreamPushItem> offlinePushItems = new ArrayList<>(pushItemMap.values());
Integer code = mediaList.getInteger("code"); if (offlinePushItems.size() > 0) {
List<StreamPushItem> streamPushItems = null; String type = "PUSH";
if (code == 0 ) { int runLimit = 300;
if (dataStr != null) { if (offlinePushItems.size() > runLimit) {
streamPushItems = handleJSON(dataStr, mediaServerItem); for (int i = 0; i < offlinePushItems.size(); i += runLimit) {
} int toIndex = i + runLimit;
} if (i + runLimit > offlinePushItems.size()) {
toIndex = offlinePushItems.size();
if (streamPushItems != null) {
for (StreamPushItem streamPushItem : streamPushItems) {
pushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream());
streamInfoPushItemMap.remove(streamPushItem.getApp() + streamPushItem.getStream());
streamAuthorityInfoInfoMap.remove(streamPushItem.getApp() + streamPushItem.getStream());
}
}
List<StreamPushItem> offlinePushItems = new ArrayList<>(pushItemMap.values());
if (offlinePushItems.size() > 0) {
String type = "PUSH";
int runLimit = 300;
if (offlinePushItems.size() > runLimit) {
for (int i = 0; i < offlinePushItems.size(); i += runLimit) {
int toIndex = i + runLimit;
if (i + runLimit > offlinePushItems.size()) {
toIndex = offlinePushItems.size();
}
List<StreamPushItem> streamPushItemsSub = offlinePushItems.subList(i, toIndex);
streamPushMapper.delAll(streamPushItemsSub);
} }
}else { List<StreamPushItem> streamPushItemsSub = offlinePushItems.subList(i, toIndex);
streamPushMapper.delAll(offlinePushItems); streamPushMapper.delAll(streamPushItemsSub);
}
}
Collection<OnStreamChangedHookParam> offlineOnStreamChangedHookParamList = streamInfoPushItemMap.values();
if (offlineOnStreamChangedHookParamList.size() > 0) {
String type = "PUSH";
for (OnStreamChangedHookParam offlineOnStreamChangedHookParam : offlineOnStreamChangedHookParamList) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("serverId", userSetting.getServerId());
jsonObject.put("app", offlineOnStreamChangedHookParam.getApp());
jsonObject.put("stream", offlineOnStreamChangedHookParam.getStream());
jsonObject.put("register", false);
jsonObject.put("mediaServerId", mediaServerId);
redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
// 移除redis内流的信息
redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream());
// 冗余数据,自己系统中自用
redisCatchStorage.removePushListItem(offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream(), mediaServerItem.getId());
} }
}else {
streamPushMapper.delAll(offlinePushItems);
} }
Collection<StreamAuthorityInfo> streamAuthorityInfos = streamAuthorityInfoInfoMap.values(); }
if (streamAuthorityInfos.size() > 0) { Collection<OnStreamChangedHookParam> offlineOnStreamChangedHookParamList = streamInfoPushItemMap.values();
for (StreamAuthorityInfo streamAuthorityInfo : streamAuthorityInfos) { if (offlineOnStreamChangedHookParamList.size() > 0) {
// 移除redis内流的信息 String type = "PUSH";
redisCatchStorage.removeStreamAuthorityInfo(streamAuthorityInfo.getApp(), streamAuthorityInfo.getStream()); for (OnStreamChangedHookParam offlineOnStreamChangedHookParam : offlineOnStreamChangedHookParamList) {
} JSONObject jsonObject = new JSONObject();
jsonObject.put("serverId", userSetting.getServerId());
jsonObject.put("app", offlineOnStreamChangedHookParam.getApp());
jsonObject.put("stream", offlineOnStreamChangedHookParam.getStream());
jsonObject.put("register", false);
jsonObject.put("mediaServerId", mediaServerId);
redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
// 移除redis内流的信息
redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream());
// 冗余数据,自己系统中自用
redisCatchStorage.removePushListItem(offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream(), mediaServerItem.getId());
} }
})); }
Collection<StreamAuthorityInfo> streamAuthorityInfos = streamAuthorityInfoInfoMap.values();
if (streamAuthorityInfos.size() > 0) {
for (StreamAuthorityInfo streamAuthorityInfo : streamAuthorityInfos) {
// 移除redis内流的信息
redisCatchStorage.removeStreamAuthorityInfo(streamAuthorityInfo.getApp(), streamAuthorityInfo.getStream());
}
}
} }
@Override @Override
@ -471,7 +449,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
if (delStream > 0) { if (delStream > 0) {
for (GbStream gbStream : gbStreams) { for (GbStream gbStream : gbStreams) {
MediaServer mediaServerItem = mediaServerService.getOne(gbStream.getMediaServerId()); MediaServer mediaServerItem = mediaServerService.getOne(gbStream.getMediaServerId());
zlmresTfulUtils.closeStreams(mediaServerItem, gbStream.getApp(), gbStream.getStream()); mediaServerService.closeStreams(mediaServerItem, gbStream.getApp(), gbStream.getStream());
} }
} }

View File

@ -16,17 +16,14 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.IInviteStreamService;
import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.*; import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
@ -70,24 +67,15 @@ public class PlayController {
@Autowired @Autowired
private IVideoManagerStorage storager; private IVideoManagerStorage storager;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired @Autowired
private IInviteStreamService inviteStreamService; private IInviteStreamService inviteStreamService;
@Autowired
private ZLMRESTfulUtils zlmresTfulUtils;
@Autowired @Autowired
private DeferredResultHolder resultHolder; private DeferredResultHolder resultHolder;
@Autowired @Autowired
private IPlayService playService; private IPlayService playService;
@Autowired
private IMediaService mediaService;
@Autowired @Autowired
private IMediaServerService mediaServerService; private IMediaServerService mediaServerService;
@ -202,50 +190,6 @@ public class PlayController {
json.put("isSubStream", isSubStream); json.put("isSubStream", isSubStream);
return json; return json;
} }
/**
* h264ffmpeg h264 + aac
* @param streamId ID
*/
@Operation(summary = "将不是h264的视频通过ffmpeg 转码为h264 + aac", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "streamId", description = "视频流ID", required = true)
@PostMapping("/convert/{streamId}")
public JSONObject playConvert(@PathVariable String streamId) {
// StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, streamId);
if (inviteInfo == null || inviteInfo.getStreamInfo() == null) {
logger.warn("视频转码API调用失败, 视频流已经停止!");
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到视频流信息, 视频流可能已经停止");
}
MediaServer mediaInfo = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId);
if (!rtpInfo.getBoolean("exist")) {
logger.warn("视频转码API调用失败, 视频流已停止推流!");
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到视频流信息, 视频流可能已停止推流");
} else {
String dstUrl = String.format("rtmp://%s:%s/convert/%s", "127.0.0.1", mediaInfo.getRtmpPort(),
streamId );
String srcUrl = String.format("rtsp://%s:%s/rtp/%s", "127.0.0.1", mediaInfo.getRtspPort(), streamId);
JSONObject jsonObject = zlmresTfulUtils.addFFmpegSource(mediaInfo, srcUrl, dstUrl, "1000000", true, false, null);
logger.info(jsonObject.toJSONString());
if (jsonObject != null && jsonObject.getInteger("code") == 0) {
JSONObject data = jsonObject.getJSONObject("data");
if (data != null) {
JSONObject result = new JSONObject();
result.put("key", data.getString("key"));
StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStreamWithCheck("convert", streamId, mediaInfo.getId(), false);
result.put("StreamInfo", streamInfoResult);
return result;
}else {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "转码失败");
}
}else {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "转码失败");
}
}
}
/** /**
* *
*/ */
@ -261,14 +205,8 @@ public class PlayController {
if (mediaInfo == null) { if (mediaInfo == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "使用的流媒体已经停止运行" ); throw new ControllerException(ErrorCode.ERROR100.getCode(), "使用的流媒体已经停止运行" );
}else { }else {
JSONObject jsonObject = zlmresTfulUtils.delFFmpegSource(mediaInfo, key); Boolean deleted = mediaServerService.delFFmpegSource(mediaInfo, key);
logger.info(jsonObject.toJSONString()); if (!deleted) {
if (jsonObject != null && jsonObject.getInteger("code") == 0) {
JSONObject data = jsonObject.getJSONObject("data");
if (data == null || data.getBoolean("flag") == null || !data.getBoolean("flag")) {
throw new ControllerException(ErrorCode.ERROR100 );
}
}else {
throw new ControllerException(ErrorCode.ERROR100 ); throw new ControllerException(ErrorCode.ERROR100 );
} }
} }

View File

@ -27,6 +27,7 @@ import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.context.request.async.DeferredResult;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@ -135,7 +136,7 @@ public class StreamProxyController {
@ResponseBody @ResponseBody
@Operation(summary = "获取ffmpeg.cmd模板", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Operation(summary = "获取ffmpeg.cmd模板", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "mediaServerId", description = "流媒体ID", required = true) @Parameter(name = "mediaServerId", description = "流媒体ID", required = true)
public JSONObject getFFmpegCMDs(@RequestParam String mediaServerId){ public Map<String, String> getFFmpegCMDs(@RequestParam String mediaServerId){
logger.debug("获取节点[ {} ]ffmpeg.cmd模板", mediaServerId ); logger.debug("获取节点[ {} ]ffmpeg.cmd模板", mediaServerId );
MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId);