bonus-edge-proxy/src/videoService/video_service_manager.cc

129 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/service/video_service_manager.cc (重构后)
#include "video_service_manager.h"
#include "spdlog/spdlog.h"
#include <fstream>
// [新增] 包含我们的新工厂
#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<IAnalysisModule> 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<VideoService>(
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.");
}