Development Guide
This guide covers everything you need to start contributing code to Media Sort. For an overview of how the codebase is organized, see the Architecture Overview page.
Prerequisites
Section titled “Prerequisites”- Rust 1.96 or later (install via rustup)
- Clang (required by
libmpv-sysfor FFI bindings) - libmpv development files:
- Linux:
libmpv-dev(Debian/Ubuntu) or equivalent - macOS:
brew install mpv - Windows: vcpkg or manual installation
- Linux:
- Platform libraries (Linux):
libasound2-dev(ALSA for audio)libx11-dev,libwayland-dev(window system)- Vulkan drivers and loader
Building
Section titled “Building”# Build the entire workspacecargo build --workspace
# Build only the GUI binarycargo build -p media-sort-gui
# Release buildcargo build --workspace --releaseRunning
Section titled “Running”# Run the GUI (opens your system Pictures directory by default)cargo run -p media-sort-gui
# Open a specific directorycargo run -p media-sort-gui -- /path/to/media
# Run with interactive demo modecargo run -p media-sort-gui -- --demoTesting
Section titled “Testing”# Run all testscargo test --workspace
# Run tests for a specific cratecargo test -p media-sort-corecargo test -p media-sort-backendcargo test -p media-sort-guiTests live in:
crates/media-sort-core/tests/: integration testscrates/media-sort-backend/tests/: integration tests (with test fixtures intests/fixtures/)crates/media-sort-gui/src/:#[cfg(test)]unit tests
Code Style
Section titled “Code Style”Before committing, run formatter and linter:
# Format all codecargo fmt --all --
# Run clippy with warnings as errorscargo clippy --workspace --all-targets -- -D warningsPre-commit hooks enforce these automatically. If clippy fails, the commit is rejected.
Internationalization
Section titled “Internationalization”User-facing strings live in Fluent (.ftl) files:
resources/locale/├── en/main.ftl├── de/main.ftl└── ja/main.ftlWhen you add a new user-facing string in the code, you must add the corresponding entry to all three locale files. The English file serves as the source of truth.
The build script (crates/media-sort-core/build.rs) automatically detects changes to locale files and regenerates the lookup code.
Working with Settings
Section titled “Working with Settings”Settings are defined in crates/media-sort-core/src/settings/. To add a new persisted setting:
- Add the field to the appropriate sub-struct (e.g.,
GeneralSettings) - Add
#[serde(default)]so old configs remain loadable - If the setting has a UI toggle, update the settings dialog view
- Call
state.settings.save()after mutation - Update the documentation in
website/(bothsettings.mdxandconfig-file.mdx)
Video Playback Pipeline
Section titled “Video Playback Pipeline”Video playback involves several layers:
- Startup:
main.rsqueries mpv for supported formats and initializes theMediaRegistry - Subscription: A
VideoWorkerthread runs an mpv event loop - Communication: GUI sends
VideoCommandvia channel; worker responds withVideoEvent - Rendering: Frame data arrives as RGBA pixels, rendered via custom wgpu shader for zero-copy Vulkan interop
- Lifecycle:
Deactivatestops rendering when navigating away from a video
See crates/media-sort-backend/src/media/mpv_context.rs for the video worker implementation and crates/media-sort-gui/src/widgets/video_shader.rs for the GPU shader.
Demo System
Section titled “Demo System”Media Sort includes a headless automation engine used to generate demo videos for the documentation website:
# Render all demo flows to MP4 videoscd website && npm run render-demosDemo flow specifications are JSON files in resources/demo_flows/. The automation engine (crates/iced-automation/) runs the full application headlessly (no window) and captures frames via the rendering pipeline.
Documentation
Section titled “Documentation”The website at mediasort.app is an Astro/Starlight project in the website/ directory:
cd websitenpm cinpm run dev # Start dev servernpm run render-demos # Render demo videosnpm run build # Production buildDocumentation pages live in website/src/content/docs/ with one subdirectory per locale (en/, de/, ja/). The sidebar is configured in astro.config.mjs.
Environment Variables
Section titled “Environment Variables”| Variable | Purpose |
|---|---|
UI_TEST |
Switches config path to ui_test_config.toml in the current directory |
LANG / LC_ALL |
Override locale detection (used during demo video rendering) |