BookTranslator
BookTranslator

Como traduzir legendas ASS/SSA sem quebrar estilos, posições ou karaokê

Traduza apenas o diálogo visível em um arquivo .ass e depois verifique timing, tags, karaokê e fontes. Com um arquivo de exemplo, um verificador gratuito e um teste local de LLM com 9 execuções.

BookTranslator

BookTranslator Team

14 min read

Um arquivo de legenda ASS ou SSA é um pequeno programa: um cabeçalho, uma tabela de estilos e uma lista de eventos cronometrados cujo último campo mistura diálogo com código de formatação. Para traduzi-lo, altere apenas as palavras legíveis nesse último campo, deixe todo o resto byte a byte intacto e depois verifique três coisas que nenhuma ferramenta de tradução corrige para você: as fontes, os códigos de espaçamento e as linhas de karaokê.

Traduzimos uma amostra de 14 eventos para chinês simplificado nove vezes com um modelo local, usando três prompts diferentes, e verificamos cada resultado com um script que escrevemos. O timing, as posições, as cores, os comentários e os desenhos sobreviveram nas nove execuções. O que quebrou foram as partes do arquivo que pressupõem o inglês: nas nove, as fontes dos estilos não tinham caracteres chineses, então o arquivo dependeria do player para substituir a fonte, e um espaço rígido da linha em inglês virou uma lacuna visível no chinês. A linha de karaokê voltou com o timing apontando para as palavras erradas em todas as execuções, e em quatro execuções algumas sílabas não destacaram nada.

Resposta rápida: o que traduzir e o que deixar em paz

