// src/service/video_service_manager.cc (重构后) #include "video_service_manager.h" #include "spdlog/spdlog.h" #include // [新增] 包含我们的新工厂 #include "analysis/factory/ModuleFactory.h" // [移除] 不再需要直接依赖 // #include "algorithm/IntrusionModule.h" VideoServiceManager::~VideoServiceManager() { stop_all(); } bool VideoServiceManager::load_config(const std::string &config_path) { std::ifstream ifs(config_path); if (!ifs.is_open()) { spdlog::error("Failed to open video config file: {}", config_path); return false; } try { nlohmann::json video_json; ifs >> video_json; m_enabled = video_json.value("/video_service/enabled"_json_pointer, false); if (video_json.contains("video_streams") && video_json["video_streams"].is_array()) { m_stream_configs_json = video_json["video_streams"]; } else { spdlog::warn("Video config contains no 'video_streams' array."); m_stream_configs_json = nlohmann::json::array(); } spdlog::info("Successfully loaded video config. Service enabled: {}. " "Streams found: {}", m_enabled, m_stream_configs_json.size()); return true; } catch (const nlohmann::json::exception &e) { spdlog::error("Failed to parse video config file '{}'. Error: {}", config_path, e.what()); return false; } } void VideoServiceManager::load_and_start() { if (!m_enabled) { spdlog::warn("VideoService is disabled in video configuration. No streams " "will be started."); return; } spdlog::info("Found {} video stream configurations.", m_stream_configs_json.size()); for (const auto &sc_json : m_stream_configs_json) { std::string id = sc_json.value("id", "unknown"); bool enabled = sc_json.value("enabled", false); if (!enabled) { spdlog::info("Video stream '{}' is disabled in config, skipping.", id); continue; } std::string input_url = sc_json.value("input_url", ""); std::string output_rtsp = sc_json.value("output_rtsp", ""); nlohmann::json module_config = sc_json.value("module_config", nlohmann::json::object()); // --- (这是核心修改) --- // (旧的 if/else if (module_type) 逻辑被完全移除) std::unique_ptr module = nullptr; try { // 1. 根据配置创建 "AI模块" // 我们不再关心 module_type 是什么, // ModuleFactory 会根据 module_config 的内容自动创建正确的模块 // (例如, 它可以检查 module_config.inference_engine_type == "yolov8") spdlog::info("Creating module for stream '{}' via ModuleFactory...", id); module = ModuleFactory::CreateModule(module_config); if (module == nullptr) { spdlog::error("ModuleFactory failed to create module for stream '{}' " "(Input: {}). Check config.", id, input_url); continue; } // 2. 创建 "管线" (VideoService) 并注入模块 // (这部分代码与 相比保持不变) auto service = std::make_unique( std::move(module), input_url, output_rtsp, module_config // 仍然传递 config,供 module->init() 使用 ); // 3. 启动服务 (逻辑不变) if (service->start()) { spdlog::info("Successfully started video service for stream '{}' " ". Output is [{}].", id, output_rtsp); services_.push_back(std::move(service)); } else { spdlog::error( "Failed to start video service for stream '{}' [Input: {}].", id, input_url); } } catch (const std::exception &e) { spdlog::error( "Exception while creating VideoService for stream '{}' [{}]: {}", id, input_url, e.what()); } // --- (修改结束) --- } spdlog::info( "VideoServiceManager finished setup. {} streams are now running.", services_.size()); } void VideoServiceManager::stop_all() { spdlog::info("Stopping all video services ({})...", services_.size()); for (auto &service : services_) { if (service) { service->stop(); } } services_.clear(); spdlog::info("All video services stopped and cleared."); }