Take control of your privacy. Build a completely local, open-source AI surveillance system that never touches the cloud.
Your surveillance cameras might be watching you - and so might someone else. Cloud-connected cameras have their feeds sold on the dark web. With Frigate:
- 100% Local - Nothing leaves your network
- AI-Powered - Object detection, facial recognition, semantic search
- Open Source - You own it, you control it
- Hardware Flexible - Runs on a Raspberry Pi to a full server
| Feature | Description |
|---|---|
| Live Viewing | Real-time camera feeds in your browser |
| AI Detection | Person, car, pet, and object detection |
| Recording | Motion-based or continuous recording |
| Facial Recognition | Know who's at your door |
| Semantic Search | Search your footage with natural language |
| PTZ Control | Pan, tilt, zoom your cameras from the UI |
| Home Assistant | Full integration for automations |
Here's exactly what I used in the video:
| Component | Link | Price |
|---|---|---|
| Raspberry Pi 5 (8GB) | Buy on Amazon | ~$80 |
| Hailo-8L AI HAT | Buy on Amazon | ~$70 |
| Reolink E1 Pro Camera | Buy on Amazon | ~$56 |
| Google Coral USB | Buy on Amazon | ~$100 |
- Shopping List
- Hardware Requirements
- Quick Start (Raspberry Pi)
- Desktop/Server Setup
- Camera Setup (Reolink)
- Progressive Configuration Guide
- WiFi Troubleshooting
- AI Accelerator Setup
- Home Assistant Integration
- Troubleshooting
| Component | Recommendation | Notes |
|---|---|---|
| Computer | Raspberry Pi 5 (8GB) | 4GB works but 8GB recommended |
| Storage | 128GB+ microSD or NVMe | NVMe via HAT recommended for recording |
| AI Accelerator | Hailo-8L AI HAT (~$70) | Optional but highly recommended |
| Cameras | Reolink E1 Pro (~$56 each) | PTZ, WiFi, RTSP support |
| Component | Recommendation | Notes |
|---|---|---|
| Computer | Any x86 Linux machine | Old gaming PC works great |
| GPU | NVIDIA GPU (optional) | For hardware video decoding |
| AI Accelerator | Google Coral USB (~$100) | Handles all AI inference |
| Storage | SSD + HDD/NAS | SSD for cache, HDD for recordings |
Any RTSP-compatible camera works. Tested/recommended brands:
- Reolink E1 Pro - Budget-friendly, PTZ, WiFi (what I used)
- Reolink RLC-series - Outdoor, PoE options
- Amcrest - Good RTSP support
- Dahua - Professional grade
- UniFi Protect - Works with RTSP enabled
Key camera features to look for:
- RTSP support (required)
- Dual stream (main + sub stream)
- H.264 or H.265 encoding
- 5GHz WiFi support (for wireless cameras)
- Download Raspberry Pi Imager
- Flash Raspberry Pi OS (64-bit) to your SD card
- Enable SSH in the imager settings
- Boot your Pi and connect via SSH
ssh your-username@your-pi-ip# Update system
sudo apt update && sudo apt upgrade -y
# Enable PCIe Gen 3 for Hailo (if using AI HAT)
sudo raspi-config nonint do_pcie_speed 3# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add your user to docker group
sudo usermod -aG docker $USER
# Log out and back in, then verify
docker --versionmkdir -p ~/frigate/{config,storage}
cd ~/frigatenano docker-compose.ymlBasic Docker Compose (no AI accelerator):
version: "3.9"
services:
frigate:
container_name: frigate
privileged: true
restart: unless-stopped
image: ghcr.io/blakeblackshear/frigate:stable
shm_size: "64mb"
volumes:
- /etc/localtime:/etc/localtime:ro
- ./config:/config
- ./storage:/media/frigate
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "5000:5000" # Web UI
- "8554:8554" # RTSP feeds
- "8555:8555/tcp" # WebRTC
- "8555:8555/udp" # WebRTC
environment:
- FRIGATE_RTSP_PASSWORD=YourSecurePasswordnano config/config.ymlmqtt:
enabled: false
cameras:
# Empty for now - we'll add cameras nextdocker compose up -d
# Check if it's running
docker ps
# View logs
docker logs frigate --tail 50Open your browser and go to: http://your-pi-ip:5000
You should see the Frigate dashboard (empty, but working).
- Open the Reolink app on your phone
- Add your camera and connect it to WiFi
- Go to Settings > Network > Advanced
- Enable RTSP (default port: 554)
- Enable ONVIF if you want PTZ control
Reolink cameras use this format:
# Main stream (high quality - for recording)
rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_main
# Sub stream (low quality - for AI detection)
rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_sub
Replace:
PASSWORDwith your camera passwordCAMERA_IPwith your camera's IP address
# Install ffmpeg
sudo apt install ffmpeg -y
# Test the stream (records 5 seconds)
ffmpeg -i "rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_sub" \
-t 5 -c copy test.mp4
# Check if file was created
ls -la test.mp4If test.mp4 exists and plays, your RTSP stream is working!
Edit your config:
nano ~/frigate/config/config.ymlmqtt:
enabled: false
ffmpeg:
input_args: preset-rtsp-generic
cameras:
front_door: # Name your camera
enabled: true
ffmpeg:
inputs:
- path: rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_sub
roles:
- detect
detect:
enabled: false # Start with detection OFF
width: 896
height: 512
fps: 5Restart Frigate:
cd ~/frigate && docker compose restartCheck the web UI - you should see your camera feed!
Build your config step by step. Each phase adds new capabilities.
Just get the camera streaming - no AI yet.
mqtt:
enabled: false
ffmpeg:
input_args: preset-rtsp-generic
cameras:
front_door:
enabled: true
ffmpeg:
inputs:
- path: rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_sub
roles:
- detect
detect:
enabled: false
width: 896
height: 512
fps: 5Verify: Camera feed appears in UI.
Turn on object detection (uses CPU without accelerator).
mqtt:
enabled: false
ffmpeg:
input_args: preset-rtsp-generic
objects:
track:
- person
- car
- dog
- cat
cameras:
front_door:
enabled: true
ffmpeg:
inputs:
- path: rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_sub
roles:
- detect
detect:
enabled: true # NOW enabled
width: 896
height: 512
fps: 5Verify: You see detection boxes around people, cars, pets.
Use main stream for recording, sub stream for detection.
mqtt:
enabled: false
ffmpeg:
input_args: preset-rtsp-generic
objects:
track:
- person
- car
- dog
- cat
record:
enabled: true
retain:
days: 7
mode: motion
cameras:
front_door:
enabled: true
ffmpeg:
inputs:
- path: rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_main
roles:
- record
- path: rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_sub
roles:
- detect
detect:
enabled: true
width: 896
height: 512
fps: 5
record:
enabled: true
alerts:
retain:
days: 14
pre_capture: 5
post_capture: 5Verify: Recordings appear in the Review tab.
Simply duplicate the camera config with new name and IP.
cameras:
front_door:
# ... front door config ...
backyard:
enabled: true
ffmpeg:
inputs:
- path: rtsp://admin:PASSWORD@CAMERA_IP_2:554/h265Preview_01_main
roles:
- record
- path: rtsp://admin:PASSWORD@CAMERA_IP_2:554/h265Preview_01_sub
roles:
- detect
detect:
enabled: true
width: 896
height: 512
fps: 5
record:
enabled: trueFor cameras with pan/tilt/zoom:
cameras:
front_door:
# ... existing config ...
onvif:
host: CAMERA_IP
port: 8000
user: admin
password: PASSWORDVerify: PTZ controls appear in camera view.
Hailo-8L AI HAT (Raspberry Pi 5)
CRITICAL: Frigate 0.15.x requires Hailo driver version 4.19. Do NOT use the latest drivers!
# 1. Enable PCIe Gen 3
sudo raspi-config nonint do_pcie_speed 3
# 2. Update system
sudo apt update && sudo apt upgrade -y
# 3. Install SPECIFIC versions (4.19.x)
sudo apt install -y \
hailo-dkms=4.19.0-1 \
hailort=4.19.0-3 \
python3-hailort=4.19.0-2 \
hailo-tappas-core=3.30.0-1
# 4. LOCK versions to prevent auto-update
sudo apt-mark hold hailo-dkms hailort python3-hailort hailo-tappas-core
# 5. Reboot
sudo reboothailortcli fw-control identifyYou should see:
Driver version: 4.19.0
Firmware version: 4.19.0
version: "3.9"
services:
frigate:
container_name: frigate
privileged: true
restart: unless-stopped
image: ghcr.io/blakeblackshear/frigate:stable-h8l # Note: h8l image!
shm_size: "128mb"
devices:
- /dev/hailo0:/dev/hailo0 # Hailo AI chip
- /dev/video11:/dev/video11 # RPi hardware decoder
volumes:
- /etc/localtime:/etc/localtime:ro
- ./config:/config
- ./storage:/media/frigate
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "5000:5000"
- "8554:8554"
- "8555:8555/tcp"
- "8555:8555/udp"
environment:
- FRIGATE_RTSP_PASSWORD=YourSecurePasswordmqtt:
enabled: false
# Hailo detector configuration
detectors:
hailo:
type: hailo8l
device: PCIe
model:
width: 300
height: 300
input_tensor: nhwc
input_pixel_format: bgr
model_type: ssd
path: /config/model_cache/h8l_cache/ssd_mobilenet_v1.hef
# Use RPi hardware acceleration
ffmpeg:
hwaccel_args: preset-rpi-64-h264
input_args: preset-rtsp-generic
objects:
track:
- person
- car
- dog
- cat
cameras:
# ... your cameras ...| Metric | CPU Only | With Hailo-8L |
|---|---|---|
| Inference Speed | 60-80ms | 8-10ms |
| CPU Usage | 200%+ | 15-20% |
| Max Cameras | 1-2 | 4-6 |
Google Coral USB (Desktop)
# Add Coral repository
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | \
sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
sudo apt-key add -
sudo apt update
# Install runtime (standard speed)
sudo apt install libedgetpu1-std
# OR install max speed (runs hotter)
# sudo apt install libedgetpu1-maxversion: "3.9"
services:
frigate:
container_name: frigate
privileged: true
restart: unless-stopped
image: ghcr.io/blakeblackshear/frigate:stable
shm_size: "256mb"
devices:
- /dev/bus/usb:/dev/bus/usb # Coral USB passthrough
volumes:
- /etc/localtime:/etc/localtime:ro
- ./config:/config
- ./storage:/media/frigate
ports:
- "5000:5000"
- "8554:8554"
- "8555:8555/tcp"
- "8555:8555/udp"detectors:
coral:
type: edgetpu
device: usb
# ... rest of config ...WiFi Troubleshooting (The Hidden Metric)
This section is gold. I ran 10 WiFi cameras and my network died after 12 hours. The problem wasn't bandwidth - it was something else entirely.
- Network works great for 12-20 hours
- Then everything dies - cameras freeze, internet stops
- Rebooting Frigate fixes it temporarily
- Repeat cycle
I thought it was bandwidth. 10 cameras streaming = lots of data, right?
Wrong. My bandwidth usage was barely touched. The real culprit was airtime saturation.
The Hidden Metric: TX Retry Rate
In my UniFi controller, I found this metric:
- Dumbledore (upstairs AP): 29.1% TX retry rate
- Hagrid (downstairs AP): 7.1% TX retry rate
What does this mean?
TX retry rate = percentage of packets that failed on first transmit and had to be resent.
At 29.1%, nearly 1 in 3 packets was failing!
Think of it like this:
Imagine 15 people trying to have conversations in a room that only fits 5. Everyone's talking over each other, constantly repeating "What did you say?"
The math:
- 10 cameras × 2 streams each = 20 video streams
- Each stream = ~200 packets/second
- Total: ~3,000+ packets/second fighting for airtime
- WiFi is half-duplex - only one device can transmit at a time
- Result: Constant collisions, retries, degradation
Why did it take 12-20 hours to fail?
- Reolink cameras have a known RTSP degradation issue after ~20 hours of continuous streaming
- As streams degrade, more retries happen
- More retries = more airtime consumption
- Eventually hits critical mass and everything collapses
Enable Constant Bit Rate (CBR):
- Reolink app > Settings > Display > Encoding
- Set "Fluency First" to ON
- Reduces bitrate spikes that cause congestion
Reduce main stream bitrate:
- Main stream: 2048 kbps (down from 3072+)
- Sub stream: 512 kbps
Use TCP instead of UDP:
- More reliable on congested WiFi
- Frigate handles this automatically with
preset-rtsp-generic
Since cameras degrade after ~20 hours, schedule daily reboots:
- Reolink app > Settings > System > Auto Reboot
- Enable daily reboot
- Stagger times across cameras:
- Camera 1: 3:00 AM
- Camera 2: 3:10 AM
- Camera 3: 3:20 AM
- etc.
This prevents all cameras from rebooting simultaneously and resets the RTSP connection.
Without go2rtc: Each device (Frigate, Home Assistant, your phone) opens its own connection to the camera.
With go2rtc: One connection to the camera, restreamed to all devices.
Add go2rtc to your config:
go2rtc:
streams:
front_door:
- ffmpeg:rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_main#video=copy#audio=copy
front_door_sub:
- ffmpeg:rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_sub
cameras:
front_door:
ffmpeg:
inputs:
- path: rtsp://127.0.0.1:8554/front_door
input_args: preset-rtsp-restream
roles:
- record
- path: rtsp://127.0.0.1:8554/front_door_sub
input_args: preset-rtsp-restream
roles:
- detectThe rule: 3-4 cameras per access point maximum.
I had 5 cameras on each of my 2 APs. After adding a 3rd AP:
- TX retry rate dropped from 29% to 6%
- Network stability restored
- 3-4 cameras per AP = sustainable
Tips for multiple APs:
- Use non-overlapping 5GHz channels (36, 52, 100+)
- Disable 2.4GHz for camera SSID (5GHz only)
- Lock cameras to specific APs if possible
If you can run cable:
- Eliminates all WiFi issues
- Zero airtime consumption
- Most reliable long-term solution
Priority order for running cable:
- Outdoor cameras (weather + distance issues)
- Cameras with weak signal (<-70 dBm)
- High-traffic cameras
UniFi Controller metrics to watch:
- TX Retry Rate: Should be <10%
- Channel Utilization: Should be <50% per AP
- WiFi Experience: Should be >85%
Frigate metrics:
- Settings > System Metrics
- Watch inference speed and detector usage
Frigate integrates beautifully with Home Assistant.
- HACS > Integrations > Search "Frigate"
- Install and restart Home Assistant
- Add integration: Settings > Integrations > Add > Frigate
- Enter your Frigate URL:
http://frigate-ip:5000
- All cameras as camera entities
- Motion/person/car sensors
- Event snapshots and clips
- Automation triggers
automation:
- alias: "Notify on Person Detection"
trigger:
- platform: state
entity_id: binary_sensor.front_door_person_occupancy
to: "on"
action:
- service: notify.mobile_app
data:
message: "Person detected at front door!"
data:
image: "{{ state_attr('camera.front_door', 'entity_picture') }}"# Test RTSP stream
ffmpeg -i "rtsp://admin:PASSWORD@CAMERA_IP:554/h265Preview_01_sub" -t 5 test.mp4
# Check Frigate logs
docker logs frigate | grep -i error- Enable AI accelerator (Hailo or Coral)
- Reduce detection FPS (5 → 3)
- Add motion masks to ignore busy areas
- Reduce number of tracked objects
- Check WiFi signal strength (aim for >-70 dBm)
- Enable scheduled camera reboots
- Use go2rtc to reduce connections
- Consider adding access points
# Check if Hailo is recognized
hailortcli fw-control identify
# Should show driver version 4.19.0
# If not, reinstall drivers with specific versions# Check logs
docker logs frigate
# Common issues:
# - Config syntax error (validate YAML)
# - Device not passed through
# - shm_size too small (increase it)# Start Frigate
cd ~/frigate && docker compose up -d
# Stop Frigate
cd ~/frigate && docker compose down
# Restart Frigate
cd ~/frigate && docker compose restart
# View logs
docker logs frigate --tail 100
# Check status
docker ps | grep frigate
# Edit config
nano ~/frigate/config/config.ymlMain stream: rtsp://admin:PASSWORD@IP:554/h265Preview_01_main
Sub stream: rtsp://admin:PASSWORD@IP:554/h265Preview_01_sub
| Port | Service |
|---|---|
| 5000 | Web UI |
| 8554 | RTSP restream |
| 8555 | WebRTC |
If this guide helped you, consider:
- Subscribing to NetworkChuck on YouTube
- Starring this repo
- Sharing with others who want local surveillance
Made with coffee by NetworkChuck