You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:02:17