
Install GStreamer 1.18 on Raspberry Pi 4.
Last updated: August 17, 2023
Introduction.
GStreamer is a pipeline-based multimedia framework that links various media processes to a complex workflow. For example, with a single line of code, it can retrieve images from a camera, convert them to Mpeg, and send them as UDP packets over Ethernet to another computer. Obviously, GStreamer is complex software used by more advanced programmers.
One of the main reasons for using GStreamer is the lack of latency. The OpenCV video capture module uses large video buffers, holding the frames. For example, if your camera has a frame rate of 30 FPS and your image processing algorithm can handle a maximum of 20 FPS, the synchronisation is lost very quickly due to the stacking in the video buffer. The absence of buffer flushing makes things even worse.
In this situation, GStreamer comes to the rescue. With the buffering of just one frame, you will always get an actual frame as output.
Recently the Raspberry Pi has released the Bullseye operating system. One of the changes compared to older Buster version is the absence of the Userland video engine. It leaves GStreamer as one of the default methods for capturing live video. At the same time, Bullseye uses now GStreamer 1.18.4. The Bullseye section below gives you the detailed information.

The guide covers the following topics.
- Version 1.18.4. We start with a survey of the current version 1.18.4 of Bullseye.
- Version 1.14.4. The default Buster GStreamer version 1.14.4and the installation of rpicamsrc on 32-bit systems.
- Version 1.18.4. The second part covers installing GStreamer 1.18.4 on your Raspberry Pi Buster.
- Streaming examples. In the last part, a lot of streaming examples, including streaming to YouTube are explored.
Bullseye Version 1.18.4.
When you scan your system for GStreamer, you will find several packages of version 1.18.4 already installed. They are essential for your Raspberry desktop.

There are a few additional plugins you must install before you can stream live video. For those familiar with the previous 1.14.4 version of Buster, it's almost the same list of libraries. Please, follow the commands below.
# install a missing dependency
$ sudo apt-get install libx264-dev libjpeg-dev
# install the remaining plugins
$ sudo apt-get install libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
libgstreamer-plugins-bad1.0-dev \
gstreamer1.0-plugins-ugly \
gstreamer1.0-tools \
gstreamer1.0-gl \
gstreamer1.0-gtk3
# if you have Qt5 install this plugin
$ sudo apt-get install gstreamer1.0-qt5
# install if you want to work with audio
$ sudo apt-get install gstreamer1.0-pulseaudio
Streaming.
With all GStreamer modules installed let's test the installation with $ gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink .

The major difference between Buster and Bullseye is the camera source. In Buster, you could call v4l2src device=/dev/video0 or rpicamsrc. In Bullseye, the only working camera source now is libcamerasrc. An example $ gst-launch-1.0 libcamerasrc ! video/x-raw, width=640, height=480, framerate=30/1 ! videoconvert ! videoscale ! clockoverlay time-format="%D %H:%M:%S" ! autovideosink

Keep this in mind when composing your pipelins; use libcamerasrc in Bullseye.
RTSP streaming.
If you want to set up an RTSP stream from your Raspberry Pi, you could run into trouble with Bullseyes. Most RTSP servers, like the GStreamer rtsp server, don't support the new libcamera. You have to install the MediaMTX server in that case. Install instructions are found in the streaming section.
LCCV.
If you only want a working camera in OpenCV, consider LCCV. A few lines of C++ code integrating low-level libcamera routines with OpenCV. It requires fewer resources and also consumes less CPU time. You can find LCCV on our GitHub.
Raspberry Pi OS (Legacy).
Bullseye has a lot of changes (and surprises) under the hood. Suddenly, many users are facing missing libraries causing their software to stop working.
For example, consider the missing v4l2-ctl camera interface. That's why the Raspberry Foundation has restored some of the 'old' features with a legacy version of the Raspberry Pi Buster OS. The release is frozen and not supported. You can install this plugin by using the raspi-config tool. Find more information here.
For the GStreamer, this legacy version means the replacement of libcamerasrc by the well-known v4l2src device=/dev/video0. The raspicamsrc is still deprecated in the old version. If you plan on using the older Raspberry Pi OS, all the examples in the last section will work with the v4l2src device=/dev/video0 source. Ignore the Bullseye hint.
Buster Version 1.14.4.
When you scan your system for GStreamer, you will find several packages already installed. They are essential for your Raspberry desktop.

