Storage & Backup
Backup Footage to Local Storage
Download and archive Rhombus camera footage to local storage like NAS or external drives using the API for compliance, retention, and offline access.
On this page
- Overview
- How it works
- Prerequisites
- Installation
- Install required software
- Download the backup script
- Verify installation
- Configuration
- Command-line parameters
- Usage examples
- Basic backup (last hour)
- Specific time range
- Single camera backup
- Location-based backup
- WAN access (remote backup)
- Debug mode
- Output files
- Scheduling automated backups
- Using cron (Linux/macOS/NAS)
- Using Task Scheduler (Windows)
- API endpoints used
- Camera enumeration
- Audio gateway list
- Session token generation
- Video media URIs
- Audio media URIs
- Performance optimization
- Threading configuration
- Storage considerations
- Network optimization
- Retention and cleanup
- Troubleshooting
- Best practices
- Security considerations
- API key protection
- Network security
- Storage security
- Compliance considerations
- Advanced configuration
- Custom output directory
- Email notifications
- Webhook integration
- Next steps
- Additional resources
Sample implementation — not covered by Rhombus Support
This guide is a sample implementation and is not covered by Rhombus Support. While Rhombus does not officially support on-premise backup, this guide demonstrates how to implement a local backup solution using the Rhombus API.
Use this implementation at your own discretion and ensure it meets your organization's backup and compliance requirements.
Overview
This guide shows how to back up video and audio footage from Rhombus cameras to local storage devices such as Network Attached Storage (NAS), external hard drives, or local servers. The solution uses a Python script that uses the Rhombus API to download footage in parallel across multiple cameras.
The implementation supports:
- Multi-camera downloads with threading for improved performance
- Video and audio synchronization with automatic merging
- Flexible scheduling using cron jobs or task schedulers
- Customizable time ranges for historical footage backup
- Location-based filtering to backup specific sites
How it works
- Camera Discovery
The script queries the Rhombus API to enumerate all cameras in your organization, filtering by connection status, location, or specific camera UUIDs.
- Session Authentication
A federated session token is generated for each camera, providing temporary (1-hour) credentials for media access without exposing your API key in download URLs. Cameras on your LAN accept only federated tokens, by design, so LAN mode always uses one.
- Media Download
For each camera, the script:
- Requests MPD (MPEG-DASH) playlist URIs for video and audio streams
- Downloads the initialization segment (
seg_init.mp4) - Downloads sequential 2-second media segments
- Writes segments to local storage
- Audio-Video Merging
If audio is available, the script uses FFmpeg to merge video and audio streams into a single file, then cleans up temporary files.
Prerequisites
Before implementing local backup, ensure you have:
- Python 3.7 or higher installed on your backup system
- Rhombus API key from the Rhombus Console
- Network connectivity to Rhombus cameras (LAN or WAN)
- Sufficient storage space on your backup device (estimate 1-2 GB per camera per day)
- FFmpeg installed for audio-video merging
Calculate your storage requirements based on camera count, retention period, and recording quality. A typical Rhombus camera generates approximately 40-60 GB per month of footage.
Installation
Install required software
# Update package list
sudo apt update
# Install Python 3 and pip
sudo apt install python3 python3-pip
# Install FFmpeg
sudo apt install ffmpeg
# Install Git (to clone the repository)
sudo apt install git# Install Homebrew if not already installed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Python 3
brew install python
# Install FFmpeg
brew install ffmpeg
# Install Git
brew install git# Install Python from python.org
# Download from: https://www.python.org/downloads/
# Install FFmpeg
# Download from: https://ffmpeg.org/download.html#build-windows
# Add FFmpeg to your PATH environment variable
# Install Git
# Download from: https://git-scm.com/download/win# Enable SSH in Control Panel > Terminal & SNMP
# Install Python via Package Center
# Search for and install "Python 3"
# Install ffmpeg via SynoCommunity
# Add SynoCommunity package source: https://synocommunity.com/
# Install ffmpeg from Community packages
# Install Git via Package CenterDownload the backup script
Clone the Rhombus API examples repository:
# Clone the repository
git clone https://github.com/RhombusSystems/api-examples-python.git
# Navigate to the NAS backup directory
cd api-examples-python/NAS-Backup-v2
# Install Python dependencies
pip3 install -r requirements.txtVerify installation
Test that all components are installed correctly:
# Check Python version
python3 --version
# Check FFmpeg installation
ffmpeg -version
# Check pip packages
pip3 list | grep -E "(requests|ffmpeg|urllib3|xmltodict)"Configuration
Command-line parameters
The backup script supports the following parameters:
Your Rhombus API key for authentication. Required unless using certificate-based authentication.
Example: --api_key YOUR_API_KEY_HERE
Unix epoch timestamp for backup start time. Defaults to 1 hour ago if not specified.
Example: --start_time 1693526400 (August 31, 2023 at 16:00:00 UTC)
Duration in seconds to backup from start time. Defaults to 3600 seconds (1 hour).
Example: --duration 7200 (2 hours)
Filter backup to cameras at a specific location. Useful for multi-site deployments.
Example: --location_uuid location-uuid-here
Backup footage from a specific camera only.
Example: --camera_uuid camera-uuid-here
Use WAN addresses instead of LAN. Enable when backup system is outside your local network.
Example: --usewan
Enable debug logging for troubleshooting.
Example: --debug
Path to client certificate for mTLS authentication (advanced use case).
Example: --cert /path/to/cert.pem
Path to private key for mTLS authentication (advanced use case).
Example: --private_key /path/to/key.pem
Usage examples
Basic backup (last hour)
Backup the last hour of footage from all cameras:
python3 copy_footage_script_threading.py \
--api_key YOUR_API_KEYSpecific time range
Backup footage from a specific 2-hour window:
python3 copy_footage_script_threading.py \
--api_key YOUR_API_KEY \
--start_time 1693526400 \
--duration 7200Single camera backup
Backup footage from one specific camera:
python3 copy_footage_script_threading.py \
--api_key YOUR_API_KEY \
--camera_uuid camera-uuid-here \
--duration 3600Location-based backup
Backup all cameras at a specific location:
python3 copy_footage_script_threading.py \
--api_key YOUR_API_KEY \
--location_uuid location-uuid-here \
--duration 3600WAN access (remote backup)
Backup from outside your local network:
python3 copy_footage_script_threading.py \
--api_key YOUR_API_KEY \
--usewan \
--duration 3600Debug mode
Enable detailed logging for troubleshooting:
python3 copy_footage_script_threading.py \
--api_key YOUR_API_KEY \
--debug \
--duration 3600Output files
Downloaded footage files follow this naming convention:
{CameraName}_{CameraUUID}_{Timestamp}_{Type}.{Extension}Examples:
FrontDoor_abc123def456_1693526400_video.mp4
Lobby_def789ghi012_1693526400_videoWithAudio.mp4
Warehouse_ghi345jkl678_1693526400_video.mp4File Types:
- Video-only files:
.mp4format (when no audio is available) - Merged files:
.mp4format (video + audio combined via FFmpeg) - Temporary files:
.webmformat (automatically deleted after merging)
The script automatically cleans up temporary files after successful merging. Only final .mp4 files remain in your backup directory.
Scheduling automated backups
Using cron (Linux/macOS/NAS)
Create automated backups using cron jobs:
- Edit Crontab
Open your crontab configuration:
bashcrontab -e - Add Backup Schedule
Add one of the following examples based on your needs:
bash# Backup every hour at minute 0 0 * * * * cd /path/to/api-examples-python/NAS-Backup-v2 && /usr/bin/python3 copy_footage_script_threading.py --api_key YOUR_API_KEY --duration 3600 >> /var/log/rhombus_backup.log 2>&1# Backup last 24 hours at midnight 0 0 * * * cd /path/to/api-examples-python/NAS-Backup-v2 && /usr/bin/python3 copy_footage_script_threading.py --api_key YOUR_API_KEY --duration 86400 >> /var/log/rhombus_backup.log 2>&1# Backup every 4 hours 0 */4 * * * cd /path/to/api-examples-python/NAS-Backup-v2 && /usr/bin/python3 copy_footage_script_threading.py --api_key YOUR_API_KEY --duration 14400 >> /var/log/rhombus_backup.log 2>&1# Backup every 2 hours during business hours (8 AM - 6 PM, Mon-Fri) 0 8-18/2 * * 1-5 cd /path/to/api-examples-python/NAS-Backup-v2 && /usr/bin/python3 copy_footage_script_threading.py --api_key YOUR_API_KEY --duration 7200 >> /var/log/rhombus_backup.log 2>&1 - Save and Verify
Save the crontab and verify it's scheduled:
bash# List current cron jobs crontab -l # Check cron service status sudo systemctl status cron
Cron Schedule Reference:
0 * * * *- Every hour at minute 0*/30 * * * *- Every 30 minutes0 */4 * * *- Every 4 hours0 0 * * *- Daily at midnight0 2 * * 0- Weekly on Sunday at 2 AM
Using Task Scheduler (Windows)
- Open Task Scheduler
Press
Win + R, typetaskschd.msc, and press Enter. - Create New Task
- Click "Create Task" in the right panel
- Name it "Rhombus Footage Backup"
- Select "Run whether user is logged on or not"
- Set Trigger
- Go to the Triggers tab
- Click New
- Choose frequency (Daily, Weekly, etc.)
- Set start time and recurrence
- Configure Action
- Go to the Actions tab
- Click New
- Action: Start a program
- Program:
C:\Python39\python.exe(adjust path) - Arguments:
copy_footage_script_threading.py --api_key YOUR_API_KEY --duration 3600 - Start in:
C:\path\to\NAS-Backup-v2
- Save and Test
- Click OK to save
- Right-click the task and select "Run" to test
API endpoints used
The backup script interacts with the following Rhombus API endpoints:
Camera enumeration
POST https://api2.rhombussystems.com/api/camera/getMinimalCameraStateListRetrieves list of cameras with connection status and location information.
Audio gateway list
POST https://api2.rhombussystems.com/api/audiogateway/getMinimalAudioGatewayStateListFetches audio devices associated with cameras.
Session token generation
POST https://api2.rhombussystems.com/api/org/generateFederatedSessionTokenCreates a federated token for media access. The script asks for one hour; the response's expiresAtMs says when the token expires, and no federated token lasts more than 24 hours.
Video media URIs
POST https://api2.rhombussystems.com/api/camera/getMediaUrisObtains MPD (MPEG-DASH) playlist templates for video streams.
Audio media URIs
POST https://api2.rhombussystems.com/api/audiogateway/getMediaUrisObtains MPD templates for audio streams.
All REST API calls authenticate with your API key (x-auth-scheme: api-token and x-auth-apikey) or, with --cert and --private_key, a certificate key over mTLS. Certificate keys work only on the REST API; media downloads use the federated token the script mints.
Performance optimization
Threading configuration
The script uses Python's ThreadPoolExecutor with a maximum of 4 concurrent workers. This balances download speed with API rate limits and system resources.
To adjust thread count, modify the script:
# In copy_footage_script_threading.py
with ThreadPoolExecutor(max_workers=4) as executor: # Change 4 to desired valueRecommendations:
- 2-4 workers: Standard NAS or low-end systems
- 4-8 workers: High-performance NAS or servers
- 8-16 workers: Enterprise servers with high bandwidth
Increasing thread count beyond recommended values may trigger rate limiting or overload your network/storage.
Storage considerations
Calculate Required Space:
Storage (GB) = Cameras × Days × 1.5 GB/dayExample:
- 10 cameras × 30 days × 1.5 GB = 450 GB required
Best Practices:
- Maintain at least 20% free space on backup device
- Implement retention policies to delete old footage
- Monitor disk usage regularly
- Use compression if long-term archival is needed
Network optimization
LAN vs WAN:
- LAN Mode (default): Faster downloads, uses local network addresses
- WAN Mode (
--usewan): Required for remote backup, slower but accessible from anywhere
Bandwidth Requirements:
- Approximately 2-4 Mbps per concurrent camera download
- 4 workers = 8-16 Mbps recommended bandwidth
Retention and cleanup
Implement a retention policy to manage storage usage:
# Create cleanup script
cat > cleanup_old_footage.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/path/to/backup/directory"
RETENTION_DAYS=30
find "$BACKUP_DIR" -name "*.mp4" -type f -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.webm" -type f -mtime +$RETENTION_DAYS -delete
echo "Deleted footage older than $RETENTION_DAYS days"
EOF
chmod +x cleanup_old_footage.sh# Add to crontab (runs every Sunday at 3 AM)
0 3 * * 0 /path/to/cleanup_old_footage.sh >> /var/log/rhombus_cleanup.log 2>&1import os
import time
from pathlib import Path
def cleanup_old_files(backup_dir, retention_days):
"""Remove footage files older than retention period"""
cutoff_time = time.time() - (retention_days * 86400)
removed_count = 0
freed_space = 0
for file in Path(backup_dir).glob("**/*.mp4"):
if file.stat().st_mtime < cutoff_time:
size = file.stat().st_size
file.unlink()
removed_count += 1
freed_space += size
print(f"Removed {removed_count} files")
print(f"Freed {freed_space / (1024**3):.2f} GB")
# Usage
cleanup_old_files("/path/to/backup", retention_days=30)Troubleshooting
Script Fails with Authentication Error
Symptoms:
401responses whose JSONerrorCodeisINVALID_CREDENTIAL(an unknown or deleted key),CREDENTIAL_EXPIRED(the key has expired) orUNAUTHENTICATED(no key reached the server)
Solutions:
- Verify API key is correct in Rhombus Console and hasn't expired
- Ensure API key has camera access permissions
- Check that
x-auth-schemeheader is set correctly - Regenerate API key if compromised
# Test API authentication
curl -X POST https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY"Downloads Are Very Slow
Symptoms:
- Downloads take longer than expected
- Network timeout errors
Solutions:
- Use LAN mode instead of WAN if backing up locally
- Reduce thread count in
ThreadPoolExecutor - Check network bandwidth and camera connectivity
- Verify storage device write speed
- Consider scheduling backups during off-peak hours
# Test with fewer threads and debug mode
python3 copy_footage_script_threading.py \
--api_key YOUR_API_KEY \
--debug \
--duration 600 # Start with 10 minutesFFmpeg Merge Fails
Symptoms:
- Temporary
.webmfiles remain - No merged
.mp4output - FFmpeg error messages
Solutions:
- Verify FFmpeg is installed and in PATH
- Check that both video and audio files were downloaded
- Ensure sufficient disk space for temporary files
- Update FFmpeg to latest version
# Check FFmpeg installation
which ffmpeg
ffmpeg -version
# Manual merge test
ffmpeg -i video.webm -i audio.webm -c copy output.mp4No Cameras Found
Symptoms:
- Script reports 0 cameras to backup
- Empty camera list
Solutions:
- Verify cameras are online in Rhombus Console
- Check location UUID filter if specified
- Ensure API key has access to cameras
- Review camera connection status filters in script
# List all cameras via API
curl -X POST https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
| python3 -m json.toolDisk Space Issues
Symptoms:
- Script fails with write errors
No space left on devicemessages
Solutions:
- Check available disk space:
df -h - Implement retention policy to delete old footage
- Reduce backup duration or frequency
- Add additional storage capacity
- Use compression for archived footage
# Check disk usage
df -h /path/to/backup
# Find largest files
du -sh /path/to/backup/* | sort -hr | head -10Cron Job Not Running
Symptoms:
- Scheduled backups don't execute
- No new footage files created
Solutions:
- Check cron service status:
systemctl status cron - Verify crontab syntax:
crontab -l - Check cron logs:
grep CRON /var/log/syslog - Ensure script paths are absolute
- Verify user permissions
# Test cron job manually
cd /path/to/NAS-Backup-v2
/usr/bin/python3 copy_footage_script_threading.py --api_key YOUR_API_KEY
# Check cron logs
tail -f /var/log/syslog | grep CRONBest practices
Never hardcode API keys in scripts. Use environment variables or secure key management systems. Rotate API keys regularly.
Set up monitoring and alerting for backup failures. Review logs regularly to ensure backups complete successfully.
Regularly test restoring footage from backups to verify integrity and confirm your recovery process works.
Define and enforce retention policies to manage storage costs and comply with data protection regulations.
Consider multiple backup locations (onsite + offsite) for critical footage. Implement the 3-2-1 backup rule.
Maintain documentation of your backup configuration, schedules, and recovery procedures for your team.
Security considerations
Follow these security best practices when implementing local backup:
API key protection
- Store securely: Use environment variables or credential managers
- Restrict access: Limit file permissions on scripts containing keys
- Rotate regularly: Change API keys periodically
- Audit usage: Monitor API key activity in Rhombus Console
# Store API key in environment variable
export RHOMBUS_API_KEY="your-api-key-here"
# Use in script
python3 copy_footage_script_threading.py --api_key "$RHOMBUS_API_KEY"
# Restrict script permissions
chmod 600 backup_script.shNetwork security
- Use LAN mode when possible to avoid WAN exposure
- Implement firewall rules to restrict access
- Consider VPN for remote backup scenarios
- Enable mTLS authentication for enhanced security
Storage security
- Encrypt backup storage devices
- Restrict file system permissions
- Implement access controls on NAS/server
- Regularly audit who has access to backup files
Compliance considerations
When implementing local backup, consider:
Data Retention:
- Follow your organization's data retention policies
- Comply with industry regulations (HIPAA, GDPR, etc.)
- Document retention periods and deletion procedures
Access Control:
- Maintain audit logs of who accesses backup footage
- Implement role-based access controls
- Document authorized personnel
Data Protection:
- Encrypt data at rest and in transit
- Implement secure deletion procedures
- Regular security assessments
Advanced configuration
Custom output directory
Modify the script to save files to a specific directory:
# In copy_footage_script_threading.py
OUTPUT_DIR = "/mnt/nas/rhombus_backups"
# Create directory structure by date
import datetime
date_dir = datetime.datetime.now().strftime("%Y-%m-%d")
output_path = os.path.join(OUTPUT_DIR, date_dir)
os.makedirs(output_path, exist_ok=True)Email notifications
Add email alerts for backup completion or failures:
import os
import smtplib
from email.mime.text import MIMEText
def send_notification(status, message):
msg = MIMEText(message)
msg['Subject'] = f'Rhombus Backup {status}'
msg['From'] = 'backup@yourcompany.com'
msg['To'] = 'admin@yourcompany.com'
with smtplib.SMTP('smtp.gmail.com', 587) as server:
server.starttls()
server.login(os.environ['SMTP_EMAIL'], os.environ['SMTP_PASSWORD'])
server.send_message(msg)
# Use after backup completes
try:
# ... backup code ...
send_notification("Success", "All cameras backed up successfully")
except Exception as e:
send_notification("Failed", f"Backup failed: {str(e)}")Webhook integration
Trigger webhooks after backup completion:
import datetime
import requests
def trigger_webhook(status, cameras_backed_up):
webhook_url = "https://your-webhook-endpoint.com/backup"
payload = {
"status": status,
"timestamp": datetime.datetime.now().isoformat(),
"cameras": cameras_backed_up
}
requests.post(webhook_url, json=payload)Next steps
Learn how to stream live footage from Rhombus cameras
Set up webhooks to receive real-time events
Access the complete backup script source code
Contact Rhombus Support for help with your integration.
Additional resources
- Rhombus API Documentation: Complete API reference for all endpoints
- Python Requests Documentation: docs.python-requests.org
- FFmpeg Documentation: ffmpeg.org/documentation
- Cron Documentation: man7.org/linux/man-pages/man5/crontab.5.html
For questions about the Rhombus API endpoints this sample uses, email support@rhombus.com.