BookTranslator
BookTranslator

Come tradurre i sottotitoli ASS/SSA senza rompere stili, posizioni o karaoke

Traduci solo il dialogo visibile in un file .ass, poi controlla tempi, tag, karaoke e font. Con un file di esempio, un checker gratuito e un test locale su 9 esecuzioni con LLM.

BookTranslator

BookTranslator Team

14 min read

Un file di sottotitoli ASS o SSA è un piccolo programma: un'intestazione, una tabella di stili e un elenco di eventi temporizzati il cui ultimo campo mescola dialogo e codice di formattazione. Per tradurlo, modifica solo le parole leggibili in quel ultimo campo, lascia tutto il resto identico byte per byte, e poi controlla tre cose che nessuno strumento di traduzione sistema per te: i font, i codici di spaziatura e le righe karaoke.

Abbiamo tradotto un campione di 14 eventi in cinese semplificato nove volte con un modello locale, usando tre prompt diversi, e abbiamo verificato ogni risultato con uno script che abbiamo scritto. Tempi, posizioni, colori, commenti e disegni sono sopravvissuti in tutte e nove le esecuzioni. Quello che si è rotto sono le parti del file che presuppongono l'inglese: in tutte e nove, i font degli stili non avevano caratteri cinesi, quindi il file si sarebbe affidato al player per sostituire un font, e uno spazio duro della riga inglese è diventato un vuoto visibile in cinese. La riga karaoke è tornata con i tempi puntati sulle parole sbagliate in ogni esecuzione, e in quattro esecuzioni alcune sillabe non evidenziavano nulla.

Risposta rapida: cosa tradurre e cosa lasciare stare

Parte del fileEsempio dal nostro campioneTradurlo?
Intestazione [Script Info]PlayResX: 1920, WrapStyle: 0No. Le posizioni sono calcolate da questi valori.
[V4+ Styles]Style: Default,Trebuchet MS,64,...No, tranne il nome del font, che potresti dover cambiare di proposito
Campi evento 1–90,0:00:01.00,0:00:03.20,Default,Jun,0,0,0,No. Sono livello, tempi, stile, parlante, margini ed effetto.
Blocchi di override{\i1}, {\an8\pos(960,120)}, {\k25}No
Disegni{\p1}m 0 0 l 200 0 200 60 0 60{\p0}No. Questa è una forma vettoriale, non testo.
Eventi Comment:Comment: ...,Earlier draft: Try the stacks.Opzionale. I commenti non appaiono mai sullo schermo.
Note tra parentesi graffe{TL note: "stacks" means the closed shelves}Opzionale. I player le ignorano.
Dialogo visibileDid you find the second volume?Sì
Codici di riga\N, \n, \hMantieni \N. Decidi caso per caso per \n e \h.

Il resto di questa guida spiega perché ogni riga è importante e come verificare il risultato.

Come è costruita una riga ASS

Ogni riga nella sezione [Events] segue il formato dichiarato appena sopra:

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.

Solo il decimo campo, Text, contiene qualcosa che lo spettatore legge. La guida al formato dei file ASS del progetto libass nota che quest'ultimo campo "può contenere virgole", ed è per questo che una divisione imprudente su ogni virgola spezza una riga come Well, if it's there, then, we go now. Uno strumento sicuro divide solo sulle prime nove virgole.

Dentro Text, tutto ciò che è tra parentesi graffe è un blocco di override. Il riferimento ai tag di override di Aegisub definisce i codici che incontrerai più spesso:

  • \N forza un'interruzione di riga in ogni modalità di a capo. \n interrompe la riga solo nella modalità di a capo 2 e altrimenti è uno spazio. \h è uno spazio non separabile.
  • \an8 imposta l'allineamento usando la disposizione del tastierino numerico, quindi 8 è in alto al centro. \pos(960,120) posiziona la riga alle coordinate dello script.
  • \k25 è una sillaba karaoke; le durate sono in centesimi di secondo, quindi 25 significa un quarto di secondo.
  • Dopo \p1, il testo "verrà quindi interpretato come istruzioni di disegno", perciò un traduttore che "traduce" m 0 0 l 200 0 distrugge una forma.
  • Il testo non riconosciuto dentro le parentesi graffe "viene silenziosamente ignorato", ed è per questo che i file dei fansub spesso contengono note del traduttore tra parentesi graffe.