Parte do arquivoExemplo da nossa amostraTraduzir?
Cabeçalho [Script Info]PlayResX: 1920, WrapStyle: 0Não. As posições são calculadas a partir desses valores.
[V4+ Styles]Style: Default,Trebuchet MS,64,...Não, exceto o nome da fonte, que você pode precisar alterar de propósito
Campos 1–9 do evento0,0:00:01.00,0:00:03.20,Default,Jun,0,0,0,Não. São camada, timing, estilo, falante, margens e efeito.
Blocos de override{\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. Comentários nunca aparecem na tela.
Notas entre chaves{TL note: "stacks" means the closed shelves}Opcional. Os players as ignoram.
Diálogo visívelDid you find the second volume?Sim
Códigos de linha\N, \n, \hMantenha \N. Decida caso a caso para \n e \h.

O restante deste guia explica por que cada linha importa e como verificar o resultado.

Como uma linha ASS é construída

Cada linha na seção [Events] segue o formato declarado logo acima dela:

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 arquivo ASS do projeto libass observa que este último campo "pode conter vírgulas", e é por isso que uma divisão descuidada em cada vírgula 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 chaves é um bloco de substituição. A referência de tags de substituição do Aegisub define os códigos que você encontrará com mais frequência:

  • \N força uma quebra de linha em todos os modos de quebra. \n quebra a linha apenas no modo de quebra 2 e, caso contrário, é um espaço. \h é um espaço não separável.
  • \an8 define o alinhamento usando o layout do teclado numérico, então 8 é superior centralizado. \pos(960,120) posiciona a linha nas coordenadas do script.
  • \k25 é uma sílaba de karaokê; as durações são em centissegundos, então 25 significa um quarto de segundo.
  • Após \p1, o texto "será então interpretado como instruções de desenho", então um tradutor que "traduz" m 0 0 l 200 0 destrói uma forma.
  • Texto não reconhecido dentro de chaves "é silenciosamente ignorado", e é por isso que arquivos de fansub frequentemente carregam notas do tradutor entre chaves.

Linhas que começam com Comment: usam os mesmos campos, mas de acordo com o guia do libass "nada será exibido na tela".

O que testamos

Escrevemos sample-source.ass, uma cena de 14 eventos ambientada em uma livraria, com um exemplo de cada recurso acima: itálico, uma quebra forçada, vírgulas no diálogo, uma nota entre chaves, uma linha de comentário, uma placa posicionada, 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 rolagem Banner e uma linha de karaokê de seis sílabas.

Em seguida, pedimos a um modelo local para traduzi-lo para chinês simplificado de três maneiras:

  1. Arquivo inteiro. Cole o arquivo .ass completo e peça o arquivo traduzido de volta.
  2. Somente texto. Envie apenas o campo Text de cada linha de diálogo como JSON, com as tags embutidas, e a instrução de manter cada bloco {...} e cada \N, \n e \h.
  3. Protegido. O mesmo, mas substitua cada bloco entre chaves e código de linha por um marcador numerado primeiro, e recoloque os originais depois.

Na segunda e terceira condições, o script nunca envia o desenho vetorial ou a linha de comentário ao modelo, então essas linhas só poderiam ser danificadas na condição de arquivo inteiro.

O modelo foi o Qwen 3.6 27B (Q4_K_M) no LM Studio 0.4.8 em um Apple M4 Max com 64 GB de memória, com o raciocínio desativado e temperatura 0,3. Executamos cada condição três vezes, nove execuções no total. A primeira tentativa da terceira execução terminou quando o servidor local derrubou a conexão, então o reiniciamos e executamos a terceira rodada novamente. O script é run_llm_ass_test.py, e todas as nove saídas são publicadas sem edição junto a ele; o README lista todos os arquivos. Se você nunca configurou um modelo local, nosso guia de tradução com LLM local cobre as configurações.

Este foi um pequeno teste de um modelo, um par de idiomas e uma amostra. Ele mostra quais problemas acontecem e como detectá-los. Não classifica ferramentas ou prompts.

Resultado: A maquinaria sobreviveu; as suposições do inglês, não

Verificamos 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çãoArquivo completoSomente textoProtegido
Tempo, estilos e campos 1–9 inalterados3 de 33 de 33 de 3
Tags de substituição inalteradas3 de 32 de 33 de 3
Linhas de desenho e comentário intactas3 de 33 de 33 de 3
Fontes de estilo capazes de renderizar a tradução0 de 30 de 30 de 3
\h e \n mantidos como lacunas no texto em chinês3 de 33 de 33 de 3
Todas as tags de karaokê mantidas, cada uma com texto3 de 30 de 31 de 3

Dois resultados nos surpreenderam. Colar o arquivo inteiro 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 somente texto, que parece mais seguro, produziu as únicas tags quebradas. Em uma execução, ele retornou {\k25}翻{\k30}页,{\k45}开{\k60}灯 para uma linha com seis tags de karaokê. As duas últimas tags e 1,20 segundo de tempo de destaque desapareceram, então o destaque 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 é "use o prompt X". É que o dano estrutural que você teme é fácil de detectar, e o dano que realmente passou em todas as nove execuções está em três pontos que as páginas de ferramentas para tradução de ASS não discutem.

1. As fontes não conseguem desenhar o novo idioma

Os estilos da amostra usam Trebuchet MS para diálogo e Georgia para placas, o que é normal para um lançamento em inglês. Nenhuma das fontes contém caracteres chineses. Quando apontamos o teste de glifos do verificador para os dois arquivos de fonte, 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 player pode substituir por outra fonte instalada, então a legenda ainda pode aparecer, mas o lançamento deixa de controlar sua aparência, e um espectador cujo sistema não tenha uma fonte adequada pode ver quadrados vazios. A correção é uma edição deliberada no campo Fontname de cada estilo. Quando alteramos os três estilos em uma saída para Hiragino Sans GB, uma fonte chinesa que acompanha o macOS, e rodamos o teste de glifos com essa fonte, os erros de glifos foram para zero.

Escolha uma fonte que seus espectadores realmente tenham, ou inclua-a com o vídeo. O guia do libass diz que os lançamentos devem anexar todas as fontes que usam, de preferência ao contêiner MKV. Como a fonte do idioma de destino é nova, anexá-la agora faz parte do trabalho de tradução.

2. Códigos de espaçamento carregam 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 toda execução manteve o \h em algum lugar: cinco execuções o colocaram entre 12号房间 e 在楼上, três o puseram antes do número, e uma o colocou entre duas cópias do número. De qualquer forma, o espectador vê um espaço perdido. Wait\nhere. teve o mesmo problema. Com WrapStyle: 0, o \n é renderizado como espaço, então 在\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 você quiser uma quebra forçada, e coloque-o em um ponto natural da frase de destino. O verificador relata contagens alteradas de \h e \n como avisos em vez de erros por esse motivo, e avisa quando um deles sobrevive dentro de texto em chinês, japonês ou coreano.

3. A sincronia do karaokê pertence às palavras originais

A linha de karaokê {\k25}Turn {\k30}the {\k45}page, {\k60}turn {\k40}the {\k80}light sincroniza cada sílaba em inglês com a música. Uma tradução não pode manter essa sincronia de forma significativa, porque as palavras chinesas não caem nas mesmas batidas. Nossas execuções mostram as diferentes maneiras como isso dá errado:

  • Em quatro execuções, todas as seis tags foram mantidas, cada uma em uma palavra diferente da anterior. Uma delas terminou com {\k40}打{\k80}开, "abrir", e removeu "light" da linha completamente.
  • Em quatro execuções, uma sílaba não destacou nada, como 打开{\k40}{\k80}灯 (0,40 segundo de destaque em uma sílaba vazia). Em duas delas, uma sílaba de 0,45 segundo também destacou apenas uma vírgula.
  • Em uma execução, duas tags desapareceram, como descrito acima.

O verificador sinaliza uma linha de karaokê traduzida no local e qualquer sílaba deixada sem texto. A correção melhor é editorial: não traduza o karaokê no local. Mantenha a linha original sincronizada para cantar junto, e adicione a tradução como um evento separado: copie o evento de karaokê, dê a ele seu próprio estilo (por exemplo, menor e posicionado na parte inferior), remova as tags \k e traduza o texto. Ressincronize sílaba por sílaba apenas se você estiver preparado para sincronizá-la ao áudio você mesmo.

Um Fluxo de Trabalho que Funciona

  1. Torne a fonte legível primeiro. Se o arquivo mostrar caracteres corrompidos, corrija a codificação antes de qualquer coisa. Nosso guia de codificação usa exemplos de SRT, mas os mesmos passos em nível de byte funcionam para um arquivo .ass e mantêm os bytes originais seguros. O verificador lê apenas UTF-8 e UTF-16.

  2. Decida o escopo. Liste os estilos e decida quais são diálogo, quais são placas na tela e quais são karaokê. Placas geralmente precisam de tradução; karaokê geralmente precisa de uma linha separada; comentários e notas entre chaves são você quem decide.

  3. Traduza apenas o campo Text. Use uma ferramenta que analise ASS em vez de tratá-lo como texto simples, ou proteja as tags você mesmo como na nossa terceira condição. Mantenha o arquivo de origem junto da saída.

  4. Execute a verificação estrutural.

    python3 check_ass_translation.py source.ass translated.ass
    

    Ela compara contagem de eventos, tipos de evento, campos 1–9, valores de estilo, blocos de substituição, desenhos, linhas de comentário, \N, sílabas e durações de karaokê, e linhas que voltaram vazias ou inalteradas. Ela não julga a qualidade da tradução.

  5. Corrija as fontes de propósito. Altere Fontname em cada estilo que agora contém texto no idioma de destino e, em seguida, execute o teste de glifos com o arquivo de fonte que você 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 você possa confirmar que cada alteração foi intencional.

  6. Limpe os códigos de espaçamento e o karaokê conforme descrito acima.

  7. Assista com o vídeo. Abra o arquivo no Aegisub ou no seu player. Verifique se as placas ainda se encaixam nas formas desenhadas atrás delas, porque uma caixa \p mantém seu tamanho em inglês enquanto uma placa traduzida pode ser muito mais longa ou mais curta. Verifique se as linhas não são longas demais para o tempo em tela. Nenhum dos dois problemas é visível no próprio arquivo.

Onde o BookTranslator se encaixa

O Tradutor de Legendas do BookTranslator aceita arquivos SRT, VTT, ASS e SSA. De acordo com a página do produto, ele mantém os carimbos de tempo e a ordem das legendas e mantém a estilização ASS e SSA suportada anexada a cada entrada de legenda, para que você não precise extrair e reinserir o texto manualmente. Ele traduz o diálogo com as linhas ao redor como contexto, o que ajuda com nomes e piadas recorrentes ao longo de um episódio inteiro.

Não executamos esta amostra no BookTranslator para este artigo. Qualquer que seja a ferramenta que você usar, execute as etapas 4 a 7 no resultado. Um estilo que mantém sua fonte em inglês ainda é um estilo que não consegue desenhar caracteres chineses, e o karaokê traduzido no local ainda precisa de uma decisão editorial. Para o restante do fluxo de trabalho de legendas, consulte nosso guia de tradução de legendas com IA, nossa comparação de softwares de tradução de legendas e, se 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, posições, desenhos e karaokê, o que também elimina a maioria dos problemas acima. Essa é uma troca razoável se o seu destino exibe apenas legendas simples, ou se a estilização nunca foi importante para o lançamento. É a troca errada para lançamentos de anime e música em que as placas e o karaokê fazem parte da obra. Decida com base em onde o arquivo será exibido, não em qual formato é mais fácil de traduzir.

Obtenha os arquivos de teste

Tudo deste teste é gratuito para reutilização:

Posts Relacionados