2025-10-17 13:38:55 +08:00
|
|
|
#include <unistd.h>
|
2025-10-15 08:50:01 +08:00
|
|
|
|
2025-09-08 14:55:07 +08:00
|
|
|
#include <atomic>
|
2025-09-10 12:49:41 +08:00
|
|
|
#include <chrono>
|
2025-10-17 13:38:55 +08:00
|
|
|
#include <csignal>
|
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
|
|
#include "app_config.hpp"
|
|
|
|
|
#include "logger.hpp"
|
|
|
|
|
#include "mqtt_client_wrapper.hpp"
|
2025-11-14 09:42:17 +08:00
|
|
|
#include "record_manager.hpp"
|
2025-10-17 13:38:55 +08:00
|
|
|
#include "rtmp_manager.hpp"
|
2025-09-08 14:55:07 +08:00
|
|
|
|
2025-10-15 09:01:15 +08:00
|
|
|
std::atomic<bool> g_running(true);
|
2025-09-08 14:55:07 +08:00
|
|
|
|
2025-10-15 08:50:01 +08:00
|
|
|
static void signal_handler(int signum)
|
2025-09-08 14:55:07 +08:00
|
|
|
{
|
2026-05-09 10:51:10 +08:00
|
|
|
(void)signum;
|
2025-09-10 12:49:41 +08:00
|
|
|
g_running.store(false, std::memory_order_relaxed);
|
2025-10-15 08:50:01 +08:00
|
|
|
const char msg[] = "[MAIN] Signal received, shutting down...\n";
|
2025-09-10 12:49:41 +08:00
|
|
|
write(STDERR_FILENO, msg, sizeof(msg) - 1);
|
2025-09-08 14:55:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
2025-10-15 08:50:01 +08:00
|
|
|
struct sigaction sa{};
|
|
|
|
|
sa.sa_handler = signal_handler;
|
|
|
|
|
sigemptyset(&sa.sa_mask);
|
|
|
|
|
sa.sa_flags = 0;
|
|
|
|
|
sigaction(SIGINT, &sa, nullptr);
|
|
|
|
|
sigaction(SIGTERM, &sa, nullptr);
|
2025-09-08 14:55:07 +08:00
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
|
2025-11-13 14:42:01 +08:00
|
|
|
Logger::init(get_executable_dir_file_path("logs"), 7);
|
2025-10-17 15:29:38 +08:00
|
|
|
LOG_INFO("[MAIN] ===== Vehicle Video Service Starting =====");
|
2025-09-08 14:55:07 +08:00
|
|
|
|
2025-11-14 14:49:45 +08:00
|
|
|
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;
|
|
|
|
|
}
|
2025-11-14 09:42:17 +08:00
|
|
|
|
2026-05-09 10:51:10 +08:00
|
|
|
g_record_manager = std::make_shared<RecordManager>(g_app_config.srs.record_config);
|
|
|
|
|
|
2025-11-14 14:49:45 +08:00
|
|
|
RTMPManager::init();
|
2025-11-14 09:42:17 +08:00
|
|
|
|
2025-11-14 14:49:45 +08:00
|
|
|
LOG_INFO("[MAIN] Starting all record streams...");
|
|
|
|
|
RTMPManager::start_all();
|
2025-11-14 09:42:17 +08:00
|
|
|
|
2025-11-14 14:49:45 +08:00
|
|
|
std::thread mqtt_thread(
|
|
|
|
|
[]
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
LOG_INFO("[MAIN] MQTT thread started.");
|
2026-05-09 10:51:10 +08:00
|
|
|
mqtt_client_thread_func();
|
2025-11-14 14:49:45 +08:00
|
|
|
}
|
|
|
|
|
catch (const std::exception& e)
|
|
|
|
|
{
|
|
|
|
|
LOG_ERROR(std::string("[MAIN] MQTT thread crashed: ") + e.what());
|
|
|
|
|
}
|
|
|
|
|
LOG_INFO("[MAIN] MQTT thread exiting...");
|
|
|
|
|
});
|
2025-11-14 09:42:17 +08:00
|
|
|
|
2025-11-14 14:44:13 +08:00
|
|
|
while (g_running.load(std::memory_order_relaxed)) std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
2025-11-14 09:42:17 +08:00
|
|
|
|
2025-11-14 14:49:45 +08:00
|
|
|
LOG_INFO("[MAIN] Shutdown requested. Stopping RTMP streams...");
|
2025-11-14 18:33:35 +08:00
|
|
|
|
2025-11-14 18:40:00 +08:00
|
|
|
if (g_record_manager) g_record_manager->stopAutoScan();
|
2025-11-14 18:33:35 +08:00
|
|
|
|
2025-11-14 14:49:45 +08:00
|
|
|
RTMPManager::stop_all();
|
2025-11-14 09:42:17 +08:00
|
|
|
|
2025-11-14 14:49:45 +08:00
|
|
|
if (mqtt_thread.joinable())
|
|
|
|
|
{
|
|
|
|
|
mqtt_thread.join();
|
|
|
|
|
LOG_INFO("[MAIN] MQTT thread joined.");
|
|
|
|
|
}
|
2025-11-14 09:42:17 +08:00
|
|
|
|
2025-10-17 15:29:38 +08:00
|
|
|
LOG_INFO("[MAIN] ===== Vehicle Video Service Exited Cleanly =====");
|
2025-09-08 14:55:07 +08:00
|
|
|
return 0;
|
2025-10-15 08:50:01 +08:00
|
|
|
}
|