Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 136 additions & 26 deletions documentation/asciidoc/computers/camera/streaming.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -142,65 +142,175 @@ On a Pi 5 you would have to replace `v4l2h264enc extra-controls="controls,repeat

On the client we could use the same playback pipeline as we did just above, or other streaming media players.

=== WebRTC
=== Third-Party Streaming Servers

Streaming over WebRTC (for example, to web browsers) is best accomplished using third party software. https://github.com/bluenviron/mediamtx[MediaMTX], for example, includes native Raspberry Pi camera support which makes it easy to use.
There are a number of very capable third-party streaming servers available and, while Raspberry Pi does not specifically recommend any particular one, we give some introductory guidance on using a number of popular ones.

To install it, download the latest version from the https://github.com/bluenviron/mediamtx/releases[releases] page. Raspberry Pi OS 64-bit users will want the "linux_arm64v8" compressed tar file (ending `.tar.gz`). Unpack it and you will get a `mediamtx` executable and a configuration file called `mediamtx.yml`.
* https://github.com/bluenviron/mediamtx[MediaMTX]

It's worth backing up the `mediamtx.yml` file because it documents many Raspberry Pi camera options that you may want to investigate later.
* https://mistserver.org/[MistServer]

* https://github.com/AlexxIT/go2rtc[Go2rtc]

All of the above are capable of ingesting Raspberry Pi camera streams created by `rpicam-vid`, and re-streaming to RTSP clients, or to web browsers using WebRTC, or using many other formats. MediaMTX can sometimes be a good choice because it supports Raspberry Pi cameras as a native option through libcamera, by-passing the need for external executables (like `rpicam-vid`).

The list above is not exhaustive, however, we have confirmed that these applications work correctly together with the Raspberry Pi camera system.

=== Streaming with MediaMTX

As stated above, MediaMTX will accept an input stream from the Pi's camera system (for example, created by`rpicam-vid`), and re-stream it to other clients. Additionally, however, it supports Raspberry Pi cameras as a built-in native "source".

==== Installation and Configuration

To install it, download the latest version from the https://github.com/bluenviron/mediamtx/releases[releases] page. Raspberry Pi OS 64-bit users will want the "linux_arm64" compressed tar file (ending `.tar.gz`). There is also an "armv7" version for 32-bit OS users. Unpack it (using `tar -xvzf <filename.tar.gz>`) and you will get a `mediamtx` executable and a configuration file called `mediamtx.yml`. Ensure the executable file has the correct permissions (use `chmod a+x mediamtx` to make it executable).

There is no need for any specific configuration at this point, but it's worth backing up the `mediamtx.yml` file because it documents many Raspberry Pi camera options that you may want to investigate later.

==== Adding a Camera Stream

To stream the camera, replace the contents of `mediamtx.yml` by:
----
paths:
cam:
source: rpiCamera
----
and start the `mediamtx` executable. On a browser, enter `http://<ip-addr>:8889/cam` into the address bar.
and start the `mediamtx` executable (type its name at a command promt, qualifying the full path if necessary). The use of `rpiCamera` here is how we tell MediaMTX to start and control the camera system for itself.

If you want MediaMTX to acquire the camera only when the stream is requested, add the following line to the previous `mediamtx.yml`:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidplowman Does the user need to start/restart the mediamtx executable after any change to the configuration file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, actually I think you probably don't, it notices the update and re-reads it. Having said that, do you trust it to update its configuration while running? I suspect most folks would just restart it anyway. So I'm not super-100% sure really...!

----
sourceOnDemand: yes
----
Consult the original `mediamtx.yml` for additional configuration parameters that let you select the image size, the camera mode, the bitrate and so on - just search for `rpi`.
To be sure changes have taken effect, it may be necessary to stop (if it's running in a terminal just use Ctrl-C) and restart `mediamtx`. Consult the original `mediamtx.yml` for additional configuration parameters that let you select the image size, the camera mode, the bitrate and so on - just search for `rpi`.

==== Customised image streams with WebRTC
As an alternative, we could run `rpicam-vid` externally to MediaMTX, setting up `mediamtx.yml` as follows:
----
paths:
cam:
source: udp://127.0.0.1:1234
----
We could actually run any external program to output an MPEG-TS stream to this address. In the case of `rpicam-vid` it might look like:
[source,console]
----
$ rpicam-vid -t 0 -n --codec libav --low-latency --libav-format mpegts -o udp://127.0.0.1:1234?pkt_size=1316
----
Note how this gives us the opportunity to alter the images in some way, perhaps using the rpicam-apps post-processing features, or the Picamera2 Python module. We've also used the `--low-latency` option which suppresses B-frames (on a Pi 5 or later; earlier Pis won't generate any), which is often advisable because some streaming formats that clients request do not support them.

