Jak opravit kódování titulků SRT bez ztráty původního textu
Diagnostikujte zkomolený text v SRT, rozlište chyby dekódování od ztracených znaků a vytvořte samostatnou kopii v UTF-8 pomocí bezpečného nástroje v Pythonu a reprodukovatelných ukázek.

Pokud se v titulcích SRT zobrazuje café místo café, neukládejte soubor okamžitě jako UTF-8. Nejprve si uschovejte nedotčenou kopii jeho bajtů, najděte dekódování, které dává správná slova, a ověřený text zapište do samostatného souboru. Uložením chybných znaků v novém kódování pouze zafixujete chybné znaky.
Zásadní rozdíl spočívá v tom, co je platné kódování a co správný text. V níže uvedeném experimentu se dvěma titulky projde jeden poškozený soubor přísnou kontrolou UTF-8 a neobsahuje žádné náhradní znaky. Přesto je v něm francouzský text špatně. Jiný soubor projde toutéž kontrolou poté, co bylo šest původních znaků nahrazeno znakem �.
Tento návod nabízí lokální nástroj v Pythonu pro kontrolu a převod, zdrojové soubory ke stažení a reprodukovatelný test. Řeší diagnostiku na úrovni souboru a explicitní převod – nikoli automatickou detekci kódování, synchronizaci videa ani záruku obnovení chybějících písmen.
Nejprve zjistěte, co je ve skutečnosti poškozené
Přípona .srt označuje formát titulků, nikoli garantované kódování. SRT obsahuje čísla titulků, časové značky, text a oddělovače; záznam o formátu SRT Knihovny Kongresu jej popisuje jako prostý text bez jednotného standardu kódování znaků.
Viditelný projev berte jako důvod k prověření, nikoli jako hotovou diagnózu:
| Co vidíte | Co zkontrolovat | Vhodný další krok |
|---|---|---|
| Akcenty nebo symboly se v jedné aplikaci zobrazují špatně | Zobrazí se správný text, když nedotčený soubor znovu otevřete se známým zdrojovým kódováním? | Pokud ano, použijte toto explicitní dekódování před exportem nové kopie. |
café zůstává v souboru správně načteném jako UTF-8 | Byl formát UTF-8 dříve chybně načten jako jiné kódování a takto uložen? | Vraťte se k původním bajtům nebo prozkoumejte přesnou historii převodu. Další uložení v UTF-8 problém neopraví. |
� se zobrazuje na místě, kam patří písmeno nebo symbol | Je znak U+FFFD skutečně uložen v souboru, nebo jej aktuální aplikace pouze vkládá při pokusu o zobrazení nedekódovatelných bajtů? | Zkontrolujte nedotčený zdrojový soubor. Uložený zástupný znak nedokáže určit původní znak. |
| V přehrávači se zobrazují obdélníčky, ale spolehlivý textový prohlížeč ukazuje zamýšlené znaky | Jsou základní kódové body správné? Načítá přehrávač skutečně tentýž soubor? | Než začnete soubor měnit, prověřte nastavení dekódování, podporu písma nebo vykreslování v přehrávači. |
Znaky a jejich zobrazené tvary jsou dvě odlišné věci. Oficiální vysvětlení kódování Unicode v dokumentaci Pythonu rozlišuje kódové body od glyfů vykreslených písmem. Správný text v editoru naznačuje pravděpodobný problém na straně přehrávače; nedokazuje však, že instalace konkrétního písma situaci vyřeší. Žádné konkrétní písmo ani přehrávač nebyly pro tento článek testovány.
Zálohujte bajty a poté zkontrolujte dekódování
Stáhněte si skript subtitle_encoding.py a uložte jej vedle souboru SRT, který chcete prověřit. Následující příkazy vyžadují nainstalovaný Python 3 a žádné další balíčky. Místní testy v tomto článku proběhly s verzí Python 3.14.3 na systému macOS. Pokud vaše instalace v systému Windows používá spouštěč Pythonu, nahraďte py -3 za python3; toto prostředí zde nebylo testováno.
Otevřete v dané složce terminál. V uvedených příkladech nahraďte input.srt skutečným názvem vašeho souboru. Cesty obsahující mezery ponechte v uvozovkách.
Vytvořte nedotčenou kopii
python3 subtitle_encoding.py backup "input.srt" "original-bytes.srt"
Cílový soubor nesmí předem existovat. Nástroj zkopíruje bajty bez jejich dekódování, kopii zpětně přečte a vypíše její kontrolní součet SHA-256. Jako cíl také odmítne zdrojovou cestu. Tuto zálohu si ponechte i poté, co vytvoříte použitelné titulky.
Zkontrolujte UTF-8 bez ukládání změn
python3 subtitle_encoding.py inspect "original-bytes.srt"
Výpis obsahuje strict_utf8, utf8_bom, vybrané dekódování a – pokud dekódování uspěje – náhled textu a replacement_characters . Výchozí textové zobrazení používá utf-8-sig, což si poradí i s počáteční signaturou UTF-8.
strict_utf8: falseznamená, že bajty neprošly kontrolou UTF-8. To vám však neřekne , které jiné kódování je to správné.strict_utf8: trueznamená, že je lze dekódovat jako UTF-8. To však neznamená , že jsou slova v pořádku.- Nenulový počet nahrazení znamená, že zvolené dekódování vygenerovalo znaky U+FFFD. Před vytvořením nového souboru je prověřte.
Inspekce vypisuje JSON bezpečný pro ASCII, takže písmo v terminálu nemůže identitu znaku skrýt: \u00e9 znamená éa \ufffd představuje zástupný znak. Chcete-li podezřelý řádek prozkoumat podrobně, vyžádejte si jeho fyzické číslo řádku – nikoli číslo titulku:
python3 subtitle_encoding.py inspect "original-bytes.srt" --encoding cp1252 --line 3
Jedná se o test pouze pro čtení v kódování Windows-1252, což je v Pythonu kodek cp1252 . Použijte jej, pokud nastavení exportu nebo historie původu tuto volbu potvrzují, nikoli proto, že v tomto příkladu byla zrovna použita francouzština. Přehled řádku pojmenuje každý znak a zobrazí jeho kódový bod; U+20AC je znak eura.
Kódování vybírejte na základě důkazů, nikoli podle prvního úspěšného náhledu
Zeptejte se tvůrce souboru na skutečné kódování exportu, zkontrolujte nastavení exportní aplikace nebo text porovnejte s důvěryhodným původním přepisem. Zkontrolujte jména s diakritikou, interpunkci, symboly měn a reprezentativní řádky v celém souboru. Pokud daný jazyk neovládáte, úspěšné dekódování tuto kontrolu za vás provést nedokáže.
Označení „ANSI“ není pro výběr zdrojového kodeku dostatečně přesné. Ani Windows-1252 a Latin-1 nejsou zaměnitelné. V uvedeném experimentu se jediný bajt 80 dekóduje jako € pod cp1252, ale na řídicí znak U+0080 pod kódováním latin-1. Obě operace proběhnou úspěšně. Která z nich byla zamýšlena, poznáme pouze ze spolehlivého zdrojového textu.
Jiné jazyky mohou používat odlišná starší kódování, ale samotný název jazyka kódování neurčuje. Pokud původ souboru neznáte a navrhovaná čtení se liší, před převodem se zastavte a obstarejte si spolehlivější informace o zdroji.
Převod provádějte až po ověření čitelnosti zdrojového textu
U zdroje, u kterého bylo ověřeno kódování Windows-1252, vytvořte samostatný soubor v UTF-8:
python3 subtitle_encoding.py convert "original-bytes.srt" "repaired-utf8.srt" --from-encoding cp1252
python3 subtitle_encoding.py inspect "repaired-utf8.srt"
Konvertor striktně dekóduje celý zdroj, zakóduje daný text do UTF-8, zkontroluje, zda dekódování výstupu vrátí stejný text, a zapsané bajty znovu načte. Neupravuje číslování titulků, časové značky, dialogy, značky ani konce řádků. Nová sekvence bajtů se může lišit, i když dekódovaný text zůstává naprosto identický.
Nástroj záměrně odmítá:
- přepsat existující cílový soubor;
- pokračovat dál při chybě striktního dekódování; nebo
- zapsat text obsahující znak U+FFFD, i kdyby byl tento znak zamýšlený.
Poslední omezení je opatrné záměrně: tento nástroj nedokáže posoudit, co měl náhradní znak původně představovat. Pokud by se odstranil jen proto, aby příkaz proběhl, zahodily by se tím důkazy namísto obnovení textu. Dokumentace k obsluze chyb v Pythonu vysvětluje, proč se režimy replace a ignore liší od striktního dekódování: problematická data totiž nahrazují nebo zahazují. Ani jedno do tohoto kroku převodu nepatří.
Dojde-li k chybě I/O, poškozený výstup nepoužívejte. Může po něm zůstat částečně zapsaný nový soubor; ponechte si originál a pro další pokus zvolte nový název cílového souboru. Kompletní popis chování nástroje a jeho použití najdete v souboru README ke stažení.
A co UTF-8 s BOM?
UTF-8 BOM je úvodní sekvence bajtů EF BB BF. Kodek utf-8-sig v Pythonu tuto signaturu při dekódování odstraní a při kódování ji naopak přidá.
Pro ověřený zdroj v kódování UTF-8 s BOM použijte --from-encoding utf-8-sig. Nástroj standardně zapisuje UTF-8 bez BOM; přidejte --with-bom pouze v případě, kdy to vyžadují požadavky přijímající aplikace. Změna BOM nedokáže proměnit café na café. Tento experiment neurčuje kompatibilitu s žádným konkrétním přehrávačem, editorem ani platformou pro nahrávání.
Pět malých souborů ukazuje, proč pouhá platnost UTF-8 nestačí
V experimentu jsou použity dva zcela vlastní francouzské titulkové segmenty. Nejsou převzaty z filmu, od zákazníka ani z překladatelského produktu:
1
00:00:01,000 --> 00:00:04,000
Émile dit : « Le prix est de 12,50 €. »
2
00:00:05,000 --> 00:00:08,000
Le café est fermé.
Dne 13. září 2026 skript využívající standardní knihovnu Pythonu 3.14.3 vygeneroval pět bajtových reprezentací a každou z nich porovnal s tímto známým zdrojem. Jedná se o deterministické kontroly bajtů a řetězců, nikoli o srovnávací test kvality překladu. Odkazované soubory si raději uložte na disk, než abyste kopírovali jejich náhledy z prohlížeče: smyslem experimentu jsou právě rozdílné bajty.
| Kopie ke stažení | Bajty | Striktní UTF-8? | Správný text při dekódování jako UTF-8? | Uložený znak U+FFFD v textu UTF-8 |
|---|---|---|---|---|
| Původní UTF-8 | 132 | Ano | Ano | 0 |
| Původní Windows-1252 | 125 | Ne | Nelze dekódovat jako UTF-8; správné při cp1252 | Neuplatňuje se |
| Nesprávný dekodér, znovu uloženo jako UTF-8 | 147 | Ano | Ne | 0 |
| Zástupné znaky, znovu uloženo jako UTF-8 | 137 | Ano | Ne | 6 |
| Správně převedené UTF-8 | 132 | Ano | Ano | 0 |
Každá kopie si zachovává stejné dva řetězce časových značek. Správně převedený soubor je bajt po bajtu identický s originálem v UTF-8. Dva poškozené soubory UTF-8 dokazují něco specifičtějšího, ale užitečného: ani platné kódování, ani nezměněné časové značky nezaručují správný text titulků. Shodné časové značky také neříkají nic o tom, zda tato smyšlená stopa sedí ke skutečnému videu.
Chcete-li si těchto pět souborů sami zreprodukovat, stáhněte si reproduce.py a spusťte jej s názvem adresáře, který dosud neexistuje:
python3 reproduce.py encoding-experiment
Skript zapíše testovací soubory a results.json obsahující celý text, transformace, hashe, verzi běhového prostředí a kontrolní tvrzení. Porovnejte jej se zaznamenanými výsledky experimentu; časová značka vygenerování se bude lišit. Skripty i původní výukové soubory obsahují licenci MIT.
Kontroly lokálního převodníku prověřily také odmítnutí přepisu existujícího výstupu, odmítnutí zdrojové cesty, selhání při nesprávném kodeku, odmítnutí U+FFFD, zachování konců řádků CRLF a explicitní výstup s BOM. Tyto kontroly ověřují chování tohoto nástroje při práci se soubory. Netestují vykreslování v přehrávači, časování na reálném médiu ani překlad přes BookTranslator.
Pokud již byly poškozené znaky uloženy
Uložený mojibake: prozkoumejte přesnou historii
Naše kopie s mojibake prošla známým řetězcem: původní bajty UTF-8 byly dekódovány jako Windows-1252 a tyto chybné znaky byly následně uloženy jako UTF-8. Výsledek obsahuje café a rozbitou sekvenci pro euro €.
Protože se při této konkrétní transformaci neztratily žádné bajty, reprodukční skript ji dokáže zvrátit: zakóduje chybný text zpět přes cp1252a výsledné bajty pak dekóduje jako UTF-8. Následně ověří obnovený text oproti originálu.
To je důkaz pro tento známý řetězec, nikoli návod k použití plošné operace „opravit mojibake“ na každý soubor SRT. Soubor může obsahovat legitimní znaky, smíšenou historii nebo text již pozměněný předchozím pokusem o opravu. Dejte přednost nedotčenému zdroji a běžnému postupu převodu. Pokud vám zbyl pouze uložený mojibake, uchovejte jej a zjistěte, jak vznikl, než se pokusíte o inverzní transformaci na další kopii.
Uložené zástupné znaky: chybějící písmeno zde není zakódováno
Tento ztrátový vzorek vznikl dekódováním bajtů Windows-1252 jako UTF-8 se zapnutou náhradou znaků a následným uložením výsledku. Různé původní znaky se proměnily ve stejnou značku � . Uložená značka neobsahuje dostatek informací k tomu, aby bylo možné určit, jaký původní znak na dané pozici stál.
Nezaměňujte to s pouhým zobrazením � v aplikaci. Pokud původní bajty zůstaly netknuté, správné dekódování může text stále obnovit – stejně jako v případě našeho zdroje ve Windows-1252. Než soubor prohlásíte za nenávratně poškozený, zkontrolujte původní zdroj.
Pokud jediná dochovaná kopie skutečně nahradila chybějící text znakem U+FFFD nebo doslovnými otazníky, exportujte či získejte čistý zdroj znovu, případně ověřte ruční přepis podle spolehlivého materiálu. Obyčejný otazník může být také legitimní interpunkce; jeho samotná přítomnost nic nedokazuje. Pravděpodobná náhrada navržená modelem je pouhý odhad, nikoli obnovená data ze souboru.
Cílem je čitelný zdroj – nikoli jen úspěšně proběhlý příkaz
Než opravený soubor přijmete, porovnejte reprezentativní slova a symboly s důvěryhodným zdrojem, ujistěte se, že se nezměnily řádky s číslováním titulků a časovými údaji, a otevřete nový soubor v aplikaci, ve které jej budete používat. Skript sice zachovává dekódovaný text, nepředstavuje však validátor syntaxe SRT ani akceptační test přehrávání.
Pokud jsou nyní titulky čitelné a nepotřebujete jiný jazyk, máte hotovo. Pokud potřebujete provést vizuální kontrolu s videem nebo další úpravy, srovnání softwaru na titulky vysvětluje úlohy jednotlivých nástrojů.
Teprve ve chvíli, kdy je zdrojový text spolehlivý – a vy skutečně potřebujete jiný jazyk – přejděte na překladač titulků od BookTranslator a postup překladu titulků pomocí AI. K opravě kódování, překladu a kontrole výsledné stopy přistupujte jako k odděleným krokům. Žádný z nich sám o sobě nezaručuje, že ty ostatní proběhly úspěšně.
Související příspěvky





