// main.cpp #include #include #include #include #include #include "app_config.hpp" #include "logger.hpp" #include "mqtt_client_wrapper.hpp" #include "record_manager.hpp" #include "rtmp_manager.hpp" std::atomic g_running(true); static void signal_handler(int signum) { g_running.store(false, std::memory_order_relaxed); const char msg[] = "[MAIN] Signal received, shutting down...\n"; 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() { // ---------- 信号处理 ---------- struct sigaction sa{}; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGINT, &sa, nullptr); sigaction(SIGTERM, &sa, nullptr); signal(SIGPIPE, SIG_IGN); // ---------- 初始化日志 ---------- 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::cout << "[RecordManager] scanning " << base << " ..." << std::endl; // rm.scanAll(); // std::cout << "\n=== 全部扫描结果 ===\n"; // // 遍历所有 stream // rm.dumpIndex(); // // 测试一次查询:你可以换成真实时间戳 // 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"); // auto segments = rm.querySegments("AHD1_main", start, end); // 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& 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"); // try // { // // 加载配置 // g_app_config = AppConfig::load_from_file(get_executable_dir_file_path("config.json")); // LOG_INFO("[MAIN] Loaded config from config.json"); // } // catch (const std::exception& e) // { // LOG_ERROR(std::string("[MAIN] Failed to load config: ") + e.what()); // return -1; // } // // ---------- 初始化 GStreamer ---------- // RTMPManager::init(); // // ---------- 自动推流(8 路录像守护) ---------- // LOG_INFO("[MAIN] Starting all record streams..."); // RTMPManager::start_all(); // // 启动 MQTT 线程 // std::thread mqtt_thread( // [] // { // try // { // LOG_INFO("[MAIN] MQTT thread started."); // mqtt_client_thread_func(); // 在回调里执行推流控制 // } // catch (const std::exception& e) // { // LOG_ERROR(std::string("[MAIN] MQTT thread crashed: ") + e.what()); // } // LOG_INFO("[MAIN] MQTT thread exiting..."); // }); // // 主循环,仅等待退出信号 // while (g_running.load(std::memory_order_relaxed)) std::this_thread::sleep_for(std::chrono::milliseconds(200)); // // ---------- 退出清理 ---------- // LOG_INFO("[MAIN] Shutdown requested. Stopping RTMP streams..."); // RTMPManager::stop_all(); // if (mqtt_thread.joinable()) // { // mqtt_thread.join(); // LOG_INFO("[MAIN] MQTT thread joined."); // } LOG_INFO("[MAIN] ===== Vehicle Video Service Exited Cleanly ====="); return 0; }