优化云端录像播放逻辑

This commit is contained in:
648540858
2025-04-13 20:14:48 +08:00
parent ce55f9b6f9
commit c8822e2b86
8 changed files with 117 additions and 10 deletions

View File

@@ -71,4 +71,8 @@ public interface IMediaNodeServerService {
List<String> listRtpServer(MediaServer mediaServer);
void loadMP4File(MediaServer mediaServer, String app, String stream, String datePath);
void seekRecordStamp(MediaServer mediaServer, String app, String stream, int stamp);
void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed);
}

View File

@@ -161,4 +161,8 @@ public interface IMediaServerService {
List<String> listRtpServer(MediaServer mediaServer);
StreamInfo loadMP4File(MediaServer mediaServer, String app, String stream, String datePath);
void seekRecordStamp(MediaServer mediaServer, String app, String stream, int stamp);
void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed);
}

View File

@@ -311,6 +311,10 @@ public class MediaServerServiceImpl implements IMediaServerService {
if (mediaServerInRedis == null || !ssrcFactory.hasMediaServerSSRC(mediaServerInDataBase.getId())) {
ssrcFactory.initMediaServerSSRC(mediaServerInDataBase.getId(),null);
}
if (mediaSerItem.getSecret() != null && !mediaServerInDataBase.getSecret().equals(mediaSerItem.getSecret())) {
mediaServerInDataBase.setSecret(mediaSerItem.getSecret());
}
mediaServerInDataBase.setSecret(mediaSerItem.getSecret());
String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId();
redisTemplate.opsForHash().put(key, mediaServerInDataBase.getId(), mediaServerInDataBase);
if (mediaServerInDataBase.isStatus()) {
@@ -977,4 +981,24 @@ public class MediaServerServiceImpl implements IMediaServerService {
mediaNodeServerService.loadMP4File(mediaServer, app, stream, datePath);
return getStreamInfoByAppAndStream(mediaServer, app, stream, null, null);
}
@Override
public void seekRecordStamp(MediaServer mediaServer, String app, String stream, int stamp) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) {
log.info("[seekRecordStamp] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServer.getType());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类");
}
mediaNodeServerService.seekRecordStamp(mediaServer, app, stream, stamp);
}
@Override
public void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed) {
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
if (mediaNodeServerService == null) {
log.info("[setRecordSpeed] 失败, mediaServer的类型 {},未找到对应的实现类", mediaServer.getType());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类");
}
mediaNodeServerService.setRecordSpeed(mediaServer, app, stream, speed);
}
}

View File

@@ -560,4 +560,26 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
}
}
@Override
public void seekRecordStamp(MediaServer mediaServer, String app, String stream, int stamp) {
JSONObject jsonObject = zlmresTfulUtils.seekRecordStamp(mediaServer, app, stream, stamp, "ts");
if (jsonObject == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "请求失败");
}
if (jsonObject.getInteger("code") != 0) {
throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
}
}
@Override
public void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed) {
JSONObject jsonObject = zlmresTfulUtils.setRecordSpeed(mediaServer, app, stream, speed, "ts");
if (jsonObject == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "请求失败");
}
if (jsonObject.getInteger("code") != 0) {
throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
}
}
}

View File

@@ -438,12 +438,13 @@ public class ZLMRESTfulUtils {
return sendPost(mediaServer, "setRecordSpeed",param, null);
}
public JSONObject seekRecordStamp(MediaServer mediaServer, String app, String stream, long stamp) {
public JSONObject seekRecordStamp(MediaServer mediaServer, String app, String stream, long stamp, String schema) {
Map<String, Object> param = new HashMap<>(1);
param.put("vhost", "__defaultVhost__");
param.put("app", app);
param.put("stream", stream);
param.put("stamp", stamp);
param.put("schema", schema);
return sendPost(mediaServer, "seekRecordStamp",param, null);
}
}

View File

@@ -59,4 +59,9 @@ public interface ICloudRecordService {
* 加载录像文件,形成录像流
*/
void loadRecord(String app, String stream, String date, ErrorCallback<StreamInfo> callback);
void seekRecord(String mediaServerId,String app, String stream, Integer seek);
void setRecordSpeed(String mediaServerId, String app, String stream, Integer speed);
}

