Como traduzir legendas ASS/SSA sem quebrar estilos, posições ou karaoke
Traduza apenas o diálogo visível num ficheiro .ass e depois verifique a temporização, as etiquetas, o karaoke e os tipos de letra. Com um ficheiro de exemplo, um verificador gratuito e um teste local de LLM com 9 execuções.

Um ficheiro de legendas ASS ou SSA é um pequeno programa: um cabeçalho, uma tabela de estilos e uma lista de eventos temporizados cujo último campo mistura diálogo com código de formatação. Para o traduzir, altere apenas as palavras legíveis desse último campo, deixe tudo o resto exatamente igual byte a byte e depois verifique três coisas que nenhuma ferramenta de tradução corrige por si: os tipos de letra, os códigos de espaçamento e as linhas de karaoke.
Traduzimos uma amostra de 14 eventos para chinês simplificado nove vezes com um modelo local, usando três prompts diferentes, e verificámos cada resultado com um script que escrevemos. A temporização, as posições, as cores, os comentários e os desenhos sobreviveram nas nove execuções. O que se quebrou foram as partes do ficheiro que assumem o inglês: nas nove, os tipos de letra dos estilos não tinham caracteres chineses, pelo que o ficheiro dependeria do leitor para substituir um tipo de letra, e um espaço rígido da linha inglesa tornou-se uma lacuna visível no chinês. A linha de karaoke voltou com a temporização apontada para as palavras erradas em todas as execuções e, em quatro execuções, algumas sílabas não realçaram nada.
Resposta rápida: o que traduzir e o que deixar em paz
| Parte do ficheiro | Exemplo da nossa amostra | Traduzir? |
|---|---|---|
Cabeçalho [Script Info] | PlayResX: 1920, WrapStyle: 0 | Não. As posições são calculadas a partir destes valores. |
[V4+ Styles] | Style: Default,Trebuchet MS,64,... | Não, exceto o nome do tipo de letra, que pode precisar de alterar de propósito |
| Campos 1–9 do evento | 0,0:00:01.00,0:00:03.20,Default,Jun,0,0,0, | Não. Estes são camada, temporização, estilo, falante, margens e efeito. |
| Blocos de substituição | {\i1}, {\an8\pos(960,120)}, {\k25} | Não |
| Desenhos | {\p1}m 0 0 l 200 0 200 60 0 60{\p0} | Não. Isto é uma forma vetorial, não texto. |
Eventos Comment: | Comment: ...,Earlier draft: Try the stacks. | Opcional. Os comentários nunca aparecem no ecrã. |
| Notas entre chavetas | {TL note: "stacks" means the closed shelves} | Opcional. Os leitores ignoram-nas. |
| Diálogo visível | Did you find the second volume? | Sim |
| Códigos de linha | \N, \n, \h | Mantenha \N. Decida caso a caso para \n e \h. |
O resto deste guia explica por que cada linha é importante e como verificar o resultado.
Como uma linha ASS é construída
Cada linha na secção [Events] segue o formato declarado imediatamente acima:
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.
Apenas o décimo campo, Text, contém algo que o espectador lê. O guia do formato de ficheiro ASS do projeto libass observa que este último campo "pode conter vírgulas", razão pela qual uma divisão descuidada em todas as vírgulas quebra uma linha como Well, if it's there, then, we go now. Uma ferramenta segura divide apenas nas primeiras nove vírgulas.
Dentro de Text, qualquer coisa entre chavetas é um bloco de substituição. A referência de etiquetas de substituição do Aegisub define os códigos que encontrará com mais frequência:
\Nforça uma quebra de linha em todos os modos de ajuste.\nquebra a linha apenas no modo de ajuste 2 e, caso contrário, é um espaço.\hé um espaço não separável.\an8define o alinhamento usando o layout do teclado numérico, pelo que 8 é centro superior.\pos(960,120)coloca a linha nas coordenadas do script.\k25é uma sílaba de karaoke; as durações são em centésimos de segundo, pelo que 25 significa um quarto de segundo.- Após
\p1, o texto "será então interpretado como instruções de desenho", pelo que um tradutor que "traduza"m 0 0 l 200 0destrói uma forma. - Texto não reconhecido dentro de chavetas "é silenciosamente ignorado", razão pela qual os ficheiros de fansub frequentemente contêm notas do tradutor entre chavetas.
As linhas que começam com Comment: usam os mesmos campos, mas de acordo com o guia libass "nada será exibido no ecrã."
O que testámos
Escrevemos sample-source.ass, uma cena de 14 eventos ambientada numa livraria, com um exemplo de cada funcionalidade acima: itálico, uma quebra forçada, vírgulas no diálogo, uma nota entre chavetas, uma linha de comentário, um sinal posicionado, uma caixa vetorial, um fade, um espaço não separável, uma mudança de cor com \r, uma quebra suave, um efeito de Banner deslizante e uma linha de karaoke com seis sílabas.
Depois pedimos a um modelo local para traduzir para chinês simplificado de três formas:
- Ficheiro completo. Cole o ficheiro
.assinteiro e peça o ficheiro traduzido de volta. - Apenas texto. Envie apenas o campo
Textde cada linha de diálogo como JSON, com as etiquetas inline, e a instrução para manter cada bloco{...}e cada\N,\ne\h. - Protegido. O mesmo, mas substitua primeiro cada bloco entre chavetas e código de linha por um marcador numerado, e reponha os originais depois.
Na segunda e terceira condições, o script nunca envia o desenho vetorial ou a linha de comentário para o modelo, pelo que essas linhas só podiam ser danificadas na condição de ficheiro completo.
O modelo foi o Qwen 3.6 27B (Q4_K_M) no LM Studio 0.4.8 num Apple M4 Max com 64 GB de memória, com o raciocínio desativado e temperatura 0,3. Executámos cada condição três vezes, nove execuções no total. A primeira tentativa da terceira execução terminou quando o servidor local perdeu a ligação, pelo que o reiniciámos e executámos a terceira ronda novamente. O script é run_llm_ass_test.py, e todas as nove saídas são publicadas sem edição ao lado dele; o README lista todos os ficheiros. Se nunca configurou um modelo local, o nosso guia de tradução com LLM local cobre as definições.
Este foi um pequeno teste de um modelo, um par de línguas e uma amostra. Mostra que problemas acontecem e como detetá-los. Não classifica ferramentas ou prompts.
Resultado: A maquinaria sobreviveu; as suposições inglesas não
Verificámos cada saída com check_ass_translation.py. A saída completa está em check-results.txt, e results.csv tem uma linha por execução, incluindo problemas que o script não consegue ver.
| Verificação | Ficheiro completo | Apenas texto | Protegido |
|---|---|---|---|
| Tempos, estilos e campos 1–9 inalterados | 3 de 3 | 3 de 3 | 3 de 3 |
| Etiquetas de substituição inalteradas | 3 de 3 | 2 de 3 | 3 de 3 |
| Linhas de desenho e comentário intactas | 3 de 3 | 3 de 3 | 3 de 3 |
| Tipos de letra dos estilos capazes de desenhar a tradução | 0 de 3 | 0 de 3 | 0 de 3 |
\h e \n deixados como lacunas no texto chinês | 3 de 3 | 3 de 3 | 3 de 3 |
| Todas as etiquetas de karaoke mantidas, cada uma com texto | 3 de 3 | 0 de 3 | 1 de 3 |
Dois resultados surpreenderam-nos. Colar o ficheiro completo manteve a estrutura intacta nas três execuções, embora em duas delas também tenha traduzido a linha Title do cabeçalho. E o prompt só de texto, que parece mais seguro, produziu as únicas etiquetas quebradas. Numa execução, devolveu {\k25}翻{\k30}页,{\k45}开{\k60}灯 para uma linha com seis etiquetas de karaoke. As duas últimas etiquetas e 1,20 segundos de temporização do realce desapareceram, pelo que o realce terminaria bem antes da linha. A mesma execução transformou Room\h12 is upstairs. em 12\h12号房间在楼上。, com o número do quarto duplicado.
Portanto, a lição útil não é "usar o prompt X". É que o dano estrutural que receia é fácil de detetar, e o dano que realmente passou nas nove execuções reside em três pontos que as páginas de ferramentas para tradução de ASS não abordam.
1. Os tipos de letra não conseguem desenhar o novo idioma
Os estilos da amostra usam Trebuchet MS para o diálogo e Georgia para os letreiros, o que é normal para uma versão em inglês. Nenhum dos tipos de letra contém caracteres chineses. Quando apontámos o teste de glifos do verificador aos dois ficheiros de tipos de letra, todos os 12 eventos de texto traduzidos em cada execução falharam:
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. 书人仅作员工库架闭限
Um leitor pode substituir por outro tipo de letra instalado, pelo que a legenda pode ainda aparecer, mas a versão deixa de controlar o seu aspeto, e um espetador cujo sistema não tenha um tipo de letra adequado pode ver caixas vazias. A correção é uma edição deliberada do campo Fontname de cada estilo. Quando alterámos os três estilos numa saída para Hiragino Sans GB, um tipo de letra chinês incluído no macOS, e executámos o teste de glifos com esse tipo de letra, os erros de glifos passaram a zero.
Escolha um tipo de letra que os seus espetadores realmente tenham, ou inclua-o com o vídeo. O guia do libass diz que as versões devem anexar todos os tipos de letra que utilizam, de preferência ao contentor MKV. Como o tipo de letra do idioma de destino é novo, anexá-lo passa a fazer parte do trabalho de tradução.
2. Os códigos de espaçamento transportam hábitos do inglês
Room\h12 cola "Room" a "12" para que nunca se separem entre linhas. Em chinês, as palavras não são separadas por espaços, mas todas as execuções mantiveram o \h em algum lugar: cinco execuções colocaram-no entre 12号房间 e 在楼上, três colocaram-no antes do número, e uma colocou-o entre duas cópias do número. De qualquer forma, o espetador vê um espaço indesejado. Wait\nhere. teve o mesmo problema. Com WrapStyle: 0, o \n é renderizado como um espaço, pelo que 在\n这里等 mostra uma lacuna no meio de uma frase de três palavras.
A estrutura está bem aqui; o idioma não. Para um idioma de destino sem espaços entre palavras, remova \h e \n do texto traduzido. Mantenha \N apenas onde quiser uma quebra forçada, e coloque-o num ponto natural da frase de destino. O verificador reporta contagens alteradas de \h e \n como avisos em vez de erros por esta razão, e avisa quando um deles sobrevive dentro de texto chinês, japonês ou coreano.
3. A temporização do karaoke pertence às palavras originais
A linha de karaoke {\k25}Turn {\k30}the {\k45}page, {\k60}turn {\k40}the {\k80}light temporiza cada sílaba inglesa com a música. Uma tradução não pode manter essa temporização de forma significativa, porque as palavras chinesas não caem nas mesmas batidas. As nossas execuções mostram as diferentes formas como isto corre mal:
- Em quatro execuções, todas as seis etiquetas foram mantidas, cada uma numa palavra diferente da anterior. Uma delas terminou com
{\k40}打{\k80}开, "abrir", e eliminou "light" da linha por completo. - Em quatro execuções, uma sílaba não realçou nada, como
打开{\k40}{\k80}灯(0,40 segundos de realce numa sílaba vazia). Em duas dessas, uma sílaba de 0,45 segundos também realçou apenas uma vírgula. - Numa execução, duas etiquetas desapareceram, como descrito acima.
O verificador sinaliza uma linha de karaoke traduzida no local e qualquer sílaba que fique sem texto. A melhor correção é editorial: não traduza o karaoke no local. Mantenha a linha temporizada original para cantar acompanhando, e adicione a tradução como um evento separado: copie o evento de karaoke, dê-lhe um estilo próprio (por exemplo, mais pequeno e colocado na parte inferior), remova as etiquetas \k e traduza o texto. Retemporize-o sílaba a sílaba apenas se estiver preparado para o temporizar com o áudio você mesmo.
Um fluxo de trabalho que se mantém
-
Torne a fonte legível primeiro. Se o ficheiro mostrar caracteres corrompidos, corrija a codificação antes de qualquer outra coisa. O nosso guia de codificação usa exemplos SRT, mas os mesmos passos ao nível dos bytes funcionam para um ficheiro
.asse mantêm os bytes originais seguros. O verificador lê apenas UTF-8 e UTF-16. -
Decida o âmbito. Liste os estilos e decida quais são diálogo, quais são letreiros no ecrã e quais são karaoke. Os letreiros normalmente precisam de tradução; o karaoke normalmente precisa de uma linha separada; os comentários e as notas entre chavetas são você que decide.
-
Traduza apenas o campo
Text. Use uma ferramenta que analise ASS em vez de o tratar como texto simples, ou proteja as etiquetas você mesmo como na nossa terceira condição. Mantenha o ficheiro de origem junto da saída. -
Execute a verificação estrutural.
python3 check_ass_translation.py source.ass translated.assCompara a contagem de eventos, os tipos de eventos, os campos 1–9, os valores de estilo, os blocos de substituição, os desenhos, as linhas de comentário,
\N, as sílabas e durações de karaoke, e as linhas que voltaram vazias ou inalteradas. Não avalia a qualidade da tradução. -
Corrija as fontes de propósito. Altere o
Fontnameem cada estilo que agora contém texto no idioma de destino e, em seguida, execute o teste de glifos com o ficheiro de fonte que vai distribuir:pip install fonttools python3 check_ass_translation.py source.ass translated.ass --font "Noto Sans SC=/path/to/NotoSansSC-Regular.otf"Um nome de fonte alterado aparece como um aviso, para que possa confirmar que cada alteração foi intencional.
-
Limpe os códigos de espaçamento e o karaoke conforme descrito acima.
-
Veja com o vídeo. Abra o ficheiro no Aegisub ou no seu leitor. Verifique se os letreiros ainda se ajustam às formas desenhadas por trás deles, porque uma caixa
\pmantém o tamanho em inglês enquanto um letreiro traduzido pode ser muito mais longo ou mais curto. Verifique se as linhas não são demasiado longas para o tempo em ecrã. Nenhum dos problemas é visível no próprio ficheiro.
Onde o BookTranslator se Encaixa
O Tradutor de Legendas do BookTranslator aceita ficheiros SRT, VTT, ASS e SSA. De acordo com a página do produto, mantém os carimbos de tempo e a ordem das entradas e mantém o estilo ASS e SSA suportado associado a cada entrada de legenda, para que não tenha de extrair e reinserir o texto manualmente. Traduz o diálogo com as linhas circundantes como contexto, o que ajuda com nomes e piadas recorrentes ao longo de um episódio inteiro.
Não executámos esta amostra no BookTranslator para este artigo. Independentemente da ferramenta que usar, execute os passos 4 a 7 no resultado. Um estilo que mantém a fonte inglesa continua a ser um estilo que não consegue desenhar chinês, e o karaoke traduzido no local ainda requer uma decisão editorial. Para o resto do fluxo de trabalho de legendas, consulte o nosso guia de tradução de legendas com IA, a nossa comparação de software de tradução de legendas e, se a sua tradução for para o YouTube, o fluxo de trabalho de legendas do YouTube.
Quando Converter para SRT em Vez Disso
Converter ASS para SRT antes de traduzir remove os estilos, as posições, os desenhos e o karaoke, o que também remove a maioria dos problemas acima. É uma troca razoável se o seu destino apenas mostrar legendas simples, ou se o estilo nunca foi importante para o lançamento. É a troca errada para lançamentos de anime e música em que os letreiros e o karaoke fazem parte da obra. Decida com base no local onde o ficheiro será exibido, não no formato que é mais fácil de traduzir.
Obtenha os Ficheiros de Teste
Tudo deste teste é gratuito para reutilização:
- sample-source.ass: a amostra em inglês com 14 eventos;
- check_ass_translation.py: o verificador (biblioteca padrão do Python; o teste
--fontrequer fontTools); - run_llm_ass_test.py: as três condições de prompt para qualquer servidor local compatível com OpenAI;
- results.csv e check-results.txt: resultados por execução;
- README.txt: a lista de ficheiros e as definições de teste, com as nove saídas não editadas na pasta
outputs.
Publicações relacionadas




