Streaming a Webcam with GStreamer and NanoPing
In this guide, we will use GStreamer to stream a webcam (/dev/video0) source from a sender device to a receiver device using NanoPing.
This guide assumes Ubuntu 24.10 (similar Linux distributions should work).
Installing Required Tools
On both the sender and receiver sides, install the required GStreamer tools by running:
sudo apt-get install gstreamer1.0-tools
sudo apt-get install gstreamer1.0-plugins-good
sudo apt-get install gstreamer1.0-plugins-ugly
sudo apt-get install gstreamer1.0-libav
Streaming Over NanoPing
This guide covers two basic ways to stream data using NanoPing:
-
UDP Tunnel Mode The sender streams video to localhost UDP, which is picked up by a NanoPing Local UDP component. On the receiver side, NanoPing delivers the stream to localhost UDP, which is then consumed by GStreamer.
-
TUN Tunnel Mode Devices must be configured so the receiver's TUN IP is reachable from the sender. If NanoPing is set up as a VPN, the TUN IP of the receiver must be reachable from the sender device.
Launching the GStreamer Sender
Once GStreamer is successfully installed, run the following command on the sender device:
gst-launch-1.0 v4l2src device=/dev/video0 ! \
video/x-raw,width=640,height=480 ! \
videoconvert ! \
x264enc tune=zerolatency ! \
rtph264pay config-interval=1 pt=96 ! \
multiudpsink clients=10.0.0.1:5000
What This Command Does
- Captures video from /dev/video0
- Sets resolution to 640x480
- Converts the video format
- Encodes the video using H.264 with low-latency tuning
- Packages the stream in RTP
- Sends the stream to 10.0.0.1 on UDP port 5000
Adjustments for NanoPing Modes
- UDP Tunnel Mode: Change
10.0.0.1:5000to the IP and port where yourUDP Localcomponent is configured. - TUN Tunnel Mode: Change
10.0.0.1:5000to the IP and port of the remote device, typically the TUN IP of the receiver or another reachable IP.
Launching the GStreamer Receiver
On the receiver device, run:
gst-launch-1.0 udpsrc port=5000 caps="application/x-rtp, media=video, encoding-name=H264, payload=96" ! \
rtph264depay ! \
avdec_h264 ! \
videoconvert ! \
textoverlay text="UDP" valignment=top halignment=center font-desc="Sans, 36" ! \
autovideosink
What This Command Does
- Listens for incoming RTP-encoded video on UDP port 5000
- Uses the specified RTP caps to interpret the incoming stream as H.264 video
- Removes the RTP header (
rtph264depay) - Decodes the H.264 video (
avdec_h264) - Converts the video format for display
- Adds a text overlay labeled “UDP” at the top center
- Displays the video in a window using the default video sink
Adjustments for NanoPing Modes
- UDP Tunnel Mode: Use the port configured in the
UDP Remotecomponent. - TUN Tunnel Mode: Ensure the port matches the one used as the destination in the sender command.
Lifecycle Handler Configuration
The pipeline configuration files (JSON) often use a lifecycle_handler to automatically start GStreamer processes in the background when the node starts.
These commands are defined in the pre_start array. You must ensure the command paths and plugins match your local operating system.
1. Updating the Executable Path
The example configurations typically default to the macOS (Apple Silicon) Homebrew path: "/opt/homebrew/bin/gst-launch-1.0".
You must change this string in the JSON file to match your system:
| OS | Typical Path |
|---|---|
| macOS (Apple Silicon) | /opt/homebrew/bin/gst-launch-1.0 |
| macOS (Intel) | /usr/local/bin/gst-launch-1.0 |
| Linux (Ubuntu/Debian) | /usr/bin/gst-launch-1.0 |
2. Updating the Video Source
The input command in the example uses avfvideosrc, which is specific to macOS cameras. If you are running on Linux or Windows, you must change the source plugin in the first command of the list.
For macOS (Default)
avfvideosrc device-index=0 ! ...
For Linux (Ubuntu/Raspberry Pi)
Replace avfvideosrc with v4l2src:
v4l2src device=/dev/video0 ! ...
Example: Lifecycle Handler JSON
Below is the section of the JSON you need to edit. Note the cmd fields where the path and source are defined:
"lifecycle_handler": {
"pre_start": [
{
"comment": "Video Source (Camera) -> Sender",
"cmd": "/PATH/TO/gst-launch-1.0 avfvideosrc device-index=0 ! video/x-raw,width=640,height=480 ! videoconvert ! x264enc tune=zerolatency ! rtph264pay config-interval=1 pt=96 ! multiudpsink clients=127.0.0.1:5000,127.0.0.1:5001",
"policy": "RUN_IN_BACKGROUND"
},
]
}