diff --git a/src/main.cpp b/src/main.cpp index 63392ff..34739cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,53 +21,6 @@ static void signal_handler(int signum) write(STDERR_FILENO, msg, sizeof(msg) - 1); } -void test_mp4_info(const std::string& path) -{ - MP4FileHandle file = MP4Read(path.c_str()); - if (file == MP4_INVALID_FILE_HANDLE) - { - std::cerr << "Failed to open: " << path << std::endl; - return; - } - - std::cout << "=== MP4 Info for: " << path << " ===\n"; - - // duration (in seconds) - MP4Duration duration = MP4GetDuration(file); - uint32_t timeScale = MP4GetTimeScale(file); - double seconds = (double)duration / timeScale; - - std::cout << "Duration: " << seconds << " sec\n"; - - // video track - MP4TrackId videoTrack = MP4FindTrackId(file, 0, MP4_VIDEO_TRACK_TYPE); - if (videoTrack != MP4_INVALID_TRACK_ID) - { - uint32_t width = MP4GetTrackVideoWidth(file, videoTrack); - uint32_t height = MP4GetTrackVideoHeight(file, videoTrack); - - std::cout << "Video Track: YES\n"; - std::cout << "Resolution: " << width << " x " << height << "\n"; - } - else - { - std::cout << "Video Track: NO\n"; - } - - // audio track - MP4TrackId audioTrack = MP4FindTrackId(file, 0, MP4_AUDIO_TRACK_TYPE); - if (audioTrack != MP4_INVALID_TRACK_ID) - { - std::cout << "Audio Track: YES\n"; - } - else - { - std::cout << "Audio Track: NO\n"; - } - - MP4Close(file); -} - int main() { // ---------- 信号处理 ---------- @@ -83,46 +36,43 @@ int main() Logger::init(get_executable_dir_file_path("logs"), 7); LOG_INFO("[MAIN] ===== Vehicle Video Service Starting ====="); - // std::string base = "/sata/record/"; - // RecordManager rm(base); + std::string base = "/sata/record/"; + RecordManager rm(base); - // std::cout << "[RecordManager] scanning " << base << " ..." << std::endl; + std::cout << "[RecordManager] scanning " << base << " ..." << std::endl; - // rm.scanAll(); + rm.scanAll(); - // std::cout << "\n=== 全部扫描结果 ===\n"; + std::cout << "\n=== 全部扫描结果 ===\n"; - // // 遍历所有 stream - // rm.dumpIndex(); + // 遍历所有 stream + rm.dumpIndex(); - // // 测试一次查询:你可以换成真实时间戳 - // std::cout << "\n=== 测试 querySegments() ===\n"; + // 测试一次查询:你可以换成真实时间戳 + std::cout << "\n=== 测试 querySegments() ===\n"; - // // 随便选一个时间区间,比如 2025-11-13 10:23:00 ~ 11:00:00 - // // 你可以换成真实值 - // int64_t start = RecordManager::toMsTimestamp("2025-11-13 10:00:00"); - // int64_t end = RecordManager::toMsTimestamp("2025-11-13 14:30:00"); + // 随便选一个时间区间,比如 2025-11-13 10:23:00 ~ 11:00:00 + // 你可以换成真实值 + int64_t start = RecordManager::toMsTimestamp("2025-11-13 10:00:00"); + int64_t end = RecordManager::toMsTimestamp("2025-11-13 14:30:00"); - // auto segments = rm.querySegments("AHD1_main", start, end); + auto segments = rm.querySegments("AHD1_main", start, end); - // std::cout << "找到录像段数量 = " << segments.size() << "\n"; + std::cout << "找到录像段数量 = " << segments.size() << "\n"; - // for (auto& seg : segments) - // { - // std::cout << "\n--- Segment " << seg.index << " ---\n"; - // std::cout << "segmentId = " << seg.segment_id << "\n"; - // std::cout << "start_ms = " << seg.start_ms << "\n"; - // std::cout << "end_ms = " << seg.end_ms << "\n"; - // std::cout << "files = " << seg.files.size() << "\n"; + for (auto& seg : segments) + { + std::cout << "\n--- Segment " << seg.index << " ---\n"; + std::cout << "segmentId = " << seg.segment_id << "\n"; + std::cout << "start_ms = " << seg.start_ms << "\n"; + std::cout << "end_ms = " << seg.end_ms << "\n"; + std::cout << "files = " << seg.files.size() << "\n"; - // for (auto& f : seg.files) - // { - // std::cout << " file: " << f.path << "\n [" << f.start_ms << " ~ " << f.end_ms << "]\n"; - // } - // } - - test_mp4_info("/sata/record/AHD1_main/2025-11-13/13/13-40-44.mp4"); - test_mp4_info("/sata/record/AHD1_main/2025-11-13/13/13-59-16.mp4"); + for (auto& f : seg.files) + { + std::cout << " file: " << f.path << "\n [" << f.start_ms << " ~ " << f.end_ms << "]\n"; + } + } // try // { diff --git a/src/record_manager.cpp b/src/record_manager.cpp index 6da4e28..86df248 100644 --- a/src/record_manager.cpp +++ b/src/record_manager.cpp @@ -63,31 +63,41 @@ RecordFileInfo RecordManager::parseFile(const fs::path& p) { // 目录结构倒推 auto filename = p.filename().string(); // 10-23-17.mp4 - auto hour_dir = p.parent_path().filename().string(); // 10 auto date_dir = p.parent_path().parent_path().filename().string(); // 2025-11-13 auto stream_dir = p.parent_path().parent_path().parent_path().filename().string(); info.stream = stream_dir; - // 日期解析 - int y = 0, mon = 0, d = 0; + int y = 0, mon = 0, d = 0, h = 0, m = 0, s = 0; sscanf(date_dir.c_str(), "%d-%d-%d", &y, &mon, &d); - - // 文件名解析 H-M-S - int h = 0, m = 0, s = 0; sscanf(filename.c_str(), "%d-%d-%d", &h, &m, &s); - std::tm t{}; - t.tm_year = y - 1900; - t.tm_mon = mon - 1; - t.tm_mday = d; - t.tm_hour = h; - t.tm_min = m; - t.tm_sec = s; + std::tm tm{}; + tm.tm_year = y - 1900; + tm.tm_mon = mon - 1; + tm.tm_mday = d; + tm.tm_hour = h; + tm.tm_min = m; + tm.tm_sec = s; - int64_t epoch = std::mktime(&t) * 1000LL; - info.start_ms = epoch; - info.end_ms = epoch + 60 * 1000; // 默认 1 分钟 + int64_t start = std::mktime(&tm) * 1000LL; + info.start_ms = start; + + // ====== 加入 mp4v2 读取真实 duration ====== + 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; + } + else + { + // 出错 fallback + info.end_ms = start + 60000; + } } catch (...) { @@ -137,7 +147,7 @@ std::vector RecordManager::querySegments(const std::string& strea auto& prev = hits[i - 1]; auto& cur = hits[i]; - bool continuous = (cur.start_ms <= prev.end_ms + 1500); // 允许 1.5 秒误差 + bool continuous = (cur.start_ms - prev.end_ms) <= 2000; if (continuous) {