diff --git a/src/rtmp_manager.cpp b/src/rtmp_manager.cpp index c093cc0..f90ccb7 100644 --- a/src/rtmp_manager.cpp +++ b/src/rtmp_manager.cpp @@ -100,9 +100,11 @@ GstElement *RTMPManager::create_pipeline(const Camera &cam, StreamType type) } const std::string stream_name = cam.name + stream_type_suffix(type); - const std::string app = pick_app(type); + const std::string app = (type == StreamType::MAIN) ? "record" : "live"; // 🎯 主码流录像,子码流远程推流 + + // 👇 确保明确指定 vhost,避免 “no vhost 127.0.0.1” 错误 + const std::string location = "rtmp://127.0.0.1:1935/" + app + "/" + stream_name + "?vhost=" + app; - // NV12 -> mpph264enc -> h264parse -> flvmux(+静音音轨) -> rtmpsink std::string pipeline_str = "v4l2src device=" + cam.device + " ! video/x-raw,width=" + std::to_string(width) + ",height=" + std::to_string(height) + ",framerate=" + std::to_string(fps) + "/1 " @@ -113,10 +115,10 @@ GstElement *RTMPManager::create_pipeline(const Camera &cam, StreamType type) "! h264parse " "! flvmux name=mux streamable=true " "audiotestsrc wave=silence ! audioconvert ! audioresample ! voaacenc ! aacparse ! mux. " - "mux. ! rtmpsink name=rtmp_sink location=\"rtmp://127.0.0.1/" + - app + "/" + stream_name + " live=1\" sync=false"; + "mux. ! rtmpsink name=rtmp_sink location=\"" + + location + "\" sync=false"; - LOG_INFO("[RTMP] Creating pipeline for '" + stream_name + "' -> app '" + app + "': " + pipeline_str); + LOG_INFO("[RTMP] Creating pipeline for '" + stream_name + "' → app '" + app + "', url=" + location); GError *error = nullptr; GstElement *pipeline = gst_parse_launch(pipeline_str.c_str(), &error); @@ -126,6 +128,7 @@ GstElement *RTMPManager::create_pipeline(const Camera &cam, StreamType type) g_error_free(error); return nullptr; } + return pipeline; }