基于gstreamer的rtsp推送和转发


前段时间因为实验室项目要求,需要读取摄像头并推rtsp流,由于我们实验室不是做与之相关的工作,所以并没有什么参考资料或者学长去问,只能自己在网上瞎找,也是费了很大的劲儿才最终实现,不过也只是简单推流。

本教程系统为ubuntu16.04

一、配置gstreamer环境

安装gstreamer基础库

sudo apt-get install libgl1-mesa-dev
sudo apt-get install gstreamer1.0-libav
sudo apt-get install gstreamer1.0-plugins-bad
sudo apt-get install gstreamer1.0-plugins-base
sudo apt-get install gstreamer1.0-plugins-ugly
sudo apt-get install gstreamer1.0-plugins-good

装完之后最好在bachrc中加两句路径,不加的话有时候gstreamer不好用,读不到组件。

sudo gedit ~/.bachrc   //打开bachrc文件

//在bachrc文件中加下边两句,我试过只加第二句也可以
export LD_LIBRARY_PATH=/usr/local/lib
export GST_PLUGIN_PATH=/usr/local/lib:/usr/lib/x86_64-linux-gnu/gstreamer-1.0

source ~/.bachrc  //在终端输入,每次改完bachrc都要source一下

加完上边两句刚开始报错,不用管它,等一会儿就好啦

做完这些基本gstreamer就能用了,可以用下边命令试一下:

gst-launch-1.0 rtspsrc latency=20 location="rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov" ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink


出现上边这个画面应该就配置好环境了

二、安装gstreamer-rtsp-server

git clone  -b 1.8 https://github.com/GStreamer/gst-rtsp-server.git  //下载源码
cd gst-rtsp-server       //目录名可能不正确,自己注意点,就是刚刚下载的目录
./autogen.sh
sudo make
sudo make install

三、读取usb摄像头并推rtsp流

直接上源码:

#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#define DEFAULT_RTSP_PORT "7551"

static char *port = (char *) DEFAULT_RTSP_PORT;

static GOptionEntry entries[] = {
  {"port", 'p', 0, G_OPTION_ARG_STRING, &port,
      "Port to listen on (default: " DEFAULT_RTSP_PORT ")", "PORT"},
  {NULL}
};

int
main (int argc, char *argv[])
{
  GMainLoop *loop;
  GstRTSPServer *server;
  GstRTSPMountPoints *mounts;
  GstRTSPMediaFactory *factory;
  GOptionContext *optctx;
  GError *error = NULL;

  optctx = g_option_context_new ("<launch line> - Test RTSP Server, Launch\n\n"
      "Example: \"( videotestsrc ! x264enc ! rtph264pay name=pay0 pt=96 )\"");
  g_option_context_add_main_entries (optctx, entries, NULL);
  g_option_context_add_group (optctx, gst_init_get_option_group ());
  if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
    g_printerr ("Error parsing options: %s\n", error->message);
    g_option_context_free (optctx);
    g_clear_error (&error);
    return -1;
  }
  g_option_context_free (optctx);

  loop = g_main_loop_new (NULL, FALSE);

  /* create a server instance */
  server = gst_rtsp_server_new ();
  g_object_set (server, "service", port, NULL);

  /* 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, argv[1]);

  /* 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:%s/test\n", port);
  g_main_loop_run (loop);

  return 0;
}

编译指令:

gcc test-launch.c -o test $(pkg-config --cflags --libs gstreamer-rtsp-server-1.0 gstreamer-1.0)

源码其实就是刚刚下载编译的gst-rtsp-server文件夹下边的examples文件夹中的test-launch.c文件,我一点都没改,因为主要还是在终端执行的命令。

编译完成后,会生成一个名为test的可执行文件。在当前目录下打开终端,输入:

./test "( v4l2src device=/dev/video0 norm=255 ! video/x-raw-yuv,format='fourcc'YUY2,width=640,height=480 ! x264enc tune="zerolatency" threads=4  ! rtph264pay name=pay0 pt=96 )"

其中device=/dev/video0是你读取的摄像头编号,如果是笔记本,video0应该是笔记本自带摄像头。
再开一个终端,输入:

gst-launch-1.0 rtspsrc latency=20 location="rtsp://127.0.0.1:7551/test" ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink

应该就能看到你自己了

四、转发rtsp

转发rtsp和读取usb摄像头的源码可以一模一样,因为最主要的还是在执行可执行文件时的命令,为了便于大家理解,我还是对上述源码做微小的改动:

#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#define DEFAULT_RTSP_PORT "8551"

static char *port = (char *) DEFAULT_RTSP_PORT;

static GOptionEntry entries[] = {
  {"port", 'p', 0, G_OPTION_ARG_STRING, &port,
      "Port to listen on (default: " DEFAULT_RTSP_PORT ")", "PORT"},
  {NULL}
};

int
main (int argc, char *argv[])
{
  GMainLoop *loop;
  GstRTSPServer *server;
  GstRTSPMountPoints *mounts;
  GstRTSPMediaFactory *factory1;
  GOptionContext *optctx;
  GError *error = NULL;

  optctx = g_option_context_new ("<launch line> - Test RTSP Server, Launch\n\n"
      "Example: \"( videotestsrc ! x264enc ! rtph264pay name=pay0 pt=96 )\"");
  g_option_context_add_main_entries (optctx, entries, NULL);
  g_option_context_add_group (optctx, gst_init_get_option_group ());
  if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
    g_printerr ("Error parsing options: %s\n", error->message);
    g_option_context_free (optctx);
    g_clear_error (&error);
    return -1;
  }
  g_option_context_free (optctx);

  loop = g_main_loop_new (NULL, FALSE);

  /* create a server instance */
  server = gst_rtsp_server_new ();
  g_object_set (server, "service", port, NULL);

  /* 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 */
   * 
  factory1 = gst_rtsp_media_factory_new ();
  gst_rtsp_media_factory_set_launch (factory1, argv[1]);

  /* attach the test factory to the /test url */
  
  gst_rtsp_mount_points_add_factory (mounts, "/test1", factory1);

  /* 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:%s/test1\n", port);
  g_main_loop_run (loop);

  return 0;
}

我只是把端口号修改成8551,factory和test名字做了修改
编译指令同上,名字可以换一下:

gcc test-tra.c -o test-tra $(pkg-config --cflags --libs gstreamer-rtsp-server-1.0 gstreamer-1.0)

打开终端,执行:

./test-tra "( rtspsrc latency=20  location=rtsp://127.0.0.1:7551/test ! queue ! rtph264depay ! queue ! rtph264pay name=pay0 pt=96 )"

在执行这个命令之前要执行上边推usb摄像头的命令,但不要用gstreamer直接打开直推的码流,要用下边这个命令:

gst-launch-1.0 rtspsrc latency=20 location="rtsp://127.0.0.1:8551/test1" ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink

也可以用公共的rtsp地址测试:

gst-launch-1.0 rtspsrc latency=20 location="rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov" ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink

至此,基本读取usb摄像头推rtsp和转发就都实现了。

  • 14
    点赞
  • 142
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜聿于

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值