fix(playback): require a meaningful Cyrillic letter share before choosing CP1251

Codex review round 6 on #1471: an isolated accented CP1252 word decodes
under CP1251 to a tiny pure-Cyrillic word ("À table" -> "А table") whose
single vote flipped the file to Cyrillic. The chooser now also requires
Cyrillic letters to carry a meaningful share of all letters — genuinely
Cyrillic dialogue dominates its own letter count even with embedded Latin
names, while isolated accents never do.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Fable 5 committed 2026-08-23 12:28:51 +02:00
1 parent 6ad9278230
commit 333d62fc1f
3 files changed
+40 -7

No files matched your search

@@ -695,9 +695,11 @@ Per-engine implementations:
BOMs, strict UTF-8, then `chooseLegacySingleByteDecode`, which picks
between Windows-1251 and Windows-1252 by the plausibility of the 1251
candidate's decoded words — pure-Cyrillic words vote for 1251, words
mixing Cyrillic with ASCII letters vote against, since misread Latin text
like "était" decodes to the mixed-script "йtait" that real subtitles never
contain), because `Blob.text()`'s silent UTF-8 substitution turns common
mixing Cyrillic with ASCII letters vote against (misread Latin text like
"était" decodes to the mixed-script "йtait" that real subtitles never
contain), and Cyrillic must also carry a meaningful share of all letters
so an isolated accented CP1252 word ("À table" → "А table") cannot flip
the file), because `Blob.text()`'s silent UTF-8 substitution turns common
legacy-encoded SRT files into mojibake. `WebVideoExternalSubtitles` parses
the file (`external-subtitle-cues.util.ts`) and renders it through a native
`TextTrack` on the video element, so it works under every source kind. The