在本教程中,我将向你展示如何使用 C++ 和 GStreamer 将你的网络摄像头数据流传输到 RTMP 服务器。
要求
- C++基础知识
- GStreamer基础知识
- 网络摄像头
创建源代码
首先,我们需要实际编写代码,使我们能够将网络摄像头数据流传输到 RTMP 服务器。
打开名为“main.cpp”的文件并添加以下标题:
#include<gst/gst.h>
接下来编写/复制以下主函数:
int main(int argc, char *argv[])
{
GstElement *pipeline, *source, *videoconvert, *videoscale, *capsfilter, *queue, *encoder, *muxer, *sink;
GstCaps *caps;
GstBus *bus;
GstMessage *message;
// Initialize GStreamer
gst_init(&argc, &argv);
// Set properties
g_object_set(encoder, "bitrate", 5000, NULL);
g_object_set(muxer, "streamable", TRUE, NULL);
g_object_set(sink, "location", "rtmp://localhost/stream", NULL);
caps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 3840,
"height", G_TYPE_INT, 2160,
NULL);
g_object_set(capsfilter, "caps", caps, NULL);
gst_caps_unref(caps);
pipeline = gst_pipeline_new("rtmpcam");
gst_bin_add_many(GST_BIN(pipeline), source, videoconvert, videoscale, capsfilter, queue, encoder, muxer, sink, NULL);
if (!gst_element_link_many(source, videoconvert, videoscale, capsfilter, queue, encoder, muxer, sink, NULL))
{
g_error("Failed to link elements");
return -1;
}
gst_element_set_state(pipeline, GST_STATE_PLAYING);
bus = gst_element_get_bus(pipeline);
message = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, static_cast<GstMessageType>(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
if (message != NULL)
{
gst_message_unref(message);
}
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
}
现在我将解释每个部分在做什么。
首先,我们创建变量并使用以下内容初始化 GStreamer:
GstElement *pipeline, *source, *videoconvert, *videoscale, *capsfilter, *queue, *encoder, *muxer, *sink;
GstCaps *caps;
GstBus *bus;
GstMessage *message;
// Initialize GStreamer
gst_init(&argc, &argv);
然后为元素设置几个属性。
// Set properties
g_object_set(encoder, "bitrate", 5000, NULL);
g_object_set(muxer, "streamable", TRUE, NULL);
g_object_set(sink, "location", "rtmp://localhost/stream", NULL);
这里将编码比特率设置为 5000,使 muxer 可流式传输并将 RTMP url 设置为我们要流式传输到的位置。
接下来设置视频的上限,这里将其设置为 4K 分辨率,但如果这对你的情况来说太大了,可以随意调整数字。
caps = gst_caps_new_simple("video/x-raw",
"width", G_TYPE_INT, 3840,
"height", G_TYPE_INT, 2160,
NULL);
g_object_set(capsfilter, "caps", caps, NULL);
gst_caps_unref(caps);
接下来需要将元素添加并链接在一起,通过以下方式完成:
gst_bin_add_many(GST_BIN(pipeline), source, videoconvert, videoscale, capsfilter, queue, encoder, muxer, sink, NULL);
if (!gst_element_link_many(source, videoconvert, videoscale, capsfilter, queue, encoder, muxer, sink, NULL))
{
g_error("Failed to link elements");
return -1;
}
接下来将管道的状态设置为播放以实际启动流。
gst_element_set_state(pipeline, GST_STATE_PLAYING);
任何错误或 EOS 信号都可以通过以下方式获取:
bus = gst_element_get_bus(pipeline);
message = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, static_cast<GstMessageType>(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
接下来清理所有资源:
if (message != NULL)
{
gst_message_unref(message);
}
gst_object_unref(bus);
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
return 0;
完毕!最后需要创建一个脚本,这样我们才能实际构建示例。
创建 CMakeLists 文件
接下来我们将准备一个CMakeLists文件来构建上述源代码。创建一个 “CmakeLists.txt “文件,并在其中填入以下内容:
cmake_minimum_required(VERSION 3.10)
project(rtmpcam)
set(CMAKE_CXX_STANDARD 14)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GST REQUIRED gstreamer-1.0)
include_directories(${GST_INCLUDE_DIRS})
add_executable(rtmpcam main.cpp)
target_link_libraries(rtmpcam ${GST_LIBRARIES})
这会将我们的项目与 GStreamer 库文件链接起来。
构建项目,运行以下命令:
mkdir build
cd build
cmake ..
make
通过以上构建的源代码,你现在应该看到一个“rtmpcam”可执行文件。
现在,在我们使用这个可执行文件之前,我们需要一个RTMP服务器。我将使用MediaMTX(https://github.com/aler9/mediamtx),但你可以随意使用任何你希望的RTMP服务器。
如果你使用的是 mediamtx,则可以通过以下 docker 命令轻松运行它:
docker run --rm -it -e MTX_PROTOCOLS=tcp -p 8554:8554 -p 1935:1935 -p 8888:8888 -p 8889:8889 aler9/rtsp-simple-server
运行示例
现在可以试用可执行文件了 🙂
这可以通过以下方式完成:
./rtmpcam
现在,如果你打开 VLC 并尝试播放 URL (rtmp://localhost:1935/stream),应该能够看到您的网络摄像头画面。
作者:Ethan Denvir,全栈开发工程师
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/23415.html