Overview
Backend Architecture (Rust)
The Rust backend handles all media processing, process management, and system integration.Core Modules
Located insrc-tauri/src/conversion/, the backend is organized into specialized modules:
| Module | File | Responsibility |
|---|---|---|
| Manager | manager.rs | Async task queue, concurrency control, process lifecycle |
| Worker | worker.rs | FFmpeg process execution, progress parsing |
| Probe | probe.rs | Media metadata extraction via FFprobe |
| Upscale | upscale.rs | AI upscaling pipeline (frame extraction → upscale → encode) |
| Args | args.rs | FFmpeg argument construction |
| Codec | codec.rs | Video/audio codec configuration |
| Filters | filters.rs | Video/audio filter chain building |
| Types | types.rs | Shared data structures |
| Commands | commands.rs | Tauri command handlers (IPC entry points) |
Conversion Manager
TheConversionManager (manager.rs:35-199) is the core orchestrator:
- Async Task Queue: Uses
tokio::mpsc::channelfor message passing (manager.rs:44) - Concurrency Control: Limits concurrent FFmpeg processes (default: 2) via
AtomicUsize(manager.rs:46) - Process Management: Tracks PIDs for pause/resume/cancel operations (
manager.rs:38) - Cross-Platform Signals:
- Unix:
SIGSTOP/SIGCONT/SIGKILLvia libc (manager.rs:273-314) - Windows:
NtSuspendProcess/NtResumeProcessvia Win32 API (manager.rs:374-410)
- Unix:
Message Flow
Reference:manager.rs:53-191
FFmpeg Worker
The worker (worker.rs) executes FFmpeg as a Tauri sidecar process:
- Build FFmpeg arguments from
ConversionConfig(worker.rs:26-32) - Spawn FFmpeg sidecar via
tauri-plugin-shell(worker.rs:34-42) - Parse stderr for progress (
worker.rs:88-136):- Extract current time via regex:
time=(\d{2}:\d{2}:\d{2}\.\d{2})(utils.rs) - Calculate percentage:
(current_time / total_duration) * 100
- Extract current time via regex:
- Emit IPC events to frontend (
worker.rs:50, 127)
worker.rs:15-158
Probe Module
Media metadata extraction via FFprobe (probe.rs:8-133):
- Spawn FFprobe with JSON output:
-print_format json -show_format -show_streams(probe.rs:12-20) - Parse JSON into
FfprobeOutputstruct viaserde_json(probe.rs:37) - Extract metadata:
- Video: codec, resolution, frame rate, bitrate (
probe.rs:49-73) - Audio: tracks, channels, sample rate, language (
probe.rs:75-97) - Subtitles: codec, language, labels (
probe.rs:99-113)
- Video: codec, resolution, frame rate, bitrate (
probe.rs:8-133
AI Upscaling Pipeline
The upscale worker (upscale.rs) implements a multi-stage pipeline:
Stage 1: Frame Extraction (upscale.rs:311-430)
- Decode video to PNG sequence via FFmpeg
- Apply pre-upscale filters (crop, deinterlace, etc.)
- Output to temp directory:
$TEMP/frame_upscale_{id}/input/frame_%08d.png
upscale.rs:456-556)
- Spawn
realesrgan-ncnn-vulkansidecar - Models:
realesr-animevideov3-x2(2x) orx4(4x) - Thread config:
load:process:savebased on resolution (upscale.rs:148-171) - Parse stderr for frame completion:
→or->indicators (upscale.rs:525-543)
upscale.rs:558-636)
- Encode upscaled PNG sequence back to video
- Mux with original audio/subtitle tracks from source file
- Apply post-upscale video codec settings
upscale.rs:238-636
Sidecar Execution Model
Frame bundles FFmpeg, FFprobe, and Real-ESRGAN as Tauri sidecars:- Binary Resolution: Tauri resolves platform-specific binaries from
src-tauri/binaries/ - Spawn:
app.shell().sidecar("ffmpeg")launches subprocess (worker.rs:34-38) - IPC: Communicate via stdin/stdout/stderr (
CommandEvent::Stderr) - Lifecycle: Track PID for pause/resume/kill operations
src-tauri/tauri.conf.json:
Frontend Architecture (SvelteKit)
The frontend is built with Svelte 5 (Runes API) and SvelteKit as the meta-framework.Directory Structure
State Management
Frame uses Svelte 5 Runes for reactive state:$state: Mutable reactive state$derived: Computed values (like Svelte 4’s$:)$effect: Side effects (replaces lifecycle hooks)$props: Component props
IPC Communication
Frontend communicates with Rust backend via Tauri commands and events: Commands (frontend → backend):src-tauri/src/lib.rs:156-168 for command registration
Concurrent Processing Design
Task Queue System
Frame implements a bounded concurrency queue:- Default: 2 concurrent FFmpeg processes
- User-adjustable:
set_max_concurrency(value)command - Reason: FFmpeg is CPU/GPU intensive; too many concurrent processes cause thrashing
manager.rs:201-246, types.rs:71 (DEFAULT_MAX_CONCURRENCY)
Async Runtime
Frame uses Tokio as the async runtime:tokio::sync::mpsc: Message passing between manager and workerstokio::spawn: Spawn async taskstauri::async_runtime::spawn: Tauri’s wrapper for spawning tasks
manager.rs:53-191
Dependencies
Rust (Backend)
| Crate | Version | Purpose |
|---|---|---|
tauri | 2.9.5 | Application framework |
tauri-plugin-shell | 2.3.4 | Sidecar process execution |
tauri-plugin-dialog | 2.6.0 | Native file dialogs |
tauri-plugin-fs | 2.4.5 | Filesystem operations |
tauri-plugin-store | 2.3.0 | Persistent key-value storage |
tokio | 1.49.0 | Async runtime |
serde / serde_json | 1.0 | Serialization |
regex | 1.12.2 | FFmpeg output parsing |
thiserror | 2.0.18 | Error handling |
src-tauri/Cargo.toml
Frontend (TypeScript/Svelte)
| Package | Version | Purpose |
|---|---|---|
@sveltejs/kit | 2.50.0 | Meta-framework |
svelte | 5.47.1 | UI framework (Runes) |
@tauri-apps/api | 2.9.1 | Tauri IPC bindings |
tailwindcss | 4.1.18 | CSS framework |
svelte-i18n | 4.0.1 | Internationalization |
typescript | 5.9.3 | Type safety |
package.json
Platform-Specific Code
Frame includes platform-specific implementations:Window Effects
Process Control
- Unix:
libc::kill(pid, SIGSTOP/SIGCONT/SIGKILL)(manager.rs:273-314) - Windows:
NtSuspendProcess/NtResumeProcessviantdll.dll(manager.rs:374-410)
src-tauri/src/lib.rs:27-52, manager.rs:266-372
Performance Optimizations
Release Build Profile
Regex Compilation
FFmpeg output parsing uses precompiled regexes viaonce_cell:
src-tauri/src/conversion/utils.rs
Next Steps
Building from Source
Set up your development environment
Contributing
Learn the contribution workflow