#!/bin/bash # ============================================================================= # Frigate Clip Sync: USB Drive → NAS # Copies alert/detection clips and exports to NAS for long-term retention. # Frigate handles short-term cleanup on USB (7 days). # The cleanup-frigate-media.sh script handles NAS cleanup (90 days). # Run via cron: 0 2 * * * /mnt/docker-data/scripts/sync-frigate-to-nas.sh # ============================================================================= USB_DIR="/mnt/frigate-recordings" NAS_DIR="/mnt/docker-data/media/frigate" LOG_FILE="/var/log/frigate-sync.log" log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG_FILE" } # Verify both paths exist if [ ! -d "$USB_DIR" ]; then log "ERROR: USB drive not mounted at $USB_DIR" exit 1 fi if [ ! -d "$NAS_DIR" ]; then log "ERROR: NAS not mounted at $NAS_DIR" exit 1 fi log "=== Frigate clip sync started ===" # Sync clips (alert/detection event media) if [ -d "$USB_DIR/clips" ]; then log "Syncing clips..." rsync -av --no-o --no-g "$USB_DIR/clips/" "$NAS_DIR/clips/" >> "$LOG_FILE" 2>&1 log "Clips sync complete" fi # Sync exports (user-saved clips) if [ -d "$USB_DIR/exports" ]; then log "Syncing exports..." rsync -av --no-o --no-g "$USB_DIR/exports/" "$NAS_DIR/exports/" >> "$LOG_FILE" 2>&1 log "Exports sync complete" fi # Report sizes USB_CLIPS=$(du -sh "$USB_DIR/clips" 2>/dev/null | cut -f1) USB_RECORDINGS=$(du -sh "$USB_DIR/recordings" 2>/dev/null | cut -f1) NAS_CLIPS=$(du -sh "$NAS_DIR/clips" 2>/dev/null | cut -f1) NAS_EXPORTS=$(du -sh "$NAS_DIR/exports" 2>/dev/null | cut -f1) log "USB clips: $USB_CLIPS | USB recordings: $USB_RECORDINGS" log "NAS clips: $NAS_CLIPS | NAS exports: $NAS_EXPORTS" log "=== Sync complete ==="