diff --git a/README.md b/README.md index 3533246..e824dae 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ Local stats dashboard — watch time, anime library, vocabulary growth, mining t
| YouTube | -App-owned subtitle picker with downloaded/native track selection and local fallback generation | +Auto-loaded yt-dlp subtitle tracks with manual retry picker on demand |
| AniList | diff --git a/changes/2026-03-23-youtube-autoload-manual-picker.md b/changes/2026-03-23-youtube-autoload-manual-picker.md index 0597f99..2cd9435 100644 --- a/changes/2026-03-23-youtube-autoload-manual-picker.md +++ b/changes/2026-03-23-youtube-autoload-manual-picker.md @@ -3,7 +3,8 @@ area: launcher - Changed app-owned YouTube playback to auto-load the default primary subtitle and a best-effort secondary subtitle at startup instead of forcing the picker modal first. - Kept startup playback gating tied only to primary subtitle load and tokenization readiness; secondary failures no longer block resume. -- Added a default `Ctrl+Shift+J` keybinding that opens the YouTube subtitle picker manually during active YouTube playback. +- Added a default `Ctrl+Alt+C` keybinding that opens the YouTube subtitle picker manually during active YouTube playback. - Routed primary YouTube subtitle auto-load failures through the configured notification output path so failed startup still resumes cleanly. +- Kept `youtubeSubgen.whisper*` settings as legacy compatibility configuration only; normal startup now resolves tracks through YouTube source download/selection. - Fixed startup-launched YouTube playback so primary subtitle overlay updates continue after auto-load completes. - Fixed auto-loaded YouTube primary subtitles so parsed cues appear in the subtitle sidebar without needing a manual picker retry. diff --git a/config.example.jsonc b/config.example.jsonc index ab7af4a..b94e0c2 100644 --- a/config.example.jsonc +++ b/config.example.jsonc @@ -187,7 +187,7 @@ // ========================================== // Secondary Subtitles // Dual subtitle track options. - // Used by subminer YouTube subtitle generation as secondary language preferences. + // Used by the YouTube subtitle loading flow as secondary language preferences. // Hot-reload: defaultMode updates live while SubMiner is running. // ========================================== "secondarySub": { @@ -414,24 +414,24 @@ }, // Jimaku API configuration and defaults. // ========================================== - // YouTube Subtitle Generation - // Defaults for SubMiner YouTube subtitle generation. + // YouTube Playback Settings + // Defaults for SubMiner YouTube subtitle loading and languages. // ========================================== "youtubeSubgen": { - "whisperBin": "", // Path to whisper.cpp CLI used as fallback transcription engine. - "whisperModel": "", // Path to whisper model used for fallback transcription. - "whisperVadModel": "", // Path to optional whisper VAD model used for subtitle generation. - "whisperThreads": 4, // Thread count passed to whisper.cpp subtitle generation runs. - "fixWithAi": false, // Use shared AI provider to post-process whisper-generated YouTube subtitles. Values: true | false + "whisperBin": "", // Legacy compatibility path kept for external subtitle fallback tools; not used by default. + "whisperModel": "", // Legacy compatibility model path kept for external subtitle fallback tooling; not used by default. + "whisperVadModel": "", // Legacy compatibility VAD path kept for external subtitle fallback tooling; not used by default. + "whisperThreads": 4, // Legacy thread tuning for subtitle fallback tooling; not used by default. + "fixWithAi": false, // Legacy subtitle fallback post-processing switch kept for compatibility; use is currently disabled by default. Values: true | false "ai": { - "model": "", // Optional model override for YouTube subtitle AI post-processing. - "systemPrompt": "" // Optional system prompt override for YouTube subtitle AI post-processing. + "model": "", // Optional model override for legacy subtitle fallback post-processing; not used by default. + "systemPrompt": "" // Optional system prompt override for legacy subtitle fallback post-processing; not used by default. }, // Ai setting. "primarySubLanguages": [ "ja", "jpn" ] // Comma-separated primary subtitle language priority used by the launcher. - }, // Defaults for SubMiner YouTube subtitle generation. + }, // Defaults for SubMiner YouTube subtitle loading and languages. // ========================================== // Anilist diff --git a/docs-site/changelog.md b/docs-site/changelog.md index 6b05b2e..0eac350 100644 --- a/docs-site/changelog.md +++ b/docs-site/changelog.md @@ -2,9 +2,9 @@ ## v0.9.0 (2026-03-22) - Added an app-owned YouTube subtitle flow that boots mpv paused, auto-loads the default primary subtitle plus a best-effort secondary subtitle, and resumes once the primary subtitle is loaded and tokenized. -- Added a manual YouTube subtitle picker on `Ctrl+Shift+J` so subtitle selection can be retried on demand during active YouTube playback. -- Added explicit launcher/app YouTube subtitle modes `download` and `generate`, with `download` as the default path. -- Disabled mpv native YouTube subtitle auto-loading for the app-owned flow so injected external subtitle files stay authoritative. +- Added a manual YouTube subtitle picker on `Ctrl+Alt+C` so subtitle selection can be retried on demand during active YouTube playback. +- Standardized on the default YouTube subtitle auto-load startup flow and removed explicit subtitle mode switching. +- Disabled conflicting mpv native subtitle auto-selection for the app-owned flow so injected explicit tracks stay authoritative. - Added OSD status updates covering YouTube playback startup, subtitle acquisition, and subtitle loading. - Improved sidebar startup/resume behavior and overlay/sidebar subtitle synchronization. diff --git a/docs-site/configuration.md b/docs-site/configuration.md index 95aa4d8..4b26898 100644 --- a/docs-site/configuration.md +++ b/docs-site/configuration.md @@ -127,7 +127,7 @@ The configuration file includes several main sections: - [**Discord Rich Presence**](#discord-rich-presence) - Optional Discord activity card updates - [**Immersion Tracking**](#immersion-tracking) - Track subtitle sessions and mining activity in SQLite - [**Stats Dashboard**](#stats-dashboard) - Local dashboard and overlay for immersion progress -- [**YouTube Subtitle Generation**](#youtube-subtitle-generation) - Launcher defaults for yt-dlp + local whisper fallback +- [**YouTube Playback Settings**](#youtube-playback-settings) - Defaults for YouTube subtitle loading ## Core Settings @@ -469,7 +469,7 @@ See `config.example.jsonc` for detailed configuration options and more examples. | `Space` | `["cycle", "pause"]` | Toggle pause | | `KeyJ` | `["cycle", "sid"]` | Cycle primary subtitle track | | `Shift+KeyJ` | `["cycle", "secondary-sid"]` | Cycle secondary subtitle track | -| `Ctrl+Shift+KeyJ` | `["__youtube-picker-open"]` | Open the manual YouTube subtitle picker | +| `Ctrl+Alt+KeyC` | `["__youtube-picker-open"]` | Open the manual YouTube subtitle picker | | `ArrowRight` | `["seek", 5]` | Seek forward 5 seconds | | `ArrowLeft` | `["seek", -5]` | Seek backward 5 seconds | | `ArrowUp` | `["seek", 60]` | Seek forward 60 seconds | @@ -741,7 +741,7 @@ Palette controls: ### Shared AI Provider Shared OpenAI-compatible transport settings live at the top level under `ai`. -Anki and YouTube subtitle cleanup both read this provider, then apply feature-local overrides where supported. +Anki reads this provider directly. Legacy subtitle fallback keeps the same provider shape for compatibility, then applies feature-local overrides where supported. ```json { @@ -765,10 +765,10 @@ Anki and YouTube subtitle cleanup both read this provider, then apply feature-lo | `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: +SubMiner uses the shared provider for: - Anki translation/enrichment when `ankiConnect.ai.enabled` is `true` -- YouTube whisper subtitle post-processing when `youtubeSubgen.fixWithAi` is `true` +- Legacy subtitle fallback compatibility when `youtubeSubgen.fixWithAi` is `true` ### AnkiConnect @@ -1326,22 +1326,13 @@ Usage notes: - The dashboard reads from the same immersion-tracking database, so keep `immersionTracking.enabled` on if you want data to appear. - The UI includes Overview, Library, Trends, Vocabulary, and Sessions tabs. -### YouTube Subtitle Generation +### YouTube Playback Settings -Set defaults used by the `subminer` launcher for YouTube subtitle generation: +Set defaults used by the `subminer` launcher for YouTube subtitle loading: ```json { "youtubeSubgen": { - "whisperBin": "/path/to/whisper-cli", - "whisperModel": "/path/to/ggml-model.bin", - "whisperVadModel": "/path/to/ggml-vad.bin", - "whisperThreads": 4, - "fixWithAi": false, - "ai": { - "model": "openai/gpt-4o-mini", - "systemPrompt": "Fix subtitle mistakes only." - }, "primarySubLanguages": ["ja", "jpn"] } } @@ -1349,28 +1340,20 @@ Set defaults used by the `subminer` launcher for YouTube subtitle generation: | Option | Values | Description | | --------------------- | -------------------- | ---------------------------------------------------------------------------------------------- | -| `whisperBin` | string path | Path to `whisper.cpp` CLI binary used as fallback transcription engine | -| `whisperModel` | string path | Path to whisper model used by fallback transcription | -| `whisperVadModel` | string path | Optional whisper VAD model path | -| `whisperThreads` | integer | Thread count passed to whisper runs | -| `fixWithAi` | `true`, `false` | Run shared AI post-processing on whisper-generated subtitles | -| `ai.model` | string | Optional model override for YouTube AI subtitle cleanup | -| `ai.systemPrompt` | string | Optional system prompt override for YouTube AI subtitle cleanup | -| `primarySubLanguages` | string[] | Primary subtitle language priority for YouTube subtitle generation (default `["ja", "jpn"]`) | +| `primarySubLanguages` | string[] | Primary subtitle language priority for YouTube auto-loading (default `["ja", "jpn"]`) | -Launcher behavior: +Current launcher behavior: -- For YouTube URLs, SubMiner auto-loads the default primary subtitle plus a best-effort secondary subtitle during startup. -- SubMiner probes manual/native YouTube subtitle tracks first. -- Missing tracks fall back to local `whisper.cpp`. -- Playback waits only for the primary subtitle to load and tokenize; startup secondary failures never block playback. -- English secondary subtitles can use whisper translate fallback when no manual track exists. -- If `fixWithAi` is enabled, only whisper-generated `.srt` output is post-processed with the shared top-level `ai` provider. +- For YouTube URLs, SubMiner probes subtitle tracks with yt-dlp and loads auto-selected tracks before regular playback starts. +- SubMiner loads the primary subtitle plus a best-effort secondary subtitle. +- Playback waits only for primary subtitle readiness; secondary failures do not block playback. +- English secondary subtitles are selected from `secondarySub.secondarySubLanguages` when primary language matches are unavailable. +- If primary subtitle loading fails, use `Ctrl+Alt+C` to open the subtitle modal and pick a track. Language targets are derived from subtitle config: - primary track: `youtubeSubgen.primarySubLanguages` (falls back to `["ja","jpn"]`) - secondary track: `secondarySub.secondarySubLanguages` (falls back to English when empty) -- Subtitle files are generated or downloaded before mpv starts; the older launcher mode switch has been removed. +- Tracks are resolved and loaded before mpv starts; the older launcher mode switch has been removed. Precedence for launcher defaults is: CLI flag > environment variable > `config.jsonc` > built-in default. diff --git a/docs-site/development.md b/docs-site/development.md index 435b239..62c78be 100644 --- a/docs-site/development.md +++ b/docs-site/development.md @@ -231,13 +231,13 @@ Run `make help` for a full list of targets. Key ones: | `SUBMINER_ROFI_THEME` | Override rofi theme path for launcher picker | | `SUBMINER_LOG_LEVEL` | Override app logger level (`debug`, `info`, `warn`, `error`) | | `SUBMINER_MPV_LOG` | Override mpv/app shared log file path | -| `SUBMINER_WHISPER_BIN` | Override `youtubeSubgen.whisperBin` for launcher | -| `SUBMINER_WHISPER_MODEL` | Override `youtubeSubgen.whisperModel` for launcher | -| `SUBMINER_WHISPER_VAD_MODEL` | Override `youtubeSubgen.whisperVadModel` for launcher | -| `SUBMINER_WHISPER_THREADS` | Override `youtubeSubgen.whisperThreads` for launcher | -| `SUBMINER_YT_SUBGEN_OUT_DIR` | Override generated subtitle output directory | -| `SUBMINER_YT_SUBGEN_AUDIO_FORMAT` | Override extraction format used for whisper fallback | -| `SUBMINER_YT_SUBGEN_KEEP_TEMP` | Set to `1` to keep temporary subtitle-generation workspace | +| `SUBMINER_WHISPER_BIN` | Override legacy `youtubeSubgen.whisperBin` fallback compatibility path | +| `SUBMINER_WHISPER_MODEL` | Override legacy `youtubeSubgen.whisperModel` fallback compatibility path | +| `SUBMINER_WHISPER_VAD_MODEL` | Override legacy `youtubeSubgen.whisperVadModel` fallback compatibility path | +| `SUBMINER_WHISPER_THREADS` | Override legacy `youtubeSubgen.whisperThreads` fallback compatibility value | +| `SUBMINER_YT_SUBGEN_OUT_DIR` | Override legacy fallback subtitle output directory | +| `SUBMINER_YT_SUBGEN_AUDIO_FORMAT` | Override extraction format used by legacy fallback subtitle path | +| `SUBMINER_YT_SUBGEN_KEEP_TEMP` | Set to `1` to keep legacy fallback subtitle workspace | | `SUBMINER_JIMAKU_API_KEY` | Override Jimaku API key for launcher subtitle downloads | | `SUBMINER_JIMAKU_API_KEY_COMMAND` | Command used to resolve Jimaku API key at runtime | | `SUBMINER_JIMAKU_API_BASE_URL` | Override Jimaku API base URL | diff --git a/docs-site/index.md b/docs-site/index.md index 6a1e377..aee23cc 100644 --- a/docs-site/index.md +++ b/docs-site/index.md @@ -51,8 +51,8 @@ features: - icon: src: /assets/video.svg alt: Video playback icon - title: YouTube & Whisper - details: Play YouTube URLs or searches with native subtitles, or generate them with whisper.cpp and optional AI cleanup. + title: YouTube Playback + details: Play YouTube URLs or searches with native subtitles and auto-loaded tracks. link: /usage#youtube-playback linkText: YouTube playback - icon: diff --git a/docs-site/launcher-script.md b/docs-site/launcher-script.md index c65b7d8..a1f8871 100644 --- a/docs-site/launcher-script.md +++ b/docs-site/launcher-script.md @@ -66,7 +66,6 @@ subminer --setup # Open first-run setup popup | Subcommand | Purpose | | -------------------------- | ---------------------------------------------------------- | | `subminer jellyfin` / `jf` | Jellyfin workflows (`-d` discovery, `-p` play, `-l` login) | -| `subminer yt` / `youtube` | YouTube shorthand (`-o`, `-m`) | | `subminer doctor` | Dependency + config + socket diagnostics | | `subminer config path` | Print active config file path | | `subminer config show` | Print active config contents | diff --git a/docs-site/public/config.example.jsonc b/docs-site/public/config.example.jsonc index ab7af4a..b94e0c2 100644 --- a/docs-site/public/config.example.jsonc +++ b/docs-site/public/config.example.jsonc @@ -187,7 +187,7 @@ // ========================================== // Secondary Subtitles // Dual subtitle track options. - // Used by subminer YouTube subtitle generation as secondary language preferences. + // Used by the YouTube subtitle loading flow as secondary language preferences. // Hot-reload: defaultMode updates live while SubMiner is running. // ========================================== "secondarySub": { @@ -414,24 +414,24 @@ }, // Jimaku API configuration and defaults. // ========================================== - // YouTube Subtitle Generation - // Defaults for SubMiner YouTube subtitle generation. + // YouTube Playback Settings + // Defaults for SubMiner YouTube subtitle loading and languages. // ========================================== "youtubeSubgen": { - "whisperBin": "", // Path to whisper.cpp CLI used as fallback transcription engine. - "whisperModel": "", // Path to whisper model used for fallback transcription. - "whisperVadModel": "", // Path to optional whisper VAD model used for subtitle generation. - "whisperThreads": 4, // Thread count passed to whisper.cpp subtitle generation runs. - "fixWithAi": false, // Use shared AI provider to post-process whisper-generated YouTube subtitles. Values: true | false + "whisperBin": "", // Legacy compatibility path kept for external subtitle fallback tools; not used by default. + "whisperModel": "", // Legacy compatibility model path kept for external subtitle fallback tooling; not used by default. + "whisperVadModel": "", // Legacy compatibility VAD path kept for external subtitle fallback tooling; not used by default. + "whisperThreads": 4, // Legacy thread tuning for subtitle fallback tooling; not used by default. + "fixWithAi": false, // Legacy subtitle fallback post-processing switch kept for compatibility; use is currently disabled by default. Values: true | false "ai": { - "model": "", // Optional model override for YouTube subtitle AI post-processing. - "systemPrompt": "" // Optional system prompt override for YouTube subtitle AI post-processing. + "model": "", // Optional model override for legacy subtitle fallback post-processing; not used by default. + "systemPrompt": "" // Optional system prompt override for legacy subtitle fallback post-processing; not used by default. }, // Ai setting. "primarySubLanguages": [ "ja", "jpn" ] // Comma-separated primary subtitle language priority used by the launcher. - }, // Defaults for SubMiner YouTube subtitle generation. + }, // Defaults for SubMiner YouTube subtitle loading and languages. // ========================================== // Anilist diff --git a/docs-site/shortcuts.md b/docs-site/shortcuts.md index 503aa17..73521e2 100644 --- a/docs-site/shortcuts.md +++ b/docs-site/shortcuts.md @@ -67,6 +67,7 @@ Mouse-hover playback behavior is configured separately from shortcuts: `subtitle | `Ctrl/Cmd+Shift+V` | Cycle secondary subtitle mode (hidden → visible → hover) | `shortcuts.toggleSecondarySub` | | `Ctrl/Cmd+Shift+O` | Open runtime options palette | `shortcuts.openRuntimeOptions` | | `Ctrl+Shift+J` | Open Jimaku subtitle search modal | `shortcuts.openJimaku` | +| `Ctrl+Alt+C` | Open the manual YouTube subtitle picker | `keybindings` | | `Ctrl+Alt+S` | Open subtitle sync (subsync) modal | `shortcuts.triggerSubsync` | | `\` | Toggle subtitle sidebar | `subtitleSidebar.toggleKey` | | `` ` `` | Toggle stats overlay | `stats.toggleKey` | diff --git a/docs-site/troubleshooting.md b/docs-site/troubleshooting.md index c9e5094..cadca60 100644 --- a/docs-site/troubleshooting.md +++ b/docs-site/troubleshooting.md @@ -29,7 +29,7 @@ SubMiner retries the connection automatically with increasing delays (200 ms, 50 - Common spikes come from: - first subtitle parse/tokenization bursts - media generation (`ffmpeg` audio/image and AVIF paths) - - media sync and subtitle tooling (`alass`, `ffsubsync`, `whisper` fallback path) + - media sync and subtitle tooling (`alass`, `ffsubsync`) - `ankiConnect` enrichment (plus polling overhead when proxy mode is disabled) ### If playback feels sluggish @@ -57,7 +57,7 @@ SubMiner retries the connection automatically with increasing delays (200 ms, 50 - disable AI translation when not needed (`ankiConnect.ai.enabled: false`) - if needed, run immersion telemetry with lower duration expectations (`immersionTracking.enabled: false` for constrained sessions) -- prefer YouTube `--mode automatic` over `preprocess` on low-resource systems +- favor the default lightweight YouTube subtitle startup settings on low-resource systems ### Practical low-impact profile diff --git a/docs-site/usage.md b/docs-site/usage.md index ede927b..ba3f7aa 100644 --- a/docs-site/usage.md +++ b/docs-site/usage.md @@ -78,8 +78,6 @@ subminer mpv idle # Launch detached idle mpv with SubMiner defau subminer dictionary /path/to/file-or-directory # Generate character dictionary ZIP from target (manual Yomitan import) subminer texthooker # Launch texthooker-only mode subminer app --anilist # Pass args directly to SubMiner binary (example: AniList login flow) -subminer yt -o ~/subs https://youtu.be/... # YouTube subcommand: output directory shortcut -subminer yt --keep-temp --whisper-bin /path/to/whisper-cli --whisper-model /path/to/model.bin --whisper-vad-model /path/to/ggml-vad.bin https://youtu.be/... # Keep generated subtitle workspace for debugging # Direct packaged app control SubMiner.AppImage --background # Start in background (tray + IPC wait, minimal logs) @@ -137,14 +135,13 @@ This flow requires `mpv.exe` to be on `PATH`. If it is installed elsewhere, set ### Launcher Subcommands - `subminer jellyfin` / `subminer jf`: Jellyfin-focused workflow aliases. -- `subminer yt` / `subminer youtube`: YouTube-focused shorthand flags (`-o`, `--keep-temp`, `--whisper-*`). - `subminer doctor`: health checks for core dependencies and runtime paths. - `subminer config`: config helpers (`path`, `show`). - `subminer mpv`: mpv helpers (`status`, `socket`, `idle`). - `subminer dictionary