使用GStreamer进行推流
使用GStreamer进行推流
1. GStreamer安装
安装:
https://blog.csdn.net/kkae8643150/article/details/123126507
直接使用包管理器可能有些插件没有安装,推荐使用源码安装。测试开发板是NVIDIA Jetson,这里需要使用NVIDIA的GStreamer插件。
2. 使用GStreamer进行推流
测试程序:https://github.com/GStreamer/gst-rtsp-server/blob/1.14.5/examples/test-launch.c
2.1 搭建本地RTSP服务器
2.1.1 安装必要的库
sudo apt-get install libgstrtspserver-1.0 libgstreamer1.0-dev
2.1.2 编写测试程序代码
test-launch.c
:
源程序:https://github.com/GStreamer/gst-rtsp-server/blob/1.14.5/examples/test-launch.c
2.1.3 编译
gcc test-launch.c -o test-launch $(pkg-config --cflags --libs gstreamer-1.0 gstreamer-rtsp-server-1.0)
编程成功后,会在当前目录下生成一个test-launch
可执行文件。
按照下面文章过程执行即可:
https://forums.developer.nvidia.com/t/jetson-nano-faq/82953#q-is-there-any-example-of-running-rtsp-streaming-8
此时我们直接访问开发板的8554端口,就可以看到视频流了。
2.2 推流到RTMP服务器
2.2.1 直接使用GStreamer推流
使用SRS作为RTMP服务器,开放服务器的1935端口。
执行如下命令:
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! nvvidconv ! nvv4l2h264enc ! h264parse ! flvmux streamable=true ! rtmpsink location='rtmp://自己服务器IP:1935/live/stream1'
调用gst的库封装这个命令。
#include <gst/gst.h>
// 将"120.55.XXX.XXX"替换为自己的服务器IP
#define SERVER_IP "120.55.XXX.XXX"
#define SERVER_PORT "1935"
#define STREAM_NAME "stream1"
int main (int argc, char *argv[])
{
gst_init(&argc, &argv);
// gst通过管道来传递前后插件之间的数据,我们首先将主管道创建
GstElement *pipeline = gst_pipeline_new("mainpip");
// 创建需要使用的插件并设置对应的参数
GstElement *src = gst_element_factory_make("nvarguscamerasrc", "src");
g_object_set(G_OBJECT(src), "sensor-id", 0, NULL);
GstElement *convert = gst_element_factory_make("nvvidconv", "convert");
GstElement *encoder = gst_element_factory_make("nvv4l2h264enc", "encoder");
GstElement *parser = gst_element_factory_make("h264parse", "parser");
GstElement *mux = gst_element_factory_make("flvmux", "mux");
g_object_set(G_OBJECT(mux), "streamable", TRUE, NULL);
GstElement *rtmpsink = gst_element_factory_make("rtmpsink", "rtmpsink");
// 设置服务器的IP和端口以及流名称
g_object_set(G_OBJECT(rtmpsink), "location", "rtmp://"SERVER_IP":"SERVER_PORT"/live/"STREAM_NAME, NULL);
// 是否成功创建
if (!pipeline || !src || !convert || !encoder || !parser || !mux || !rtmpsink) {
g_printerr("One or more elements could not be created. Exiting.\n");
return -1;
}
// 将元素添加到管道中
gst_bin_add_many(GST_BIN(pipeline), src, convert, encoder, parser, mux, rtmpsink, NULL);
// 连接各元素
if (!gst_element_link_many(src, convert, encoder, parser, mux, rtmpsink, NULL)) {
g_printerr("Elements could not be linked. Exiting.\n");
gst_object_unref(pipeline);
return -1;
}
// 设置管道状态为启动
gst_element_set_state(pipeline, GST_STATE_PLAYING);
// 启动循环
GstBus *bus = gst_element_get_bus(pipeline);
GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
// 停止并释放资源
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}
编译:
gcc tt.c -o tt $(pkg-config --cflags --libs gstreamer-1.0)
3. 使用ffmpeg间接推送Gstreamer服务器的流
启动2.1.3中的程序,然后执行如下命令:
ffmpeg -i "rtsp://127.0.0.1:8554/test" -f flv -r 25 -s 1920x1080 -an "rtmp://服务器IP:1935/live/stream1"