A Raspberry Pi service that automatically detects USB drives, SD cards, and other removable media, and copies files to configured network locations. Features a web interface for management and MQTT integration with Home Assistant.
One-line installation:
curl -sSL https://raw.githubusercontent.com/bscholer/media-ingest-pi/main/install.sh | bashThen access the web interface at http://<raspberry-pi-ip>
- π Auto-detection: Automatically detect USB drives/SD cards when plugged in
- π Device Profiles: Configure per-device settings (drop location, file types, naming patterns)
- π― Multi-Destination Support: Configure multiple transfer rules per device - send photos to one location, videos to another, panoramas to a third, all from the same SD card!
- π Advanced Filtering: Filter files by extension, source path patterns, or filename patterns
- π Web Interface: Modern web UI for management and monitoring with tabbed device configuration
- π Real-time Progress: Track transfers with live progress updates
- π‘ LED Progress Indicator: Visual progress display on WS2812B LED strip
- π Home Assistant Integration: MQTT notifications and discovery
- π Smart Naming: Template-based file naming with multiple variables
- β Checksum Verification: Ensure file integrity with optional checksums
- ποΈ Optional Deletion: Automatically delete source files after successful transfer
One-liner installer that sets everything up automatically:
curl -sSL https://raw.githubusercontent.com/bscholer/media-ingest-pi/main/install.sh | bashOr if you prefer to review the script first:
curl -sSL https://raw.githubusercontent.com/bscholer/media-ingest-pi/main/install.sh -o install.sh
chmod +x install.sh
./install.shAfter installation, configure everything through the web interface - no manual config file editing needed!
- Raspberry Pi (any model with USB ports)
- Python 3.9 or higher
- Network storage location (NAS, SMB share, etc.)
- Optional: MQTT broker (e.g., Mosquitto, Home Assistant)
- Clone the repository:
git clone https://github.com/bscholer/media-ingest-pi.git
cd media-ingest-pi- Install Python dependencies:
pip3 install -r requirements.txt --user- Create directories:
mkdir -p config data- Run the service (port 80 requires sudo):
sudo python3 src/main.py- Access the web interface and complete setup:
http://<raspberry-pi-ip>
Configuration files will be created automatically on first run. Configure your settings and devices through the web UI!
To run automatically on boot:
sudo cp media-ingest.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable media-ingest
sudo systemctl start media-ingestNote about Port 80: The default configuration uses port 80 (standard HTTP port), which is a privileged port on Linux. The systemd service is configured to allow binding to port 80 without running as root using CAP_NET_BIND_SERVICE capability. If you run manually, you'll need to use sudo python3 src/main.py or change the port to a non-privileged port (1024+) in config/settings.yaml.
All configuration is done through the web interface! Visit the Settings and Devices pages to configure the service.
Create device profiles through the web UI. Each profile can include:
- Name: Friendly name for the device
- Identifiers: UUID, label, or vendor to match devices
- Auto-ingest: Automatically start transfer when device is detected
- Transfer Rules: Multiple rules per device, each with:
- Name: Descriptive name for the rule (e.g., "RAW Photos", "Videos")
- Drop location: Where to save files (local path or network share)
- File types: Filter by extensions (e.g.,
.jpg,.raw,.mp4) - Source path patterns: Filter by directory structure (e.g.,
**/DCIM/**,**/PANO/**) - Filename patterns: Filter by filename (e.g.,
IMG_*,*_PANO_*) - Naming pattern: Template for renaming files (see below)
- Preserve structure: Keep folder hierarchy or flatten to one directory
- Delete after: Remove files from source after successful transfer
- Enabled: Enable/disable the profile
Example: A camera SD card can have three rules:
- RAW photos (
.dng,.cr2) β/mnt/nas/photos/raw - JPEG photos (
.jpg) β/mnt/nas/photos/jpeg - Videos (
.mp4) β/mnt/nas/videos
Configure these in the Settings page:
- MQTT: Enable Home Assistant integration with broker details
- Default drop location: Fallback location for unmatched devices
- Temp directory: Temporary storage during transfers
- Checksum verification: Verify file integrity after transfer
- Concurrent transfers: Number of parallel file copies
- LED Strip: Configure WS2812B LED strip for visual progress indication
Display transfer progress on an addressable WS2812B LED strip! Configure through the Settings page:
- Enable/Disable: Toggle LED strip functionality
- GPIO Pin: Pin number in BCM mode (default: GPIO 18, physical pin 12)
- LED Count: Number of LEDs in your strip
- Brightness: Adjust brightness (0-255)
- Colors: Customize colors for idle, progress, success, and error states
Animations:
- π Idle: Breathing blue animation when no transfers are active
- π Progress: Green fill bar showing transfer completion percentage
- β Success: Pulsing green animation on successful completion
- β Error: Flashing red animation on transfer errors
Hardware Requirements:
- WS2812B/NeoPixel LED strip (or compatible: WS2811, SK6812)
- Power supply suitable for your LED count (5V, ~60mA per LED at full brightness)
- Connect LED data line to GPIO 18 (or your chosen pin)
- Common ground connection between Pi and LED power supply
Note: The LED strip requires PWM and will need to run with elevated privileges. The service handles this automatically when run via systemd.
While the web UI is recommended, you can also edit YAML files directly in the config/ directory if needed. See config/settings.example.yaml and config/devices.example.yaml for structure reference.
Use these variables in naming patterns:
{date}: YYYY-MM-DD{datetime}: YYYY-MM-DD_HH-MM-SS{device}: Device name (sanitized){counter}or{counter:04d}: Sequential number with padding{original}: Original filename without extension{ext}: File extension{year},{month},{day}: Individual date components{uuid}: Random UUID
Example: {date}_{device}_{counter:04d}{ext} β 2025-10-19_Camera-SD-Card_0001.jpg
- Dashboard (
/): Active transfers, recent activity, device status - Devices (
/devices): Manage device profiles - Settings (
/settings): Configure MQTT and global settings - History (
/history): View transfer history
When MQTT is enabled, the service publishes events to Home Assistant:
- Device detected
- Transfer started/progress/completed/failed
- Home Assistant auto-discovery
MIT License - See LICENSE file for details
Contributions welcome! Please open an issue or pull request. See CONTRIBUTING


