mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-23 00:11:28 -07:00
docs: update docs for youtube subtitle and mining flow
This commit is contained in:
@@ -29,7 +29,8 @@ In both modes, the enrichment workflow is the same:
|
||||
4. Fills the translation field from the secondary subtitle or AI.
|
||||
5. Writes metadata to the miscInfo field.
|
||||
|
||||
Polling mode uses the query `"deck:<your-deck>" added:1` to find recently added cards. If no deck is configured, it searches all decks.
|
||||
Polling mode uses the query `"deck:<ankiConnect.deck>" added:1` to find recently added cards. If no deck is configured, it searches all decks.
|
||||
Known-word sync scope is controlled by `ankiConnect.knownWords.decks` (object map), with `ankiConnect.deck` used as legacy fallback.
|
||||
|
||||
### Proxy Mode Setup (Yomitan / Texthooker)
|
||||
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
|
||||
## v0.8.0 (2026-03-22)
|
||||
- Added a configurable subtitle sidebar feature (`subtitleSidebar`) with overlay/embedded rendering, click-to-seek cue list, and hot-reloadable visibility and behavior controls.
|
||||
- Added release docs updates for sidebar configuration, including options, sample config, and toggle shortcut behavior.
|
||||
- Synced sidebar and overlay subtitle states during playback transitions via IPC-backed snapshot plumbing.
|
||||
- Fixed sidebar cue tracking to remain stable across timing edge cases and stale subtitle refreshes.
|
||||
- Improved sidebar resume/start behavior by jumping directly to the first resolved active cue.
|
||||
- Added a rendered sidebar modal with cue list display, click-to-seek, active-cue highlighting, and embedded layout support.
|
||||
- Added sidebar snapshot plumbing between main and renderer for overlay/sidebar synchronization.
|
||||
- Added sidebar configuration options for visibility and behavior (enabled, layout, toggle key, autoOpen, pauseOnHover, autoScroll) plus typography and sizing controls.
|
||||
- Documented `subtitleSidebar` configuration and behavior in user-facing docs (configuration.md, shortcuts.md, config.example.jsonc).
|
||||
- Updated subtitle prefetch/rendering flow to keep overlay and sidebar state in sync through media transitions.
|
||||
- Kept sidebar cue tracking stable across playback transitions and timing edge cases.
|
||||
- Fixed sidebar startup/resume positioning to jump directly to the first resolved active cue.
|
||||
- Prevented stale subtitle refreshes from regressing active-cue state.
|
||||
|
||||
## v0.7.0 (2026-03-19)
|
||||
- Added a full local immersion dashboard release line with Overview, Library, Trends, Vocabulary, and Sessions drill-down views backed by SQLite tracking data.
|
||||
|
||||
@@ -17,6 +17,11 @@ For most users, start with this minimal configuration:
|
||||
"ankiConnect": {
|
||||
"enabled": true,
|
||||
"deck": "YourDeckName",
|
||||
"knownWords": {
|
||||
"decks": {
|
||||
"YourDeckName": ["Word", "Word Reading", "Expression"]
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"sentence": "Sentence",
|
||||
"audio": "Audio",
|
||||
@@ -26,6 +31,8 @@ For most users, start with this minimal configuration:
|
||||
}
|
||||
```
|
||||
|
||||
`ankiConnect.deck` is still accepted for backward-compatible polling scope and legacy known-word fallback behavior. For known-word cache scope, prefer `ankiConnect.knownWords.decks` with deck-to-fields mapping.
|
||||
|
||||
Then customize as needed using the sections below.
|
||||
|
||||
## Configuration File
|
||||
@@ -348,7 +355,8 @@ Configure the parsed-subtitle sidebar modal.
|
||||
```json
|
||||
{
|
||||
"subtitleSidebar": {
|
||||
"enabled": true,
|
||||
"enabled": false,
|
||||
"autoOpen": false,
|
||||
"layout": "overlay",
|
||||
"toggleKey": "Backslash",
|
||||
"pauseVideoOnHover": false,
|
||||
@@ -362,12 +370,13 @@ Configure the parsed-subtitle sidebar modal.
|
||||
| Option | Values | Description |
|
||||
| --------------------------- | ---------------- | -------------------------------------------------------------------------------- |
|
||||
| `enabled` | boolean | Enable subtitle sidebar support (`false` by default) |
|
||||
| `autoOpen` | boolean | Open sidebar automatically on overlay startup (`false` by default) |
|
||||
| `layout` | string | `"overlay"` floats over mpv; `"embedded"` reserves right-side player space to mimic browser-like layout |
|
||||
| `toggleKey` | string | `KeyboardEvent.code` used to open/close the sidebar (default: `"Backslash"`) |
|
||||
| `pauseVideoOnHover` | boolean | Pause playback while hovering the sidebar cue list |
|
||||
| `autoScroll` | boolean | Keep the active cue in view while playback advances |
|
||||
| `maxWidth` | number | Maximum sidebar width in CSS pixels (default: `420`) |
|
||||
| `opacity` | number | Sidebar opacity between `0` and `1` (default: `0.78`) |
|
||||
| `opacity` | number | Sidebar opacity between `0` and `1` (default: `0.95`) |
|
||||
| `backgroundColor` | string | Sidebar shell background color |
|
||||
| `textColor` | hex color | Default cue text color |
|
||||
| `fontFamily` | string | CSS `font-family` value applied to sidebar cue text |
|
||||
@@ -751,6 +760,8 @@ Anki and YouTube subtitle cleanup both read this provider, then apply feature-lo
|
||||
| `apiKey` | string | Static API key for the shared provider |
|
||||
| `apiKeyCommand` | string | Shell command used to resolve the API key |
|
||||
| `baseUrl` | string (URL) | OpenAI-compatible base URL |
|
||||
| `model` | string | Optional model override for shared provider workflows |
|
||||
| `systemPrompt` | string | Optional system prompt override for shared provider workflows |
|
||||
| `requestTimeoutMs` | integer milliseconds | Shared request timeout (default: `15000`) |
|
||||
|
||||
SubMiner uses the shared provider in two places:
|
||||
@@ -840,8 +851,8 @@ This example is intentionally compact. The option table below documents availabl
|
||||
| `proxy.port` | number | Bind port for local AnkiConnect proxy (default: `8766`) |
|
||||
| `proxy.upstreamUrl` | string (URL) | Upstream AnkiConnect URL that proxy forwards to (default: `http://127.0.0.1:8765`) |
|
||||
| `tags` | array of strings | Tags automatically added to cards mined/updated by SubMiner (default: `['SubMiner']`; set `[]` to disable automatic tagging). |
|
||||
| `deck` | string | Anki deck to monitor for new cards |
|
||||
| `ankiConnect.knownWords.decks` | array of strings | Decks used for known-word cache lookups. When omitted/empty, falls back to `ankiConnect.deck`. |
|
||||
| `ankiConnect.deck` | string | Legacy Anki polling/compatibility scope. Newer known-word cache scoping should use `ankiConnect.knownWords.decks`. |
|
||||
| `ankiConnect.knownWords.decks` | object | Deck→fields mapping for known-word cache queries (for example `{ "Kaishi 1.5k": ["Word", "Word Reading"] }`). |
|
||||
| `fields.word` | string | Card field for mined word / expression text (default: `Expression`) |
|
||||
| `fields.audio` | string | Card field for audio files (default: `ExpressionAudio`) |
|
||||
| `fields.image` | string | Card field for images (default: `Picture`) |
|
||||
@@ -862,6 +873,7 @@ This example is intentionally compact. The option table below documents availabl
|
||||
| `media.animatedMaxWidth` | number (px) | Max width for animated AVIF (default: `640`) |
|
||||
| `media.animatedMaxHeight` | number (px) | Optional max height for animated AVIF. Unset keeps source aspect-constrained height. |
|
||||
| `media.animatedCrf` | number (0-63) | CRF quality for AVIF; lower = higher quality (default: `35`) |
|
||||
| `media.syncAnimatedImageToWordAudio` | `true`, `false` | Whether animated AVIF includes an opening frame synced to sentence word-audio timing (default: `true`). |
|
||||
| `media.audioPadding` | number (seconds) | Padding around audio clip timing (default: `0.5`) |
|
||||
| `media.fallbackDuration` | number (seconds) | Default duration if timing unavailable (default: `3.0`) |
|
||||
| `media.maxMediaDuration` | number (seconds) | Max duration for generated media from multi-line copy (default: `30`, `0` to disable) |
|
||||
@@ -870,10 +882,11 @@ This example is intentionally compact. The option table below documents availabl
|
||||
| `behavior.mediaInsertMode` | `"append"`, `"prepend"` | Where to insert new media when overwrite is off (default: `"append"`) |
|
||||
| `behavior.highlightWord` | `true`, `false` | Highlight the word in sentence context (default: `true`) |
|
||||
| `ankiConnect.knownWords.highlightEnabled` | `true`, `false` | Enable fast local highlighting for words already known in Anki (default: `false`) |
|
||||
| `ankiConnect.knownWords.addMinedWordsImmediately` | `true`, `false` | Add words from successful mines into the local known-word cache immediately (default: `true`) |
|
||||
| `ankiConnect.knownWords.color` | hex color string | Text color for tokens already found in the local known-word cache (default: `"#a6da95"`). |
|
||||
| `ankiConnect.knownWords.matchMode` | `"headword"`, `"surface"` | Matching strategy for known-word highlighting (default: `"headword"`). `headword` uses token headwords; `surface` uses visible subtitle text. |
|
||||
| `ankiConnect.knownWords.refreshMinutes` | number | Minutes between known-word cache refreshes (default: `1440`) |
|
||||
| `ankiConnect.knownWords.decks` | array of strings | Decks used by known-word cache refresh. Leave empty for compatibility with legacy `deck` scope. |
|
||||
| `ankiConnect.knownWords.decks` | object | Deck→fields mapping used for known-word cache query scope (e.g. `{ "Kaishi 1.5k": ["Word", "Word Reading"] }`). |
|
||||
| `ankiConnect.nPlusOne.nPlusOne` | hex color string | Text color for the single target token to study when exactly one unknown candidate exists in a sentence (default: `"#c6a0f6"`). |
|
||||
| `ankiConnect.nPlusOne.minSentenceWords` | number | Minimum number of words required in a sentence before single unknown-word N+1 highlighting can trigger (default: `3`). |
|
||||
| `behavior.notificationType` | `"osd"`, `"system"`, `"both"`, `"none"` | Notification type on card update (default: `"osd"`) |
|
||||
@@ -919,7 +932,7 @@ Known-word cache policy:
|
||||
- `ankiConnect.nPlusOne.nPlusOne` sets the color for the single target token when exactly one eligible unknown word exists.
|
||||
- `ankiConnect.nPlusOne.minSentenceWords` sets the minimum token count required in a sentence for N+1 highlighting (default: `3`).
|
||||
- `ankiConnect.knownWords.color` sets the known-word highlight color for tokens already in Anki.
|
||||
- `ankiConnect.knownWords.decks` accepts one or more decks. If empty, it uses the legacy single `ankiConnect.deck` value as scope.
|
||||
- `ankiConnect.knownWords.decks` accepts an object keyed by deck name. If omitted or empty, it falls back to the legacy `ankiConnect.deck` single-deck scope.
|
||||
- Cache state is persisted to `known-words-cache.json` under the app `userData` directory.
|
||||
- The cache is automatically invalidated when the configured scope changes (for example, when deck changes).
|
||||
- Cache lookups are in-memory. By default, token headwords are matched against cached `Expression` / `Word` values; set `ankiConnect.knownWords.matchMode` to `"surface"` for raw subtitle text matching.
|
||||
@@ -1283,7 +1296,7 @@ Configure the local stats UI served from SubMiner and the in-app stats overlay t
|
||||
{
|
||||
"stats": {
|
||||
"toggleKey": "Backquote",
|
||||
"serverPort": 5175,
|
||||
"serverPort": 6969,
|
||||
"autoStartServer": true,
|
||||
"autoOpenBrowser": true
|
||||
}
|
||||
@@ -1293,7 +1306,7 @@ Configure the local stats UI served from SubMiner and the in-app stats overlay t
|
||||
| Option | Values | Description |
|
||||
| ----------------- | ----------------- | --------------------------------------------------------------------------- |
|
||||
| `toggleKey` | Electron key code | Overlay-local key code used to toggle the stats overlay. Default `Backquote`. |
|
||||
| `serverPort` | integer | Localhost port for the browser stats UI. Default `5175`. |
|
||||
| `serverPort` | integer | Localhost port for the browser stats UI. Default `6969`. |
|
||||
| `autoStartServer` | `true`, `false` | Start the local stats HTTP server automatically once immersion tracking is active. Default `true`. |
|
||||
| `autoOpenBrowser` | `true`, `false` | When `subminer stats` starts the server on demand, also open the dashboard in your default browser. Default `true`. |
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ The same immersion data powers the stats dashboard.
|
||||
- Launcher command: run `subminer stats` to start the local stats server on demand and open the dashboard in your browser.
|
||||
- Background server: run `subminer stats -b` to start or reuse a dedicated background stats daemon without keeping the launcher attached, and `subminer stats -s` to stop that daemon.
|
||||
- Maintenance command: run `subminer stats cleanup` or `subminer stats cleanup -v` to backfill/repair vocabulary metadata (`headword`, `reading`, POS) and purge stale or excluded rows from `imm_words` on demand.
|
||||
- Browser page: open `http://127.0.0.1:5175` directly if the local stats server is already running.
|
||||
- Browser page: open `http://127.0.0.1:6969` directly if the local stats server is already running.
|
||||
|
||||
### Dashboard Tabs
|
||||
|
||||
@@ -68,7 +68,7 @@ Stats server config lives under `stats`:
|
||||
{
|
||||
"stats": {
|
||||
"toggleKey": "Backquote",
|
||||
"serverPort": 5175,
|
||||
"serverPort": 6969,
|
||||
"autoStartServer": true,
|
||||
"autoOpenBrowser": true
|
||||
}
|
||||
|
||||
@@ -6,11 +6,28 @@ This guide walks through the sentence mining loop — from watching a video to c
|
||||
|
||||
SubMiner runs as a transparent overlay on top of mpv. As subtitles play, the overlay displays them as interactive text. You hover a word, trigger Yomitan lookup with your configured lookup key/modifier, then create an Anki card with a single action. SubMiner automatically attaches the sentence, audio clip, and screenshot.
|
||||
|
||||
```text
|
||||
Watch video → See subtitle → Hover word + trigger lookup → Yomitan popup → Add to Anki
|
||||
↓
|
||||
SubMiner auto-fills:
|
||||
sentence, audio, image, translation
|
||||
```mermaid
|
||||
flowchart LR
|
||||
classDef step fill:#c6a0f6,stroke:#494d64,color:#24273a,stroke-width:1.5px
|
||||
classDef action fill:#8aadf4,stroke:#494d64,color:#24273a,stroke-width:1.5px
|
||||
classDef result fill:#a6da95,stroke:#494d64,color:#24273a,stroke-width:1.5px
|
||||
classDef enrich fill:#8bd5ca,stroke:#494d64,color:#24273a,stroke-width:1.5px
|
||||
|
||||
Watch["Watch Video"]:::step
|
||||
Sub["Subtitle Appears"]:::step
|
||||
Hover["Hover Word"]:::action
|
||||
Lookup["Trigger Lookup"]:::action
|
||||
Yomi["Yomitan Popup"]:::result
|
||||
Add["Add to Anki"]:::result
|
||||
|
||||
Watch --> Sub --> Hover --> Lookup --> Yomi --> Add
|
||||
|
||||
Add --> Enrich["SubMiner Enriches"]:::enrich
|
||||
|
||||
Enrich --> S["Sentence"]:::enrich
|
||||
Enrich --> A["Audio Clip"]:::enrich
|
||||
Enrich --> I["Screenshot"]:::enrich
|
||||
Enrich --> T["Translation"]:::enrich
|
||||
```
|
||||
|
||||
## Subtitle Delivery Path (Startup + Runtime)
|
||||
@@ -208,7 +225,7 @@ Enable it in your config:
|
||||
}
|
||||
```
|
||||
|
||||
Open the dashboard in the overlay with `stats.toggleKey` (default: `` ` ``), launch it in a browser with `subminer stats`, keep a dedicated background server alive with `subminer stats -b`, stop that background server with `subminer stats -s`, or visit `http://127.0.0.1:5175` directly if the local stats server is already running. The dashboard covers overview totals, anime progress, session detail, and vocabulary drill-down from the same local immersion database.
|
||||
Open the dashboard in the overlay with `stats.toggleKey` (default: `` ` ``), launch it in a browser with `subminer stats`, keep a dedicated background server alive with `subminer stats -b`, stop that background server with `subminer stats -s`, or visit `http://127.0.0.1:6969` directly if the local stats server is already running. The dashboard covers overview totals, anime progress, session detail, and vocabulary drill-down from the same local immersion database.
|
||||
|
||||
See [Immersion Tracking](/immersion-tracking) for dashboard details, schema, and retention settings.
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB |
BIN
docs-site/public/screenshots/one-key-mining.png
Normal file
BIN
docs-site/public/screenshots/one-key-mining.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 614 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
@@ -24,7 +24,7 @@ N+1 highlighting identifies sentences where you know every word except one, maki
|
||||
| --- | --- | --- |
|
||||
| `ankiConnect.knownWords.highlightEnabled` | `false` | Enable known-word cache lookups used by N+1 highlighting |
|
||||
| `ankiConnect.knownWords.refreshMinutes` | `1440` | Minutes between Anki cache refreshes |
|
||||
| `ankiConnect.knownWords.decks` | `[]` | Decks to query (falls back to `ankiConnect.deck`) |
|
||||
| `ankiConnect.knownWords.decks` | `{}` | Deck→fields map for known-word cache queries (legacy fallback: `ankiConnect.deck`) |
|
||||
| `ankiConnect.knownWords.matchMode` | `"headword"` | `"headword"` (dictionary form) or `"surface"` (raw text) |
|
||||
| `ankiConnect.nPlusOne.minSentenceWords` | `3` | Minimum tokens in a sentence for N+1 to trigger |
|
||||
| `ankiConnect.nPlusOne.nPlusOne` | `#c6a0f6` | Color for the single unknown target word |
|
||||
|
||||
Reference in New Issue
Block a user