From b0e66efe823608a6cc9be8c4af05ed16a403a909 Mon Sep 17 00:00:00 2001 From: cxh Date: Fri, 14 Nov 2025 14:31:04 +0800 Subject: [PATCH] log --- src/record_manager.cpp | 102 +++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 61 deletions(-) diff --git a/src/record_manager.cpp b/src/record_manager.cpp index e4f9a2a..54e9c05 100644 --- a/src/record_manager.cpp +++ b/src/record_manager.cpp @@ -5,6 +5,8 @@ #include #include +#include "logger.hpp" + namespace fs = std::filesystem; // @@ -12,18 +14,17 @@ namespace fs = std::filesystem; // RecordManager::RecordManager(const std::string& srs_record_cfg_path) : srs_record_cfg_path_(srs_record_cfg_path) { - std::cout << "[RecordManager] Loading SRS config: " << srs_record_cfg_path_ << "\n"; + LOG_INFO("[RecordManager] Loading SRS config: " + srs_record_cfg_path_); bool ok = loadSrsConfig(); if (!ok) { - std::cout << "[RecordManager] ERROR loading SRS config\n"; + LOG_ERROR("[RecordManager] Failed to load SRS config."); } else { - std::cout << "[RecordManager] SRS config loaded successfully.\n"; - std::cout << " record_dir_ = " << record_dir_ << "\n"; - std::cout << " dvr_duration_sec = " << dvr_duration_sec_ << "\n"; + LOG_INFO("[RecordManager] SRS config loaded. record_dir=" + record_dir_ + + ", dvr_duration=" + std::to_string(dvr_duration_sec_) + "s"); } } @@ -35,51 +36,48 @@ bool RecordManager::loadSrsConfig() std::ifstream ifs(srs_record_cfg_path_); if (!ifs.is_open()) { - std::cerr << "[RecordManager] Failed to open SRS config: " << srs_record_cfg_path_ << "\n"; + LOG_ERROR("[RecordManager] Cannot open SRS config file: " + srs_record_cfg_path_); return false; } std::string line; std::string dvr_path; + while (std::getline(ifs, line)) { - // 去掉前后空白 line.erase(0, line.find_first_not_of(" \t")); if (line.empty() || line[0] == '#') continue; + // 解析 dvr_path if (line.find("dvr_path") != std::string::npos) { auto pos = line.find('/'); auto semicolon = line.find(';'); if (pos != std::string::npos && semicolon != std::string::npos) - { dvr_path = line.substr(pos, semicolon - pos); - } } + + // 解析 dvr_duration else if (line.find("dvr_duration") != std::string::npos) { int sec = 0; - if (sscanf(line.c_str(), "dvr_duration %d", &sec) == 1) - { - dvr_duration_sec_ = sec; - } + if (sscanf(line.c_str(), "dvr_duration %d", &sec) == 1) dvr_duration_sec_ = sec; } } - if (!dvr_path.empty()) + if (dvr_path.empty()) { - // 例子:/sata/record/[stream]/[2006]-[01]-[02]/... - // → record_dir_ = /sata/record/ - auto pos = dvr_path.find("[stream]"); - if (pos != std::string::npos) - { - record_dir_ = dvr_path.substr(0, pos); - } + LOG_ERROR("[RecordManager] dvr_path not found in config."); + return false; } - if (record_dir_.empty()) + // /sata/record/[stream]/[2006]-[01]-[02]/... + auto pos = dvr_path.find("[stream]"); + if (pos != std::string::npos) + record_dir_ = dvr_path.substr(0, pos); + else { - std::cerr << "[RecordManager] ERROR: cannot parse dvr_path.\n"; + LOG_ERROR("[RecordManager] Cannot extract record_dir from dvr_path: " + dvr_path); return false; } @@ -93,7 +91,11 @@ void RecordManager::scanAll() { index_.clear(); - if (!fs::exists(record_dir_)) return; + if (!fs::exists(record_dir_)) + { + LOG_WARN("[RecordManager] record_dir not exist: " + record_dir_); + return; + } for (auto const& entry : fs::recursive_directory_iterator(record_dir_)) { @@ -108,11 +110,12 @@ void RecordManager::scanAll() index_[info.stream].push_back(info); } - // 各 stream 排序 for (auto& kv : index_) { sortStream(kv.first); } + + LOG_INFO("[RecordManager] scanAll completed. streams=" + std::to_string(index_.size())); } // @@ -121,7 +124,6 @@ void RecordManager::scanAll() void RecordManager::sortStream(const std::string& stream) { auto& files = index_[stream]; - std::sort(files.begin(), files.end(), [](const RecordFileInfo& a, const RecordFileInfo& b) { return a.start_ms < b.start_ms; }); } @@ -129,9 +131,6 @@ void RecordManager::sortStream(const std::string& stream) // // 解析路径得到文件时间戳 // -// 格式: -/// sata/record/AHD1_main/2025-11-13/10/10-23-17.mp4 -// RecordFileInfo RecordManager::parseFile(const fs::path& p) { RecordFileInfo info; @@ -139,9 +138,8 @@ RecordFileInfo RecordManager::parseFile(const fs::path& p) try { - // 目录结构倒推 auto filename = p.filename().string(); // 10-23-17.mp4 - auto date_dir = p.parent_path().parent_path().filename().string(); // 2025-11-13 + auto date_dir = p.parent_path().parent_path().filename().string(); // yyyy-mm-dd auto stream_dir = p.parent_path().parent_path().parent_path().filename().string(); info.stream = stream_dir; @@ -161,20 +159,17 @@ RecordFileInfo RecordManager::parseFile(const fs::path& p) int64_t start = std::mktime(&tm) * 1000LL; info.start_ms = start; - // ====== 加入 mp4v2 读取真实 duration ====== + // 读取 mp4 时长 MP4FileHandle hFile = MP4Read(info.path.c_str()); if (hFile != MP4_INVALID_FILE_HANDLE) { double durSec = MP4GetDuration(hFile) / (double)MP4GetTimeScale(hFile); MP4Close(hFile); - - int64_t dur_ms = (int64_t)(durSec * 1000.0); - info.end_ms = start + dur_ms; + info.end_ms = start + (int64_t)(durSec * 1000.0); } else { - // 出错 fallback - info.end_ms = start + 60000; + info.end_ms = start + 60000; // fallback } } catch (...) @@ -187,38 +182,32 @@ RecordFileInfo RecordManager::parseFile(const fs::path& p) } // -// 查询某段时间的录像段 +// 查询录像段 // std::vector RecordManager::querySegments(const std::string& stream, int64_t start_ms, int64_t end_ms) { std::vector result; - if (!index_.count(stream)) return result; const auto& files = index_[stream]; - std::vector hits; - // 先找到落在时间区间内的文件 for (const auto& f : files) { bool overlap = !(f.end_ms <= start_ms || f.start_ms >= end_ms); - if (overlap) hits.push_back(f); } if (hits.empty()) return result; - // 合并连续文件为段 std::sort(hits.begin(), hits.end(), [](auto& a, auto& b) { return a.start_ms < b.start_ms; }); int idx = 1; RecordSegment seg{}; seg.index = idx; seg.start_ms = hits[0].start_ms; - seg.files.push_back(hits[0]); seg.end_ms = hits[0].end_ms; - seg.segment_id = hits[0].stream + "_" + std::to_string(seg.start_ms) + "_" + std::to_string(seg.end_ms); + seg.files.push_back(hits[0]); for (size_t i = 1; i < hits.size(); ++i) { @@ -234,36 +223,29 @@ std::vector RecordManager::querySegments(const std::string& strea } else { - // 关闭上一段 - seg.segment_id = - seg.files[0].stream + "_" + std::to_string(seg.start_ms) + "_" + std::to_string(seg.end_ms); + seg.segment_id = stream + "_" + std::to_string(seg.start_ms) + "_" + std::to_string(seg.end_ms); result.push_back(seg); - // 开新段 idx++; seg = RecordSegment{}; seg.index = idx; - seg.files.push_back(cur); seg.start_ms = cur.start_ms; seg.end_ms = cur.end_ms; + seg.files.push_back(cur); } } - // 最后一段补进去 - seg.segment_id = seg.files[0].stream + "_" + std::to_string(seg.start_ms) + "_" + std::to_string(seg.end_ms); + seg.segment_id = stream + "_" + std::to_string(seg.start_ms) + "_" + std::to_string(seg.end_ms); result.push_back(seg); return result; } // -// 根据 segmentId 反查 segment +// 根据 segmentId 获取 segment // RecordSegment RecordManager::getSegment(const std::string& segmentId) { - // segmentId 格式: - // AHD1_main_1731465600000_1731467400000 - auto pos1 = segmentId.find('_'); auto pos2 = segmentId.find('_', pos1 + 1); if (pos1 == std::string::npos || pos2 == std::string::npos) return {}; @@ -273,23 +255,21 @@ RecordSegment RecordManager::getSegment(const std::string& segmentId) int64_t end_ms = std::stoll(segmentId.substr(pos2 + 1)); auto segs = querySegments(stream, start_ms, end_ms); - for (auto& s : segs) { if (s.start_ms == start_ms && s.end_ms == end_ms) return s; } - return {}; } int64_t RecordManager::toMsTimestamp(const std::string& s) { - std::tm tm = {}; + std::tm tm{}; char* ret = strptime(s.c_str(), "%Y-%m-%d %H:%M:%S", &tm); if (!ret) return -1; - time_t t = mktime(&tm); // local time (UTC+8) - return static_cast(t) * 1000; + time_t t = mktime(&tm); + return (int64_t)t * 1000; } std::string RecordManager::toReadable(int64_t ms)