基于gstreamer的支持动态获取多路流的rtsp server(笔记)

上篇文章讲了streamer的rtsp推流的基本用法

下面讲搭建动态多路流的rtsp server。有两种方式能达到效果,一种采用main_loop_run运行在线程里,另一种则是创建factory等操作可在有需要的时候动态创建。代码基于gst自带的示例test-readme.c改造,编译同gst示例

一、方法一代码

#include <gst/gst.h>
 
#include <gst/rtsp-server/rtsp-server.h>
#include <pthread.h>
 
void* testFun(void *args)
{
  GMainLoop *loop = (GMainLoop *) args;
  g_main_loop_run (loop);
}
 
int
main (int argc, char *argv[])
{
  GMainLoop *loop;
  GstRTSPServer *server;
  GstRTSPMountPoints *mounts;
  GstRTSPMediaFactory *factory;
 
  gst_init (&argc, &argv);
 
  loop = g_main_loop_new (NULL, FALSE);
  pthread_t tTest;
  pthread_create(&tTest, NULL, testFun, loop);
 
  /* create a server instance */
  server = gst_rtsp_server_new ();
  gst_rtsp_server_set_service (server, "8555");
 
  /* get the mount points for this server, every server has a default object
   * that be used to map uri mount points to media factories */
  mounts = gst_rtsp_server_get_mount_points (server);
 
  /* make a media factory for a test stream. The default media factory can use
   * gst-launch syntax to create pipelines. 
   * any launch line works as long as it contains elements named pay%d. Each
   * element with pay%d names will be a stream */
  factory = gst_rtsp_media_factory_new ();
  gst_rtsp_media_factory_set_launch (factory,
      "( videotestsrc is-live=1 ! x264enc ! rtph264pay name=pay0 pt=96 )");
 
  gst_rtsp_media_factory_set_shared (factory, TRUE);
 
  /* attach the test factory to the /test url */
  gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
 
  /* don't need the ref to the mapper anymore */
  g_object_unref (mounts);
 
  /* attach the server to the default maincontext */
  gst_rtsp_server_attach (server, NULL);
 
  /* start serving */
  g_print ("stream ready at rtsp://127.0.0.1:8554/test\n");
  //g_main_loop_run (loop);
  pthread_join(tTest, NULL);
 
  return 0;
}

二、方法二的代码

#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
 
const char* port = "10001";
 
static void
handle_client (GstRTSPClient * client, GstRTSPContext * ctx,
    GstRTSPServer * server, gpointer user_data)
{
  GstRTSPClientClass *klass;
  GstRTSPMountPoints *mounts;
  GstRTSPMediaFactory *factory;
  GstRTSPUrl *uri;
  gchar *path;
  gchar *launch = "( videotestsrc is-live=1 ! x264enc ! rtph264pay name=pay0 pt=96 )";
 
  uri = ctx->uri;
 
  if (!uri)
    return;
 
  klass = GST_RTSP_CLIENT_GET_CLASS (client);
  path = klass->make_path_from_uri (client, uri);
 
  mounts = gst_rtsp_server_get_mount_points (server);
  factory = gst_rtsp_mount_points_match (mounts, path, NULL);
  if (!factory)
  {
    factory = gst_rtsp_media_factory_new ();
    gst_rtsp_media_factory_set_launch (factory, launch);
    gst_rtsp_media_factory_set_shared (factory, TRUE);
 
    //g_signal_connect (factory, "media-constructed", (GCallback)
      //                                              media_constructed, NULL);
 
    gst_rtsp_mount_points_add_factory (mounts, path, factory);
    g_print ("new factory: %s\n", launch);
  }
  else
  {
    g_object_unref (factory);
  }
  g_object_unref (mounts);
  g_free (path);
  //g_free (launch);
}
 
static void
client_connected (GstRTSPServer * server,
    GstRTSPClient * client, gpointer user_data)
{
  g_signal_connect_object (client, "options-request", (GCallback)
      handle_client, server, G_CONNECT_AFTER);
}
 
static gboolean
timeout (GstRTSPServer * server)
{
  GstRTSPSessionPool *pool;
 
  pool = gst_rtsp_server_get_session_pool (server);
  gst_rtsp_session_pool_cleanup (pool);
  g_object_unref (pool);
 
  return TRUE;
}
 
int
main (int argc, char *argv[])
{
  GMainLoop *loop;
  GstRTSPServer *server;
  GError *error = NULL;
 
  gst_init (&argc, &argv);
 
  loop = g_main_loop_new (NULL, FALSE);
 
  /* create a server instance */
  server = gst_rtsp_server_new ();
  gst_rtsp_server_set_service (server, port);
 
  /* attach the server to the default maincontext */
  gst_rtsp_server_attach (server, NULL);
 
  g_signal_connect (server, "client-connected", (GCallback)
      client_connected, NULL);
 
  g_timeout_add_seconds (2, (GSourceFunc) timeout, server);
 
  g_object_unref (server);
 
  /* start serving */
  g_print ("rtsp://127.0.0.1:%s/\n", port);
  g_main_loop_run (loop);
 
  return 0;
}
由于偷懒,handle_client函数里直接用的teat-readme里的代码。如果想获取自定义的流,可以将改函数里的内容替换为test-appsrc相关代码

 下载链接:https://download.csdn.net/download/yingyemin/11016282

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
GStreamer是一个功能强大且具有灵活性的开源多媒体框架,可以用于处理音频和视频数据。在GStreamer中,可以使用rtsp插件来处理和传输RTSP(实时传输协议)多路视频。 使用GStreamer处理多路视频,我们需要以下步骤: 1. 导入相关的GStreamer库和插件:首先,需要将GStreamer的核心库和rtsp插件导入到程序中。这些库和插件可以与GStreamer的Python绑定一起使用。 2. 创建GStreamer的图:通过创建GStreamer的Playbin元素,并设置其uri属性为rtsp://服务器地址/视频路径,可以创建一个包含多路视频GStreamer图。可以指定多个uri地址来处理多路视频。 3. 设置视频处理相关的配置:可以使用GStreamer的其他插件来进行视频的处理,如解码、滤镜、编码等。可以根据需要添加各种插件,并根据要求进行配置。 4. 添加准备、启动和停止的控制逻辑:可以使用GStreamer提供的信号来控制视频的准备、启动和停止。可以连接相应的信号,当视频准备好后自动开始播放,当停止信号触发时停止播放。 5. 运行GStreamer主循环:使用GStreamer的主循环函数,例如Gst.Element.get_bus().timed_pop_filtered(),来运行GStreamer的数据处理循环。该循环会自动处理从视频中接收到的数据,并将其传递给指定的处理器和输出。 通过以上步骤,我们可以使用GStreamer来处理和传输多路视频。可以根据需要配置和定制多路视频的处理和输出,以满足特定的应用需求。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值