View File

@@ -290,20 +290,16 @@ public class CloudRecordServiceImpl implements ICloudRecordService {
long startTimestamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestampMs(date + " 00:00:00");
long endTimestamp = startTimestamp + 24 * 60 * 60 * 1000;
List<String> mediaServerIds = cloudRecordServiceMapper.queryMediaServerId(app, stream, startTimestamp, endTimestamp);
if (mediaServerIds.isEmpty()) {
List<CloudRecordItem> recordItemList = cloudRecordServiceMapper.getList(null, app, stream, startTimestamp, endTimestamp, null, null, null, false);
if (recordItemList.isEmpty()) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "此时间无录像");
}
if (mediaServerIds.size() > 1) {
log.info("[云端录像] loadMP4File时发现录像文件分布在不通的zlm上默认使用第一个zlm开启录像");
}
String mediaServerId = mediaServerIds.get(0);
String mediaServerId = recordItemList.get(0).getMediaServerId();
MediaServer mediaServer = mediaServerService.getOne(mediaServerId);
if (mediaServer == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体节点不存在: " + mediaServerId);
}
String buildStream = stream + "/" + date;
String buildStream = stream + "_" + date;
MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServer, app, buildStream);
if (mediaInfo != null) {
if (callback != null) {
@@ -320,6 +316,25 @@ public class CloudRecordServiceImpl implements ICloudRecordService {
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
}
});
mediaServerService.loadMP4File(mediaServer, app, buildStream, String.format("%s/%s/%s/%s", mediaServer.getRecordPath(), app, stream, date));
String dateDir = recordItemList.get(0).getFilePath().substring(0, recordItemList.get(0).getFilePath().lastIndexOf("/"));
mediaServerService.loadMP4File(mediaServer, app, buildStream, dateDir);
}
@Override
public void seekRecord(String mediaServerId,String app, String stream, Integer seek) {
MediaServer mediaServer = mediaServerService.getOne(mediaServerId);
if (mediaServer == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体节点不存在: " + mediaServerId);
}
mediaServerService.seekRecordStamp(mediaServer, app, stream, seek);
}
@Override
public void setRecordSpeed(String mediaServerId, String app, String stream, Integer speed) {
MediaServer mediaServer = mediaServerService.getOne(mediaServerId);
if (mediaServer == null) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体节点不存在: " + mediaServerId);
}
mediaServerService.setRecordSpeed(mediaServer, app, stream, speed);
}
}

View File

@@ -307,6 +307,38 @@ public class CloudRecordController {
return result;
}
@ResponseBody
@GetMapping("/seek")
@Operation(summary = "定位录像播放到制定位置")
@Parameter(name = "mediaServerId", description = "使用的节点Id", required = true)
@Parameter(name = "stream", description = "流ID", required = true)
@Parameter(name = "seek", description = "要定位的时间位置,从录像开始的时间算起", required = true)
public void seekRecord(
@RequestParam(required = true) String mediaServerId,
@RequestParam(required = true) String app,
@RequestParam(required = true) String stream,
@RequestParam(required = true) Integer seek
) {
cloudRecordService.seekRecord(mediaServerId, app, stream, seek);
}
@ResponseBody
@GetMapping("/speed")
@Operation(summary = "设置录像播放速度")
@Parameter(name = "mediaServerId", description = "使用的节点Id", required = true)
@Parameter(name = "stream", description = "流ID", required = true)
@Parameter(name = "speed", description = "要设置的录像倍速", required = true)
public void setRecordSpeed(
@RequestParam(required = true) String mediaServerId,
@RequestParam(required = true) String app,
@RequestParam(required = true) String stream,
@RequestParam(required = true) Integer speed
) {
cloudRecordService.setRecordSpeed(mediaServerId, app, stream, speed);
}
/************************* 以下这些接口只适合wvp和zlm部署在同一台服务器的情况且wvp只有一个zlm节点的情况 ***************************************/
/**