Raspberry Pi RTSP Surveillance Guide

Raspberry Pi RTSP Surveillance Guide

A Raspberry Pi RTSP surveillance setup receives live video streams from IP cameras over your local network, records motion-triggered or continuous footage to a USB SSD, and serves a browser-accessible dashboard for live viewing. The Pi 4 handles two to four 720p streams comfortably with motionEyeOS. Adding a Coral USB accelerator enables Frigate’s object detection pipeline for person and vehicle alerts. No cloud account, no recurring fees, and no data leaving the network.

Last tested: Raspberry Pi OS Bookworm Lite 64-bit | April 11, 2026 | Raspberry Pi 4 Model B (4GB) | motionEyeOS | Reolink and Amcrest RTSP cameras

Key Takeaways

  • Raspberry Pi 4 with 4GB RAM handles two to four simultaneous RTSP streams at 720p. More cameras or higher resolution require a Pi 5 or reduced frame rates.
  • motionEyeOS is the fastest path to a working multi-camera dashboard. Flash the image, boot, add cameras by RTSP URL, done.
  • Frigate provides object detection (person, vehicle, animal) but requires more CPU. A Coral USB accelerator makes detection practical on Pi 4.
  • Store recordings on a USB SSD, not the microSD card. Continuous video writes will destroy a microSD card within weeks or months.
  • Use Tailscale or ZeroTier for remote access instead of port forwarding. Port forwarding puts the Pi directly on the public internet.
  • Assign a static IP to the Pi via your router’s DHCP reservation so RTSP URLs and browser bookmarks stay valid after reboots.
Raspberry Pi RTSP surveillance architecture diagram showing IP cameras streaming to Pi running motionEyeOS or Frigate with recordings on USB SSD and browser dashboard access

Hardware Selection

Choosing the right Pi model

ModelMax streams (720p)Object detectionNotes
Pi Zero W1NoSingle camera only, no USB 3.0
Pi 3B+1-2No100Mbps Ethernet, limited headroom
Pi 4 (4GB)3-4With Coral USBBest general-purpose choice
Pi 55+Better without CoralFastest option, more thermal headroom

Pi 4 with 4GB is the practical choice for most builds. It has USB 3.0 for fast SSD storage, Gigabit Ethernet for stable stream ingestion, and enough CPU for motionEyeOS with several cameras. Pi 5 handles more simultaneous streams and runs object detection faster, but the Pi 4 is sufficient unless you are managing five or more cameras or need software detection without a Coral accelerator.

Storage planning

Do not record video to the microSD card. A single 720p camera at modest bitrate writes 10 to 15GB per day. Continuous writes at that rate will exhaust a microSD card in weeks. A USB 3.0 SSD handles the write load without degradation and provides much faster write throughput. A 500GB SSD stores several weeks of motion-triggered footage for a typical two to four camera setup. See Booting Raspberry Pi from USB SSD for the full setup, and Preventing SD Card Corruption on Raspberry Pi if you must use microSD.

Power and cooling

Use the official 5V/3A power supply. Cheap adapters that sag under load cause USB disconnects and filesystem corruption, both of which look like software problems but are power problems. The Pi 4 running multiple camera streams continuously generates enough heat to throttle without active cooling. An active cooling case with a fan keeps temperatures below 70 degrees C under sustained load. Monitor with vcgencmd measure_temp and vcgencmd get_throttled.

Choosing RTSP Cameras

What RTSP means in practice

RTSP (Real-Time Streaming Protocol) is the standard that lets IP cameras send live video over a local network. Most IP cameras support it, but documentation quality varies. You need the RTSP URL for each camera to add it to motionEyeOS or Frigate. A typical URL looks like:

rtsp://username:password@192.168.1.100:554/stream1

The port is usually 554. The stream path varies by manufacturer. Reolink uses /h264Preview_01_main for the main stream. Amcrest uses /cam/realmonitor?channel=1&subtype=0. Check the manufacturer’s documentation or community forums for the exact path before buying if RTSP access is not clearly documented.

Recommended camera characteristics

  • Documented RTSP URL with username/password authentication support
  • Configurable resolution and bitrate (essential for managing Pi CPU load)
  • IP66 or IP67 rating for outdoor installations
  • PoE support if running cable is practical (eliminates a separate power run per camera)
  • Fixed or varifocal lens matching the viewing distance needed (3.6mm for wide entry coverage, 8mm+ for longer distances)

