5.8 KiB
5.8 KiB
MovieMapper
Desktop application for organizing and managing movie and TV show collections. Scan media directories, extract metadata with FFmpeg, tag files as extras or commentary, and move them into Jellyfin-compatible folder structures — with a full audit trail.
Features
- Directory scanning — non-recursive folder browsing with real-time progress
- Metadata extraction — duration, video quality, and FPS via
ffprobe - File tagging — mark files as
extraorcommentarywith visual state - Jellyfin-compatible moves — tagged files move into spec-compliant folders
(
extras/,commentary/,behind the scenes/, ...) - TheTVDB integration — search shows, browse seasons/episodes, map episodes
to
SxxExxnaming convention - Audit logging — every move/rename writes a
.auditentry in the target directory; nothing happens silently - Progress reporting — IPC-driven progress updates during scans
Architecture
Three implementations share the same core concepts (scanner → metadata → tagging → mapping → audit):
┌─────────────────────────────────────────────────────────────┐
│ MovieMapper │
├──────────────┬──────────────────────────┬───────────────────┤
│ Electron │ Rust core (crate) │ iOS (Swift) │
│ desktop app │ movie_mapper │ companion client │
│ ├──────────────────────────┤ │
│ main.js │ model/ Show, Season, │ SharedModels/ │
│ renderer.js │ Episode │ Swift mirrors │
│ index.html │ service/ │ │
│ utils/ │ FileScanner │ build.sh │
│ │ MetadataExtractor │ archive.sh │
│ Electron │ TVDBClient │ Xcode project │
│ IPC bridge │ FileMapper │ │
│ │ TagManager │ │
│ │ AuditLogger │ │
└──────────────┴──────────────────────────┴───────────────────┘
| Component | Stack | Role |
|---|---|---|
main.js, renderer.js |
Electron (Node 20) | Desktop UI, IPC handlers, filesystem ops |
utils/fileUtils.js |
Node + fluent-ffmpeg | Directory scanning, ffprobe metadata |
Rust/ (crate movie_mapper) |
Rust, tokio, reqwest | Reusable core: scanner, TVDB client, mapper, tags, audit |
backend/ (crate) |
Rust | Async backend integration layer |
ui/ (crate) |
Rust, Iced | Native Rust UI prototype |
SharedModels/ |
Swift | Data models for the iOS companion |
Data flow
directory scan ──▶ ffprobe metadata ──▶ tag (extra/commentary)
│
▼
Jellyfin folder mapping
│
▼
.audit log entry per operation
Project structure
├── main.js # Electron main process (IPC, file ops, TVDB)
├── renderer.js # Renderer process (UI state, events)
├── index.html # UI (dark theme)
├── preload.js # Context bridge
├── utils/fileUtils.js # Directory scan + ffprobe metadata
├── tests/ # vitest suite (118 tests)
│ └── legacy/ # Earlier node:test integration tests
├── Rust/ # Rust core crate (movie_mapper)
│ ├── src/service/ # Scanner, TVDB client, mapper, tags, audit
│ ├── src/model/ # Show, Season, Episode, MediaFile
│ └── tests/ # Unit, integration, e2e, benchmarks
├── backend/ # Rust backend integration crate
├── ui/ # Rust Iced UI prototype
├── SharedModels/ # Swift models (iOS companion)
└── docs/ # Design docs, phase summaries, plans
Getting started
Desktop app (Electron)
Prerequisites: Node.js 20+, npm, ffmpeg/ffprobe on PATH.
npm install
cp .env.example .env # add your TVDB_API_KEY
npm start
Rust core
cargo build --workspace
cargo test --workspace
Tests
npm test # vitest suite (JS)
cargo test --workspace # Rust unit + integration
Configuration
| Variable | Required | Description |
|---|---|---|
TVDB_API_KEY |
for TVDB search | TheTVDB v4 API token |
Jellyfin folder compatibility
Moves target the Jellyfin extras folder specification:
behind the scenes, deleted scenes, interviews, scenes, samples,
shorts, featurettes, clips, other, extras, trailers,
theme-music, backdrops.