-
-
Notifications
You must be signed in to change notification settings - Fork 33
Home
This wiki provides comprehensive information on configuring and using the pi_webrtc
for video streaming, along with detailed technical insights on encoders, signaling protocols, and recording options.
Available flags for pi_webrtc
:
Option | Default | Description |
---|---|---|
-h , --help
|
Display help information about the available options. | |
--fps |
30 |
Set the camera frame rate (frames per second). |
--width |
640 |
Set the camera frame width (in pixels). |
--height |
480 |
Set the camera frame height (in pixels). |
--rotation_angle |
0 |
Set the rotation angle of the frame (0, 90, 180, 270) via V4L2. |
--sample_rate |
44100 |
Set the audio sample rate (in Hz). |
--no_audio |
false |
Run without an audio source. |
--hw_accel |
false |
Enable hardware acceleration by sharing DMA buffers between the decoder, scaler, and encoder to reduce CPU usage. |
--use_libcamera |
false |
Read YUV420 from the camera via libcamera, the --device and --v4l2_format flags will be suspended. |
--v4l2_format |
mjpeg |
Set the V4L2 input format (i420 , mjpeg , h264 ) if supported by the camera. |
--device |
/dev/video0 |
Read the specific camera device file via V4L2. |
--uid |
Set the unique identifier string for the device. | |
--stun_url |
stun:stun.l.google.com:19302 |
Set the STUN server URL for WebRTC. Example: stun:xxx.xxx.xxx . |
--turn_url |
Set the TURN server URL for WebRTC. Example: turn:xxx.xxx.xxx:3478?transport=tcp . |
|
--turn_username |
Set the TURN server username for WebRTC authentication. | |
--turn_password |
Set the TURN server password for WebRTC authentication. | |
--record_path |
Set the path where recording video files will be saved. If the value is empty or unavailable, the recorder will not start. | |
--mqtt_port |
1883 |
Set the MQTT server port. |
--mqtt_host |
localhost |
Set the MQTT server host. |
--mqtt_username |
Set the MQTT server username. | |
--mqtt_password |
Set the MQTT server password. | |
--http_port |
8080 |
Set the HTTP signaling port. |
Note
The fps
, width
, and height
settings might be reduced in the live stream due to network or device performance issues if detected by WebRTC. However, the recording will always maintain the same width
and height
.
There are two ways to read images from the camera. The V4L2
only supports the v1 and v2 cameras and the HQ camera. After Camera Module 3, future updates will be based on Libcamera
.
This is for older Pi OS (before Bookworm), please modify the camera_auto_detect=1
flag in file /boot/firmware/config.txt
to
# camera_auto_detect=1
camera_auto_detect=0
start_x=1
gpu_mem=256
Set camera_auto_detect=0
in order to read camera by V4L2. The size of gpu_mem
depends on desired resolution, 256
MB for 1080p.
This is the Raspberry Pi officially recommended way to read the camera.
Use the default setting camera_auto_detect=1
in /boot/firmware/config.txt
.
In this project, Libcamera only provides the yuv420
format, and the --device
and --v4l2_format
flags will be disabled if --use_libcamera
flag is used.
Since yuv420
is an uncompressed format, you should check the bandwidth of the CSI/USB interface to ensure the camera can handle high resolution and frame rate images.
Each MIPI lane provides 1.5 Gbps bandwidth on the Pi 5, but each MIPI lane provides 1 Gbps on earlier models. [ref]
Interface | 1-lane MIPI (older Pi) | 2-lane MIPI (Pi 4) | 4-lane MIPI (Pi 5) | USB 2.0 | USB 3.0 |
---|---|---|---|---|---|
Bandwith | 1 Gbps | 2 Gbps | 6 Gbps | 0.48 Gbps | 5 Gbps |
For example:
YUV 4:2:0 need 12 bits/pixel. 4Kp60 = 3840 x 2160 x 60 x 12 = 5.56 Gbps.
Resolution | 4Kp60 | 4Kp30 | 1080p60 | 1080p30 |
---|---|---|---|---|
Bandwith | 5.56 Gbps | 2.78 Gbps | 1.39 Gbps | 0.70 Gbps |
The encoder used in WebRTC depends on whether the --hw_accel flag is set and the SDP context offered by the client. I recommend running v4l2-ctl -d /dev/video0 --list-formats-ext
to check which formats your camera supports before specifying the V4L2 source format, allowing you to choose the most suitable encoding mode.
Tip
pi_webrtc
delivers the best recording performance if your camera provides h264 streams.
Run with --hw_accel
.
pi_webrtc
will list only H264
in the SDP
context.
Hardware H264 encoding is only available on the Raspberry Pi 3, 4, and Zero 2. The Raspberry Pi 5 no longer supports the hardware encoder. For other single-board computers, such as Radxa, Odroid, etc., H264 hardware encoding may be supported according to their specifications. However, if their codecs do not implement the V4L2 driver, it is recommended to use Software
encoding instead. The Raspberry Pi codec device files are located at [ref]:
Codec | Location |
---|---|
decoder | /dev/video10 |
encoder | /dev/video11 |
scaler | /dev/video12 |
-
For
h264
camera source/path/to/pi_webrtc --device=/dev/video0 --v4l2_format=h264 --fps=30 --width=1280 --height=960 --hw_accel ...
graph LR A(Camera) -- h264 --> B(hw decoder) -- yuv420 --> C(hw scaler) --yuv420--> D(hw encoder) --h264-->E(webrtc client) A --h264--> F(mp4)
This command grabs the
h264
stream directly from the camera and uses the hardware decoder to convert it toyuv420
. If WebRTC detects network or device performance issues, the hardware scaler will automatically adjust by scaling down the decodedyuv420
frame resolution, and vice versa when conditions improve. When the resolution changes, the hardware encoder will be reset to match the new resolution. All frame data is transferred via DMA (zero-copy) between hardware codecs. Furthermore, if the--record_path
flag is set (enabling recording), theh264
packets from the camera are directly copied into MP4 files. -
For
mjpeg
camera source/path/to/pi_webrtc --device=/dev/video0 --v4l2_format=mjpeg --fps=30 --width=1280 --height=960 --hw_accel ...
graph LR A(camera) -- mjpeg --> B(hw decoder) -- yuv420 --> C(hw scaler) --yuv420--> D(hw encoder) --h264-->E(webrtc client) B --yuv420--> F(openh264) -- h264--> G(mp4)
All processes are similar to the
h264
source camera in hardware mode. The main difference isOpenH264
software encoder will be used in video recording. -
For
i420
camera source# use v4l2 camera /path/to/pi_webrtc --device=/dev/video0 --v4l2_format=i420 --fps=30 --width=1280 --height=960 --hw_accel ... # use libcamera /path/to/pi_webrtc --use_libcamera --fps=30 --width=1280 --height=960 --hw_accel ...
graph LR A(camera) -- yuv420 --> C(hw scaler) --yuv420--> D(hw encoder) --h264-->E(webrtc client) A --yuv420--> F(openh264) -- h264--> G(mp4)
This command captures uncompressed
yuv420
from the camera. Since it is uncompressed, the CSI/USB bandwidth may not support high resolution and fps.i420
is useful when running on a Pi Zero or if CPU usage is excessively high due to many background services. TheOpenH264
software encoder will be used for video recording, but this method is typically chosen because of limited system resources, and the recorder is usually not enabled.
Run without --hw_accel
.
pi_webrtc
will list all H264
, VP8
, VP9
and AV1
codecs in the SDP
context. The encoder used depends on the SDP
provided by the client. For example, if the client's SDP
only includes H264, WebRTC will use the H264
encoder for live streaming. Make sure the client's SDP
contains the only codec you want to use."
- For
h264
camera sourceIt's not available in/path/to/pi_webrtc --device=/dev/video0 --v4l2_format=h264 --fps=30 --width=1280 --height=960 ...
pi_webrtc
. I didn't implement H264 software decoding. - For
mjpeg
camera source/path/to/pi_webrtc --device=/dev/video0 --v4l2_format=mjpeg --fps=30 --width=1280 --height=960 ...
graph LR A(camera) -- mjpeg --> B(libyuv) -- yuv420 --> C(libyuv scaler) --yuv420--> D(openh264) --h264-->E(webrtc client) B --yuv420--> F(openh264) -- h264--> G(mp4)
mjpeg
frames will be decoded intoyuv420
bylibyuv
. If WebRTC requires a lower resolution for live streaming, the scaling will also be handled bylibyuv
. The recording will use separate instances of theOpenH264
encoder. - For
i420
camera source# use v4l2 camera /path/to/pi_webrtc --device=/dev/video0 --v4l2_format=i420 --fps=30 --width=1280 --height=960 ... # use libcamera /path/to/pi_webrtc --use_libcamera --fps=30 --width=1280 --height=960 ...
graph LR A(camera) -- yuv420 --> C(libyuv scaler) --yuv420--> D(openh264) --h264-->E(webrtc client) A --yuv420--> F(openh264) -- h264--> G(mp4)
pi_webrtc
registers itself with the MQTT server
at the beginning and waits for the app client
to send a request to initiate the connection. The diagram below shows how the connection process operates between the app client
, MQTT server
, and pi_webrtc
. Assume that the --uid
is set to home-pi-5
, and ${mqttId}
is another random UID used to identify each MQTT connection.
sequenceDiagram
Note over pi_webrtc, mqtt server: sub: home-pi-5/sdp/+/offer<br>sub: home-pi-5/ice/+/offer
client--> pi_webrtc: start connecting
Note over client, mqtt server: sub: home-pi-5/sdp/${mqttId}<br>sub: home-pi-5/ice/${mqttId}
client ->> mqtt server: client's SDP
Note over client, mqtt server: pub: home-pi-5/sdp/${mqttId}/offer
mqtt server ->> pi_webrtc: client's SDP
pi_webrtc ->> mqtt server : pi's SDP
Note over pi_webrtc, mqtt server: pub: home-pi-5/sdp/${mqttId}
mqtt server ->> client: pi's SDP
client ->> mqtt server: client's ICE
Note over client, mqtt server: pub: home-pi-5/ice/${mqttId}/offer
mqtt server ->> pi_webrtc: client's ICE
pi_webrtc ->> mqtt server : pi's ICE
Note over pi_webrtc, mqtt server: pub: home-pi-5/ice/${mqttId}
mqtt server ->> client: pi's ICE
client ->pi_webrtc: connected
You can play the video directly using a URL like https://pi.example.net
without server registration.
This allows you to stream video like a traditional RTSP/RTMP stream using a simple URL, if your player supports WHEP.
sequenceDiagram
participant Server as pi_webrtc
participant Client as WHEP Player
Client->>Server: client's SDP/ICE
Note over Client, Server: POST to `https://pi.example.net`
Server->>Client: pi's SDP/ICE
Note over Client, Server: 201 Created
Client->Server: connected
The video files will be recorded every minute, and each video file will generate a snapshot image for preview. If the disk space falls below 400MB
, it will start rotation.
Format | |
---|---|
Video | H264 |
Audio | AAC |
Other useful tools, commands, or information are not included in this project but are potentially useful.
Command | Description |
---|---|
v4l2-ctl --list-devices |
Show available devices in V4L2. |
v4l2-ctl -d /dev/video0 --list-formats-ext |
Show supported formats from devices. Not only the camera but also the codecs. |
sudo fdisk -l |
List partition tables to help set up USB disks. |
vcgencmd get_camera |
Check whether the camera is detected or not. |