Le righe che iniziano con Comment: usano gli stessi campi, ma secondo la guida di libass "nulla verrà visualizzato sullo schermo".

Cosa abbiamo testato

Abbiamo scritto sample-source.ass, una scena di 14 eventi ambientata in una libreria, con un esempio di ciascuna funzione sopra: corsivo, un'interruzione forzata, virgole nel dialogo, una nota tra parentesi graffe, una riga di commento, un cartello posizionato, un riquadro vettoriale, una dissolvenza, uno spazio non separabile, un cambio di colore con \r, un'interruzione morbida, un effetto Banner scorrevole e una riga karaoke di sei sillabe.

Poi abbiamo chiesto a un modello locale di tradurlo in cinese semplificato in tre modi:

  1. File intero. Incolla l'intero file .ass e chiedi indietro il file tradotto.
  2. Solo testo. Invia solo il campo Text di ogni riga di dialogo come JSON, con i tag inline, e l'istruzione di mantenere ogni blocco {...} e ogni \N, \n e \h.
  3. Protetto. Lo stesso, ma sostituendo prima ogni blocco tra parentesi graffe e codice di riga con un segnaposto numerato, e reinserendo gli originali in seguito.

Nella seconda e terza condizione lo script non invia mai al modello il disegno vettoriale o la riga di commento, quindi quelle righe potevano essere danneggiate solo nella condizione a file intero.

Il modello era Qwen 3.6 27B (Q4_K_M) in LM Studio 0.4.8 su un Apple M4 Max con 64 GB di memoria, con il thinking disattivato e temperatura 0.3. Abbiamo eseguito ogni condizione tre volte, nove esecuzioni in totale. Il primo tentativo della terza esecuzione è terminato quando il server locale ha interrotto la connessione, quindi l'abbiamo riavviato e abbiamo eseguito di nuovo il terzo giro. Lo script è run_llm_ass_test.py, e tutti e nove gli output sono pubblicati senza modifiche insieme ad esso; il README elenca ogni file. Se non hai mai configurato un modello locale, la nostra guida alla traduzione con LLM locale copre le impostazioni.

Questo è stato un piccolo test su un modello, una coppia linguistica e un campione. Mostra quali problemi si verificano e come individuarli. Non classifica strumenti o prompt.

Risultato: il meccanismo è sopravvissuto; le assunzioni inglesi no

Abbiamo controllato ogni output con check_ass_translation.py. L'output completo è in check-results.txt, e results.csv ha una riga per esecuzione, inclusi i problemi che lo script non riesce a vedere.

ControlloFile interoSolo testoProtetto
Tempi, stili e campi 1–9 invariati3 di 33 di 33 di 3
Tag di override invariati3 di 32 di 33 di 3
Righe di disegno e commento intatte3 di 33 di 33 di 3
Font degli stili in grado di disegnare la traduzione0 di 30 di 30 di 3
\h e \n lasciati come spazi nel testo cinese3 di 33 di 33 di 3
Tutti i tag karaoke mantenuti, ciascuno con il proprio testo3 su 30 su 31 su 3

Due risultati ci hanno sorpreso. Incollare l'intero file ha mantenuto la struttura intatta in tutte e tre le esecuzioni, anche se in due di esse è stata tradotta anche la riga Title nell'intestazione. E il prompt solo testo, che sembra più sicuro, ha prodotto gli unici tag corrotti. In un'esecuzione ha restituito {\k25}翻{\k30}页,{\k45}开{\k60}灯 per una riga con sei tag karaoke. Gli ultimi due tag e 1,20 secondi di temporizzazione dell'evidenziazione erano spariti, quindi l'evidenziazione sarebbe terminata ben prima della riga. La stessa esecuzione ha trasformato Room\h12 is upstairs. in 12\h12号房间在楼上。, con il numero della stanza due volte.

