diff --git a/src/rtsp/gst/factory.rs b/src/rtsp/gst/factory.rs index c7a88c46..6d9c590a 100644 --- a/src/rtsp/gst/factory.rs +++ b/src/rtsp/gst/factory.rs @@ -35,11 +35,18 @@ impl Default for NeoMediaFactory { impl NeoMediaFactory { fn new() -> Self { let factory = Object::new::(); - factory.set_shared(false); + // Share a single GStreamer pipeline across all RTSP clients. + // Without this, each client (go2rtc, ffprobe, health checks) creates + // its own pipeline and camera stream session, exhausting resources + // and accumulating CLOSE_WAIT connections during 24/7 operation. + factory.set_shared(true); factory.set_eos_shutdown(false); factory.set_stop_on_disconnect(false); // factory.set_publish_clock_mode(gstreamer_rtsp_server::RTSPPublishClockMode::Clock); - factory.set_suspend_mode(gstreamer_rtsp_server::RTSPSuspendMode::Reset); + // Keep the pipeline alive when clients disconnect instead of tearing + // it down and rebuilding. Reset mode causes resource churn when + // monitoring tools periodically probe the stream. + factory.set_suspend_mode(gstreamer_rtsp_server::RTSPSuspendMode::None); factory.set_launch("videotestsrc pattern=\"snow\" ! video/x-raw,width=896,height=512,framerate=25/1 ! textoverlay name=\"inittextoverlay\" text=\"Stream not Ready\" valignment=top halignment=left font-desc=\"Sans, 32\" ! jpegenc ! rtpjpegpay name=pay0"); factory.set_transport_mode(RTSPTransportMode::PLAY); factory