* fix(jellyfin): show overlay, inject plugin, and fix stats title on playb - Show visible overlay automatically during Jellyfin playback so subtitleStyle applies - Inject bundled mpv plugin on auto-launch so keybindings work without overlay focus - Group Jellyfin playback stats under item metadata (jellyfin://host/item/id) instead of stream URLs so episodes merge with matching local titles - Mark ffsubsync unavailable in subsync modal for remote media paths - Drain queued second-instance commands even when onReady throws * fix(overlay): stabilize macOS focus handoff and sidebar Yomitan pause - Keep overlay visible during macOS foreground probe after overlay blur - Hold sidebar hover-pause while a Yomitan lookup popup remains open * fix(jellyfin): fix discovery loop, device identity, tray state, and Disc - Derive device identity from OS hostname; remove legacy configurable client/device fields - Prevent discovery playback from reloading active item, misreporting pause state, and duplicate overlay restores - Restart stale tray discovery sessions without re-login when server drops SubMiner cast target - Sync tray discovery checkbox state on Linux after CLI/startup/remote-session changes - Stop Discord presence falling back to stream URLs; prime title before tokenized stream loads - Fix picker library discovery when log level is above info - Fix config.example.jsonc trailing commas and array formatting * docs(release): trim and consolidate prerelease notes for 0.15.0 - Remove breaking changes section and several redundant bullet points - Consolidate per-platform updater notes into a single entry - Normalize em-dash separators to hyphens in section headers * fix(config): remove trailing commas from config.example.jsonc - Strip trailing commas throughout both config.example.jsonc copies - Reformat inline arrays to multi-line for JSON strictness - Update Jellyfin subtitle preload and playback launch tests and impl * fix(tokenizer): preserve known-word highlight when POS filters suppress - Known-word cache matches now set isKnown=true even for tokens excluded by POS filters - POS exclusion gate suppresses N+1, frequency, and JLPT only; known status is computed before the gate - Jellyfin subtitle preload continues after cleanup failures instead of aborting - Update config docs and option description to document the known-word bypass behavior * fix(jellyfin): send explicit hide/show overlay instead of toggle - Track overlay visibility in plugin state; y-t uses explicit hide/show commands when state is known - Prevent paused Jellyfin playback from resuming on overlay hide - Fix subtitle cache cleanup to only remove dirs after successful cleanup * fix(jellyfin): fix remote progress sync, seek reporting, and startup sto - arm active playback before loadfile with loadedMediaPath: null to suppress premature stop events - force immediate progress report on seek-like position jumps at the mpv time-pos level - send positionTicks and failed=false in reportStopped payload - remove EventName from HTTP timeline payloads (websocket-only field) - add startup grace window to drop stop events before media finishes loading * fix(jellyfin): fix overlay toggle sync, redirect reload, and AppImage bi - Sync visible-overlay state back to plugin via script messages to avoid toggle/hide drift - Collapse duplicate toggle events within 250ms to prevent hide-then-show on single keypress - Preserve manual hide across Jellyfin path-changing redirects even when media-title drops - Rearm managed subtitle defaults on path-changing redirects - Route toggleVisibleOverlay session binding through plugin toggle instead of app-side IPC - Show Linux/Hyprland overlay passively (showInactive) to avoid stealing mpv keyboard focus - Fix AppImage binary resolution to prefer $APPIMAGE env over mounted inner binary - Add stats window layer management so delete/update dialogs appear above stats window - Fix Jellyfin remote progress sync during Linux websocket reconnect windows * Fix CodeRabbit review feedback * fix(jellyfin): subtitle timing, resume progress, and overlay sync - Add per-stream subtitle delay persistence and auto timeline-offset correction - Strip server-selected subtitle stream from mpv load URL; suppress plugin subtitle rearm and auto-start during app-managed preload - Fix resume position lost when mpv resets on stop; use last known position for final progress/stopped reports - Keep Play vs Resume distinct to avoid early seek race on normal play - Fix discovery resume when remote play sends StartPositionTicks=0 despite saved progress - Deduplicate show/hide overlay commands using recorded visibility state - Rewrite docs-site Jellyfin page around cast-to-device UX * test: update lifecycle cleanup assertion * fix: clear aborted playback state, fix overlay passthrough, and guard du - Reset app_managed_playback_pending on lifecycle cleanup to prevent state leak into next item - Record visible overlay action only after command succeeds, not before - Non-native passive overlay now always click-through on re-show (fix isNonNativePassiveOverlay ordering) - Defer activeParsedSubtitleMediaPath assignment until after prefetch completes - Move autoplay gate release into the hide branch of toggleVisibleOverlay - Clear active Jellyfin playback when stopping media that never loaded - Reset managed subtitle delay and delay key when no external tracks are available - Await async removeDir in subtitle cache cleanup - Guard duplicate delete clicks in MediaDetailView and SessionsTab with refs - Escape key in DeleteConfirmDialog now calls stopPropagation and stopImmediatePropagation
SubMiner
Integrates Yomitan and mpv - on-screen lookups, mine to Anki, and track immersion without leaving the player
Features
Dictionary Lookups
Hover over any word and trigger a lookup to get the full Yomitan popup - definitions, pitch accent, and frequency data - without ever leaving mpv.
Instant Anki Mining
Create an Anki card with the sentence, audio clip, screenshot, and machine translation from the exact playback moment with one key press, click, or controller input.
Reading Annotations
Real-time subtitle annotations with frequency highlighting, JLPT tags, N+1 targeting, and a character name dictionary. Grammar-only tokens and particles render as plain text so you focus on what matters.
Immersion Dashboard
Local stats dashboard tracking watch time, vocabulary growth, mining throughput, session history, and trends. All stored locally, no third-party tracking.
Playlist Browser
Browse sibling episode files and the active mpv queue in one overlay modal. Open it with Ctrl+Alt+P to append episodes from the current directory, jump to queued items, remove entries, or reorder the playlist without leaving playback.
Integrations
| YouTube | Auto-loaded yt-dlp subtitle tracks at startup with config-driven primary/secondary language priorities and a manual overlay picker on demand (Ctrl+Alt+C) |
| AniList | Automatic episode tracking and progress sync |
| Jellyfin | Browse, launch, and cast media from your Jellyfin server with setup and discovery controls in the app tray |
| Jimaku | Search and download Japanese subtitles |
| alass / ffsubsync | Manual subtitle retiming — requires alass or ffsubsync on your PATH (optional; subtitle syncing is disabled without them) |
| WebSocket | Plain subtitle feed plus a dedicated annotated feed for texthooker pages and custom tools |
Requirements
Only mpv and Anki+AnkiConnect are required. Everything else is optional but enhances the experience.
| Dependency | Status | What it does |
|---|---|---|
| mpv | Required | The video player SubMiner overlays on |
| Anki + AnkiConnect | Required | Card creation from the Yomitan popup |
| ffmpeg | Recommended | Audio clips & screenshots for Anki cards |
| MeCab + mecab-ipadic | Recommended | More precise annotations and filtering |
| yt-dlp | Optional | YouTube playback |
| fzf / rofi | Optional | Video picker in the launcher |
| alass / ffsubsync | Optional | Subtitle sync |
Platform-specific install commands
Arch Linux:
sudo pacman -S --needed mpv ffmpeg mecab mecab-ipadic
macOS:
brew install mpv ffmpeg mecab mecab-ipadic
Windows: Install mpv and ffmpeg and ensure both are on PATH.
See the full requirements list for optional dependencies.
Quick Start
1. Install SubMiner
Arch Linux (AUR)
paru -S subminer-bin
Linux (AppImage)
mkdir -p ~/.local/bin
wget https://github.com/ksyasuda/SubMiner/releases/latest/download/SubMiner.AppImage -O ~/.local/bin/SubMiner.AppImage \
&& chmod +x ~/.local/bin/SubMiner.AppImage
wget https://github.com/ksyasuda/SubMiner/releases/latest/download/subminer -O ~/.local/bin/subminer \
&& chmod +x ~/.local/bin/subminer
macOS (DMG)
Download the latest DMG from GitHub Releases and drag SubMiner.app into /Applications.
Windows
Download and run the latest installer (.exe) from GitHub Releases.
From source
See the build-from-source guide.
2. Launch & Set Up
Run SubMiner and the first-run setup wizard will guide you through importing Yomitan dictionaries and optionally installing the subminer command-line launcher.
# Linux
subminer app --setup
# macOS — open SubMiner.app, or:
subminer app --setup
On Windows, just run SubMiner.exe and the setup will open automatically on first launch.
3. Mine
subminer video.mkv # launch mpv with SubMiner
subminer /path/to/dir # pick a file with fzf
subminer -R /path/to/dir # pick a file with rofi (Linux only)
On Windows, use the SubMiner mpv shortcut created during setup. Double-click it or drag a video file onto it.
Documentation
Full guides on configuration, Anki setup, Jellyfin, immersion tracking, and more: docs.subminer.moe
Acknowledgments
SubMiner builds on the work of these open-source projects:
| Project | Role |
|---|---|
| Anacreon-Script | Inspiration for the mining workflow |
| asbplayer | Inspiration for subtitle sidebar and logic for YouTube subtitle parsing |
| Bee's Character Dictionary | Character name recognition in subtitles |
| GameSentenceMiner | Inspiration for Electron overlay with Yomitan integration |
| jellyfin-mpv-shim | Jellyfin integration |
| Jimaku.cc | Japanese subtitle search and downloads |
| Renji's Texthooker Page | Base for the WebSocket texthooker integration |
| Yomitan | Dictionary engine powering all lookups and the morphological parser |
| yomitan-jlpt-vocab | JLPT level tags for vocabulary |