Quindi la lezione utile non è "usa il prompt X". È che il danno strutturale che temi è facile da rilevare, e il danno che è effettivamente passato in tutte e nove le esecuzioni si trova in tre punti di cui le pagine degli strumenti per la traduzione ASS non parlano.

1. I font non possono disegnare la nuova lingua

Gli stili del campione usano Trebuchet MS per i dialoghi e Georgia per i cartelli, il che è normale per una versione inglese. Nessuno dei due font contiene caratteri cinesi. Quando abbiamo puntato il test dei glifi del checker sui due file di font, tutti i 12 eventi di testo tradotti in ogni esecuzione hanno fallito:

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 potrebbe sostituire un altro font installato, quindi il sottotitolo potrebbe comunque apparire, ma la release non controlla più il suo aspetto, e uno spettatore il cui sistema manca di un font adatto potrebbe vedere quadrati vuoti. La soluzione è una modifica deliberata al campo Fontname di ogni stile. Quando abbiamo cambiato tutti e tre gli stili in un output in Hiragino Sans GB, un font cinese fornito con macOS, e abbiamo eseguito il test dei glifi su quel font, gli errori dei glifi sono scesi a zero.

Scegli un font che i tuoi spettatori avranno effettivamente, oppure distribuiscilo con il video. La guida di libass dice che le release dovrebbero allegare ogni font che usano, preferibilmente al contenitore MKV. Poiché il font della lingua di destinazione è nuovo, allegarlo ora fa parte del lavoro di traduzione.

2. I codici di spaziatura portano abitudini inglesi

Room\h12 incolla "Room" a "12" in modo che non si separino mai tra le righe. In cinese le parole non sono separate da spazi, ma ogni esecuzione ha mantenuto \h da qualche parte: cinque esecuzioni lo hanno messo tra 12号房间 e 在楼上, tre lo hanno messo prima del numero, e una lo ha messo tra due copie del numero. In ogni caso, lo spettatore vede uno spazio indesiderato. Wait\nhere. ha avuto lo stesso problema. Con WrapStyle: 0, il \n viene reso come uno spazio, quindi 在\n这里等 mostra un vuoto nel mezzo di una frase di tre parole.

La struttura qui va bene; la lingua no. Per una lingua di destinazione senza spazi tra le parole, rimuovi \h e \n dal testo tradotto. Mantieni \N solo dove vuoi un'interruzione forzata, e posizionalo in un punto naturale nella frase di destinazione. Il checker segnala i conteggi modificati di \h e \n come avvisi anziché errori per questo motivo, e avvisa quando uno sopravvive all'interno di testo cinese, giapponese o coreano.

3. La temporizzazione karaoke appartiene alle parole originali

La riga karaoke {\k25}Turn {\k30}the {\k45}page, {\k60}turn {\k40}the {\k80}light temporizza ogni sillaba inglese sulla canzone. Una traduzione non può mantenere quella temporizzazione in modo significativo, perché le parole cinesi non cadono sugli stessi battiti. Le nostre esecuzioni mostrano i diversi modi in cui va storto:

  • In quattro esecuzioni tutti e sei i tag sono stati mantenuti, ciascuno su una parola diversa rispetto a prima. Uno di essi è terminato con {\k40}打{\k80}开, "apri", e ha eliminato completamente "light" dalla riga.
  • In quattro esecuzioni una sillaba non evidenziava nulla, come 打开{\k40}{\k80}灯 (0,40 secondi di evidenziazione su una sillaba vuota). In due di queste, una sillaba di 0,45 secondi evidenziava solo una virgola.
  • In un'esecuzione due tag sono scomparsi, come descritto sopra.

Il checker segnala una riga karaoke tradotta sul posto e qualsiasi sillaba rimasta senza testo. La soluzione migliore è editoriale: non tradurre il karaoke sul posto. Mantieni la riga temporizzata originale per cantare insieme, e aggiungi la traduzione come evento separato: copia l'evento karaoke, assegnagli uno stile proprio (ad esempio, più piccolo e posizionato in basso), rimuovi i tag \k e traduci il testo. Ri-temporizza sillaba per sillaba solo se sei pronto a temporizzarlo tu stesso sull'audio.

