如何让GstRTSPServer支持指定前缀下的任意路径或全路径?
解决GstRTSPServer支持前缀任意路径的问题
要让GstRTSPServer支持指定前缀下的任意路径,需修改挂载点匹配模式,并让媒体工厂能接收、处理完整请求路径,具体实现如下:
1. 核心调整点
- 改用前缀匹配模式挂载工厂,替代默认的精确路径匹配
- 在自定义工厂中解析请求路径,按需生成媒体流
- 禁用流名强制匹配,避免剩余路径被误判为流名导致报错
修改后的完整代码
#include <gst/rtsp-server/rtsp-server.h> typedef struct MyRTSPMediaFactory { GstRTSPMediaFactory parent; } MyRTSPMediaFactory; typedef struct MyRTSPMediaFactoryClass { GstRTSPMediaFactoryClass parent_class; } MyRTSPMediaFactoryClass; G_DEFINE_TYPE(MyRTSPMediaFactory, my_rtsp_media_factory, GST_TYPE_RTSP_MEDIA_FACTORY); static GstElement *my_rtsp_media_factory_create_element(GstRTSPMediaFactory* factory, const GstRTSPUrl* url) { // 获取完整请求路径 gchar *path = gst_rtsp_url_get_request_uri(url); g_print("Received request for path: %s\n", path); GError *error = NULL; GstElement *pipeline = NULL; // 根据路径生成对应媒体流,示例按路径后缀区分 if (g_str_has_suffix(path, "fubar")) { pipeline = gst_parse_launch("videotestsrc pattern=ball ! jpegenc ! rtpjpegpay name=pay0 pt=96", &error); } else { pipeline = gst_parse_launch("videotestsrc ! jpegenc ! rtpjpegpay name=pay0 pt=96", &error); } g_free(path); if (error) { g_printerr("Pipeline create error: %s\n", error->message); g_error_free(error); return NULL; } return pipeline; } static void my_rtsp_media_factory_init(MyRTSPMediaFactory* factory) { // 禁用流名强制匹配,避免剩余路径被当作流名检查 gst_rtsp_media_factory_set_shared(factory, TRUE); } static void my_rtsp_media_factory_class_init(MyRTSPMediaFactoryClass* klass) { GstRTSPMediaFactoryClass *mediafactory_class = GST_RTSP_MEDIA_FACTORY_CLASS(klass); mediafactory_class->create_element = my_rtsp_media_factory_create_element; } int main(int argc, char* argv[]) { gst_init (&argc, &argv); GMainLoop* loop = g_main_loop_new(NULL, FALSE); GstRTSPServer* server = gst_rtsp_server_new(); GstRTSPMountPoints* mounts = gst_rtsp_server_get_mount_points(server); GstRTSPMediaFactory* factory = (GstRTSPMediaFactory*)g_object_new(my_rtsp_media_factory_get_type(), NULL); gst_rtsp_server_set_service(server, "8554"); // 使用前缀匹配模式挂载工厂,所有以"/"开头的路径都会匹配 gst_rtsp_mount_points_add_factory_full(mounts, "/", factory, GST_RTSP_MOUNT_MATCH_PREFIX); gst_rtsp_server_attach(server, NULL); g_main_loop_run(loop); g_object_unref(mounts); g_object_unref(server); g_main_loop_unref(loop); return 0; }
关键说明
- 前缀匹配:
GST_RTSP_MOUNT_MATCH_PREFIX会让所有以指定路径为前缀的请求都匹配到该工厂,比如/fubar、/test/123都会匹配/的工厂 - 路径解析:通过
gst_rtsp_url_get_request_uri获取完整请求路径,可根据路径参数生成不同的媒体流 - 流名检查:
gst_rtsp_media_factory_set_shared(factory, TRUE)会关闭流名强制匹配逻辑,避免服务器将路径剩余部分当作流名检查,解决"流不存在"的报错
编译运行后,访问rtsp://192.168.10.215:8554/fubar或其他任意子路径均可正常工作,工厂会根据请求路径生成对应媒体流。
内容的提问来源于stack exchange,提问作者skyking
相关产品推荐
相关产品推荐

