Skip to content

A simple, self-hosted "poor man's NVR" (Network Video Recorder) that records multiple RTSP security cameras to local disk 24/7 and uploads recordings to Google Drive during configurable off-peak hours.

License

Notifications You must be signed in to change notification settings

Monster-ZeroX/EZVIZ-NVR-DIY

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DIY EZVIZ NVR

A simple, self-hosted "poor man's NVR" (Network Video Recorder) that records multiple RTSP security cameras to local disk 24/7 and uploads recordings to Google Drive during configurable off-peak hours.

Works on both macOS and Windows.

Platform License

Overview

This project provides a lightweight solution for continuous security camera recording without expensive NVR hardware or cloud subscriptions. It's designed for EZVIZ cameras but works with any IP camera that supports RTSP.

Features

  • Continuous 24/7 recording of multiple RTSP cameras
  • Time-segmented files (10-minute chunks by default) for easy management
  • Scheduled uploads to Google Drive during off-peak hours (default: midnight to 7 AM)
  • Automatic cleanup - files are removed after successful upload
  • Cross-platform - works on macOS and Windows
  • No GUI required - runs from command line/terminal
  • Easy to customize - simple configuration files

How It Works

┌─────────────────┐     ┌──────────────┐     ┌───────────────┐
│  RTSP Cameras   │────▶│  Local Disk  │────▶│ Google Drive  │
│  (EZVIZ, etc.)  │     │  (ffmpeg)    │     │  (rclone)     │
└─────────────────┘     └──────────────┘     └───────────────┘
                              │                      │
                         24/7 recording      Only during
                         10-min segments     upload window
                                             (00:00-07:00)
  1. Recording: ffmpeg continuously captures RTSP streams and saves them as 10-minute MP4 files
  2. Uploading: rclone uploads completed files to Google Drive during the configured time window
  3. Cleanup: After successful upload, local files are automatically deleted to save disk space

Requirements

Hardware

  • A computer that can run 24/7 (Mac or Windows PC)
  • At least 50GB free disk space (more depending on camera count and upload frequency)
  • Reliable network connection

Software

macOS Windows
macOS 10.15+ (Catalina or newer) Windows 10 or 11
Homebrew winget or Chocolatey
bash (included) PowerShell 5.1+ (included)

Cameras

  • IP cameras with RTSP support
  • EZVIZ C6N tested, but any RTSP camera should work
  • RTSP URL format: rtsp://username:password@ip:port/path

Google Account

  • A Google account with Google Drive access
  • Sufficient Google Drive storage for your recordings

Quick Start – macOS

Step 1: Clone the Repository

git clone https://github.com/Monster-ZeroX/EZVIZ-NVR-DIY.git
cd EZVIZ-NVR-DIY

Step 2: Install Dependencies

