Tech Stack
Core Technologies
- Go 1.25: High-performance compiled language
- FFmpeg: Video transcoding engine
- anacrolix/torrent: BitTorrent client library
- Standard library: HTTP server and routing
Key Dependencies
Fromraffi-server/go.mod:5-87:
Architecture Overview
Server Core
Main Server
Location:main.go:26-114
- Session Store: In-memory session management
- Torrent Streamer: BitTorrent client for magnet links
- HLS Controller: FFmpeg-based transcoding pipeline
- Probe Cooldown: Rate limiting for metadata probing
- Cast Tokens: Authentication for Chromecast LAN access
Server Initialization
Location:main.go:36-113
Cleanup & Lifecycle
Location:main.go:47-88
HTTP API
Session Management
Create Session
Location:main.go:143-194
http: Direct HTTP(S) URLtorrent: Magnet link or torrent file
Get Session Info
Location:main.go:251-362
- FFprobe extracts duration, chapters, audio tracks
- Cooldown mechanism prevents excessive probing
- Retry logic with exponential backoff
- Torrent-specific handling for incomplete downloads
Stream Session
Location:main.go:364-531
seek: Start time in secondsseek_id: Seek operation ID for deduplicationforce_slice: Force new slice creation
X-Raffi-Slice-Start: Actual slice start time
Torrent Streaming
Location:src/stream/torrent.go
Torrent Streamer
- Add Torrent: Parse magnet/file, select file to stream
- Prioritize Pieces: Download sequentially from start
- Serve HTTP: Expose torrent file as HTTP endpoint
- Status Reporting: Track download progress
Torrent Flow
HLS Transcoding
Location:src/stream/hls/
HLS Controller
FFmpeg Pipeline
Transcoding Command:-ss: Seek to start time-map 0:v:0: Select first video stream-map 0:a:<audioIndex>: Select audio track-c:v libx264: H.264 video codec-preset veryfast: Fast encoding-crf 23: Quality level (lower = better)-c:a aac: AAC audio codec-hls_time 10: 10-second segments
Slice Management
Why Slices?- Seeking without restarting FFmpeg
- Memory efficient for long videos
- Progressive cleanup of old segments
- Create slice on seek or initial playback
- FFmpeg transcodes to temp directory
- Serve segments as they’re created
- Track served segments
- Cleanup when new slice starts
Metadata Probing
FFprobe Command:- Duration
- Audio streams (codec, language, title)
- Video streams
- Chapters with timestamps
Audio Track Switching
Location:main.go:116-141
- Stop current FFmpeg process
- Create new slice with different audio map
- Restart transcoding
- Client detects new slice via
X-Raffi-Slice-Startheader
Cleanup
Location:main.go:628-663
- Stop HLS transcoding (kill FFmpeg)
- Remove torrent if torrent session
- Delete session from store
- Remove temporary files
Security
CORS Configuration
Location:main.go:607-626
LAN Guard
Cast Token System:- When server binds to non-loopback (0.0.0.0), enables LAN mode
- Requires
cast_tokenfor external requests - Tokens generated with expiration
- Desktop app requests token before casting
Performance Optimizations
Concurrency
- Goroutines: Each session can transcode concurrently
- Mutex Protection: Read/write locks for shared state
- Channel-based Cleanup: Background worker goroutines
Memory Management
- Streaming: Files are streamed, not loaded into memory
- Segment Cleanup: Old HLS segments deleted after serving
- Torrent Pieces: Only download what’s needed
Caching
- Metadata Probe: Results cached in session
- Cooldown: Prevents repeated probing
- Torrent Status: Cached and updated periodically
Deployment
Bundled with Desktop
The server is compiled as a standalone binary and bundled with the desktop app: Build Script (raffi-desktop/build_binary.cjs):decoder-x86_64-unknown-linux-gnudecoder-aarch64-apple-darwindecoder-x86_64-apple-darwindecoder-windows-amd64.exe
Standalone Deployment
Can run independently for mobile clients:RAFFI_SERVER_ADDR: Listen address (default:127.0.0.1:6969)RAFFI_CAST_HOST: Override cast host for NAT scenarios
Error Handling
Graceful Degradation
- Metadata Probe Failure: Return session without metadata
- FFmpeg Crash: Log error, allow retry
- Torrent Timeout: Progressive timeout with status reporting
Logging
Structured logging throughout:Key Design Decisions
Why Go?
- Performance: Compiled language, fast startup
- Concurrency: Goroutines for parallel transcoding
- Single Binary: No runtime dependencies
- Cross-compilation: Easy multi-platform builds
Why HLS Over Direct Streaming?
- Seeking: Restart transcoding from any position
- Quality Control: Consistent output quality
- Compatibility: Universal client support
- Bandwidth: Adaptive streaming possible
Why FFmpeg?
- Format Support: Handles any video format
- Quality: Industry-standard transcoding
- Subtitle Burning: Can embed subtitles
- Audio Selection: Easy track switching
Why In-Memory Sessions?
- Simplicity: No database required
- Performance: Fast lookups
- Temporary: Sessions are transient
- Restart Safe: No stale state on crash
Monitoring
Health Checks
Desktop app performs health checks:Metrics
Current implementation logs:- Session creation/cleanup
- Seek operations
- Torrent download progress
- FFmpeg errors