Back to Blog
Tutorial
June 18, 202612 min read

Build Your Own 4G Drone Camera for Free with a Raspberry Pi

Turn a stock Raspberry Pi, a USB 4G modem, and any RTSP/IP camera into an internet-reachable drone camera for free. Flash Raspberry Pi OS, install Tailscale, and serve the stream with MediaMTX.

A
AirCast Team
Author
4G LTE
Raspberry Pi
MediaMTX
Tailscale
DIY

You don't need an expensive video transmitter or a paid cloud service to put a drone camera on the internet. With a stock Raspberry Pi, a USB 4G modem, and any RTSP/IP camera you already own, you can build a fully internet-reachable drone camera using only free software: Raspberry Pi OS, the MediaMTX media server, and the free tier of Tailscale. This guide walks through the exact steps, command by command.

What "Free" Actually Means Here

The hardware is yours to source — a Pi, a SIM with data, and a camera. The software stack is completely free:

  • Raspberry Pi OS — the official, free Debian-based OS for the Pi
  • MediaMTX — a free, open-source media server that pulls the camera's RTSP stream once and re-serves it to any number of viewers, over RTSP or straight in the browser via WebRTC
  • Tailscale — a WireGuard-based mesh VPN whose free plan covers personal devices, giving you a secure path to the Pi from anywhere without port forwarding, a static public IP, or a paid relay

The result: your camera, sitting on a private wired subnet behind the Pi, becomes watchable from your laptop across the public internet over 4G — encrypted end to end, no cloud video bill.

What You'll Need

  • Raspberry Pi 4 (2GB+ RAM) and a 16GB+ microSD card
  • USB 4G/LTE modem with a SIM card and a data plan
  • Any RTSP/IP camera — in this guide the camera lives at 192.168.8.4
  • A spare Ethernet port or USB-Ethernet adapter to wire the camera directly to the Pi
  • A computer with Tailscale installed to view the stream

Step 1: Flash Raspberry Pi OS

Download Raspberry Pi Imager and flash Raspberry Pi OS (64-bit) to your microSD card. Before writing, open the Imager's settings (the gear icon) and:

  • Enable SSH (password authentication is fine to start)
  • Leave the hostname at the default raspberrypi (so the Pi answers at raspberrypi.local) or set your own
  • Set the username to pi and a password

Insert the card, plug in the USB 4G modem, and power on the Pi. Recent Raspberry Pi OS releases (Bookworm) use NetworkManager, and most USB 4G modems come up automatically as a network interface — give it a minute to register on the cellular network.

Step 2: SSH Into the Pi

Connect over your local network using the hostname you set. The default user is pi:

Once you're in, you can inspect the network at any time with nmcli, which lists every interface and its addresses — the wired ports, the 4G modem, and (after the next step) Tailscale. Confirm the Pi has internet through the modem:

ping -c3 google.com

Step 3: Install and Log In to Tailscale

Install Tailscale with the official one-line script, then bring it up:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

The command prints a URL. Open it in any browser, sign in, and approve the device. Tailscale assigns the Pi a stable 100.x.y.z address that works no matter which 4G tower or NAT it sits behind. If you ever see Access denied: profiles access denied, it's because you ran tailscale without sudo — prefix it with sudo.

To avoid typing sudo for every later Tailscale command, make your user the operator once:

sudo tailscale set --operator=$USER

After that, plain tailscale status, tailscale set ..., and friends work without sudo.

One tip worth internalizing early: refer to the Pi by its MagicDNS name (here raspberrypi) rather than its raw 100.x address. The Tailscale IP can change if you ever re-authenticate the node, which silently breaks anything you pointed at the old address — the name always follows the device.

Step 4: Wire the Camera and Give the Pi an Address on Its Subnet

Plug the camera into the Pi's wired port. The camera in this example uses the 192.168.8.0/24 network at 192.168.8.4, so the Pi needs a static address on that same subnet. Configure the wired connection with a fixed IP, and — crucially — tell it not to become the default route (your 4G modem must stay the path to the internet):

