package com.ard.work.sdk.zlxd.record;
|
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.context.SmartLifecycle;
|
import org.springframework.stereotype.Component;
|
import java.io.File;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* 录制管理器(Spring 单例 Bean)
|
*/
|
@Slf4j
|
@Component // 声明为 Spring 组件,默认单例
|
public class RecorderManager implements SmartLifecycle {
|
|
private String saveDir;
|
// 存储摄像头ID -> 录制器的映射
|
private final Map<String, RtspRecorder> recorderMap1 = new HashMap<>();
|
private final Map<String, RtspToMP4> recorderMap = new HashMap<>();
|
// Spring 生命周期标记
|
private boolean isRunning = false;
|
|
// 启动单个摄像头录制
|
public boolean startRecorder(String uniqueCamId, String rtspUrl,String saveDir) {
|
this.saveDir=saveDir;
|
try {
|
// 检查是否已在录制
|
if (recorderMap.containsKey(uniqueCamId)) {
|
log.warn("摄像头 {} 已在录制中,无需重复启动", uniqueCamId);
|
return true;
|
}
|
// 构建录制目录
|
// 创建录制器并启动
|
// RtspRecorder recorder = new RtspRecorder(uniqueCamId, rtspUrl, tempDir);
|
// recorder.start();
|
RtspToMP4 recorder = new RtspToMP4();
|
File dir = new File(saveDir);
|
if (!dir.exists()) {
|
boolean mkdirs = dir.mkdirs();
|
if (!mkdirs) {
|
log.error("[{}] 创建保存目录失败:{}", uniqueCamId, saveDir);
|
}
|
}
|
// ⭐ 可配置参数
|
Long maxSize = 1073741824L; // 1GB
|
Integer maxDuration = null; // 不限制时间
|
String filePath = saveDir + File.separator + uniqueCamId + ".mp4";
|
recorder.start(rtspUrl, filePath, maxSize, maxDuration);
|
|
recorderMap.put(uniqueCamId, recorder);
|
log.info("摄像头 {} 录制启动成功,存储路径:{}", uniqueCamId, saveDir);
|
return true;
|
} catch (Exception e) {
|
log.error("摄像头 {} 录制启动失败", uniqueCamId, e);
|
return false;
|
}
|
}
|
|
// 停止单个摄像头录制
|
public String stopRecorder(String uniqueCamId) {
|
try {
|
//RtspRecorder recorder = recorderMap.get(uniqueCamId);
|
RtspToMP4 recorder = recorderMap.get(uniqueCamId);
|
if (recorder == null) {
|
log.warn("摄像头 {} 未在录制中,无需停止", uniqueCamId);
|
return "摄像头未在录制";
|
}
|
// 停止录制
|
recorder.stop();
|
recorderMap.remove(uniqueCamId);
|
// 返回录制文件路径(根据实际生成的文件名调整)
|
String recordPath = saveDir + File.separator + uniqueCamId + ".mp4";
|
log.info("摄像头 {} 录制停止成功,文件路径:{}", uniqueCamId, recordPath);
|
return recordPath;
|
} catch (Exception e) {
|
log.error("摄像头 {} 录制停止失败", uniqueCamId, e);
|
return "停止失败:" + e.getMessage();
|
}
|
}
|
|
// 停止所有录制
|
public void stopAllRecorders() {
|
log.info("开始停止所有摄像头录制...");
|
for (String camId : recorderMap.keySet()) {
|
stopRecorder(camId);
|
}
|
recorderMap.clear();
|
log.info("所有摄像头录制已停止");
|
}
|
|
// 检查摄像头是否在录制
|
public boolean isRecording(String uniqueCamId) {
|
//RtspRecorder recorder = recorderMap.get(uniqueCamId);
|
RtspToMP4 recorder = recorderMap.get(uniqueCamId);
|
return recorder != null && recorder.isRunning();
|
}
|
|
// ====================== Spring 生命周期方法 ======================
|
@Override
|
public void start() {
|
isRunning = true;
|
}
|
|
@Override
|
public void stop() {
|
// Spring 关闭时,自动停止所有录制
|
stopAllRecorders();
|
isRunning = false;
|
log.info("RecorderManager 已销毁");
|
}
|
|
@Override
|
public boolean isRunning() {
|
return isRunning;
|
}
|
|
// 优先级:数字越小,越先启动、越后销毁
|
@Override
|
public int getPhase() {
|
return 0;
|
}
|
|
public static void main(String[] args) throws InterruptedException {
|
RecorderManager recorder = new RecorderManager();
|
recorder.startRecorder("cam1", "rtsp://admin:admin@112.98.104.134:8237/000100","D:\\home\\temp\\record");
|
|
// 录制30秒
|
log.info("开始录制,持续30秒...");
|
Thread.sleep(30000);
|
|
// 停止录制
|
recorder.stop();
|
log.info("录制已停止,文件可正常操作");
|
|
// 验证文件是否可用
|
File videoFile = new File("D:\\home\\temp\\cam1.mp4");
|
if (videoFile.exists()) {
|
log.info("录制文件已生成,大小:{} KB", videoFile.length() / 1024);
|
} else {
|
log.error("录制文件未生成");
|
}
|
}
|
}
|