From baa414a8d18f024bc872f78c3399c2fd8598e0cc Mon Sep 17 00:00:00 2001 From: nvikramraj Date: Fri, 20 Feb 2026 15:17:02 -0600 Subject: [PATCH] added rtsps support --- config/parameters.yaml | 15 ++++++++------ include/image2rtsp.hpp | 4 ++++ src/image2rtsp.cpp | 9 +++++++++ src/video.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/config/parameters.yaml b/config/parameters.yaml index 8d653c8..011bf3b 100644 --- a/config/parameters.yaml +++ b/config/parameters.yaml @@ -2,15 +2,15 @@ ros__parameters: # If the source is a ros2 topic (default case) - compressed: [False,False,False] - topic: ["/topic1","/topic2","/topic3"] + compressed: [False, False] + topic: ["/camera/camera/color/image_raw","/camera/object/vehicle"] default_pipeline: | ( appsrc name=imagesrc do-timestamp=true min-latency=0 max-latency=0 max-bytes=1000 is-live=true ! videoconvert ! videoscale ! - video/x-raw, framerate=30/1, width=640, height=480 ! - x264enc tune=zerolatency bitrate=500 key-int-max=30 ! - video/x-h264, profile=baseline ! + video/x-raw, framerate=30/1, width=1280, height=720 ! + x264enc tune=zerolatency bitrate=3000 key-int-max=30 ! + video/x-h264, profile=main ! rtph264pay name=pay0 pt=96 ) # Notice: The framerate setting does not affect the RTSP stream — it entirely depends on the ros2 topic frequency. @@ -29,8 +29,11 @@ # Notice: Here the framerate might be set to the camera framerate, otherwise "503 Service Unavailable" error will appear. # RTSP setup - mountpoint: ["/1","/2","/3"] + mountpoint: ["/rgb","/vehicle"] port: "8554" + password_protect: True + username: "Test" + password: "123" local_only: False # True = rtsp://127.0.0.1:portAndMountpoint (The stream is accessible only from the local machine) # False = rtsp://0.0.0.0:portAndMountpoint (The stream is accessible from the outside) # For example, to access the stream running on the machine with IP = 192.168.20.20, diff --git a/include/image2rtsp.hpp b/include/image2rtsp.hpp index f3f70d8..f612592 100644 --- a/include/image2rtsp.hpp +++ b/include/image2rtsp.hpp @@ -37,11 +37,15 @@ private: string pipeline; string default_pipeline; string camera_pipeline; + string username; + string password; + bool password_protect; uint framerate; bool local_only; bool camera; void video_mainloop_start(); + void setup_auth(const char* username, const char* password); void rtsp_server_add_url(const char *url, const char *sPipeline, GstElement **appsrc); void topic_callback(const sensor_msgs::msg::Image::SharedPtr msg, Stream* stream); void compressed_topic_callback(const sensor_msgs::msg::CompressedImage::SharedPtr msg, Stream* stream); diff --git a/src/image2rtsp.cpp b/src/image2rtsp.cpp index 407d22e..a9d76d7 100644 --- a/src/image2rtsp.cpp +++ b/src/image2rtsp.cpp @@ -15,6 +15,9 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){ this->declare_parameter("local_only", true); this->declare_parameter("camera", false); this->declare_parameter("compressed", is_compressed); + this->declare_parameter("username", "test"); + this->declare_parameter("password", "123"); + this->declare_parameter("password_protect", false); this->declare_parameter("default_pipeline", R"( ( appsrc name=imagesrc do-timestamp=true min-latency=0 max-latency=0 max-bytes=1000 is-live=true ! @@ -42,6 +45,9 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){ local_only = this->get_parameter("local_only").as_bool(); camera = this->get_parameter("camera").as_bool(); is_compressed = this->get_parameter("compressed").as_bool_array(); + username = this->get_parameter("username").as_string(); + password = this->get_parameter("password").as_string(); + password_protect = this->get_parameter("password_protect").as_bool(); default_pipeline = this->get_parameter("default_pipeline").as_string(); camera_pipeline = this->get_parameter("camera_pipeline").as_string(); @@ -103,6 +109,9 @@ Image2rtsp::Image2rtsp() : Node("image2rtsp"){ video_mainloop_start(); rtsp_server = rtsp_server_create(port, local_only); + if (password_protect){ + setup_auth(username.c_str(), password.c_str()); + } for (Stream &s : streams_) { s.appsrc = NULL; rtsp_server_add_url(s.mountpoint.c_str(), pipeline.c_str(), camera ? nullptr : (GstElement **)&s.appsrc); diff --git a/src/video.cpp b/src/video.cpp index e41afaf..863edc9 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -21,6 +21,7 @@ void Image2rtsp::video_mainloop_start(){ pthread_create(&tloop, NULL, &mainloop, NULL); } + GstRTSPServer *Image2rtsp::rtsp_server_create(const std::string &port, const bool local_only){ GstRTSPServer *server; @@ -38,9 +39,40 @@ GstRTSPServer *Image2rtsp::rtsp_server_create(const std::string &port, const boo return server; } +void Image2rtsp::setup_auth(const char* username, const char* password) +{ + GstRTSPAuth *auth; + GstRTSPToken *token; + gchar *basic; + + /* create auth object */ + auth = gst_rtsp_auth_new(); + + /* create token with media factory role */ + token = gst_rtsp_token_new( + GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE, G_TYPE_STRING, "user", + NULL); + + /* create basic auth string */ + basic = gst_rtsp_auth_make_basic(username, password); + + /* add user */ + gst_rtsp_auth_add_basic(auth, basic, token); + + g_free(basic); + gst_rtsp_token_unref(token); + + /* attach auth to server */ + gst_rtsp_server_set_auth(rtsp_server, auth); + + g_object_unref(auth); +} + + void Image2rtsp::rtsp_server_add_url(const char *url, const char *sPipeline, GstElement **appsrc){ GstRTSPMountPoints *mounts; GstRTSPMediaFactory *factory; + GstRTSPPermissions *permissions; ////// security /* get the mount points for this server, every server has a default object * that be used to map uri mount points to media factories */ @@ -59,6 +91,18 @@ void Image2rtsp::rtsp_server_add_url(const char *url, const char *sPipeline, Gst gst_rtsp_media_factory_set_shared(factory, TRUE); + // Adding permissions + permissions = gst_rtsp_permissions_new(); + gst_rtsp_permissions_add_role(permissions, "user", + GST_RTSP_PERM_MEDIA_FACTORY_ACCESS, G_TYPE_BOOLEAN, TRUE, + GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT, G_TYPE_BOOLEAN, TRUE, + NULL); + + gst_rtsp_media_factory_set_permissions(factory, permissions); + gst_rtsp_permissions_unref(permissions); + + /////////// + /* attach the factory to the url */ gst_rtsp_mount_points_add_factory(mounts, url, factory);