Comment traduire des sous-titres ASS/SSA sans casser les styles, les positions ni le karaoké
Traduisez uniquement le dialogue visible d'un fichier .ass, puis vérifiez le timing, les balises, le karaoké et les polices. Avec un fichier d'exemple, un vérificateur gratuit et un test de LLM local en 9 passes.

Un fichier de sous-titres ASS ou SSA est un petit programme : un en-tête, une table de styles et une liste d'événements minutés dont le dernier champ mêle dialogue et code de mise en forme. Pour le traduire, ne modifiez que les mots lisibles de ce dernier champ, laissez tout le reste strictement intact octet par octet, puis vérifiez trois choses qu'aucun outil de traduction ne corrige à votre place : les polices, les codes d'espacement et les lignes de karaoké.
Nous avons traduit un échantillon de 14 événements en chinois simplifié neuf fois avec un modèle local, en utilisant trois invites différentes, et avons vérifié chaque résultat avec un script que nous avons écrit. Le timing, les positions, les couleurs, les commentaires et les dessins ont survécu dans les neuf cas. Ce qui a cassé, ce sont les parties du fichier qui présupposent l'anglais : dans les neuf cas, les polices des styles ne contenaient aucun caractère chinois, si bien que le fichier dépendait du lecteur pour substituer une police, et une espace insécable de la ligne anglaise est devenue un vide visible dans la version chinoise. La ligne de karaoké est revenue avec son timing pointé sur les mauvais mots à chaque passe, et dans quatre passes, certaines syllabes ne mettaient rien en surbrillance du tout.
Réponse rapide : ce qu'il faut traduire et ce qu'il faut laisser tel quel
| Partie du fichier | Exemple issu de notre échantillon | Faut-il le traduire ? |
|---|---|---|
En-tête [Script Info] | PlayResX: 1920, WrapStyle: 0 | Non. Les positions sont calculées à partir de ces valeurs. |
[V4+ Styles] | Style: Default,Trebuchet MS,64,... | Non, sauf le nom de la police, qu'il peut être nécessaire de modifier volontairement |
| Champs d'événement 1–9 | 0,0:00:01.00,0:00:03.20,Default,Jun,0,0,0, | Non. Ce sont le calque, le timing, le style, le locuteur, les marges et l'effet. |
| Blocs de remplacement | {\i1}, {\an8\pos(960,120)}, {\k25} | Non |
| Dessins | {\p1}m 0 0 l 200 0 200 60 0 60{\p0} | Non. Il s'agit d'une forme vectorielle, pas de texte. |
Événements Comment: | Comment: ...,Earlier draft: Try the stacks. | Facultatif. Les commentaires n'apparaissent jamais à l'écran. |
| Notes entre accolades | {TL note: "stacks" means the closed shelves} | Facultatif. Les lecteurs les ignorent. |
| Dialogue visible | Did you find the second volume? | Oui |
| Codes de ligne | \N, \n, \h | Conservez \N. Décidez au cas par cas pour \n et \h. |
Le reste de ce guide explique pourquoi chaque ligne compte et comment vérifier le résultat.
Comment une ligne ASS est construite
Chaque ligne de la section [Events] suit le format déclaré juste au-dessus :
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.
Seul le dixième champ, Text, contient quelque chose que le spectateur lit. Le guide du format de fichier ASS du projet libass note que ce dernier champ « peut contenir des virgules », c'est pourquoi une division imprudente sur chaque virgule casse une ligne comme Well, if it's there, then, we go now. Un outil sûr ne divise que sur les neuf premières virgules.
À l'intérieur de Text, tout ce qui est entre accolades est un bloc de substitution. La référence des balises de substitution d'Aegisub définit les codes que vous rencontrerez le plus souvent :
\Nforce un saut de ligne dans tous les modes de retour à la ligne.\nne coupe la ligne qu'en mode de retour à la ligne 2 et est sinon un espace.\hest un espace insécable.\an8définit l'alignement selon la disposition du pavé numérique, donc 8 est en haut au centre.\pos(960,120)place la ligne aux coordonnées du script.\k25est une syllabe de karaoké ; les durées sont en centièmes de seconde, donc 25 signifie un quart de seconde.- Après
\p1, le texte « sera alors interprété comme des instructions de dessin », donc un traducteur qui « traduit »m 0 0 l 200 0détruit une forme. - Le texte non reconnu entre accolades « est silencieusement ignoré », c'est pourquoi les fichiers de fansub contiennent souvent des notes de traducteur entre accolades.
Les lignes qui commencent par Comment: utilisent les mêmes champs, mais selon le guide libass « rien ne sera affiché à l'écran ».
Ce que nous avons testé
Nous avons écrit sample-source.ass, une scène de 14 événements située dans une librairie, avec un exemple de chaque fonctionnalité ci-dessus : italique, saut forcé, virgules dans le dialogue, note entre accolades, ligne de commentaire, panneau positionné, boîte vectorielle, fondu, espace insécable, changement de couleur avec \r, saut doux, effet Banner défilant et une ligne de karaoké à six syllabes.
Ensuite, nous avons demandé à un modèle local de le traduire en chinois simplifié de trois manières :
- Fichier entier. Collez le fichier
.assentier et demandez le fichier traduit en retour. - Texte uniquement. Envoyez uniquement le champ
Textde chaque ligne de dialogue en JSON, avec les balises en ligne, et l'instruction de conserver chaque bloc{...}et chaque\N,\net\h. - Protégé. Idem, mais remplacez d'abord chaque bloc entre accolades et chaque code de ligne par un espace réservé numéroté, puis remettez les originaux en place ensuite.
Dans les deuxième et troisième conditions, le script n'envoie jamais le dessin vectoriel ni la ligne de commentaire au modèle, donc ces lignes ne pouvaient être endommagées que dans la condition fichier entier.
Le modèle était Qwen 3.6 27B (Q4_K_M) dans LM Studio 0.4.8 sur un Apple M4 Max avec 64 Go de mémoire, avec la réflexion désactivée et une température de 0,3. Nous avons exécuté chaque condition trois fois, neuf exécutions au total. La première tentative de la troisième exécution s'est terminée lorsque le serveur local a coupé la connexion, nous l'avons donc redémarré et avons relancé le troisième tour. Le script est run_llm_ass_test.py, et les neuf sorties sont publiées sans modification à côté ; le README liste chaque fichier. Si vous n'avez jamais configuré de modèle local, notre guide de traduction avec LLM local couvre les paramètres.
Il s'agissait d'un petit test d'un modèle, d'une paire de langues et d'un échantillon. Il montre quels problèmes surviennent et comment les détecter. Il ne classe pas les outils ni les invites.
Résultat : la mécanique a survécu ; les présupposés anglais, non
Nous avons vérifié chaque sortie avec check_ass_translation.py. La sortie complète se trouve dans check-results.txt, et results.csv contient une ligne par exécution, y compris les problèmes que le script ne peut pas voir.
| Vérification | Fichier entier | Texte uniquement | Protégé |
|---|---|---|---|
| Minutage, styles et champs 1–9 inchangés | 3 sur 3 | 3 sur 3 | 3 sur 3 |
| Balises de substitution inchangées | 3 sur 3 | 2 sur 3 | 3 sur 3 |
| Lignes de dessin et de commentaire intactes | 3 sur 3 | 3 sur 3 | 3 sur 3 |
| Polices de style capables de rendre la traduction | 0 sur 3 | 0 sur 3 | 0 sur 3 |
\h et \n laissés comme espaces dans le texte chinois | 3 sur 3 | 3 sur 3 | 3 sur 3 |
| Toutes les balises karaoké conservées, chacune avec son texte | 3 sur 3 | 0 sur 3 | 1 sur 3 |
Deux résultats nous ont surpris. Le collage du fichier entier a conservé la structure intacte dans les trois exécutions, bien que dans deux d'entre elles, il ait aussi traduit la ligne Title de l'en-tête. Et l'invite texte seul, qui semble plus sûre, a produit les seules balises cassées. Dans une exécution, elle a renvoyé {\k25}翻{\k30}页,{\k45}开{\k60}灯 pour une ligne avec six balises karaoké. Les deux dernières balises et 1,20 seconde de minutage de surbrillance avaient disparu, de sorte que la surbrillance se terminerait bien avant la ligne. La même exécution a transformé Room\h12 is upstairs. en 12\h12号房间在楼上。, avec le numéro de chambre en double.
La leçon utile n'est donc pas « utilisez l'invite X ». C'est que les dommages structurels que vous craignez sont faciles à détecter, et que les dommages qui ont réellement passé dans les neuf exécutions se situent à trois endroits dont les pages d'outils pour la traduction ASS ne parlent pas.
1. Les polices ne peuvent pas dessiner la nouvelle langue
Les styles de l'échantillon utilisent Trebuchet MS pour les dialogues et Georgia pour les panneaux, ce qui est normal pour une version anglaise. Aucune de ces polices ne contient de caractères chinois. Lorsque nous avons pointé le test de glyphes du vérificateur sur les deux fichiers de polices, les 12 événements de texte traduits dans chaque exécution ont échoué :
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 lecteur peut substituer une autre police installée, donc le sous-titre pourrait encore apparaître, mais la version ne contrôle plus son apparence, et un spectateur dont le système manque d'une police appropriée pourrait voir des carrés vides. La solution est une modification délibérée du champ Fontname de chaque style. Lorsque nous avons changé les trois styles d'une sortie en Hiragino Sans GB, une police chinoise fournie avec macOS, et exécuté le test de glyphes sur cette police, les erreurs de glyphes sont tombées à zéro.
Choisissez une police que vos spectateurs auront réellement, ou joignez-la à la vidéo. Le guide libass indique que les versions doivent joindre chaque police qu'elles utilisent, de préférence au conteneur MKV. Comme la police de la langue cible est nouvelle, la joindre fait désormais partie du travail de traduction.
2. Les codes d'espacement portent des habitudes anglaises
Room\h12 colle « Room » à « 12 » pour qu'ils ne se séparent jamais sur plusieurs lignes. En chinois, les mots ne sont pas séparés par des espaces, mais chaque exécution a conservé le \h quelque part : cinq exécutions l'ont placé entre 12号房间 et 在楼上, trois l'ont mis avant le nombre, et une l'a mis entre deux copies du nombre. Dans tous les cas, le spectateur voit un espace parasite. Wait\nhere. avait le même problème. Avec WrapStyle: 0, le \n s'affiche comme un espace, donc 在\n这里等 montre un vide au milieu d'une phrase de trois mots.
La structure est correcte ici ; la langue ne l'est pas. Pour une langue cible sans espaces entre les mots, supprimez \h et \n du texte traduit. Ne conservez \N que là où vous voulez un saut forcé, et placez-le à un point naturel dans la phrase cible. Le vérificateur signale les changements de nombre de \h et \n comme des avertissements plutôt que des erreurs pour cette raison, et il avertit lorsqu'un de ces codes survit dans un texte chinois, japonais ou coréen.
3. Le minutage karaoké appartient aux mots originaux
La ligne karaoké {\k25}Turn {\k30}the {\k45}page, {\k60}turn {\k40}the {\k80}light synchronise chaque syllabe anglaise sur la chanson. Une traduction ne peut pas conserver ce minutage de manière significative, car les mots chinois ne tombent pas sur les mêmes temps. Nos exécutions montrent les différentes façons dont cela tourne mal :
- Dans quatre exécutions, les six balises ont été conservées, chacune sur un mot différent de l'original. L'une d'elles se terminait par
{\k40}打{\k80}开, « ouvrir », et avait supprimé « light » de la ligne entièrement. - Dans quatre exécutions, une syllabe ne surlignait rien, comme
打开{\k40}{\k80}灯(0,40 seconde de surbrillance sur une syllabe vide). Dans deux de ces cas, une syllabe de 0,45 seconde ne surlignait qu'une virgule. - Dans une exécution, deux balises ont disparu, comme décrit ci-dessus.
Le vérificateur signale une ligne karaoké traduite sur place et toute syllabe laissée sans texte. La meilleure solution est éditoriale : ne traduisez pas le karaoké sur place. Conservez la ligne originale minutée pour chanter dessus, et ajoutez la traduction comme un événement séparé : copiez l'événement karaoké, donnez-lui son propre style (par exemple, plus petit et placé en bas), supprimez les balises \k, et traduisez le texte. Ne recalez le minutage syllabe par syllabe que si vous êtes prêt à le synchroniser vous-même sur l'audio.
Un flux de travail qui tient la route
-
Rendez d'abord la source lisible. Si le fichier affiche des caractères brouillés, corrigez l'encodage avant tout le reste. Notre guide d'encodage utilise des exemples SRT, mais les mêmes étapes au niveau des octets fonctionnent pour un fichier
.asset préservent les octets originaux. Le vérificateur ne lit que l'UTF-8 et l'UTF-16. -
Décidez de la portée. Listez les styles et déterminez lesquels sont des dialogues, lesquels sont des panneaux à l'écran, et lesquels sont du karaoké. Les panneaux nécessitent généralement une traduction ; le karaoké nécessite généralement une ligne séparée ; les commentaires et les notes entre accolades sont à votre appréciation.
-
Ne traduisez que le champ
Text. Utilisez un outil qui analyse l'ASS plutôt que de le traiter comme du texte brut, ou protégez vous-même les balises comme dans notre troisième condition. Gardez le fichier source à côté de la sortie. -
Exécutez la vérification structurelle.
python3 check_ass_translation.py source.ass translated.assIl compare le nombre d'événements, les types d'événements, les champs 1 à 9, les valeurs de style, les blocs de remplacement, les dessins, les lignes de commentaire,
\N, les syllabes et durées karaoké, et les lignes revenues vides ou inchangées. Il ne juge pas la qualité de la traduction. -
Corrigez les polices volontairement. Modifiez
Fontnamedans chaque style qui contient désormais du texte dans la langue cible, puis exécutez le test de glyphes sur le fichier de police que vous allez livrer :pip install fonttools python3 check_ass_translation.py source.ass translated.ass --font "Noto Sans SC=/path/to/NotoSansSC-Regular.otf"Un nom de police modifié apparaît comme un avertissement, ce qui vous permet de confirmer que chaque changement était intentionnel.
-
Nettoyez les codes d'espacement et le karaoké comme décrit ci-dessus.
-
Vérifiez avec la vidéo. Ouvrez le fichier dans Aegisub ou votre lecteur. Assurez-vous que les panneaux s'adaptent toujours aux formes dessinées derrière eux, car une boîte
\pconserve sa taille anglaise tandis qu'un panneau traduit peut être beaucoup plus long ou plus court. Vérifiez que les lignes ne sont pas trop longues pour leur temps d'affichage. Aucun de ces problèmes n'est visible dans le fichier lui-même.
Où BookTranslator intervient
Le traducteur de sous-titres de BookTranslator accepte les fichiers SRT, VTT, ASS et SSA. Selon la page produit, il conserve les horodatages et l'ordre des sous-titres et maintient le style ASS et SSA pris en charge attaché à chaque entrée de sous-titre, ce qui vous évite d'extraire et de réinsérer le texte vous-même. Il traduit les dialogues en utilisant les lignes environnantes comme contexte, ce qui aide pour les noms et les blagues récurrentes sur un épisode entier.
Nous n'avons pas fait passer cet échantillon par BookTranslator pour cet article. Quel que soit l'outil utilisé, exécutez les étapes 4 à 7 sur le résultat. Un style qui conserve sa police anglaise reste un style incapable d'afficher du chinois, et un karaoké traduit sur place nécessite toujours une décision éditoriale. Pour le reste du flux de travail des sous-titres, consultez notre guide de traduction de sous-titres par IA, notre comparatif des logiciels de traduction de sous-titres et, si votre traduction est destinée à YouTube, le flux de travail des sous-titres YouTube.
Quand convertir en SRT à la place
Convertir un fichier ASS en SRT avant la traduction supprime les styles, les positions, les dessins et le karaoké, ce qui élimine aussi la plupart des problèmes ci-dessus. C'est un compromis raisonnable si votre destination n'affiche que des sous-titres simples, ou si le style n'a jamais été important pour la sortie. C'est un mauvais compromis pour les animes et les sorties musicales où les panneaux et le karaoké font partie de l'œuvre. Décidez en fonction de l'endroit où le fichier sera affiché, et non du format le plus facile à traduire.
Obtenez les fichiers de test
Tout le contenu de ce test est librement réutilisable :
- sample-source.ass : l'échantillon anglais de 14 événements ;
- check_ass_translation.py : le vérificateur (bibliothèque standard Python ; le test
--fontnécessite fontTools) ; - run_llm_ass_test.py : les trois conditions de prompt pour tout serveur local compatible OpenAI ;
- results.csv et check-results.txt : les résultats par exécution ;
- README.txt : la liste des fichiers et les paramètres de test, avec les neuf sorties non modifiées dans le dossier
outputs.
Articles connexes




