259 lines
7.9 KiB
Markdown
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. |