There are a few additional plugins you can install. These are especially useful if you want to start streaming, one of GStreamer's popular applications.
Please follow the commands below.
# install a missing dependency
$ sudo apt-get install libx264-dev libjpeg-dev
# install the remaining plugins
$ sudo apt-get install libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
libgstreamer-plugins-bad1.0-dev \
gstreamer1.0-plugins-ugly \
gstreamer1.0-tools
# install some optional plugins
$ sudo apt-get install gstreamer1.0-gl gstreamer1.0-gtk3
# if you have Qt5 install this plugin
$ sudo apt-get install gstreamer1.0-qt5
# install if you want to work with audio
$ sudo apt-get install gstreamer1.0-pulseaudio
Streaming.
With all GStreamer modules installed let's test the installation with $ gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink .

The Raspicam can be invoked with this rather large pipeline $ gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw, width=1280, height=720, framerate=30/1 ! videoconvert ! videoscale ! clockoverlay time-format="%D %H:%M:%S" ! video/x-raw, width=640, height=360 ! autovideosink Remember to enable the Raspicam on forehand in your Raspberry Pi configuration menu.

All pipeline commands are constructed in the same way. First, the source is named, followed by several operations, after which the sink is determined. All parts of the pipeline are separated from each other by exclamation marks. For instance, in the example above, you could remove the part, which prints the date and time on the screen.
Common sense is required when composing the pipeline. The limited computing power of the Raspberry Pi does not allow for overly complex pipelines.
UDP streaming.
There are many types of streaming possible with GStreamer. UDP and TCP are most used to connect two devices. The name of the streaming refers to the Ethernet protocol used.
Let's start with UDP. We use two Raspberry Pis, both connected to the same home network. However, it could just as easily be an RPi and a laptop on the other side of the world. You need to know the address of the receiving Raspberry Pi on forehand. Follow the commands below.
Raspberry Pi 32 or 64-bit OS
# get the IP address of the recieving RPi first
$ hostname -I
# start the sender, the one with the Raspicam
$ gst-launch-1.0 -v v4l2src device=/dev/video0 num-buffers=-1 ! video/x-raw, width=640, height=480, framerate=30/1 ! videoconvert ! jpegenc ! rtpjpegpay ! udpsink host=192.168.178.84 port=5200
# start the reciever, the one with IP 192.168.178.84
$ gst-launch-1.0 -v udpsrc port=5200 ! application/x-rtp, media=video, clock-rate=90000, payload=96 ! rtpjpegdepay ! jpegdec ! videoconvert ! autovideosink
Now you can see claerly the structure of a pipline. The sender has the Raspicam located at /dev/video0 as source and sinks to the IP address of the other Raspberry Pi. The recieving RPi has UDP port 5200 as source and sinks to the screen (autovideosink).


