diff --git a/include/record_manager.hpp b/include/record_manager.hpp index 084deaa..ec7c414 100644 --- a/include/record_manager.hpp +++ b/include/record_manager.hpp @@ -44,6 +44,8 @@ class RecordManager static std::string toReadable(int64_t ms); static std::string loc_to_stream(int loc); + int getHttpPort() const { return http_port_; } + private: // === SRS 配置相关 === std::string srs_record_cfg_path_; diff --git a/src/mqtt_client_wrapper.cpp b/src/mqtt_client_wrapper.cpp index 5c7800f..0d8e928 100644 --- a/src/mqtt_client_wrapper.cpp +++ b/src/mqtt_client_wrapper.cpp @@ -10,6 +10,7 @@ #include #include "record_manager.hpp" +#include "rtmp_manager.hpp" std::shared_ptr mqtt_client; @@ -174,7 +175,73 @@ static void handle_record_query_request(const nlohmann::json& req) mqtt_client->publish(g_app_config.mqtt.topics.record_query, resp.dump(-1), 1); } -static void handle_record_play_request(const nlohmann::json& req) {} +static void handle_record_play_request(const nlohmann::json& req) +{ + // 1. 解析参数 + if (!req.contains("data") || !req["data"].is_object()) + { + LOG_WARN("[record_play] missing data"); + return; + } + + const auto& d = req["data"]; + + int loc = d.value("loc", -1); + std::string segmentId = d.value("segmentId", ""); + + if (loc < 0 || segmentId.empty()) + { + LOG_WARN("[record_play] invalid parameters"); + return; + } + + LOG_INFO("[record_play] loc=" + std::to_string(loc) + " segmentId=" + segmentId); + + // 2. 根据 segmentId 获取录像段 + auto seg = g_record_manager->getSegment(segmentId); + if (seg.files.empty()) + { + LOG_WARN("[record_play] no files found for segmentId: " + segmentId); + return; + } + + // 3. 计算总时长 + int64_t duration = seg.end_ms - seg.start_ms; + + // 4. 获取播放地址前缀 + std::string ip = get_ip_address("enP2p33s0"); + if (ip.empty()) ip = "127.0.0.1"; + + int http_port = g_record_manager->getHttpPort(); + + // 5. 构造响应 + nlohmann::json resp; + resp["type"] = "response"; + resp["seqNo"] = req.value("seqNo", "0"); + + nlohmann::json data; + data["loc"] = loc; + data["segmentId"] = segmentId; + data["startTime"] = seg.start_ms; + data["endTime"] = seg.end_ms; + data["duration"] = duration; + + // 6. 单文件列表 + nlohmann::json files = nlohmann::json::array(); + for (auto& f : seg.files) + { + nlohmann::json item; + item["url"] = "http://" + ip + ":" + std::to_string(http_port) + f.path; + item["startTime"] = f.start_ms; + item["endTime"] = f.end_ms; + files.push_back(item); + } + data["files"] = files; + resp["data"] = data; + + // 7. 回复 MQTT + mqtt_client->publish(g_app_config.mqtt.topics.record_play, resp.dump(), 1); +} static void on_mqtt_message_received(const std::string& topic, const std::string& message) {