7.9 KiB
7.9 KiB
Velour - Video Library Application Architecture
Velour is a self-hosted video library application built with Rails 8 and Hotwire, designed for personal video collections with optional multi-user support and federation capabilities.
Quick Start
Phase 1 (MVP) - Local Filesystem
- Goal: Complete local video library with grouping and transcoding
- Timeline: 5 weeks
- Documentation: Phase 1 Details
Phase 2 - Authentication & Multi-User
- Goal: User management and per-user playback history
- Documentation: Phase 2 Details
Phase 3 - Remote Sources & Import
- Goal: S3, JellyFin, and web directory integration
- Documentation: Phase 3 Details
Phase 4 - Federation
- Goal: Share libraries between Velour instances
- Documentation: Phase 4 Details
Phase 5 - Audio Support
- Goal: Add music and audiobook support using extensible MediaFile architecture
- Documentation: Phase 5 Details
Technology Stack
Core Technologies
- Ruby on Rails 8.x - Modern Rails with Solid Queue and Solid Cache
- SQLite3 - Single-user database (PostgreSQL path available)
- Hotwire - Turbo + Stimulus for reactive frontend
- Video.js - HTML5 video player with plugins
- FFmpeg - Video transcoding and metadata extraction
- Active Storage - File management for thumbnails/assets
- TailwindCSS - Utility-first CSS framework
Key Rails 8 Features
- Solid Queue - Background job processing
- ActiveJob 8.1 Continuations - Progress tracking
- Structured Event Reporting - Real-time job updates
- TurboFrame Permanent Attributes - Uninterrupted video playback
Architecture Overview
Video Processing Pipeline
- File Discovery - Automatic scanning of mounted directories
- Metadata Extraction - FFmpeg analysis with xxhash64 deduplication
- Thumbnail Generation - Preview images at 10% mark
- Transcoding - Web-compatible MP4 creation for incompatible formats
- Storage - Files remain in original locations with managed assets
Storage Flexibility
- Local Files - Primary storage, original files untouched
- Heuristic Discovery - Automatic categorization of mounted directories
- Remote Sources (Phase 3) - S3, JellyFin, web directories
- Federation (Phase 4) - Cross-instance sharing
Data Model
Work (canonical content) - has_many -> Videos (different files/qualities)
Video (inherits from MediaFile) - belongs_to -> StorageLocation (where file lives)
Video - has_many -> VideoAssets (thumbnails, previews)
Video - has_many -> PlaybackSessions (user viewing history)
Work - has_many -> ExternalIds (IMDb, TMDb references)
**Extensible Architecture**: MediaFile base class supports future Audio model
MediaFile - common functionality (streaming, processing, metadata)
Video - video-specific functionality (resolution, codecs)
Audio (Phase 5) - audio-specific functionality (bitrate, sample rate, album art)
Key Features
Phase 1 (MVP)
- ✅ Local video library scanning and organization
- ✅ Video streaming with seeking support
- ✅ Automatic transcoding to web-compatible formats
- ✅ Duplicate detection and grouping into "works"
- ✅ Uninterrupted playback with TurboFrame
- ✅ Real-time processing progress with Turbo Streams
Phase 2 (Multi-User)
- ✅ Rails authentication with OIDC extension
- ✅ Admin user bootstrap flow
- ✅ Per-user playback history and preferences
- ✅ Storage location management (admin only)
Phase 3 (Remote Sources)
- ✅ S3 storage location support
- ✅ JellyFin server integration
- ✅ Web directory browsing
- ✅ Video import system with progress tracking
Phase 4 (Federation)
- ✅ Cross-instance API with authentication
- ✅ Remote video streaming
- ✅ Federated library discovery
- ✅ Security and rate limiting
Phase 5 (Audio Support)
- ✅ Audio model inheriting from MediaFile
- ✅ Music library with album/artist organization
- ✅ Audiobook support with chapter tracking
- ✅ Audio processing and transcoding pipeline
Development Phases
Phase 1A: Core Foundation (Week 1-2)
- Models and migrations
- Storage adapter pattern
- File scanning service
- Basic UI
Phase 1B: Video Playback (Week 3)
- Video streaming with byte-range support
- Video.js integration
- Playback session tracking
Phase 1C: Processing Pipeline (Week 4)
- FFmpeg integration
- Background job processing
- Thumbnail generation
Phase 1D: Works & Grouping (Week 5)
- Duplicate detection
- Manual grouping interface
- Search and filtering
Quick Setup
Docker Compose
version: '3.8'
services:
velour:
build: .
ports:
- "3000:3000"
volumes:
- /path/to/movies:/videos/movies:ro
- /path/to/tv:/videos/tv:ro
- ./velour_data:/app/velour_data
environment:
- RAILS_ENV=production
- ADMIN_EMAIL=admin@yourdomain.com
Environment Variables
# Required
RAILS_MASTER_KEY=your_master_key
ADMIN_EMAIL=admin@yourdomain.com
# Video Processing
FFMPEG_PATH=/usr/bin/ffmpeg
VIDEOS_PATH=./velour_data/videos
MAX_TRANSCODE_SIZE_GB=50
# Background jobs (SolidQueue)
SOLID_QUEUE_PROCESSES="*:2" # 2 workers for all queues
# Optional (Phase 2+)
OIDC_ISSUER=https://your-provider.com
OIDC_CLIENT_ID=your_client_id
# Optional (Phase 3+)
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
File Structure
/app
├── app/
│ ├── models/ # ActiveRecord models
│ ├── services/ # Business logic objects
│ ├── jobs/ # Background jobs
│ └── controllers/ # Web controllers
├── lib/
│ └── osmoviehash.rb # Video fingerprinting
├── config/
│ └── routes.rb # Application routes
└── docs/
├── architecture.md # This file
└── phases/ # Detailed phase documentation
├── phase_1.md
├── phase_2.md
├── phase_3.md
└── phase_4.md
Design Decisions
Why Rails + Hotwire?
- Convention over Configuration - Faster development
- Integrated System - Single framework for frontend and backend
- Real-time Capabilities - Turbo Streams for job progress
- Video Focus - Uninterrupted playback with TurboFrame
Why SQLite First?
- Single User Focus - Simpler deployment and maintenance
- Migration Path - Easy upgrade to PostgreSQL if needed
- Performance - Excellent for personal video libraries
Why Separate Transcoding?
- Original Preservation - Never modify source files
- Quality Choice - Users keep original quality when available
- Storage Efficiency - Transcode only when needed
- Browser Compatibility - Web-friendly formats for streaming
Getting Started
-
Clone and setup:
git clone <repository> cd velour bundle install rails db:setup -
Configure storage:
# Edit docker-compose.yml volumes: - /path/to/your/movies:/videos/movies:ro - /path/to/your/tv:/videos/tv:ro -
Start the application:
docker-compose up # or rails server -
Visit http://localhost:3000 and follow the first-user setup
Contributing
When adding features:
- Follow Rails Conventions - Use generators and standard patterns
- Maintain Phase Structure - Add features to appropriate phase
- Test Thoroughly - Include model, service, and system tests
- Update Documentation - Keep architecture docs current
Resources
Next Steps: Start with Phase 1 (MVP) for complete implementation details.