MediaMTX is great if you want to stream just the camera images. But what if we want to add some extra information or overlay, or do some extra processing on the images?
==== Viewing with a Client

Before starting, ensure that you've built a version of `rpicam-apps` that includes OpenCV support. Check it by running
To view the stream using a Media Player application with the RTSP protol, and assuming a stream name of "cam", use the address

[source,console]
----
$ rpicam-hello --post-process-file rpicam-apps/assets/annotate_cv.json
rtsp://<ip-address-of-MediaMTX-machine>:8554/cam
----
and looking for the overlaid text information at the top of the image.

Next, paste the following into your `mediamtx.yml` file:
To view the stream in a web browser, use the address `http://<ip-addr-of-MediaMTX-machine>:8889/cam` (assuming a stream name of "cam").

[NOTE]
====
If you notice occasional pauses in the video stream, this may be because the UDP receive buffers on the Pi (passing data from `rpicam-vid` to MediaMTX) are too small. To increase them permanently, create a file called `/etc/sysctl.d/99-network-tuning.conf` containing
----
paths:
net.core.rmem_default=1000000
net.core.rmem_max=1000000
----
and reboot (or run `sudo sysctl -p /etc/sysctl.d/99-network-tuning.conf`).

On earlier OSes, you would have to add these lines to `/etc/sysctl.conf` instead (and reboot or run`sudo sysctl -p`).
====

The capabilities of MediaMTX far exceed the short guide here, and users are referred to the https://mediamtx.org/docs/kickoff/introduction[documentation] for more details. You will also find instructions there for setting up MediaMTX as a system service that starts at boot.

=== Streaming with MistServer

Besides MediaMTX, MistServer is another popular free media server that we can use in conjunction with the Raspberry Pi camera system. Unlike MediaMTX, there is no built-in camera support, however, it's easy enough to get MistServer to ingest a stream from `rpicam-vid` and serve it to clients in a variety of formats.

==== Installation and Configuration

You can install MistServer very simply on a Pi by following https://docs.mistserver.org/mistserver/installation/linux#armv8-64-bits-linux[these instructions] for 64-bit OSes. 32-bit OS users should use https://docs.mistserver.org/mistserver/installation/linux/#armv7-linux[this link]. You will need to run this as root, and it will even set up a system MistServer service that runs automatically.

To configure MistServer, go to the Managment Interface (MI) webpage on your Pi at `http://localhost:4242/` (or you can visit the page from another computer if you substitute your Pi's IP address). The first time you use it, it will ask you to create an admin account. After that, just accept any defaults and you're done.

Note that, as with MediaMTX, MistServer could in principle run on a different machine from the Pi with the camera.

==== Adding a Camera Stream

Return to the MI webpage and click on `Streams` in the left-hand pane. Now click `Create Stream` in the right-hand pane. You'll need to fill in a couple of details here, including:

* A stream name, such as `cam`. This is what clients will use to identify this stream.

* A source. We're going to get MistServer to start `rpicam-vid` automatically for us, so enter the following: `ts-exec: rpicam-vid -n -t 0 --width 1920 --height 1080 --codec libav --libav-format mpegts -o -`

Here, `ts-exec` means "run this command and it will output an MPEG-TS stream to `stdout`". After that, it's just a regular `rpicam-vid` command with no preview (`-n`), to run indefinitely (`-t 0`), your chosen dimensions (`--width` and `--height`) and to write all this as an MPEG-TS stream to `stdout`.

There are certainly other choices here. For example, we could run `rpicam-vid` externally ourselves, outputting maybe to a UDP socket. In this case, we'd use `tsudp` in place of `ts-exec`, and follow it with the incoming stream's IP address. Clearly the initial formulation (using `ts-exec`) _does_ require MistServer to be running on the Pi, though the second does not.

==== Viewing with a Client

To view the stream using a Media Player application using the RTSP protol, and assuming a stream name of "cam", use the address

[source,console]
----
rtsp://<ip-address-of-MistServer-machine>:8554/cam
----

To view the stream in a web page, it's easiest to use MistServer's built-in Media Player pages, so in this case we'd enter

[source,console]
----
http://<ip-address-of-MistServer-machine>:8080/cam.html
----

MistServer supports a wide range of use cases and options, so users should consult the https://docs.mistserver.org/[documentation] for more information.

=== Streaming with Go2rtc

Finally, go2rtc is another very capable media server platform that, while not offering direct integration like MediaMTX, again allows for easy inter-operation in the same way as MistServer.

==== Installation and Configuration

You can install go2rtc simply by going to the https://github.com/AlexxIT/go2rtc/releases/[releases page]. 64-bit OS users should download the `go2rtc_linux_arm64` binary, and a 32-bit version is also available. You can run this directly (after changing the permissions to make the file executable - use `chmod a+x <filename>`).

No particular configuration is needed, but once it is running you can find a management page at `http://localhost:1984/`.

Note that, as with MediaMTX, go2rtc could in principle run on a different machine from the Pi with the camera.

==== Adding a Camera Stream

You can add a camera stream by creating a file `go2rtc.yaml` in the folder from where you ran the executable (when go2rtc starts, it will output a message to the console indicating where it is looking for its "config" file). The file should contain (substituting your own desired width and height) :

[source,console]
----
streams:
cam:
source: udp://127.0.0.1:1234
- exec:rpicam-vid -n -t 0 --width 1280 --height 720 --codec libav --libav-format mpegts --low-latency -o -
----

Now, start `mediamtx` and then, if you're using a Pi 5, in a new terminal window, enter:
This will start `rpicam-vid` as shown when any client requests the "cam" stream. Note again the use of `--low-latency` which has the effect of suppressing B-frames on Pi 5 or later models. In this case, go2rtc clearly _does_ need to be running on the Raspberry Pi with the camera.

Alternatively, we could run `rpicam-vid` externally, arranging for it to output an MPEG-TS stream to the address (for example) `udp://127.0.0.1:1234`, in which case the `gortc.yaml` file should contain:

[source,console]
----
$ rpicam-vid -t 0 -n --codec libav --libav-video-codec-opts "profile=baseline" --libav-format mpegts -o udp://127.0.0.1:1234?pkt_size=1316 --post-process-file rpicam-apps/assets/annotate_cv.json
cam:
- ffmpeg:udp://127.0.0.1:1234
----
(On a Pi 4 or earlier device, leave out the `--libav-video-codec-opts "profile=baseline"` part of the command.)

On another computer, you can now visit the same address as before, namely `http://<ip-addr-of-pi>:8889/cam`.
Here, IP addresses will need adjusting if go2rtc is running on a different machine from the camera.

The reason for specifying "baseline" profile on a Pi 5 is that MediaMTX doesn't support B frames, so we need to stop the encoder from producing them. On earlier devices, with hardware encoders, B frames are never generated so there is no issue. On a Pi 5 you could alternatively remove this option and replace it with `--low-latency` which will also prevent B frames, and produce a (slightly less well compressed) stream with reduced latency.
==== Viewing with a Client

[NOTE]
====
If you notice occasional pauses in the video stream, this may be because the UDP receive buffers on the Pi (passing data from `rpicam-vid` to MediaMTX) are too small. To increase them permantently, add
To view the stream using a Media Player application using the RTSP protol, and assuming a stream name of "cam", use the address

[source,console]
----
net.core.rmem_default=1000000
net.core.rmem_max=1000000
rtsp://<ip-address-of-go2rtc-machine>:8554/cam
----
to your `/etc/sysctl.conf` file (and reboot or run `sudo sysctl -p`).
====

To view the stream in a web page, it's easiest to use go2rtc's built-in pages, so in this case we'd enter

[source,console]
----
http://<ip-address-of-go2rtc-machine>:1984/stream.html?src=cam
----

go2rtc supports a wide range of use cases and options, so users should consult the https://github.com/AlexxIT/go2rtc/blob/master/README.md[documentation] for more information.