123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- #include "config.h"
- #include <fstream>
- #include <iostream>
- #include <sstream>
- #include <boost/filesystem.hpp>
- namespace jtjai_media {
- bool ConfigManager::load_from_file(const std::string& config_file) {
- try {
- std::ifstream file(config_file);
- if (!file.is_open()) {
- std::cerr << "无法打开配置文件: " << config_file << std::endl;
- return false;
- }
-
- std::stringstream buffer;
- buffer << file.rdbuf();
- file.close();
-
- return load_from_json(buffer.str());
- } catch (const std::exception& e) {
- std::cerr << "加载配置文件时发生异常: " << e.what() << std::endl;
- return false;
- }
- }
- bool ConfigManager::load_from_json(const std::string& json_str) {
- try {
- auto json_value = boost::json::parse(json_str);
- auto json_obj = json_value.as_object();
-
- // 加载全局配置
- if (json_obj.contains("global_config")) {
- global_config_ = global_config_from_json(json_obj["global_config"].as_object());
- }
-
- // 加载流配置
- stream_configs_.clear();
- if (json_obj.contains("streams")) {
- auto streams_array = json_obj["streams"].as_array();
- for (const auto& stream_json : streams_array) {
- stream_configs_.push_back(stream_config_from_json(stream_json.as_object()));
- }
- }
-
- return validate();
- } catch (const std::exception& e) {
- std::cerr << "解析JSON配置时发生异常: " << e.what() << std::endl;
- return false;
- }
- }
- bool ConfigManager::save_to_file(const std::string& config_file) const {
- try {
- boost::json::object root;
-
- // 保存全局配置
- root["global_config"] = global_config_to_json(global_config_);
-
- // 保存流配置
- boost::json::array streams_array;
- for (const auto& stream : stream_configs_) {
- streams_array.push_back(stream_config_to_json(stream));
- }
- root["streams"] = streams_array;
-
- std::ofstream file(config_file);
- if (!file.is_open()) {
- std::cerr << "无法创建配置文件: " << config_file << std::endl;
- return false;
- }
-
- file << boost::json::serialize(root) << std::endl;
- file.close();
-
- return true;
- } catch (const std::exception& e) {
- std::cerr << "保存配置文件时发生异常: " << e.what() << std::endl;
- return false;
- }
- }
- bool ConfigManager::validate() const {
- // 检查全局配置
- if (global_config_.total_poll_duration_seconds <= 0) {
- std::cerr << "总轮询时长必须大于0秒" << std::endl;
- return false;
- }
-
- if (global_config_.max_concurrent_streams <= 0) {
- std::cerr << "最大并发流数必须大于0" << std::endl;
- return false;
- }
-
- if (global_config_.output_directory.empty()) {
- std::cerr << "输出目录不能为空" << std::endl;
- return false;
- }
-
- // 检查流配置
- if (stream_configs_.empty()) {
- std::cerr << "至少需要配置一个RTSP流" << std::endl;
- return false;
- }
-
- for (size_t i = 0; i < stream_configs_.size(); ++i) {
- const auto& stream = stream_configs_[i];
-
- if (stream.rtsp_url.empty()) {
- std::cerr << "第 " << (i + 1) << " 个流的RTSP地址不能为空" << std::endl;
- return false;
- }
-
- if (stream.duration_seconds <= 0) {
- std::cerr << "第 " << (i + 1) << " 个流的访问时长必须大于0秒" << std::endl;
- return false;
- }
-
- if (stream.weight <= 0) {
- std::cerr << "第 " << (i + 1) << " 个流的权重必须大于0" << std::endl;
- return false;
- }
-
- if (stream.output_filename.empty()) {
- std::cerr << "第 " << (i + 1) << " 个流的输出文件名不能为空" << std::endl;
- return false;
- }
- }
-
- return true;
- }
- std::string ConfigManager::to_string() const {
- std::stringstream ss;
- ss << "全局配置:\\n";
- ss << " 总轮询时长: " << global_config_.total_poll_duration_seconds << " 秒\\n";
- ss << " 最大并发流数: " << global_config_.max_concurrent_streams << "\\n";
- ss << " 输出目录: " << global_config_.output_directory << "\\n";
- ss << " 报告文件名: " << global_config_.report_filename << "\\n";
- ss << " 连接超时: " << global_config_.connection_timeout_seconds << " 秒\\n";
- ss << " 读取超时: " << global_config_.read_timeout_seconds << " 秒\\n";
- ss << " 轮询周期数: " << (global_config_.poll_cycles == -1 ? "无限循环" : std::to_string(global_config_.poll_cycles)) << "\n";
- ss << " 周期间隔: " << global_config_.cycle_interval_seconds << " 秒\n";
-
- ss << "\\n流配置 (" << stream_configs_.size() << " 个):\\n";
- for (size_t i = 0; i < stream_configs_.size(); ++i) {
- const auto& stream = stream_configs_[i];
- ss << " [" << (i + 1) << "] " << stream.rtsp_url << "\\n";
- ss << " 时长: " << stream.duration_seconds << " 秒, ";
- ss << "权重: " << stream.weight << ", ";
- ss << "输出: " << stream.output_filename << "\\n";
- }
-
- return ss.str();
- }
- boost::json::object ConfigManager::stream_config_to_json(const StreamConfig& config) const {
- boost::json::object obj;
- obj["rtsp_url"] = config.rtsp_url;
- obj["duration_seconds"] = config.duration_seconds;
- obj["weight"] = config.weight;
- obj["output_filename"] = config.output_filename;
- return obj;
- }
- StreamConfig ConfigManager::stream_config_from_json(const boost::json::object& json_obj) const {
- StreamConfig config;
-
- if (json_obj.contains("rtsp_url")) {
- config.rtsp_url = json_obj.at("rtsp_url").as_string().c_str();
- }
-
- if (json_obj.contains("duration_seconds")) {
- config.duration_seconds = static_cast<int>(json_obj.at("duration_seconds").as_int64());
- }
-
- if (json_obj.contains("weight")) {
- config.weight = json_obj.at("weight").as_double();
- }
-
- if (json_obj.contains("output_filename")) {
- config.output_filename = json_obj.at("output_filename").as_string().c_str();
- }
-
- return config;
- }
- boost::json::object ConfigManager::global_config_to_json(const GlobalConfig& config) const {
- boost::json::object obj;
- obj["total_poll_duration_seconds"] = config.total_poll_duration_seconds;
- obj["max_concurrent_streams"] = config.max_concurrent_streams;
- obj["output_directory"] = config.output_directory;
- obj["report_filename"] = config.report_filename;
- obj["connection_timeout_seconds"] = config.connection_timeout_seconds;
- obj["read_timeout_seconds"] = config.read_timeout_seconds;
- obj["poll_cycles"] = config.poll_cycles;
- obj["cycle_interval_seconds"] = config.cycle_interval_seconds;
- return obj;
- }
- GlobalConfig ConfigManager::global_config_from_json(const boost::json::object& json_obj) const {
- GlobalConfig config;
-
- if (json_obj.contains("total_poll_duration_seconds")) {
- config.total_poll_duration_seconds = static_cast<int>(json_obj.at("total_poll_duration_seconds").as_int64());
- }
-
- if (json_obj.contains("max_concurrent_streams")) {
- config.max_concurrent_streams = static_cast<int>(json_obj.at("max_concurrent_streams").as_int64());
- }
-
- if (json_obj.contains("output_directory")) {
- config.output_directory = json_obj.at("output_directory").as_string().c_str();
- }
-
- if (json_obj.contains("report_filename")) {
- config.report_filename = json_obj.at("report_filename").as_string().c_str();
- }
-
- if (json_obj.contains("connection_timeout_seconds")) {
- config.connection_timeout_seconds = static_cast<int>(json_obj.at("connection_timeout_seconds").as_int64());
- }
-
- if (json_obj.contains("read_timeout_seconds")) {
- config.read_timeout_seconds = static_cast<int>(json_obj.at("read_timeout_seconds").as_int64());
- }
-
- if (json_obj.contains("poll_cycles")) {
- config.poll_cycles = static_cast<int>(json_obj.at("poll_cycles").as_int64());
- }
-
- if (json_obj.contains("cycle_interval_seconds")) {
- config.cycle_interval_seconds = static_cast<int>(json_obj.at("cycle_interval_seconds").as_int64());
- }
-
- return config;
- }
- } // namespace jtjai_media
|