liusuyi
2026-06-01 3496700a5ba18be8ca0590a79e21a867782d1ea9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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("录制文件未生成");
        }
    }
}