layout, title, titleTemplate, hero, features
layout
title
titleTemplate
hero
features
home
SubMiner
Immersion Mining Workflow for MPV
name
text
tagline
image
actions
SubMiner
Immersion Mining for MPV
Watch, look up a word, and get an Anki card with audio and a screenshot. Without pausing your show.
src
alt
/assets/SubMiner.png
SubMiner logo
theme
text
link
brand
Install
/installation
theme
text
link
alt
Explore workflow
/mining-workflow
icon
title
details
link
linkText
src
alt
/assets/mpv.svg
mpv icon
Built for mpv
Reads subtitle state over mpv's IPC socket. Launch with the wrapper script or the mpv plugin. There is no separate bridge process to run.
/usage
How it works
icon
title
details
link
linkText
src
alt
/assets/yomitan-icon.svg
Yomitan logo
Bundled Yomitan
A Yomitan instance is bundled and preconfigured. Hover a word in the subtitle overlay to look it up and mine it.
/mining-workflow
Mining workflow
icon
title
details
link
linkText
src
alt
/assets/anki-card.svg
Anki card icon
Anki card enrichment
New cards get the subtitle line, an audio clip cut to the line timing, and a screenshot from that moment.
/anki-integration
Anki integration
icon
title
details
link
linkText
src
alt
/assets/highlight.svg
Highlight icon
Reading annotations
N+1 targeting, character-name matching, frequency highlighting, and JLPT tagging, drawn onto the subtitle line as it plays.
/subtitle-annotations
Annotation details
icon
title
details
link
linkText
src
alt
/assets/video.svg
Video playback icon
YouTube playback
Pass a YouTube URL or a ytsearch target. SubMiner picks a subtitle track for the video and loads it.
/usage#youtube-playback
YouTube playback
icon
title
details
link
linkText
src
alt
/assets/jellyfin.svg
Jellyfin icon
Jellyfin integration
Browse your Jellyfin library from the overlay and play a title through mpv. Subtitles and mining work the same as with local files.
/jellyfin-integration
Jellyfin setup
icon
title
details
link
linkText
src
alt
/assets/subtitle-download.svg
Subtitle download icon
Subtitle download and sync
Search Jimaku or TsukiHime and download a track, then retime it with alass or ffsubsync. Both run from the overlay.
/jimaku-integration
Jimaku integration
icon
title
details
link
linkText
src
alt
/assets/tokenization.svg
Tracking chart icon
Stats dashboard
A local dashboard with session history, streak calendars, word frequency, and per-series progress. You can mine cards from lines you already watched.
/immersion-tracking
Dashboard & tracking
icon
title
details
link
linkText
src
alt
/assets/cross-platform.svg
Cross-platform icon
Cross-platform
Runs on Linux (Hyprland, Sway, X11), macOS, and Windows. Overlay positioning is handled per compositor rather than assuming one window manager.
/installation
Platform setup
<script setup>
import { withBase } from 'vitepress';
const demoAssetVersion = '20260819-1';
</script>
How it fits together
01
Start
Launch through the wrapper, or from an mpv setup you already have.
02
Lookup
Hover a token in the overlay to open the Yomitan popup for that word.
03
Mine
Add the word from Yomitan, or mine the whole line as a sentence card.
04
Enrich
SubMiner fills in the audio clip, the sentence, and a screenshot from that moment.
05
Track
Review past sessions and word trends, and mine anything you missed the first time.
See it in action
Recorded from an actual playback session: subtitle hover, lookup, and the card that comes out the other end.
subminer -- playback
<style>
.landing-shell {
max-width: 1120px;
margin: 0 auto;
padding: 0.5rem 1rem 4rem;
}
.landing-shell,
.landing-shell .step-title,
.landing-shell h1,
.landing-shell h2 {
font-family: var(--tui-font-mono);
}
.VPHome :deep(.VPFeature),
.VPHome :deep(.VPButton),
.landing-shell .workflow-step,
.landing-shell .demo-window,
.landing-shell .demo-window__bar {
border-radius: 8px;
}
.step-title,
.step-number {
font-family: var(--tui-font-mono);
letter-spacing: -0.01em;
}
/* === Workflow === */
.workflow-section {
margin: 2.4rem auto 0;
padding: 0;
}
.workflow-section h2,
.demo-section h2 {
font-size: 1.45rem;
font-weight: 600;
letter-spacing: -0.01em;
margin-bottom: 1rem;
padding-bottom: 4px;
}
.workflow-section h2::after,
.demo-section h2::after {
content: '';
display: block;
margin-top: 6px;
height: 1px;
background: repeating-linear-gradient(
to right,
var(--vp-c-divider) 0,
var(--vp-c-divider) 1ch,
transparent 1ch,
transparent 1.5ch
);
}
.workflow-steps {
display: flex;
align-items: stretch;
gap: 0;
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
overflow: hidden;
}
.workflow-step {
flex: 1;
padding: 1.2rem 1.25rem;
background: var(--vp-c-bg-soft);
animation: step-enter 400ms ease-out both;
position: relative;
transition: background 180ms ease;
}
.workflow-step:hover {
background: var(--tui-step-hover-bg);
}
.workflow-step:hover .step-number {
color: var(--vp-c-brand-1);
text-shadow: 0 0 12px var(--tui-step-hover-glow);
}
.workflow-connector {
width: 1px;
background: var(--vp-c-divider);
flex-shrink: 0;
}
.workflow-step .step-number {
display: inline-block;
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.05em;
color: var(--vp-c-text-3);
margin-bottom: 0.5rem;
font-variant-numeric: tabular-nums;
transition: color 180ms ease, text-shadow 180ms ease;
}
.workflow-step .step-number::before {
content: '$ ';
color: var(--vp-c-text-3);
}
.workflow-step .step-title {
font-weight: 600;
font-size: 1rem;
margin-bottom: 0.35rem;
}
.workflow-step .step-desc {
font-size: 0.85rem;
color: var(--vp-c-text-2);
line-height: 1.5;
}
@keyframes step-enter {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width: 960px) {
.workflow-steps {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1px;
background: var(--vp-c-divider);
}
.workflow-step {
min-width: 0;
}
.workflow-step:last-child {
grid-column: 1 / -1;
}
.workflow-connector {
display: none;
}
}
@media (max-width: 640px) {
.workflow-steps {
grid-template-columns: 1fr;
}
.workflow-step:last-child {
grid-column: auto;
}
}
/* === Demo === */
.demo-section {
max-width: 960px;
margin: 3rem auto 0;
padding: 0;
}
.demo-section p {
color: var(--vp-c-text-2);
margin: 0 0 1.2rem;
line-height: 1.6;
}
.demo-window {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
overflow: hidden;
animation: step-enter 400ms ease-out 300ms both;
box-shadow:
0 4px 16px rgba(0, 0, 0, 0.18),
0 20px 48px rgba(0, 0, 0, 0.14);
}
.demo-window__bar {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 12px;
background: var(--vp-c-bg-soft);
border-bottom: 1px solid var(--vp-c-divider);
}
.demo-window__dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
.demo-window__dot:nth-child(1) { background: #ed8796; }
.demo-window__dot:nth-child(2) { background: #eed49f; }
.demo-window__dot:nth-child(3) { background: #a6da95; }
.demo-window__title {
font-family: var(--tui-font-mono);
font-size: 11px;
color: var(--vp-c-text-3);
margin-left: 6px;
}
.demo-window video {
width: 100%;
display: block;
border: none;
border-radius: 0;
box-shadow: none;
margin: 0;
}
</style>