Reolink, Amcrest, and Dahua all have well-documented RTSP implementations and configurable bitrates. Avoid cameras that only expose streams through a proprietary app or cloud service. These cannot be used with a local Pi-based system.

Step 1: Prepare the Raspberry Pi

Flash the OS

For motionEyeOS, download the Pi 4 image from the motionEyeOS GitHub releases page and flash it directly with Raspberry Pi Imager. This replaces the OS entirely. motionEyeOS is a standalone image, not a package installed on top of Raspberry Pi OS.

For a Frigate or ZoneMinder setup, flash Raspberry Pi OS Bookworm Lite 64-bit. Use Raspberry Pi Imager’s advanced settings to configure SSH, hostname, and Wi-Fi credentials before writing the image. The older method of dropping an ssh file and editing wpa_supplicant.conf is deprecated on Bookworm.

# After first boot on Raspberry Pi OS:
sudo apt update && sudo apt full-upgrade -y
sudo reboot

Assign a static IP

Assign a static IP to the Pi via your router’s DHCP reservation using the Pi’s MAC address. This is more reliable than editing network configuration files on Bookworm where NetworkManager manages interfaces. A stable IP keeps your RTSP viewer bookmarks and motionEyeOS dashboard URL consistent after every reboot.

Expected result: SSH connects to the same IP address after every reboot. ip addr show eth0 shows the reserved address.

Step 2: Choose and Install Your Surveillance Software

motionEyeOS

motionEyeOS is the fastest path to a working multi-camera dashboard. Flash the image, boot, and the web interface appears on port 80 at http://<pi-ip>. No command line required for basic setup. Add each camera by selecting Network Camera as the type and pasting the RTSP URL. motionEyeOS handles stream display, motion detection with configurable sensitivity zones, and automatic recording to attached storage.

Limitations: no object-class detection (it detects pixel changes, not people or vehicles), and frame rates above 15fps per camera stress the Pi 4 under multi-camera setups. For most home surveillance needs, these limitations are not a problem.

Frigate

Frigate runs in Docker and provides object detection using TFLite models. It classifies detected objects as person, vehicle, animal, and others, which dramatically reduces false alerts compared to pixel-change detection. On Pi 4 without a Coral accelerator, detection works but CPU usage spikes during active detection events. With a Coral USB accelerator, detection runs on the TPU at low CPU cost. See Coral TPU Raspberry Pi 5 Setup for the accelerator setup.

Frigate integrates natively with Home Assistant and can trigger push notifications, automations, and event recordings. The configuration is YAML-based and requires more initial setup than motionEyeOS.

ZoneMinder

ZoneMinder is a full-featured NVR platform capable of managing dozens of cameras with 24/7 recording, event-based recording, and a detailed event database. It is resource-heavy and not beginner-friendly. On Pi 4 it works at modest camera counts and resolutions but requires careful resource management. It is the right choice for a lab or small business setup that needs granular recording policies and multi-user access control.

Software comparison

PlatformSetup difficultyObject detectionHome AssistantBest for
motionEyeOSEasyNo (pixel change)LimitedQuick multi-camera dashboard
FrigateModerateYes (TFLite)NativeSmart alerts, HA integration
ZoneMinderComplexPlugin-basedVia APIFull NVR, multi-user

Expected result: motionEyeOS web interface loads at http://<pi-ip> on port 80. For Frigate, docker compose ps shows the container running and the web UI loads on port 5000.

Step 3: Add RTSP Cameras

motionEyeOS camera setup

In the motionEyeOS web interface, click the camera icon in the top-left corner and select Add Camera. Choose Network Camera as the type. Paste the full RTSP URL including credentials. Give the camera a descriptive name. Adjust resolution and frame rate to match what the camera is configured to output. Start with 720p at 10fps per camera and increase only if the system stays responsive.

Frigate camera configuration

Frigate cameras are defined in config.yml:

cameras:
  front_door:
    ffmpeg:
      inputs:
        - path: rtsp://username:password@192.168.1.100:554/stream1
          roles:
            - detect
            - record
    detect:
      width: 1280
      height: 720
      fps: 5
    record:
      enabled: true
      retain:
        days: 7