If nmcli shows the wired interface stuck at connecting (getting IP configuration) and it never lands on an address, that's expected — most IP cameras run no DHCP server, so there's nothing to hand the Pi an address. The static configuration below is exactly the fix:

sudo nmcli con mod "Wired connection 1" \
    ipv4.method manual \
    ipv4.addresses 192.168.8.2/24 \
    ipv4.gateway "" \
    ipv4.never-default yes \
    ipv6.method disabled

sudo nmcli con up "Wired connection 1"

(Run nmcli first if you're unsure of the connection name — the wired profile is usually Wired connection 1 or Wired connection 2.) Confirm the Pi can reach the camera:

ping -c3 192.168.8.4

A successful reply means the camera is on the Pi's local subnet. But it's still invisible to the outside world — that's what the next step fixes.

Step 5: Install MediaMTX and Point It at the Camera

The camera can only handle a connection or two, and it's unreachable from outside its private wire. MediaMTX solves both: it runs on the Pi, pulls the camera's RTSP stream over the private wire, and re-serves it on the Pi's own addresses — Tailscale included. Viewers talk to the Pi, never to the camera, and as many can watch as your 4G uplink allows. Install the arm64 build:

curl -fsSL -O https://github.com/bluenviron/mediamtx/releases/download/v1.19.2/mediamtx_v1.19.2_linux_arm64.tar.gz
tar -xzf mediamtx_v1.19.2_linux_arm64.tar.gz
sudo install -m 755 mediamtx /usr/local/bin/mediamtx

Now tell MediaMTX where the camera is. A minimal config defines one path, cam, whose source is the camera's RTSP URL. sourceOnDemand means MediaMTX only pulls from the camera while someone is actually watching — it saves 4G data when nobody is:

sudo tee /etc/mediamtx.yml <<'EOF'
paths:
  cam:
    source: rtsp://192.168.8.4:554/stream1
    sourceOnDemand: yes
EOF

The path is /stream1 here — many IP cameras expose their main profile as stream1 and a lower-resolution substream as stream2. Check your camera's manual for the exact path. Finally, run MediaMTX as a systemd service so it starts on boot and restarts if it ever crashes:

sudo tee /etc/systemd/system/mediamtx.service <<'EOF'
[Unit]
Description=MediaMTX media server
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/mediamtx /etc/mediamtx.yml
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable --now mediamtx

Check it came up cleanly with sudo systemctl status mediamtx — you should see it listening for RTSP on :8554 and WebRTC on :8889.

Step 6: Open Your Camera From Anywhere

That's it. From any machine on your tailnet, point an RTSP-capable player at the Pi's MagicDNS name — even though the Pi is on a 4G connection on the other side of the country:

vlc rtsp://raspberrypi:8554/cam

Or skip the player entirely: MediaMTX serves the same stream over WebRTC, so any browser on the tailnet can watch at:

http://raspberrypi:8889/cam

Note the path is /cam — the name you gave the path in mediamtx.yml — not the camera's own /stream1. MediaMTX pulls from the camera the moment the first viewer connects and drops the connection when the last one leaves.

Bonus: Stream Flight Telemetry Over 4G Too

The same Pi and Tailscale link can carry your flight controller's MAVLink telemetry, not just video. If your autopilot (ArduPilot or PX4) is wired to the Pi over USB, a tiny proxy called mavp2p bridges its serial port to a UDP endpoint any ground station can reach over the tailnet. Install the arm64 build on the Pi:

curl -fsSL -O https://github.com/bluenviron/mavp2p/releases/download/v1.3.3/mavp2p_v1.3.3_linux_arm64v8.tar.gz
tar -xzf mavp2p_v1.3.3_linux_arm64v8.tar.gz
sudo install -m 755 mavp2p /usr/local/bin/mavp2p

Then bridge the autopilot's serial port to a UDP server that listens on every interface, Tailscale included:

mavp2p serial:/dev/ttyACM0:115200 udps:0.0.0.0:14550

udps:0.0.0.0:14550 means mavp2p waits for ground stations to dial in and accepts several at once — no client IP is hard-coded. (Baud is ignored over USB, so the 115200 is just a placeholder.) From your laptop, point any MAVLink GCS at the Pi over Tailscale — note udpout: (dial into the server) and the MagicDNS name so it survives a re-auth:

mavproxy.py --master=udpout:raspberrypi:14550

Within a second or two the vehicle appears — heartbeat, flight mode, and a full parameter download — over the exact same 4G + Tailscale path as the video. If it just says link down, mavp2p almost certainly isn't running on the Pi (a foreground process dies when the terminal closes) — restart it, or run it as a systemd service so it comes back on boot.

One serious caution: MAVLink is unauthenticated — anyone who can reach :14550 can send commands to the aircraft (arm, change mode, even fly it). Keeping it on your private tailnet is safe; never port-forward it to the public internet.

How the Pieces Fit Together

  • The 4G modem is the Pi's default route — its connection to the internet.
  • The wired port is a private link to the camera, deliberately set to never-default so it never competes with 4G for internet traffic.
  • MediaMTX pulls one RTSP stream from the camera and re-serves it to any number of viewers over RTSP or WebRTC, so the camera never faces the network directly.
  • Tailscale gives the Pi a stable, encrypted address reachable through any NAT — that's the address your viewers connect to.

Troubleshooting

RTSP player says "Failed to connect to RTSP server"

Two common causes: (1) MediaMTX isn't running on the Pi — check sudo systemctl status mediamtx; or (2) the Pi isn't reachable over Tailscale yet. Confirm reachability first with ping raspberrypi from the viewing machine, then look at the MediaMTX logs with journalctl -u mediamtx.

MediaMTX is running but the stream never starts

The source URL in mediamtx.yml is probably wrong, so MediaMTX can't pull from the camera. journalctl -u mediamtx shows the exact connection error the moment a viewer triggers the on-demand pull. Try /stream1, /stream2, or the path from your camera's manual, and confirm the camera answers ping 192.168.8.4 from the Pi itself — that isolates the camera and cabling from anything Tailscale-related.

The Pi loses internet after wiring the camera

The wired connection grabbed the default route. Re-apply ipv4.never-default yes and clear ipv4.gateway so only the 4G modem provides the default route.

The wired interface is stuck at "getting IP configuration"

Expected, not a fault. Most IP cameras run no DHCP server, so the Pi never receives an address automatically and nmcli shows the port endlessly connecting. The static IP in Step 4 is the fix.

It worked, then broke after re-logging-in to Tailscale

Re-authenticating a node can reassign its 100.x address, so anything pointed at the old IP goes quiet. Use the MagicDNS name (raspberrypi) instead of the raw IP — the name always follows the device.

Related Guides

Prefer to Skip the CLI? This Setup Ships Preconfigured

Everything you just built by hand — the media server, Tailscale, the network configuration that keeps 4G as the default route — comes preconfigured in the free Aircast OS image. Flash it to the SD card instead of stock Raspberry Pi OS, boot the Pi, and manage the camera, stream, and connectivity from a web admin panel rather than SSH and config files. The getting-started guide walks you through flashing and reaching the dashboard.

Conclusion

For the price of hardware you may already own, you've built an internet-reachable 4G drone camera with zero recurring software cost: free Raspberry Pi OS, a free MediaMTX server, a free Tailscale tailnet, and a handful of commands. From anywhere on earth, you can now watch the camera behind a Pi on a cellular connection — in VLC or straight in the browser.

Want to go further — sub-second WebRTC streaming through a cloud SFU, adaptive bitrate over flaky cellular, and live MAVLink telemetry overlaid on the video? Start with the WebRTC streaming guide to layer ultra-low-latency video on top of this exact setup.