TCP streaming.
The other method of streaming is with TCP. The difference with UDP is the latency. UDP is faster.
The commands as listed below. Note the different IP addresses. With TCP streaming, you use the server address, the sender, instead of the receiver, as we saw with the UDP streaming.
Raspberry Pi 32 or 64-bit OS
# get the IP address of the sending RPi first
$ hostname -I
# start the sender, the one with the Raspicam and IP 192.168.178.32
$ gst-launch-1.0 -v v4l2src device=/dev/video0 num-buffers=-1 ! video/x-raw,width=640,height=480, framerate=30/1 ! videoconvert ! jpegenc ! tcpserversink host=192.168.178.32 port=5000
# start the reciever and connect to the server with IP 192.168.178.32
$ gst-launch-1.0 tcpclientsrc host=192.168.178.32 port=5000 ! jpegdec ! videoconvert ! autovideosink
Both streams, UDP and TCP, start with single frames (video/x-raw). A timestamp is inserted if necessary. Then the image is compressed with jpeg to reduce its size, decreasing the required bandwidth. Once received, the jpeg image will be decompressed and displayed on the screen. You can always change the resolution. Frame sizes of 1280x960 at 30 FPS were no problem here at the office.
RTSP streaming.
If you want to stream RTSP (Real-Time Streaming Protocol), you need a server.
GStreamer has its own server available for RTSP. It works only with the old Buster OS. It doesn't support the new libcamera found on the Bullseye OS.
If you have Bullseye, you have to install a more versatile RTSP server, like MediaMTX. For the installation, see the streaming section.
# install the rtsp server version 1.14.4
$ wget https://gstreamer.freedesktop.org/src/gst-rtsp-server/gst-rtsp-server-1.14.4.tar.xz
$ tar -xf gst-rtsp-server-1.14.4.tar.xz
$ cd gst-rtsp-server-1.14.4
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig
rpicamsrc.
Thanks to the impressive work of Jan Schmidt (thaytan), GStreamer now fully support the Raspicam. With the rpicamsrc source installed, you can now pass almost the same parameters to your pipeline as you would to the well-known raspivid application. For example, flip horizontally hflip=true, flip vertically vflip=true, preview=true, or in case of halogen lighting awb-mode=tungsten.
Nearly all of these commands are executed in the image sensor chip, unloading the CPU/GPU on your Raspberry Pi. More information about the rpicamsrc and its commands can be found on the GStreamer site.
The rpicamsrc source is incorporated in the 1.18.4 version. In the case of default Raspberry Pi version 1.14.4, you have to install the plugin yourself.
👉 Please note, rpicamsrc works only on a 32-bit operating system. Due to missing Userland components, it will not work on a 64-bit OS. Use the default v4l2src device=/dev/video0 source in this situation, as shown in the above examples.
Only Raspberry Pi 32-bit OS
# install rpicamsrc in 1.14.4
$ git clone https://github.com/thaytan/gst-rpicamsrc.git
$ cd gst-rpicamsrc
$ ./autogen.sh
$ make
$ sudo make install
$ sudo ldconfig

Check with $ gst-inspect-1.0 rpicamsrc.

The UDP or TCP streaming pipelines are shown below. We have added some raspivid commands to the pipeline in green. And for fun, we've put timestamps in the corners of the videos.
ONLY Raspberry Pi 32-bit OS with rpicamsrc
UDP
# get the IP address of the recieving RPi first
$ hostname -I
# start the sender, the one with the Raspicam
$ gst-launch-1.0 -v rpicamsrc num-buffers=-1 ! video/x-raw, width=640, height=480, framerate=30/1 ! clockoverlay time-format="%D %H:%M:%S" ! videoconvert ! jpegenc ! rtpjpegpay ! udpsink host=192.168.178.84 port=5200
# start the reciever, the one with IP 192.168.178.84
$ gst-launch-1.0 -v udpsrc port=5200 ! application/x-rtp, media=video, clock-rate=90000, payload=96 ! rtpjpegdepay ! jpegdec ! videoconvert ! autovideosink
TCP
# get the IP address of the sending RPi first
$ hostname -I
# start the sender, the one with the Raspicam and IP 192.168.178.32
$ gst-launch-1.0 -v rpicamsrc vflip=true awb-mode=tungsten preview=false num-buffers=-1 ! video/x-raw,width=640,height=480, framerate=30/1 ! timeoverlay time-mode="buffer-time" ! videoconvert ! jpegenc ! tcpserversink host=192.168.178.32 port=5000
# start the reciever and connect to the server with IP 192.168.178.32
$ gst-launch-1.0 tcpclientsrc host=192.168.178.32 port=5000 ! jpegdec ! videoconvert ! autovideosink
Buster Version 1.18.4.
Version 1.18.4.
This section walks you through the installation of GStreamer 1.18 on a Raspberry Pi 4 with a Buster operating system. With version 1.18, GStreamer fully supports the Raspicam on 32-bits operating systems. Unfortunately not on the 64-bits systems, due to the missing Userland video engine.
Because GStreamer is deeply embedded in the Raspberry Desktop, it is not easy to customize or upgrade. Parts of the old version must remain active, which sometimes causes unexpected reactions. Removing the old version entirety will destroy your desktop. It will fall back to the default Debian LXDE desktop.