Use a low detection fps (5 is usually sufficient) to reduce CPU load. The record role can use the higher-quality stream from the camera while detect uses a lower-resolution sub-stream if the camera supports dual streams.

Expected result: The camera stream appears in the motionEyeOS or Frigate dashboard. No black screen, no “stream unavailable” error. If the stream does not load, test the RTSP URL directly in VLC before troubleshooting the Pi software.

Step 4: Configure Recording and Storage

Mount the USB SSD

# Find the SSD device name
lsblk

# Format as ext4 (replace sdX with your device)
sudo mkfs.ext4 /dev/sdX1

# Create mount point and mount
sudo mkdir /mnt/surveillance
sudo mount /dev/sdX1 /mnt/surveillance

# Add to fstab for automatic mount on boot
sudo blkid /dev/sdX1  # copy the UUID
sudo nano /etc/fstab
# Add: UUID=your-uuid /mnt/surveillance ext4 defaults,nofail 0 0

In motionEyeOS, set the recording folder to /mnt/surveillance in the storage settings. In Frigate, set the media path in config.yml to the mounted SSD path.

Recording mode and retention

Motion-triggered recording is the most practical mode for home surveillance. It uses far less storage than 24/7 recording and makes reviewing footage much faster. Set pre-event and post-event buffers of 5 to 10 seconds so the clip includes context before and after the detected event. Configure automatic retention policies. motionEyeOS and Frigate both support maximum storage size or maximum days of footage before automatic deletion.

Expected result: df -h /mnt/surveillance shows the SSD mounted and available. After a motion event, a new recording file appears in the storage directory.

Step 5: Set Up Remote Access and Security

Use a VPN instead of port forwarding

Tailscale is the simplest option for secure remote access. Install it on the Pi and on your phone or laptop. Both devices appear on the same virtual network regardless of physical location. Accessing the surveillance dashboard from outside the home is then identical to local access: same IP, no port forwarding required, encrypted tunnel throughout.

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

ZeroTier works the same way with a slightly more involved setup. Both are free for personal use. Port forwarding is not recommended. It exposes the Pi’s web interface directly to the internet with no buffer.

Firewall the Pi

sudo apt install ufw -y
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp    # motionEyeOS dashboard
sudo ufw allow 5000/tcp  # Frigate dashboard (if used)
sudo ufw enable

Harden camera and Pi credentials

Change the default password on every IP camera before connecting it to the network. Most cameras ship with admin/admin or similar defaults that are trivially exploited on any LAN. Set unique passwords per camera and record them somewhere safe. On the Pi, change the default user password immediately and use SSH key authentication if accessing it remotely. Disable password-based SSH login after keys are confirmed working.

Expected result: sudo ufw status shows active rules. SSH key login works. Camera web interfaces require authentication.

Viewing Streams

Browser dashboard

motionEyeOS serves a tiled multi-camera view at http://<pi-ip>. Frigate’s dashboard at port 5000 shows live feeds, detection events with thumbnails, and timeline scrubbing. Both work in any modern browser on the local network. RTSP is converted to MJPEG or WebRTC for browser display. Native RTSP playback in browsers is not supported.

Mobile access

For Android, TinyCam Monitor and IP Cam Viewer both support RTSP streams directly. For iOS, VLC and RTSP Player handle RTSP URLs. If you have Tailscale running on your phone, the Pi’s local IP is accessible from anywhere and no special app configuration is needed.

Testing a stream with VLC

VLC is the fastest way to confirm an RTSP URL is working before adding it to motionEyeOS or Frigate. Open VLC, go to Media, Open Network Stream, and paste the RTSP URL. If VLC plays the stream, the URL and credentials are correct. If VLC cannot connect, the problem is the camera configuration or network, not the Pi software.

Maintenance

Monitor temperature and CPU load

# Check temperature
vcgencmd measure_temp

# Check for throttling
vcgencmd get_throttled

# Check per-container resource use (Frigate)
docker stats

A sustained temperature above 80 degrees C with throttling will cause frame drops that look like network problems. Add active cooling before reducing stream quality to diagnose the real cause. See Setting Up zram on Raspberry Pi for reducing overall write pressure on storage.

