added rtsps support

This commit is contained in:
nvikramraj 2026-02-20 15:17:02 -06:00
parent 12be305afe
commit baa414a8d1
4 changed files with 66 additions and 6 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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);