BookTranslator
BookTranslator

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.

BookTranslator

BookTranslator Team

13 min read

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șieruluiExemplu din eșantionul nostruSă o traduci?
Antetul [Script Info]PlayResX: 1920, WrapStyle: 0Nu. 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 evenimentului0,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 vizibilDid you find the second volume?Da
Codurile de linie\N, \n, \hPă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:

  • \N forț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. \h este un spațiu care nu se rupe.
  • \an8 setează alinierea folosind aspectul tastaturii numerice, deci 8 este sus-centru. \pos(960,120) plasează linia la coordonatele scriptului.
  • \k25 este 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 0 distruge 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:

  1. Fișier întreg. Lipiți întregul fișier .ass și cereți fișierul tradus înapoi.
  2. Doar text. Trimiteți doar câmpul Text al 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.
  3. 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.

VerificareFișier completDoar textProtejat
Temporizare, stiluri și câmpurile 1–9 neschimbate3 din 33 din 33 din 3
Etichete de suprascriere neschimbate3 din 32 din 33 din 3
Linii de desen și comentarii neatinse3 din 33 din 33 din 3
Fonturi de stil capabile să redea traducerea0 din 30 din 30 din 3
\h și \n lăsate ca spații în textul chinezesc3 din 33 din 33 din 3
Toate etichetele karaoke păstrate, fiecare cu text3 din 30 din 31 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ă

  1. 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.

  2. 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.

  3. 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.

  4. Rulează verificarea structurală.

    python3 check_ass_translation.py source.ass translated.ass
    

    Compară 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.

  5. 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ă.

  6. Curăță codurile de spațiere și karaoke așa cum s-a descris mai sus.

  7. 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:

Articole asociate