# 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](./phases/phase_1.md) ### Phase 2 - Authentication & Multi-User - **Goal**: User management and per-user playback history - **Documentation**: [Phase 2 Details](./phases/phase_2.md) ### Phase 3 - Remote Sources & Import - **Goal**: S3, JellyFin, and web directory integration - **Documentation**: [Phase 3 Details](./phases/phase_3.md) ### Phase 4 - Federation - **Goal**: Share libraries between Velour instances - **Documentation**: [Phase 4 Details](./phases/phase_4.md) ### Phase 5 - Audio Support - **Goal**: Add music and audiobook support using extensible MediaFile architecture - **Documentation**: [Phase 5 Details](./phases/phase_5.md) ## 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 1. **File Discovery** - Automatic scanning of mounted directories 2. **Metadata Extraction** - FFmpeg analysis with xxhash64 deduplication 3. **Thumbnail Generation** - Preview images at 10% mark 4. **Transcoding** - Web-compatible MP4 creation for incompatible formats 5. **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 ```ruby 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 ```yaml 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 ```bash # 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 1. **Clone and setup**: ```bash git clone cd velour bundle install rails db:setup ``` 2. **Configure storage**: ```bash # Edit docker-compose.yml volumes: - /path/to/your/movies:/videos/movies:ro - /path/to/your/tv:/videos/tv:ro ``` 3. **Start the application**: ```bash docker-compose up # or rails server ``` 4. **Visit http://localhost:3000** and follow the first-user setup ## Contributing When adding features: 1. **Follow Rails Conventions** - Use generators and standard patterns 2. **Maintain Phase Structure** - Add features to appropriate phase 3. **Test Thoroughly** - Include model, service, and system tests 4. **Update Documentation** - Keep architecture docs current ## Resources - [Rails Guides](https://guides.rubyonrails.org/) - [Hotwire Documentation](https://hotwired.dev/) - [Video.js Documentation](https://videojs.com/) - [FFmpeg Documentation](https://ffmpeg.org/ffmpeg.html) --- **Next Steps**: Start with [Phase 1 (MVP)](./phases/phase_1.md) for complete implementation details.