fix(subtitles): recover positioned ASS word spacing and drop control debris (#217)

This commit is contained in:
2026-08-25 02:22:21 -07:00
committed by GitHub
parent ed7d3f4c3d
commit e816b3b371
26 changed files with 2934 additions and 105 deletions
+7 -2
View File
@@ -1,5 +1,10 @@
type: fixed
area: subtitles
- Typeset ASS karaoke and animated signs no longer flood the primary overlay, subtitle sidebar, immersion history, or sentence mining with repeated glyph fragments or full-line color phases. Matching timed comments and full-line boundary events recover the complete authored line without merging ordinary repeated dialogue or separately positioned signs, and dialogue spoken while a song's animation is on screen is kept intact instead of being replaced by the lyric. Entrance and exit frames that run past the authored line timing still resolve to the clean line during lyric transitions, and dialogue spoken while a song's animation is on screen enters immersion and subtitle history without the fragment lines beside it.
- The secondary subtitle overlay drops layered duplicate lines from animated tracks, so a short stack of repeated words collapses to its distinct lines even when the full karaoke heuristic does not apply.
- Typeset ASS karaoke and animated signs no longer flood the primary overlay, subtitle sidebar, immersion history, or sentence mining with glyph fragments and per-frame color phases. The authored line is reconstructed once and shown from its first sung syllable until its hold ends, so a lyric's invisible lead-in and fade tail no longer surface it beside the line actually being sung.
- Reconstructed lines keep their authored word spacing, including gaps encoded only by fragment positions or hidden behind wide syllable chunks, so translations stop running words together.
- Ordinary repeated dialogue, separately positioned signs, wrapped lyric rows, and multi-row CC-style dialogue blocks are still published, and dialogue spoken while a song's animation is on screen stays intact instead of being replaced by the lyric.
- Decorative layers stay out of the published text: highlight sweeps, drop-shadow and glow copies, symbol-font glyph decoration, particle-build glyph swarms, sign walls, near-invisible texture strings, and hidden zero-scaled or zero-clipped text.
- On the live overlay, a finished lyric whose exit ghosts still linger in mpv's text keeps explaining those fragments instead of reappearing beside the line that has already taken over.
- Event-heavy karaoke files that stalled subtitle loading for several seconds now parse in well under a second.
- The secondary subtitle overlay collapses layered duplicate lines from animated tracks even when the full karaoke heuristic does not apply.
@@ -1,4 +1,5 @@
type: fixed
area: subtitles
- Prevented embedded subtitle parsing from starving network playback: mounted SMB/NFS media now uses deduplicated mpv live text, while duplicate extraction requests for local media share one ffmpeg process.
- Embedded subtitle tracks on network-mounted (SMB/NFS) media are extracted and parsed again, restoring karaoke reconstruction, sidebar cues, and mining for releases that ship subtitles only inside the container. Extraction reads the file once per episode (roughly 10 seconds per GB on gigabit), its timeout accommodates large Bluray remuxes, and duplicate requests share one ffmpeg process. Only true remote URLs keep the live-text-only path.
- While extraction is still running, or when no parsed cues exist (remote URLs, unreadable sources), per-glyph typeset karaoke no longer shows a wall of scattered letters in the overlays; concurrent dialogue lines still display.
+2 -2
View File
@@ -1,5 +1,5 @@
type: fixed
area: stats
- Typeset subtitles no longer flood the stats. Karaoke openings and animated signs are authored as one subtitle event per animation frame, and immersion tracking counted every frame, which was enough to put an OP lyric at the top of "Top Repeated Words" for good. Lines are now collapsed on the way in using the same rules the subtitle sidebar already applies: matching parsed timings record exactly the cues the sidebar shows, while shifted, changing, or unparsed sources use a strict fallback where identical, contiguous, sub-0.1s lines stop counting after a few frames. Ordinary repeated dialogue and rewatches are unaffected.
- Added a cleanup for stats already affected. The Vocabulary tab has a **Duplicates** button that scans a chosen window (7 days through all time), shows the bursts it found and the word and kanji counts they added, and collapses each run to one line once confirmed. `subminer stats cleanup --duplicate-lines` does the same from the terminal, with `--dry-run` and `--lookback-days <n>`. Only subtitle lines and the vocabulary counts they feed are touched; watch time and lines-seen totals are left as recorded.
- Typeset subtitles no longer flood the stats. Karaoke openings and animated signs are authored as one subtitle event per animation frame and immersion tracking counted every frame, which was enough to pin an OP lyric to the top of "Top Repeated Words" for good. Lines are now collapsed on the way in using the same rules the subtitle sidebar applies, with a strict fallback for shifted or unparsed sources. Ordinary repeated dialogue and rewatches are unaffected.
- Added a cleanup for stats already affected. The Vocabulary tab's **Duplicates** button scans a chosen window (7 days through all time), shows the bursts it found and the word and kanji counts they added, and collapses each run to one line once confirmed. `subminer stats cleanup --duplicate-lines` does the same from the terminal, with `--dry-run` and `--lookback-days <n>`. Watch time and lines-seen totals are left as recorded.
+2 -1
View File
@@ -1,4 +1,5 @@
type: fixed
area: subtitles
- Primary and secondary ASS subtitles now collapse layered and whitespace variants of full-span lyrics, including when playback starts or seeks into a line, reconstruct fragment-only karaoke per style, preserve authored stack order, keep canonical signs visible for their complete generated animation, navigate song lyrics by sanitized lines instead of generated animation events, and keep sidebar selections on the requested overlapping lyric while preserving unmatched dialogue and signs.
- Primary and secondary ASS subtitles collapse layered and whitespace variants of full-span lyrics, including when playback starts or seeks into a line, and reconstruct fragment-only karaoke per style while preserving the authored stack order.
- Canonical signs stay visible for their complete generated animation, song lyrics are navigated by sanitized lines instead of generated animation events, and sidebar selections stay on the requested overlapping lyric with unmatched dialogue and signs preserved.
@@ -1,4 +1,6 @@
type: fixed
area: overlay
- Secondary subtitles now parse the selected ASS/SRT/VTT source with the primary subtitle deduplication pipeline, preventing layered animation text from appearing several times in the overlay, mined cards, and statistics. Fragmented ASS karaoke keeps spaces authored at event boundaries instead of joining every word together. Long ASS lines repeated as dialogue and positioned signs are also collapsed when they differ only in whitespace or terminal punctuation. Dense multi-row sign layouts no longer become one concatenated secondary line. Live mpv text remains the fallback for unreadable tracks and applies full-line duplicate filtering before display.
- Secondary subtitles now parse the selected ASS/SRT/VTT source through the primary subtitle deduplication pipeline, so layered animation text stops appearing several times in the overlay, mined cards, and statistics.
- Long ASS lines repeated as dialogue or as positioned signs collapse when they differ only in whitespace or terminal punctuation, and dense multi-row sign layouts no longer become concatenated primary or secondary lines.
- Live mpv text remains the fallback for unreadable tracks and applies full-line duplicate filtering before display; a failed source refresh clears ASS-only cleanup so fallback text from other formats stays intact.
@@ -0,0 +1,4 @@
type: fixed
area: stats
- Immersion statistics storage now applies its SQLite busy timeout before WAL setup, avoiding transient database-lock failures when worker connections overlap.
+3 -3
View File
@@ -1,6 +1,6 @@
type: added
area: stats
- Library: duplicate cards for the same show can now be combined. Press "Select" above the library grid, tick the cards, and use "Merge Selected"; the dialog picks which entry to keep and moves every episode onto it. Sessions, mined cards, and watch time are preserved, the emptied entries disappear, and remembered title aliases keep future episodes on the merged card.
- Library: episodes can be reassigned to another library entry from the "→" button on an episode row, which is the fix when one file lands under a stray title (e.g. an episode name parsed as the series). Manual assignments now survive later filename parsing, Jellyfin refreshes, and season repair. Local episodes in the same directory reuse a uniquely corrected destination unless they parse to a title that already has its own library entry, while conflicting seasons or manual destinations are not forced together. Emptying an entry this way removes it and returns to the grid.
- Library: exact AniList title matches with compatible seasons fold duplicate cards automatically. Fuzzy same-AniList matches appear as dismissible "Possible duplicate" reviews instead of changing the library without confirmation; conflicting explicit seasons are left alone.
- Library: duplicate cards for the same show can be combined. Press "Select" above the library grid, tick the cards, and use "Merge Selected"; the dialog picks which entry to keep and moves every episode onto it. Sessions, mined cards, and watch time are preserved, emptied entries disappear, and remembered title aliases keep future episodes on the merged card.
- Library: episodes can be reassigned to another entry from the "→" button on an episode row, which is the fix when one file lands under a stray title (for example an episode name parsed as the series). Manual assignments survive later filename parsing, Jellyfin refreshes, and season repair, and emptying an entry this way removes it and returns to the grid.
- Library: exact AniList title matches with compatible seasons fold duplicate cards automatically. Fuzzy same-AniList matches appear as dismissible "Possible duplicate" reviews instead of changing the library without confirmation.