Storage monitoring

# Check SSD space
df -h /mnt/surveillance

# Find largest files
du -sh /mnt/surveillance/* | sort -rh | head -20

Set retention limits in your surveillance software and verify them periodically. A full disk stops recordings silently. The system appears healthy but no new footage is being saved.

Keep software updated

# Raspberry Pi OS packages
sudo apt update && sudo apt full-upgrade -y

# Frigate Docker image
docker compose pull && docker compose up -d

Frigate and motionEyeOS both receive updates that fix camera compatibility issues and detection bugs. Check the project GitHub pages for release notes before pulling new images on a stable system.

Troubleshooting

Stream not loading in dashboard

Test the RTSP URL in VLC first. If VLC cannot connect, the problem is the camera. Check the URL, credentials, and that the camera’s RTSP service is enabled in its web interface. If VLC connects but the dashboard does not, the issue is with how motionEyeOS or Frigate is parsing the URL. Check for special characters in the password that need URL encoding (use %40 for @, %23 for #).

High CPU or frame drops

Reduce stream resolution or frame rate at the camera level, not just in the software. Many cameras default to 1080p. Dropping to 720p or reducing bitrate at the camera significantly reduces the Pi’s decode workload. For Frigate, reduce the detect fps to 5 or lower. Object detection at 5fps catches virtually all relevant events while using a fraction of the CPU compared to 15fps or 30fps.

Camera dropping off the stream intermittently

Intermittent stream drops are almost always a network stability issue on the camera side, not the Pi. Check the camera’s network connection. Wired cameras are far more reliable than wireless for continuous streaming. Wireless cameras at the edge of Wi-Fi range will drop frames and reconnect repeatedly. Move the access point closer or run a cable.

Recordings not saving

Check that the SSD is mounted with df -h. Check available space. Confirm the software has write permission to the recording directory. For Frigate, check docker compose logs frigate for permission errors or ffmpeg failures. An nofail entry in /etc/fstab prevents a missing SSD from blocking boot but also means recordings silently fail to a non-existent mount point.

FAQ

Can a Raspberry Pi handle more than two cameras?

Yes. A Pi 4 with 4GB RAM handles three to four 720p streams at 10 to 15fps comfortably with motionEyeOS. Above that, reduce frame rates, lower resolution at the camera, or move to Pi 5. Monitor CPU load with htop and temperature with vcgencmd measure_temp to find the practical limit for your specific camera configuration.

What is the easiest platform to start with?

motionEyeOS. Flash the image, boot, open the browser interface, add cameras by RTSP URL. No command line required for basic operation. It handles motion detection, recording, and a multi-camera dashboard out of the box.

Can I access my cameras remotely?

Yes. Install Tailscale on the Pi and on your phone or laptop. Both devices appear on the same encrypted virtual network. Access the surveillance dashboard using the Pi’s Tailscale IP from anywhere. This is more secure than port forwarding and requires no router configuration.

Do I need the Coral accelerator for Frigate?

No, but it helps significantly. Without a Coral USB accelerator, Frigate runs detection on the CPU and spikes to 80 to 100 percent usage during active detection events on Pi 4. With a Coral, detection runs on the TPU at under 5ms per frame with minimal CPU involvement. For a build where Frigate will be running continuously, the Coral accelerator is worth adding.

Will a microSD card last for recording?

Not for long. Continuous or frequent motion-triggered recording generates sustained write loads that exhaust most microSD cards within weeks to months. Use a USB SSD for the recording directory. The OS on the microSD itself will last much longer since it handles primarily reads during normal operation.

References


About the Author

Chuck Wilson has been programming and building with computers since the Tandy 1000 era. His professional background includes CAD drafting, manufacturing line programming, and custom computer design. He runs PidiyLab in retirement, documenting Raspberry Pi and homelab projects that he actually deploys and maintains on real hardware. Every article on this site reflects hands-on testing on specific hardware and OS versions, not theoretical walkthroughs.

Last tested hardware: Raspberry Pi 4 Model B (4GB). Last tested OS: Raspberry Pi OS Bookworm Lite 64-bit. Tested with Reolink and Amcrest RTSP cameras.

Was this helpful?

Yes
No
Thanks for your feedback!