Un flusso di lavoro che regge

  1. Rendi prima leggibile la fonte. Se il file mostra caratteri corrotti, correggi la codifica prima di qualsiasi altra cosa. La nostra guida sulla codifica usa esempi SRT, ma gli stessi passaggi a livello di byte funzionano per un file .ass e mantengono sicuri i byte originali. Il checker legge solo UTF-8 e UTF-16.

  2. Decidi l'ambito. Elenca gli stili e decidi quali sono dialoghi, quali cartelli sullo schermo e quali karaoke. I cartelli di solito necessitano di traduzione; il karaoke di solito necessita di una riga separata; i commenti e le note tra parentesi graffe spetta a te deciderlo.

  3. Traduci solo il campo Text. Usa uno strumento che analizzi ASS invece di trattarlo come testo semplice, oppure proteggi tu stesso i tag come nella nostra terza condizione. Mantieni il file sorgente accanto all'output.

  4. Esegui il controllo strutturale.

    python3 check_ass_translation.py source.ass translated.ass
    

    Confronta il numero di eventi, i tipi di evento, i campi 1–9, i valori degli stili, i blocchi di override, i disegni, le righe di commento, \N, le sillabe e le durate karaoke e le righe tornate vuote o invariate. Non giudica la qualità della traduzione.

  5. Correggi i font di proposito. Cambia Fontname in ogni stile che ora contiene testo nella lingua di destinazione, poi esegui il test dei glifi sul file del font che distribuirai:

    pip install fonttools
    python3 check_ass_translation.py source.ass translated.ass --font "Noto Sans SC=/path/to/NotoSansSC-Regular.otf"
    

    Un nome di font modificato appare come avviso, così puoi confermare che ogni modifica è stata intenzionale.

  6. Pulisci i codici di spaziatura e il karaoke come descritto sopra.

  7. Controlla con il video. Apri il file in Aegisub o nel tuo lettore. Verifica che i cartelli si adattino ancora alle forme disegnate dietro di essi, perché un riquadro \p mantiene le sue dimensioni inglesi mentre un cartello tradotto può essere molto più lungo o più corto. Controlla che le righe non siano troppo lunghe per il tempo in cui restano sullo schermo. Nessuno dei due problemi è visibile nel file stesso.

Dove si inserisce BookTranslator

Il traduttore di sottotitoli di BookTranslator accetta file SRT, VTT, ASS e SSA. Secondo la pagina del prodotto, mantiene i timestamp e l'ordine delle cue e conserva lo stile ASS e SSA supportato associato a ogni voce di sottotitolo, così non devi estrarre e reinserire il testo manualmente. Traduce i dialoghi usando le righe circostanti come contesto, il che aiuta con nomi e battute ricorrenti lungo un intero episodio.

Non abbiamo eseguito questo esempio con BookTranslator per questo articolo. Qualunque strumento tu usi, esegui i passaggi da 4 a 7 sul risultato. Uno stile che mantiene il suo font inglese è comunque uno stile che non può disegnare il cinese, e il karaoke tradotto sul posto richiede comunque una decisione editoriale. Per il resto del flusso di lavoro sui sottotitoli, consulta la nostra guida alla traduzione automatica dei sottotitoli, il nostro confronto dei software di traduzione dei sottotitoli e, se la tua traduzione è destinata a YouTube, il flusso di lavoro per i sottotitoli di YouTube.

Quando convertire invece in SRT

Convertire ASS in SRT prima di tradurre rimuove stili, posizioni, disegni e karaoke, il che elimina anche la maggior parte dei problemi sopra. È un compromesso ragionevole se la destinazione mostra solo sottotitoli semplici, o se lo stile non è mai stato importante per la pubblicazione. È il compromesso sbagliato per uscite anime e musicali in cui cartelli e karaoke fanno parte dell'opera. Decidi in base a dove verrà mostrato il file, non a quale formato è più facile da tradurre.

Ottieni i file di test

Tutto ciò che proviene da questo test è liberamente riutilizzabile:

Post Correlati