Completely removing the old version will also remove the necessary dependencies. The newly installed version will therefore lack many features.
👉 By the way, keep in mind that you will have to reinstall OpenCV once GStreamer 1.18 is installed.
Version 1.19.2.
On September 23, 2021, Version 1.19.2 is released. There is not much new to report regarding the Raspberry Pi. Version 1.19.2 is more or less an 'intermediate version' pointed out by the GStreamer community here. The most important fact is the Rust implementation in this version, a language only a few uses on an RPi.You can install GStreamer version 1.19.2 on your Raspberry Pi without any problems. Just change the numbering in the commands from 1.18.4 to 1.19.2, and you're ready. Because some plugins have moved among themselves, you cannot combine versions 18 and 19. Put either the complete version 18 or the complete version 19 on your Raspberry Pi, no mix.
Preparation.
You have to install at least three GStreamer packages, the core gstreamer, the plugins-base and the plugins-good. As mentioned, OpenCV has to be rebuilt also, after installing GStreamer. But first remove, if available, earlier user-installed GStreamer versions.
# remove the old version
$ sudo rm -rf /usr/bin/gst-*
$ sudo rm -rf /usr/include/gstreamer-1.0
# install a few dependencies
$ sudo apt-get install cmake meson flex bison
$ sudo apt-get install libglib2.0-dev libjpeg-dev libx264-dev$ sudo apt-get install libgtk2.0-dev libcanberra-gtk* libgtk-3-dev# needed for alsasrc, alsasink$ sudo apt-get install libasound2-dev
Installation.
Next, install the core GStreamer libraries. Again, you just need to install the GStreamer in Buster. Bullseye already pre-installed 1.18.4.
Core (only Buster)
# download and unpack the lib
$ wget https://gstreamer.freedesktop.org/src/gstreamer/gstreamer-1.18.4.tar.xz
$ sudo tar -xf gstreamer-1.18.4.tar.xz
$ cd gstreamer-1.18.4
# make an installation folder
$ mkdir build && cd build
# run meson (a kind of cmake)
$ meson --prefix=/usr \
--wrap-mode=nofallback \
-D buildtype=release \
-D gst_debug=true \
-D package-origin=https://gstreamer.freedesktop.org/src/gstreamer/ \
-D package-name="GStreamer 1.18.4 BLFS" ..
If everything went well, you end up with the screen below.

Now build and test GStreamer with the next commands.
# build the software
$ ninja -j4
# test the software (optional)
$ ninja test
# install the libraries
$ sudo ninja install
$ sudo ldconfig

Testing.
It is common for some tests to fail. As long as the ninja build doesn't throw an error, don't worry.
Tests fail mainly for two reasons.
First, the required hardware (GPU) is not available on the Raspberry Pi. While you may think it shouldn't be compiled, sometimes Gstreamer needs parts of these libraries later in the build.
Second, most commonly, it takes too much time on a (simple) Raspberry Pi to run the test. Think of parsing a MPEG stream into the original frames. Now an RPi had a lot of work ahead of it. The test may take a certain amount of time, after which it will fail.
When you later install the Bad or Ugly package, even more tests will fail.
OS check.
Please check your operating system to be sure, before the next step. Run the command getconf LONG_BIT and verify your version.

Plugins-base.
Once the core libraries are installed, the next step is to install the two additional plugins. Both follow the same procedure as above, so we'll give the installation without much explanation.
However, keep one thing in mind. GStreamer scans your system for available libraries before it starts building the plugins. Even if a particular library is missing, the plugin will still be created. Only the operation that requires the missing library is not functional.
This is a bit confusing. You have your plugin up and running, but it still gives errors on some operation. You are probably missing a library on which the operation depends. In that case, you need to rebuild the plugin after installing the missing library.