VuIO Media Server
A cross-platform DLNA/UPnP media server written in Rust. Streams video, audio, and images to any DLNA-compatible device (smart TVs, receivers, game consoles).
Built with Tokio, Axum, and Redb for high performance and reliability.
Supported platforms: Windows, Linux, macOS, Docker (x64 and ARM64)
Features
- DLNA/UPnP Media Server - Stream to any DLNA device with SSDP discovery
- HTTP Range Streaming - Seek support for large media files
- Multi-format Support - MKV, MP4, AVI, MP3, FLAC, WAV, AAC, OGG, JPEG, PNG, and more
- Audio Metadata - Automatic extraction of artist, album, genre, year from tags
- Music Browsing - Browse by Artists, Albums, Genres, Years via DLNA
- Playlist Support - Auto-imports M3U/PLS playlists from media directories
- Real-time Monitoring - Detects file changes and updates database automatically
- Cross-platform - Native integration for Windows, macOS, Linux
- Redb Database - Embedded ACID-compliant database with crash recovery
Quick Start
# Run with default settings (scans ~/Videos, ~/Music, ~/Pictures)
# Specify media directory
# Custom port and name
# Multiple directories
Command Line Options
Usage: vuio [OPTIONS] [MEDIA_DIR]
Arguments:
[MEDIA_DIR] Directory containing media files
Options:
-p, --port <PORT> Port to listen on [default: 8080]
-n, --name <NAME> DLNA server name
-c, --config <CONFIG> Path to config file
--media-dir <DIR> Additional media directories
--debug Enable debug logging
-h, --help Print help
-V, --version Print version
Docker
Docker does not work on macOS due to multicast limitations.
Quick Start
Docker Compose
services:
vuio:
image: vuio:latest
container_name: vuio-server
restart: unless-stopped
network_mode: host # Required for DLNA multicast
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- ./vuio-config:/config
- /path/to/media:/media:ro
environment:
- VUIO_IP=192.168.1.100 # Your host IP (required)
- VUIO_PORT=8080
- VUIO_MEDIA_DIRS=/media
- VUIO_SERVER_NAME=VuIO
- VUIO_DB_PATH=/data/vuio.redb
Docker Volume Mounting
Single directory:
volumes:
- ./vuio-config:/config
- /path/to/media:/media:ro
Multiple directories:
volumes:
- ./vuio-config:/config
- /home/user/Movies:/media/movies:ro
- /home/user/Music:/media/music:ro
- /home/user/Pictures:/media/pictures:ro
- /mnt/nas/media:/media/nas:ro
environment:
- VUIO_MEDIA_DIRS=/media/movies,/media/music,/media/pictures,/media/nas
Network storage (NFS/SMB):
volumes:
- type: bind
source: /mnt/nas/media
target: /media
read_only: true
Docker Run
Environment Variables
| Variable | Default | Description |
|---|---|---|
VUIO_IP |
- | Required. Host IP for DLNA announcements |
VUIO_PORT |
8080 | HTTP server port |
VUIO_SERVER_NAME |
VuIO | DLNA server name |
VUIO_UUID |
random | Device UUID (set for persistence) |
VUIO_MEDIA_DIRS |
/media | Comma-separated media paths |
VUIO_SCAN_ON_STARTUP |
true | Scan media on startup |
VUIO_WATCH_CHANGES |
true | Monitor for file changes |
VUIO_CLEANUP_DELETED |
true | Remove deleted files from DB |
VUIO_SCAN_PLAYLISTS |
true | Import M3U/PLS playlists |
VUIO_DB_PATH |
/data/vuio.redb | Database file path |
VUIO_MULTICAST_TTL |
4 | Multicast TTL |
VUIO_ANNOUNCE_INTERVAL |
30 | SSDP announce interval (seconds) |
Find your host IP:
# Linux
|
# macOS
# Windows
|
Generate UUID for multiple instances:
Configuration
Native (TOML Config)
VuIO uses TOML configuration files on native platforms. Config location: ./config/config.toml
[]
= 8080
= "0.0.0.0"
= "VuIO Server"
= "auto-generated"
[]
= "Auto"
= 4
= 30
[]
= true
= true
= true
= true
= ["mp4", "mkv", "avi", "mp3", "flac", "wav", "jpg", "png"]
[[]]
= "/home/user/Videos"
= true
= ["mp4", "mkv", "avi", "mov", "wmv", "webm"]
= ["*.tmp", ".*"]
= "Warn" # Strict, Warn, or Skip
[[]]
= "/home/user/Music"
= true
= ["mp3", "flac", "wav", "aac", "ogg", "wma", "m4a", "opus"]
= ["*.tmp", ".*"]
[[]]
= "/home/user/Pictures"
= true
= ["jpg", "jpeg", "png", "gif", "bmp", "webp"]
= ["*.tmp", ".*"]
[]
= "~/.local/share/vuio/media.redb"
= false
= true
Configuration Options
Server:
port- HTTP server portinterface- Network interface to bind (0.0.0.0 for all)name- DLNA server friendly nameuuid- Device UUID (auto-generated if not set)ip- Specific IP for DLNA announcements (optional)
Network:
interface_selection- "Auto", "All", or specific interface namemulticast_ttl- Multicast time-to-liveannounce_interval_seconds- SSDP announcement interval
Media:
scan_on_startup- Scan directories on startupwatch_for_changes- Real-time file monitoringcleanup_deleted_files- Auto-remove deleted files from databasescan_playlists- Import M3U/PLS playlist filessupported_extensions- Global list of media extensions
Media Directories:
path- Directory pathrecursive- Scan subdirectoriesextensions- Override extensions for this directoryexclude_patterns- Patterns to exclude (e.g., ".tmp", ".")validation_mode- Path validation: "Strict" (fail if missing), "Warn" (log warning), "Skip" (no validation)
Database:
path- Database file locationvacuum_on_startup- Compact database on startupbackup_enabled- Enable automatic backups
Audio Features
Metadata Extraction
VuIO automatically extracts metadata from audio files:
- Title, Artist, Album, Album Artist
- Genre, Year, Track Number
- Duration
- Falls back to filename parsing when tags are missing
Supported Audio Formats
- Lossless: FLAC, WAV, AIFF
- Lossy: MP3, AAC, OGG, WMA, OPUS, M4A
Playlist Support
VuIO automatically discovers and imports playlist files:
- M3U/M3U8 - Most common format
- PLS - WinAmp/iTunes compatible
Playlists are scanned from media directories on startup and made available to DLNA clients.
Configure: scan_playlists = true or VUIO_SCAN_PLAYLISTS=true
Music Organization
Recommended directory structure:
/music/
├── Artist Name/
│ └── Album Name (Year)/
│ ├── 01 - Track.flac
│ └── folder.jpg
└── playlists/
├── favorites.m3u
└── workout.pls
Database
VuIO uses Redb, an embedded ACID-compliant database.
Reset Database
# Linux/macOS
# Windows
# Docker
VuIO will create a new database and rescan media on next startup.
Platform Notes
Windows
- Supports UNC paths (
\\server\share) - Auto-excludes
Thumbs.db,desktop.ini
macOS
- Supports network volumes under
/Volumes - Auto-excludes
.DS_Store,.AppleDouble
Linux
- Supports mounts under
/media,/mnt - Auto-excludes
lost+found,.Trash-*
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Web Server │ │ SSDP Service │ │ File Watcher │
│ (Axum/HTTP) │ │ (Discovery) │ │ (Real-time) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
┌──────────────────────┴──────────────────────┐
│ Application Core │
│ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
│ │ Config │ │ Database│ │ Platform │ │
│ │ Manager │ │ (Redb) │ │ Abstraction │ │
│ └─────────┘ └─────────┘ └─────────────┘ │
└──────────────────────┬──────────────────────┘
│
┌──────────────────────┴──────────────────────┐
│ Platform Layer │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Windows │ │ macOS │ │ Linux │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────┘
Testing
Debug logging:
RUST_LOG=debug |
Contributing
Contributions welcome! Please ensure cross-platform compatibility is maintained.
License
Dual-licensed under: