Files
velour/docs/architecture.md
Dan Milne 88a906064f
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
Much base work started
2025-10-31 14:36:14 +11:00

259 lines
7.9 KiB
Markdown

# 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 <repository>
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.