Cum să traduci subtitrările ASS/SSA fără a strica stilurile, pozițiile sau karaoke
Tradu doar dialogul vizibil dintr-un fișier .ass, apoi verifică sincronizarea, etichetele, karaoke și fonturile. Cu un fișier exemplu, un verificator gratuit și un test local cu LLM în 9 rulări.

Un fișier de subtitrare ASS sau SSA este un mic program: un antet, un tabel de stiluri și o listă de evenimente cronometrate al căror ultim câmp amestecă dialogul cu cod de formatare. Pentru a-l traduce, modifică doar cuvintele lizibile din acel ultim câmp, lasă tot restul neschimbat octet cu octet, apoi verifică trei lucruri pe care niciun instrument de traducere nu le rezolvă pentru tine: fonturile, codurile de spațiere și liniile de karaoke.
Am tradus un eșantion de 14 evenimente în chineză simplificată de nouă ori cu un model local, folosind trei prompturi diferite, și am verificat fiecare rezultat cu un script scris de noi. Sincronizarea, pozițiile, culorile, comentariile și desenele au supraviețuit în toate cele nouă. Ce s-a stricat au fost părțile fișierului care presupun limba engleză: în toate cele nouă, fonturile stilurilor nu aveau caractere chinezești, așa că fișierul s-ar baza pe player pentru a înlocui un font, iar un spațiu dur din linia engleză a devenit un gol vizibil în chineză. Linia de karaoke a revenit cu sincronizarea îndreptată spre cuvintele greșite în fiecare rulare, iar în patru rulări unele silabe nu au evidențiat nimic.
Răspuns rapid: ce să traduci și ce să lași în pace
| Parte a fișierului | Exemplu din eșantionul nostru | Să o traduci? |
|---|---|---|
Antetul [Script Info] | PlayResX: 1920, WrapStyle: 0 | Nu. Pozițiile sunt calculate din aceste valori. |
[V4+ Styles] | Style: Default,Trebuchet MS,64,... | Nu, cu excepția numelui fontului, pe care poate fi nevoie să îl schimbi intenționat |
| Câmpurile 1–9 ale evenimentului | 0,0:00:01.00,0:00:03.20,Default,Jun,0,0,0, | Nu. Acestea sunt stratul, sincronizarea, stilul, vorbitorul, marginile și efectul. |
| Blocurile de suprascriere | {\i1}, {\an8\pos(960,120)}, {\k25} | Nu |
| Desenele | {\p1}m 0 0 l 200 0 200 60 0 60{\p0} | Nu. Aceasta este o formă vectorială, nu text. |
Evenimentele Comment: | Comment: ...,Earlier draft: Try the stacks. | Opțional. Comentariile nu apar niciodată pe ecran. |
| Notele dintre acolade | {TL note: "stacks" means the closed shelves} | Opțional. Playerele le ignoră. |
| Dialogul vizibil | Did you find the second volume? | Da |
| Codurile de linie | \N, \n, \h | Păstrați \N. Decideți de la caz la caz pentru \n și \h. |
Restul acestui ghid explică de ce contează fiecare rând și cum să verificați rezultatul.
Cum este construită o linie ASS
Fiecare linie din secțiunea [Events] urmează formatul declarat imediat deasupra ei:
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:03.40,0:00:06.10,Default,Mara,0,0,0,,{\i1}I thought it was{\i0} sold out.
Doar al zecelea câmp, Text, conține ceva ce citește un spectator. Ghidul formatului de fișier ASS al proiectului libass notează că acest ultim câmp „poate conține virgule”, motiv pentru care o împărțire neglijentă la fiecare virgulă strică o linie precum Well, if it's there, then, we go now. Un instrument sigur împarte doar la primele nouă virgule.
În interiorul Text, orice se află între acolade este un bloc de suprascriere. Referința etichetelor de suprascriere din Aegisub definește codurile pe care le veți întâlni cel mai des:
\Nforțează un sfârșit de linie în orice mod de împachetare.\nîntrerupe linia doar în modul de împachetare 2 și altfel este un spațiu.\heste un spațiu care nu se rupe.\an8setează alinierea folosind aspectul tastaturii numerice, deci 8 este sus-centru.\pos(960,120)plasează linia la coordonatele scriptului.\k25este o silabă de karaoke; duratele sunt în centisecunde, deci 25 înseamnă un sfert de secundă.- După
\p1, textul „va fi apoi interpretat ca instrucțiuni de desenare”, așa că un traducător care „traduce”m 0 0 l 200 0distruge o formă. - Textul nerecunoscut din interiorul acoladelor „este ignorat în tăcere”, motiv pentru care fișierele fansub conțin adesea note ale traducătorului între acolade.
Liniile care încep cu Comment: folosesc aceleași câmpuri, dar conform ghidului libass „nimic nu va fi afișat pe ecran”.
Ce am testat
Am scris sample-source.ass, o scenă cu 14 evenimente într-o librărie, cu câte un exemplu pentru fiecare caracteristică de mai sus: cursive, o întrerupere forțată, virgule în dialog, o notă între acolade, o linie de comentariu, un semn poziționat, o casetă vectorială, un fade, un spațiu forțat, o schimbare de culoare cu \r, o întrerupere soft, un efect Banner derulant și o linie de karaoke cu șase silabe.
Apoi am rugat un model local să o traducă în chineză simplificată în trei moduri:
- Fișier întreg. Lipiți întregul fișier
.assși cereți fișierul tradus înapoi. - Doar text. Trimiteți doar câmpul
Textal fiecărei linii de dialog ca JSON, cu etichetele inline, și instrucțiunea de a păstra fiecare bloc{...}și fiecare\N,\nși\h. - Protejat. La fel, dar înlocuiți mai întâi fiecare bloc între acolade și cod de linie cu un substituent numerotat, și puneți originalele la loc după aceea.
În a doua și a treia condiție, scriptul nu trimite niciodată desenul vectorial sau linia de comentariu către model, așa că acele linii puteau fi deteriorate doar în condiția cu fișierul întreg.
Modelul a fost Qwen 3.6 27B (Q4_K_M) în LM Studio 0.4.8 pe un Apple M4 Max cu 64 GB de memorie, cu gândirea dezactivată și temperatura 0.3. Am rulat fiecare condiție de trei ori, nouă rulări în total. Prima încercare la a treia rulare s-a încheiat când serverul local a întrerupt conexiunea, așa că l-am repornit și am rulat din nou a treia rundă. Scriptul este run_llm_ass_test.py, iar toate cele nouă rezultate sunt publicate needitate alături de el; README listează fiecare fișier. Dacă nu ați configurat niciodată un model local, ghidul nostru de traducere cu LLM local acoperă setările.
Acesta a fost un test mic cu un singur model, o singură pereche de limbi și un singur eșantion. Arată ce probleme apar și cum să le prindeți. Nu clasează instrumente sau prompturi.
Rezultat: Mecanismul a supraviețuit; presupunerile englezești, nu
Am verificat fiecare rezultat cu check_ass_translation.py. Rezultatul complet este în check-results.txt, iar results.csv are un rând pe rulare, inclusiv problemele pe care scriptul nu le poate vedea.
| Verificare | Fișier complet | Doar text | Protejat |
|---|---|---|---|
| Temporizare, stiluri și câmpurile 1–9 neschimbate | 3 din 3 | 3 din 3 | 3 din 3 |
| Etichete de suprascriere neschimbate | 3 din 3 | 2 din 3 | 3 din 3 |
| Linii de desen și comentarii neatinse | 3 din 3 | 3 din 3 | 3 din 3 |
| Fonturi de stil capabile să redea traducerea | 0 din 3 | 0 din 3 | 0 din 3 |
\h și \n lăsate ca spații în textul chinezesc | 3 din 3 | 3 din 3 | 3 din 3 |
| Toate etichetele karaoke păstrate, fiecare cu text | 3 din 3 | 0 din 3 | 1 din 3 |
Două rezultate ne-au surprins. Lipirea întregului fișier a păstrat structura intactă în toate cele trei rulări, deși în două dintre ele a tradus și linia Title din antet. Iar promptul doar-text, care sună mai sigur, a produs singurele etichete stricate. Într-o rulare a returnat {\k25}翻{\k30}页,{\k45}开{\k60}灯 pentru o linie cu șase etichete karaoke. Ultimele două etichete și 1,20 secunde de temporizare a evidențierii au dispărut, așa că evidențierea s-ar fi terminat cu mult înainte de linie. Aceeași rulare a transformat Room\h12 is upstairs. în 12\h12号房间在楼上。, cu numărul camerei de două ori.
Deci lecția utilă nu este „folosește promptul X”. Ci că daunele structurale de care te temi sunt ușor de detectat, iar daunele care au trecut efectiv în toate cele nouă rulări se află în trei locuri despre care paginile de instrumente pentru traducerea ASS nu discută.
1. Fonturile nu pot desena noua limbă
Stilurile eșantionului folosesc Trebuchet MS pentru dialog și Georgia pentru semne, ceea ce este normal pentru o lansare în engleză. Niciunul dintre fonturi nu conține caractere chinezești. Când am îndreptat testul de glife al verificatorului către cele două fișiere de fonturi, toate cele 12 evenimente de text traduse din fiecare rulare au eșuat:
ERROR event 1: font 'Trebuchet MS' has no glyph for 9 characters, e.g. 了二你到卷吗找第?
ERROR event 7: font 'Georgia' has no glyph for 10 characters, e.g. 书人仅作员工库架闭限
Un player poate înlocui cu un alt font instalat, așa că subtitrarea ar putea apărea totuși, dar lansarea nu mai controlează cum arată, iar un spectator al cărui sistem nu are un font potrivit ar putea vedea casete goale. Soluția este o modificare deliberată a câmpului Fontname al fiecărui stil. Când am schimbat toate cele trei stiluri dintr-o ieșire în Hiragino Sans GB, un font chinezesc livrat cu macOS, și am rulat testul de glife pe acel font, erorile de glife au ajuns la zero.
Alege un font pe care spectatorii tăi îl vor avea cu adevărat sau livrează-l împreună cu videoclipul. Ghidul libass spune că lansările ar trebui să atașeze fiecare font pe care îl folosesc, de preferință la containerul MKV. Deoarece fontul limbii țintă este nou, atașarea lui face acum parte din sarcina de traducere.
2. Codurile de spațiere poartă obiceiuri englezești
Room\h12 lipește „Room” de „12” ca să nu se despartă niciodată pe linii. În chineză cuvintele nu sunt separate prin spații, dar fiecare rulare a păstrat \h undeva: cinci rulări l-au plasat între 12号房间 și 在楼上, trei l-au pus înaintea numărului, iar una l-a pus între două copii ale numărului. În orice caz, spectatorul vede un spațiu nedorit. Wait\nhere. a avut aceeași problemă. Cu WrapStyle: 0, \n se afișează ca un spațiu, așa că 在\n这里等 arată un gol în mijlocul unei propoziții de trei cuvinte.
Structura este în regulă aici; limba nu este. Pentru o limbă țintă fără spații între cuvinte, elimină \h și \n din textul tradus. Păstrează \N doar acolo unde vrei o întrerupere forțată și plasează-l într-un punct natural al propoziției țintă. Verificatorul raportează modificările numărului de \h și \n ca avertismente, nu ca erori, din acest motiv, și avertizează când unul supraviețuiește în text chinezesc, japonez sau coreean.
3. Temporizarea karaoke aparține cuvintelor originale
Linia karaoke {\k25}Turn {\k30}the {\k45}page, {\k60}turn {\k40}the {\k80}light temporizează fiecare silabă engleză pe melodie. O traducere nu poate păstra acea temporizare în mod semnificativ, deoarece cuvintele chinezești nu cad pe aceleași bătăi. Rulările noastre arată diferitele moduri în care merge prost:
- În patru rulări toate cele șase etichete au fost păstrate, fiecare pe un cuvânt diferit față de înainte. Una dintre ele s-a terminat cu
{\k40}打{\k80}开, „deschide”, și a eliminat complet „light” din linie. - În patru rulări o silabă nu a evidențiat nimic, cum ar fi
打开{\k40}{\k80}灯(0,40 secunde de evidențiere pe o silabă goală). În două dintre acestea, o silabă de 0,45 secunde a evidențiat doar o virgulă. - Într-o rulare două etichete au dispărut, așa cum s-a descris mai sus.
Verificatorul semnalează o linie karaoke tradusă pe loc și orice silabă rămasă fără text. Soluția mai bună este editorială: nu traduce karaoke pe loc. Păstrează linia originală temporizată pentru a cânta împreună și adaugă traducerea ca eveniment separat: copiază evenimentul karaoke, dă-i propriul stil (de exemplu, mai mic și plasat jos), elimină etichetele \k și traduce textul. Retemporizează-l silabă cu silabă doar dacă ești pregătit să îl temporizezi singur pe audio.
Un flux de lucru care rezistă
-
Fă sursa lizibilă mai întâi. Dacă fișierul afișează caractere deformate, remediază codificarea înainte de orice altceva. Ghidul nostru de codificare folosește exemple SRT, dar aceiași pași la nivel de octeți funcționează și pentru un fișier
.assși păstrează octeții originali în siguranță. Verificatorul citește doar UTF-8 și UTF-16. -
Decide domeniul de aplicare. Listează stilurile și decide care sunt dialog, care sunt semne pe ecran și care sunt karaoke. Semnele necesită de obicei traducere; karaoke necesită de obicei o linie separată; comentariile și notele dintre acolade sunt la latitudinea ta.
-
Traduce doar câmpul
Text. Folosește un instrument care analizează ASS în loc să îl trateze ca text simplu sau protejează singur etichetele ca în a treia noastră condiție. Păstrează fișierul sursă lângă ieșire. -
Rulează verificarea structurală.
python3 check_ass_translation.py source.ass translated.assCompară numărul de evenimente, tipurile de evenimente, câmpurile 1–9, valorile stilurilor, blocurile de suprascriere, desenele, liniile de comentariu,
\N, silabele și duratele karaoke și liniile care au revenit goale sau neschimbate. Nu judecă calitatea traducerii. -
Corectează fonturile intenționat. Schimbă
Fontnameîn fiecare stil care conține acum text în limba țintă, apoi rulează testul de glife pe fișierul de font pe care îl vei livra:pip install fonttools python3 check_ass_translation.py source.ass translated.ass --font "Noto Sans SC=/path/to/NotoSansSC-Regular.otf"Un nume de font modificat apare ca avertisment, astfel încât poți confirma că fiecare modificare a fost intenționată.
-
Curăță codurile de spațiere și karaoke așa cum s-a descris mai sus.
-
Urmărește-l împreună cu videoclipul. Deschide fișierul în Aegisub sau în playerul tău. Verifică dacă semnele se potrivesc în continuare formelor desenate în spatele lor, deoarece o casetă
\pîși păstrează dimensiunea englezească, în timp ce un semn tradus poate fi mult mai lung sau mai scurt. Verifică dacă rândurile nu sunt prea lungi pentru timpul lor pe ecran. Niciuna dintre probleme nu este vizibilă în fișierul în sine.
Unde se potrivește BookTranslator
Traducătorul de subtitrări BookTranslator acceptă fișiere SRT, VTT, ASS și SSA. Conform paginii produsului, păstrează marcajele temporale și ordinea replicilor și menține stilizarea ASS și SSA acceptată atașată fiecărei intrări de subtitrare, astfel încât nu trebuie să extragi și să reintroduci textul manual. Traduce dialogul folosind rândurile din jur ca context, ceea ce ajută la nume și glume recurente de-a lungul unui întreg episod.
Nu am rulat acest eșantion prin BookTranslator pentru acest articol. Indiferent de instrumentul pe care îl folosești, rulează pașii de la 4 la 7 pe rezultat. Un stil care își păstrează fontul englezesc este încă un stil care nu poate desena caractere chinezești, iar karaoke tradus pe loc necesită încă o decizie editorială. Pentru restul fluxului de lucru cu subtitrări, vezi ghidul nostru de traducere automată a subtitrărilor, comparația noastră a software-urilor de traducere a subtitrărilor și, dacă traducerea ta merge pe YouTube, fluxul de lucru pentru subtitrări YouTube.
Când să convertești în SRT în schimb
Convertirea ASS în SRT înainte de traducere elimină stilurile, pozițiile, desenele și karaoke, ceea ce elimină și majoritatea problemelor de mai sus. Acesta este un compromis rezonabil dacă destinația ta afișează doar subtitrări simple sau dacă stilizarea nu a fost niciodată importantă pentru lansare. Este un compromis greșit pentru lansările anime și muzicale în care semnele și karaoke fac parte din operă. Decide în funcție de locul unde va fi afișat fișierul, nu de formatul care este mai ușor de tradus.
Obține fișierele de test
Totul din acest test poate fi reutilizat gratuit:
- sample-source.ass: eșantionul englezesc cu 14 evenimente;
- check_ass_translation.py: verificatorul (biblioteca standard Python; testul
--fontnecesită fontTools); - run_llm_ass_test.py: cele trei condiții de prompt pentru orice server local compatibil OpenAI;
- results.csv și check-results.txt: rezultate pe fiecare rulare;
- README.txt: lista fișierelor și setările testului, cu cele nouă rezultate needitate în folderul
outputs.
Articole asociate




