Introduction
Hello! ๐
In this tutorial I will show you how you can stream your webcam to an RTMP server using C++ and GStreamer.
Requirements
- Basic knowledge of C++
- Basic knowledge of GStreamer
- A webcam
Creating The Source
First we need to actually write the code that will enable us to stream the webcam to a RTMP server. ๐
Open a file called "main.cpp" and add the following header:
#include<gst/gst.h>
Next write/copy the following main function:
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;
}
Now I will explain what each section is doing. ๐
First we create the variables and initialize GStreamer with the following:
GstElement *pipeline, *source, *videoconvert, *videoscale, *capsfilter, *queue, *encoder, *muxer, *sink;
GstCaps *caps;
GstBus *bus;
GstMessage *message;
// Initialize GStreamer
gst_init(&argc, &argv);
Then we set a couple of properties for the elements.
// 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);
Here we set the encoding bitrate to 5000, make the muxer streamable and set the RTMP url to the location we want to stream to.
Next we set the caps for the video, here we are setting it to 4K resolution but if this is too much for your case feel free to adjust the numbers. ๐
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);
Next we need to add and link the elements together, which is done via the following:
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;
}
Next we set the state of the pipeline to playing to actually start the stream.
gst_element_set_state(pipeline, GST_STATE_PLAYING);
Any errors or EOS signals are picked up with the following:
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));
Finally we need to clean up any resources.
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;
Done! ๐ Finally we need to create a script so we can actually build the example.
Create The CMakeLists File
Next we will prepare a CMakeLists file to build the above source code.
Create a "CmakeLists.txt" file and populate it with the following:
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})
This links our project with the GStreamer library files.
To build the project run the following commands:
mkdir build
cd build
cmake ..
make
The above should build the source code and you should now see a "rtmpcam" executable.
Now before we can use the executable we need an RTMP server.
I will be using MediaMTX (https://github.com/aler9/mediamtx) but feel free to use whatever RTMP server you wish.
If you are using mediamtx you can run it easily via the following docker command:
docker run --rm -it -e MTX_PROTOCOLS=tcp -p 8554:8554 -p 1935:1935 -p 8888:8888 -p 8889:8889 aler9/rtsp-simple-server
Running The Example
Now we can finally try out the executable ๐
This can be done via:
./rtmpcam
Now if you open up VLC and try and play the URL (rtmp://localhost:1935/stream), you should be able to see your webcam footage. ๐
I'm actually thinking of experimenting with MediaMTX.
Conclusion
In this tutorial I have shown how you can use C++ and GStreamer to stream your webcam to a RTMP server.
I hope this helped you as much as I had fun writing it.
The repo can be found at:
https://github.com/ethand91/gstreamer-rtmp-sample
Happy Coding! ๐
Like me work? I post about a variety of topics, if you would like to see more please like and follow me.
Also I love coffee.
If you are looking to learn Algorithm Patterns to ace the coding interview I recommend the following course
Top comments (1)
The parameter list for the call to gst_bin_add_many has several uninitialized pointers. Is this not a problem?