chmod +x scripts/mac/*.sh
./scripts/mac/install_deps_mac.sh

This installs ffmpeg, rclone, and jq via Homebrew.

Step 3: Configure rclone for Google Drive

rclone config

Follow the prompts:

  1. Press n for new remote
  2. Name it gdrive (or match RCLONE_REMOTE_NAME in your settings)
  3. Choose drive (Google Drive)
  4. Leave client_id and client_secret blank (press Enter)
  5. Choose 1 for full access
  6. Follow the browser authentication flow
  7. Press n for not a team drive
  8. Press y to confirm

Step 4: Configure Cameras and Settings

# Copy example configs
cp config/cameras.example.json config/cameras.json
cp config/settings.example.env config/settings.env

# Edit with your settings
nano config/cameras.json   # Add your camera RTSP URLs
nano config/settings.env   # Adjust paths and settings

Step 5: Start Recording

# Create logs directory
mkdir -p ~/security_cams/logs

# Start recording (caffeinate prevents sleep)
caffeinate -dims ./scripts/mac/record_cams_mac.sh

Leave this terminal window open, or see launchd setup for auto-start.

Step 6: Set Up Scheduled Uploads

Edit the crontab example and install:

# Edit paths in the file first
nano cron/crontab.example

# Install crontab
crontab cron/crontab.example

You're done! Cameras are recording, and uploads will happen automatically during the configured window.


Quick Start – Windows

Step 1: Clone the Repository

git clone https://github.com/Monster-ZeroX/EZVIZ-NVR-DIY.git
cd EZVIZ-NVR-DIY

Step 2: Install Dependencies

Open PowerShell as Administrator and run:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\scripts\windows\install_deps_windows.ps1

This installs ffmpeg and rclone via winget or Chocolatey.

Important: Close and reopen PowerShell after installation to refresh PATH.

Step 3: Configure rclone for Google Drive

rclone config

Follow the same prompts as macOS (see Step 3 above).

Step 4: Configure Cameras and Settings

# Copy example configs
Copy-Item config\cameras.example.json config\cameras.json
Copy-Item config\settings.example.env config\settings.env

# Edit with your settings
notepad config\cameras.json
notepad config\settings.env

Important for Windows: Change RECORD_BASE_DIR to a Windows path:

RECORD_BASE_DIR="C:\security_cams"

Step 5: Start Recording

.\scripts\windows\record_cams_windows.ps1

Leave this PowerShell window open, or see Task Scheduler setup for auto-start.

Step 6: Set Up Scheduled Uploads

See task_scheduler\README.md for detailed instructions. Quick version:

# Edit the XML file first to update paths
notepad task_scheduler\UploadToDrive.xml

# Import the task (run as Administrator)
schtasks /Create /TN "DIY-NVR-UploadToDrive" /XML ".\task_scheduler\UploadToDrive.xml" /RU "$env:USERNAME"

You're done! Cameras are recording, and uploads will happen automatically.


Configuration Details

cameras.json

[
  {
    "id": "cam1",
    "name": "FrontDoor",
    "rtsp_url": "rtsp://admin:VERIFICATION_CODE@192.168.1.85:554/ch1/main",
    "enabled": true
  }
]
Field Description
id Unique identifier (used for folder names)
name Human-readable name (for logs)
rtsp_url Full RTSP URL including credentials
enabled true to record, false to skip

Finding your RTSP URL: For EZVIZ cameras, the default format is:

rtsp://admin:VERIFICATION_CODE@CAMERA_IP:554/ch1/main

Where VERIFICATION_CODE is the 6-character code on your camera's label.

settings.env

Variable Description Default
RECORD_BASE_DIR Base folder for recordings $HOME/security_cams
SEGMENT_SECONDS Duration of each video file 600 (10 minutes)
RCLONE_REMOTE_NAME Name of rclone remote gdrive
RCLONE_REMOTE_PATH Folder path in Google Drive EZVIZ-Recordings
UPLOAD_WINDOW_START Upload window start (24h format) 00:00
UPLOAD_WINDOW_END Upload window end (24h format) 07:00

How the Upload Window Works

The upload script runs on a schedule (every 10 minutes by default), but only actually uploads files during the configured time window.

Default Window (00:00 - 07:00)

  • 00:00 (midnight): Uploads begin
  • 07:00: Uploads stop
  • 07:00 - 23:59: Script exits immediately, no uploads

Customizing the Window

Edit config/settings.env:

# Example: Upload only between 2 AM and 5 AM
UPLOAD_WINDOW_START="02:00"
UPLOAD_WINDOW_END="05:00"

# Example: Upload between 11 PM and 6 AM (crosses midnight)
UPLOAD_WINDOW_START="23:00"
UPLOAD_WINDOW_END="06:00"

The scripts correctly handle windows that cross midnight.

Why Use a Window?

  • Bandwidth: Upload during off-peak hours when you're not using the internet
  • Power: If your machine sleeps during the day, uploads happen at night
  • Rate limiting: Spread uploads over time to avoid Google Drive limits

Disk Space and Reliability

How Much Space Do You Need?

Rough estimates per camera at 1080p:

  • 1 hour of recording: ~500MB - 2GB (depends on camera bitrate)
  • 24 hours: ~12-48GB per camera
  • Upload window covers 7 hours: You need space for ~17-24 hours of recording

Recommendation: Start with at least 50GB free per camera.

What Happens If...

Scenario Behavior
Machine is off during upload window Files accumulate locally; uploaded next time window opens
Upload fails mid-file File stays local; retried on next run
Disk fills up ffmpeg stops recording; free space and restart
Camera goes offline ffmpeg exits; check logs and restart manually
Google Drive quota exceeded rclone fails; files stay local

Checking Disk Usage

macOS:

du -sh ~/security_cams/*

Windows:

Get-ChildItem C:\security_cams -Recurse | Measure-Object -Property Length -Sum

Advanced: Auto-Start on Boot

macOS (launchd)

See launchd/README.md for full instructions.

Quick setup:

# Edit the plist to update paths
nano launchd/com.diy-nvr.record-cams.plist

# Install
cp launchd/com.diy-nvr.record-cams.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.diy-nvr.record-cams.plist

Windows (Task Scheduler)

See task_scheduler/README.md for full instructions.

Quick setup for auto-start recording:

$Action = New-ScheduledTaskAction -Execute "powershell.exe" `
    -Argument "-ExecutionPolicy Bypass -NoProfile -WindowStyle Hidden -File `"C:\path\to\scripts\windows\record_cams_windows.ps1`""
$Trigger = New-ScheduledTaskTrigger -AtLogon -User $env:USERNAME
Register-ScheduledTask -TaskName "DIY-NVR-StartRecording" -Action $Action -Trigger $Trigger

Security Considerations

Sensitive Data

Your configuration files contain:

  • Camera IP addresses
  • Camera passwords (in RTSP URLs)
  • Network topology information

Do not commit these files to git! They are in .gitignore by default.

Recommendations

  1. Keep the repo private if you fork it
  2. Use strong camera passwords
  3. Put cameras on a separate VLAN if possible
  4. Encrypt your disk where recordings are stored
  5. Enable 2FA on your Google account

What's Safe to Commit

  • ✅ All scripts (they don't contain credentials)
  • ✅ Example config files (*.example.json, *.example.env)
  • ✅ Documentation
  • config/cameras.json (contains RTSP URLs with passwords)
  • config/settings.env (may contain paths)
  • ❌ Any log files
  • ❌ Any recordings

Troubleshooting

Recording Issues

ffmpeg exits immediately

  • Check RTSP URL is correct
  • Verify camera is accessible: ffplay rtsp://...
  • Check firewall isn't blocking port 554
  • Look at log file: $RECORD_BASE_DIR/logs/cam1_ffmpeg.log

Files are 0 bytes or very small

  • Camera might be in "sleep" mode
  • Network connectivity issues
  • Try TCP transport: -rtsp_transport tcp (already in scripts)

Upload Issues

"Outside upload window" all the time

  • Check your system clock
  • Verify UPLOAD_WINDOW_START and UPLOAD_WINDOW_END format (24-hour)

"rclone remote not found"

  • Run rclone listremotes to see configured remotes
  • Remote name must match RCLONE_REMOTE_NAME in settings

Upload stuck or slow

  • Check your internet upload speed
  • Google Drive has rate limits; try fewer --transfers
  • Check $RECORD_BASE_DIR/logs/rclone_upload.log

General Issues

Scripts won't run (macOS)

chmod +x scripts/mac/*.sh

Scripts won't run (Windows)

Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

Project Structure

EZVIZ-NVR-DIY/
├── README.md                 # This file
├── .gitignore               # Excludes config, logs, recordings
├── config/
│   ├── cameras.example.json  # Example camera configuration
│   └── settings.example.env  # Example settings
├── scripts/
│   ├── mac/
│   │   ├── install_deps_mac.sh       # Install ffmpeg, rclone, jq
│   │   ├── record_cams_mac.sh        # Start recording
│   │   └── upload_to_drive_mac.sh    # Upload to Google Drive
│   └── windows/
│       ├── install_deps_windows.ps1  # Install ffmpeg, rclone
│       ├── record_cams_windows.ps1   # Start recording
│       └── upload_to_drive_windows.ps1  # Upload to Google Drive
├── cron/
│   └── crontab.example       # Example cron configuration
├── launchd/
│   ├── README.md
│   ├── com.diy-nvr.record-cams.plist  # Auto-start recording
│   └── com.diy-nvr.upload.plist       # Scheduled uploads
└── task_scheduler/
    ├── README.md
    └── UploadToDrive.xml     # Task Scheduler export

License

MIT License - See LICENSE for details.


Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test on both macOS and Windows if possible
  5. Submit a pull request

Acknowledgments

  • ffmpeg - Video recording and processing
  • rclone - Cloud storage sync
  • Homebrew - macOS package manager
  • jq - JSON processor

About

A simple, self-hosted "poor man's NVR" (Network Video Recorder) that records multiple RTSP security cameras to local disk 24/7 and uploads recordings to Google Drive during configurable off-peak hours.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published