优化媒体节点服务的代码结构
This commit is contained in:
80
src/main/java/com/genersoft/iot/vmp/media/bean/Track.java
Normal file
80
src/main/java/com/genersoft/iot/vmp/media/bean/Track.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package com.genersoft.iot.vmp.media.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
/**
|
||||
* 视频信息
|
||||
*/
|
||||
@Schema(description = "视频信息")
|
||||
public class Track {
|
||||
@Schema(description = "观看人数")
|
||||
private Integer readerCount;
|
||||
@Schema(description = "视频编码类型")
|
||||
private String videoCodec;
|
||||
@Schema(description = "视频宽度")
|
||||
private Integer width;
|
||||
@Schema(description = "视频高度")
|
||||
private Integer height;
|
||||
@Schema(description = "音频编码类型")
|
||||
private String audioCodec;
|
||||
@Schema(description = "音频通道数")
|
||||
private Integer audioChannels;
|
||||
@Schema(description = "音频采样率")
|
||||
private Integer audioSampleRate;
|
||||
|
||||
public Integer getReaderCount() {
|
||||
return readerCount;
|
||||
}
|
||||
|
||||
public void setReaderCount(Integer readerCount) {
|
||||
this.readerCount = readerCount;
|
||||
}
|
||||
|
||||
public String getVideoCodec() {
|
||||
return videoCodec;
|
||||
}
|
||||
|
||||
public void setVideoCodec(String videoCodec) {
|
||||
this.videoCodec = videoCodec;
|
||||
}
|
||||
|
||||
public Integer getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Integer width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Integer getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Integer height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public String getAudioCodec() {
|
||||
return audioCodec;
|
||||
}
|
||||
|
||||
public void setAudioCodec(String audioCodec) {
|
||||
this.audioCodec = audioCodec;
|
||||
}
|
||||
|
||||
public Integer getAudioChannels() {
|
||||
return audioChannels;
|
||||
}
|
||||
|
||||
public void setAudioChannels(Integer audioChannels) {
|
||||
this.audioChannels = audioChannels;
|
||||
}
|
||||
|
||||
public Integer getAudioSampleRate() {
|
||||
return audioSampleRate;
|
||||
}
|
||||
|
||||
public void setAudioSampleRate(Integer audioSampleRate) {
|
||||
this.audioSampleRate = audioSampleRate;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.genersoft.iot.vmp.media.service;
|
||||
|
||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IMediaNodeServerService {
|
||||
int createRTPServer(MediaServerItem mediaServerItem, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean reUsePort, Integer tcpMode);
|
||||
|
||||
@@ -19,4 +22,10 @@ public interface IMediaNodeServerService {
|
||||
void online(MediaServerItem mediaServerItem);
|
||||
|
||||
MediaServerItem checkMediaServer(String ip, int port, String secret);
|
||||
|
||||
boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc);
|
||||
|
||||
boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName);
|
||||
|
||||
List<StreamInfo> getMediaList(MediaServerItem mediaServerItem, String app, String stream);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.genersoft.iot.vmp.media.service;
|
||||
|
||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
|
||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||
@@ -69,4 +70,10 @@ public interface IMediaServerService {
|
||||
List<MediaServerItem> getAllWithAssistPort();
|
||||
|
||||
MediaServerItem getOneFromDatabase(String id);
|
||||
|
||||
boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc);
|
||||
|
||||
boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName);
|
||||
|
||||
List<StreamInfo> getMediaList(MediaServerItem mediaInfo, String app, String stream);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.genersoft.iot.vmp.media.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
@@ -533,4 +535,33 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc) {
|
||||
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaInfo.getType());
|
||||
if (mediaNodeServerService == null) {
|
||||
logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaInfo.getType());
|
||||
return false;
|
||||
}
|
||||
return mediaNodeServerService.stopSendRtp(mediaInfo, app, stream, ssrc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) {
|
||||
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType());
|
||||
if (mediaNodeServerService == null) {
|
||||
logger.info("[stopSendRtp] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType());
|
||||
return false;
|
||||
}
|
||||
return mediaNodeServerService.deleteRecordDirectory(mediaServerItem, app, stream, date, fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StreamInfo> getMediaList(MediaServerItem mediaServerItem, String app, String stream) {
|
||||
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServerItem.getType());
|
||||
if (mediaNodeServerService == null) {
|
||||
logger.info("[getMediaList] 失败, mediaServerItem的类型: {},未找到对应的实现类", mediaServerItem.getType());
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return mediaNodeServerService.getMediaList(mediaServerItem, app, stream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ 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.cmd.ISIPCommanderForPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.media.bean.Track;
|
||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.*;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.hook.*;
|
||||
@@ -33,6 +34,7 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -368,6 +370,39 @@ public class ZLMHttpHookListener {
|
||||
}
|
||||
|
||||
List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
|
||||
Track track = new Track();
|
||||
track.setReaderCount(param.getTotalReaderCount());
|
||||
for (OnStreamChangedHookParam.MediaTrack mediaTrack : tracks) {
|
||||
switch (mediaTrack.getCodec_id()) {
|
||||
case 0:
|
||||
track.setVideoCodec("H264");
|
||||
break;
|
||||
case 1:
|
||||
track.setVideoCodec("H265");
|
||||
break;
|
||||
case 2:
|
||||
track.setAudioCodec("AAC");
|
||||
break;
|
||||
case 3:
|
||||
track.setAudioCodec("G711A");
|
||||
break;
|
||||
case 4:
|
||||
track.setAudioCodec("G711U");
|
||||
break;
|
||||
}
|
||||
if (mediaTrack.getSample_rate() > 0) {
|
||||
track.setAudioSampleRate(mediaTrack.getSample_rate());
|
||||
}
|
||||
if (mediaTrack.getChannels() > 0) {
|
||||
track.setAudioChannels(mediaTrack.getChannels());
|
||||
}
|
||||
if (mediaTrack.getHeight() > 0) {
|
||||
track.setHeight(mediaTrack.getHeight());
|
||||
}
|
||||
if (mediaTrack.getWidth() > 0) {
|
||||
track.setWidth(mediaTrack.getWidth());
|
||||
}
|
||||
}
|
||||
// TODO 重构此处逻辑
|
||||
if (param.isRegist()) {
|
||||
// 处理流注册的鉴权信息, 流注销这里不再删除鉴权信息,下次来了新的鉴权信息会对就的进行覆盖
|
||||
@@ -471,7 +506,7 @@ public class ZLMHttpHookListener {
|
||||
callId = streamAuthorityInfo.getCallId();
|
||||
}
|
||||
StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo,
|
||||
param.getApp(), param.getStream(), tracks, callId);
|
||||
param.getApp(), param.getStream(), track, callId);
|
||||
param.setStreamInfo(new StreamContent(streamInfoByAppAndStream));
|
||||
redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param);
|
||||
if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
|
||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.IStreamProxyService;
|
||||
import com.genersoft.iot.vmp.service.IStreamPushService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
|
||||
import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper;
|
||||
@@ -30,12 +29,6 @@ public class ZLMMediaListManager {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger("ZLMMediaListManager");
|
||||
|
||||
@Autowired
|
||||
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||
|
||||
@Autowired
|
||||
private IRedisCatchStorage redisCatchStorage;
|
||||
|
||||
@Autowired
|
||||
private IVideoManagerStorage storager;
|
||||
|
||||
|
||||
@@ -4,18 +4,31 @@ import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.media.bean.Track;
|
||||
import com.genersoft.iot.vmp.media.service.IMediaNodeServerService;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig;
|
||||
import com.genersoft.iot.vmp.service.impl.DeviceServiceImpl;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service("zlm")
|
||||
public class ZLMMediaNodeServerService implements IMediaNodeServerService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ZLMMediaNodeServerService.class);
|
||||
|
||||
@Autowired
|
||||
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||
|
||||
@@ -106,4 +119,77 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
|
||||
mediaServerItem.setType("zlm");
|
||||
return mediaServerItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopSendRtp(MediaServerItem mediaInfo, String app, String stream, String ssrc) {
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("vhost", "__defaultVhost__");
|
||||
param.put("app", app);
|
||||
param.put("stream", stream);
|
||||
if (!ObjectUtils.isEmpty(ssrc)) {
|
||||
param.put("ssrc", ssrc);
|
||||
}
|
||||
JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaInfo, param);
|
||||
return (jsonObject != null && jsonObject.getInteger("code") == 0);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) {
|
||||
logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件, server: {} {}:{}->{}/{}", mediaServerItem.getId(), app, stream, date, fileName);
|
||||
JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServerItem, app,
|
||||
stream, date, fileName);
|
||||
if (jsonObject.getInteger("code") == 0) {
|
||||
return true;
|
||||
}else {
|
||||
logger.info("[zlm-deleteRecordDirectory] 删除磁盘文件错误, server: {} {}:{}->{}/{}, 结果: {}", mediaServerItem.getId(), app, stream, date, fileName, jsonObject);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StreamInfo> getMediaList(MediaServerItem mediaServerItem, String app, String stream) {
|
||||
List<StreamInfo> streamInfoList = new ArrayList<>();
|
||||
JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream);
|
||||
if (mediaList != null) {
|
||||
if (mediaList.getInteger("code") == 0) {
|
||||
JSONArray data = mediaList.getJSONArray("data");
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
JSONObject mediaJSON = data.getJSONObject(0);
|
||||
JSONArray tracks = mediaJSON.getJSONArray("tracks");
|
||||
|
||||
if (authority) {
|
||||
streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, tracks, null, calld, true);
|
||||
}else {
|
||||
streamInfo = getStreamInfoByAppAndStream(mediaServerItem, app, stream, tracks, null,null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return streamInfoList;
|
||||
}
|
||||
|
||||
public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Track track, String addr, String callId, boolean isPlay) {
|
||||
StreamInfo streamInfoResult = new StreamInfo();
|
||||
streamInfoResult.setStream(stream);
|
||||
streamInfoResult.setApp(app);
|
||||
if (addr == null) {
|
||||
addr = mediaInfo.getStreamIp();
|
||||
}
|
||||
|
||||
streamInfoResult.setIp(addr);
|
||||
streamInfoResult.setMediaServerId(mediaInfo.getId());
|
||||
String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId;
|
||||
streamInfoResult.setRtmp(addr, mediaInfo.getRtmpPort(),mediaInfo.getRtmpSSlPort(), app, stream, callIdParam);
|
||||
streamInfoResult.setRtsp(addr, mediaInfo.getRtspPort(),mediaInfo.getRtspSSLPort(), app, stream, callIdParam);
|
||||
streamInfoResult.setFlv(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam);
|
||||
streamInfoResult.setFmp4(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam);
|
||||
streamInfoResult.setHls(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam);
|
||||
streamInfoResult.setTs(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam);
|
||||
streamInfoResult.setRtc(addr, mediaInfo.getHttpPort(),mediaInfo.getHttpSSlPort(), app, stream, callIdParam, isPlay);
|
||||
|
||||
streamInfoResult.setTrack(track);
|
||||
return streamInfoResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.Map;
|
||||
@Component
|
||||
public class ZLMServerFactory {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory");
|
||||
private Logger logger = LoggerFactory.getLogger("ZLMServerFactory");
|
||||
|
||||
@Autowired
|
||||
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class OnStreamChangedHookParam extends HookParam{
|
||||
/**
|
||||
* 观看总人数,包括hls/rtsp/rtmp/http-flv/ws-flv
|
||||
*/
|
||||
private String totalReaderCount;
|
||||
private int totalReaderCount;
|
||||
|
||||
/**
|
||||
* 协议 包括hls/rtsp/rtmp/http-flv/ws-flv
|
||||
@@ -374,11 +374,11 @@ public class OnStreamChangedHookParam extends HookParam{
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public String getTotalReaderCount() {
|
||||
public int getTotalReaderCount() {
|
||||
return totalReaderCount;
|
||||
}
|
||||
|
||||
public void setTotalReaderCount(String totalReaderCount) {
|
||||
public void setTotalReaderCount(int totalReaderCount) {
|
||||
this.totalReaderCount = totalReaderCount;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user