BookTranslator
BookTranslator

Как да преведете ASS/SSA субтитри, без да развалите стиловете, позициите или караокето

Преведете само видимия диалог в .ass файл, след което проверете тайминга, таговете, караокето и шрифтовете. С примерен файл, безплатна проверка и тест с локален LLM в 9 пускания.

BookTranslator

BookTranslator Team

13 min read

ASS или SSA файлът със субтитри е малка програма: заглавна част, таблица със стилове и списък от събития с време, чието последно поле смесва диалог с форматиращ код. За да го преведете, променете само четливите думи в това последно поле, оставете всичко останало байт по байт непокътнато и след това проверете три неща, които никой инструмент за превод не поправя вместо вас: шрифтовете, кодовете за разстояние и редовете за караоке.

Преведохме пример с 14 събития на опростен китайски девет пъти с локален модел, използвайки три различни подсказки, и проверихме всеки резултат със скрипт, който написахме. Таймингът, позициите, цветовете, коментарите и рисунките оцеляха и в деветте. Счупиха се частите от файла, които предполагат английски: и в деветте стиловите шрифтове нямаха китайски знаци, така че файлът щеше да разчита на плейъра да замести шрифт, а твърдият интервал от английския ред се превърна във видима празнина в китайския. Редът за караоке се върна с тайминг, насочен към грешните думи при всяко пускане, а при четири пускания някои срички не осветяваха нищо.

Бърз отговор: какво да преведете и какво да оставите непокътнато

Част от файлаПример от нашата извадкаДа се преведе ли?
Заглавна част [Script Info]PlayResX: 1920, WrapStyle: 0Не. Позициите се изчисляват от тези стойности.
[V4+ Styles]Style: Default,Trebuchet MS,64,...Не, с изключение на името на шрифта, което може да се наложи да промените умишлено
Полета 1–9 на събитието0,0:00:01.00,0:00:03.20,Default,Jun,0,0,0,Не. Това са слой, тайминг, стил, говорител, отстъпи и ефект.
Блокове за заместване{\i1}, {\an8\pos(960,120)}, {\k25}Не
Рисунки{\p1}m 0 0 l 200 0 200 60 0 60{\p0}Не. Това е векторна форма, а не текст.
Събития Comment:Comment: ...,Earlier draft: Try the stacks.По избор. Коментарите никога не се появяват на екрана.
Бележки в къдрави скоби{TL note: "stacks" means the closed shelves}По избор. Плейърите ги игнорират.
Видим диалогDid you find the second volume?Да
Кодове на редове\N, \n, \hЗапазете \N. Решете за всеки отделен случай за \n и \h.

Останалата част от това ръководство обяснява защо всеки ред е важен и как да проверите резултата.

Как е изграден един ASS ред

Всеки ред в секцията [Events] следва формата, деклариран точно над него:

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.

Само десетото поле, Text, съдържа нещо, което зрителят чете. Ръководството за файловия формат ASS на проекта libass отбелязва, че това последно поле „може да съдържа запетаи“, поради което небрежно разделяне по всяка запетая чупи ред като Well, if it's there, then, we go now. Безопасният инструмент разделя само по първите девет запетаи.

Вътре в Text всичко във къдрави скоби е блок за заместване. Справочникът за тагове за заместване на Aegisub дефинира кодовете, които ще срещнете най-често:

  • \N принуждава нов ред във всеки режим на пренасяне. \n прекъсва реда само в режим на пренасяне 2 и иначе е интервал. \h е непрекъсваем интервал.
  • \an8 задава подравняване чрез оформлението на цифровата клавиатура, така че 8 е горе в центъра. \pos(960,120) поставя реда на координати в скрипта.
  • \k25 е караоке сричка; продължителностите са в стотни от секундата, така че 25 означава четвърт секунда.
  • След \p1 текстът „ще бъде интерпретиран като инструкции за рисуване“, така че преводач, който „преведе“ m 0 0 l 200 0, унищожава фигура.
  • Неразпознатият текст в къдрави скоби „се игнорира безшумно“, поради което фенсуб файловете често съдържат бележки на преводача в къдрави скоби.

Редовете, които започват с Comment:, използват същите полета, но според ръководството на libass „нищо няма да се покаже на екрана“.

Какво тествахме

Написахме sample-source.ass, сцена с 14 събития, разположена в книжарница, с по един пример за всяка от горните функции: курсив, твърдо прекъсване, запетаи в диалога, бележка в къдрави скоби, коментарен ред, позициониран надпис, векторна кутия, затихване, твърд интервал, промяна на цвета с \r, меко прекъсване, ефект на превъртане Banner и караоке ред с шест срички.

След това помолихме локален модел да го преведе на опростен китайски по три начина:

  1. Цял файл. Поставете целия .ass файл и поискайте обратно преведения файл.
  2. Само текст. Изпратете само полето Text на всеки диалогов ред като JSON, с таговете вградени, и инструкцията да запазите всеки блок {...} и всеки \N, \n и \h.
  3. Защитен. Същото, но първо заменете всеки блок в къдрави скоби и всеки код на ред с номериран заместител и след това върнете оригиналите обратно.

Във второто и третото условие скриптът никога не изпраща векторния чертеж или коментарния ред на модела, така че тези редове можеха да бъдат повредени само в условието с целия файл.

Моделът беше Qwen 3.6 27B (Q4_K_M) в LM Studio 0.4.8 на Apple M4 Max с 64 GB памет, с изключено мислене и температура 0.3. Пуснахме всяко условие три пъти, общо девет пускания. Първият опит за третото пускане приключи, когато локалният сървър прекъсна връзката, затова го рестартирахме и пуснахме третия кръг отново. Скриптът е run_llm_ass_test.py, а всичките девет изхода са публикувани нередактирани заедно с него; README изброява всеки файл. Ако никога не сте настройвали локален модел, нашето ръководство за превод с локален LLM обхваща настройките.

Това беше малък тест на един модел, една езикова двойка и една извадка. Той показва какви проблеми се случват и как да ги хванете. Той не класира инструменти или подсказки.

Резултат: Механиката оцеля; английските предположения не

Проверихме всеки изход с check_ass_translation.py. Пълният изход е в check-results.txt, а results.csv има по един ред за всяко пускане, включително проблеми, които скриптът не може да види.

ПроверкаЦелият файлСамо текстЗащитено
Време, стилове и полета 1–9 без промяна3 от 33 от 33 от 3
Тагове за заместване без промяна3 от 32 от 33 от 3
Редове за рисуване и коментари не са засегнати3 от 33 от 33 от 3
Шрифтове на стиловете, способни да изобразят превода0 от 30 от 30 от 3
\h и \n остават като празни места в китайския текст3 от 33 от 33 от 3
Всички караоке тагове са запазени, всеки с текст3 от 30 от 31 от 3

Два резултата ни изненадаха. Поставянето на целия файл запази структурата непокътната и в трите опита, макар в два от тях да преведе и реда Title в заглавната част. А подсказката само за текст, която звучи по-безопасно, произведе единствените счупени тагове. В един опит върна {\k25}翻{\k30}页,{\k45}开{\k60}灯 за ред с шест караоке тага. Последните два тага и 1,20 секунди време за осветяване бяха изчезнали, така че осветяването щеше да приключи много преди реда. Същият опит превърна Room\h12 is upstairs. в 12\h12号房间在楼上。, с номера на стаята два пъти.

Така че полезната поука не е „използвайте подсказка X“. А това, че структурните щети, от които се страхувате, са лесни за откриване, а щетите, които всъщност се промъкнаха и в деветте опита, се намират на три места, които страниците с инструменти за превод на ASS не обсъждат.

1. Шрифтовете не могат да изобразят новия език

Стиловете в примера използват Trebuchet MS за диалог и Georgia за надписи, което е нормално за английско издание. Нито един от двата шрифта не съдържа китайски знаци. Когато насочихме теста за глифи на проверяващия към двата шрифтови файла, всичките 12 преведени текстови събития във всеки опит се провалиха:

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. 书人仅作员工库架闭限

Плейърът може да замести с друг инсталиран шрифт, така че субтитрите може все още да се покажат, но изданието вече не контролира как изглеждат, и зрител, чиято система няма подходящ шрифт, може да види празни квадратчета. Поправката е съзнателна редакция на полето Fontname на всеки стил. Когато сменихме и трите стила в един изход на Hiragino Sans GB, китайски шрифт, който се разпространява с macOS, и пуснахме теста за глифи срещу този шрифт, грешките за глифи станаха нула.

Изберете шрифт, който зрителите ви действително ще имат, или го приложете към видеото. Ръководството на libass казва, че изданията трябва да прикачат всеки шрифт, който използват, за предпочитане към MKV контейнера. Тъй като шрифтът за целевия език е нов, прикачването му сега е част от работата по превода.

2. Кодовете за интервали носят английски навици

Room\h12 слепва „Room“ с „12“, така че никога да не се разделят на нов ред. На китайски думите не се разделят с интервали, но всеки опит запази \h някъде: пет опита го поставиха между 12号房间 и 在楼上, три го поставиха преди числото, а един го постави между две копия на числото. И в двата случая зрителят вижда излишен интервал. Wait\nhere. имаше същия проблем. С WrapStyle: 0, \n се изобразява като интервал, така че 在\n这里等 показва празнина в средата на изречение от три думи.

Структурата тук е наред; езикът не е. За целеви език без интервали между думите премахнете \h и \n от преведения текст. Запазете \N само там, където искате принудително прекъсване, и го поставете на естествено място в целевото изречение. Проверяващият отчита променените бройки на \h и \n като предупреждения, а не като грешки поради тази причина, и предупреждава, когато един от тях оцелее в китайски, японски или корейски текст.

3. Времето за караоке принадлежи на оригиналните думи

Караоке редът {\k25}Turn {\k30}the {\k45}page, {\k60}turn {\k40}the {\k80}light синхронизира всяка английска сричка с песента. Преводът не може да запази това време смислено, защото китайските думи не попадат на същите тактове. Нашите опити показват различните начини, по които се обърква:

  • В четири опита и шестте тага бяха запазени, всеки на различна дума от преди. Един от тях завърши с {\k40}打{\k80}开, „отвори“, и изпусна „light“ от реда напълно.
  • В четири опита сричка не осветяваше нищо, като 打开{\k40}{\k80}灯 (0,40 секунди осветяване на празна сричка). В два от тези случаи сричка от 0,45 секунди осветяваше само запетая.
  • В един опит два тага изчезнаха, както е описано по-горе.

Проверяващият отбелязва караоке ред, преведен на място, и всяка сричка, останала без текст. По-доброто решение е редакционно: не превеждайте караоке на място. Запазете оригиналния синхронизиран ред за пеене, и добавете превода като отделно събитие: копирайте караоке събитието, дайте му собствен стил (например по-малък и поставен в долната част), премахнете \k таговете и преведете текста. Синхронизирайте го отново сричка по сричка само ако сте готови сами да го синхронизирате с аудиото.

Работен процес, който издържа

  1. Първо направете източника четим. Ако файлът показва объркани знаци, поправете кодирането преди всичко друго. Нашето ръководство за кодиране използва примери със SRT, но същите стъпки на ниво байтове работят за .ass файл и запазват оригиналните байтове в безопасност. Проверяващият чете само UTF-8 и UTF-16.

  2. Решете обхвата. Избройте стиловете и решете кои са диалог, кои са надписи на екрана и кои са караоке. Надписите обикновено се нуждаят от превод; караокето обикновено се нуждае от отделен ред; коментарите и бележките в скоби са ваше решение.

  3. Превеждайте само полето Text. Използвайте инструмент, който анализира ASS, вместо да го третира като обикновен текст, или защитете таговете сами, както в третото ни условие. Запазете изходния файл до изхода.

  4. Пуснете структурната проверка.

    python3 check_ass_translation.py source.ass translated.ass
    

    Тя сравнява броя събития, типовете събития, полета 1–9, стойностите на стиловете, блоковете за заместване, рисунките, коментарните редове, \N, караоке сричките и продължителностите, и редовете, които са се върнали празни или непроменени. Не оценява качеството на превода.

  5. Поправете шрифтовете нарочно. Променете Fontname във всеки стил, който вече съдържа текст на целевия език, след което стартирайте теста за глифи срещу файла на шрифта, който ще доставите:

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

    Промененото име на шрифт се показва като предупреждение, така че можете да потвърдите, че всяка промяна е била умишлена.

  6. Изчистете кодовете за разстояние и караокето, както е описано по-горе.

  7. Гледайте го с видеото. Отворете файла в Aegisub или във вашия плейър. Проверете дали надписите все още се побират във формите, нарисувани зад тях, защото \p кутията запазва английския си размер, докато преведеният надпис може да бъде много по-дълъг или по-къс. Проверете дали редовете не са твърде дълги за времето си на екран. Нито един от двата проблема не се вижда във самия файл.

Къде се вписва BookTranslator

Преводът на субтитри на BookTranslator приема файлове SRT, VTT, ASS и SSA. Според продуктовата страница той запазва времевите кодове и реда на репликите и поддържа стиловете на ASS и SSA прикачени към всеки запис на субтитри, така че не е нужно сами да извличате и вмъквате текста. Превежда диалога с околните редове като контекст, което помага с имената и повтарящите се шеги в целия епизод.

Не сме пускали тази извадка през BookTranslator за тази статия. Какъвто и инструмент да използвате, изпълнете стъпки от 4 до 7 върху резултата. Стил, който запазва английския си шрифт, все още е стил, който не може да изобрази китайски, а караокето, преведено на място, все още изисква редакторско решение. За останалата част от работния процес със субтитри вижте нашето ръководство за AI превод на субтитри, нашето сравнение на софтуер за превод на субтитри и, ако преводът ви отива в YouTube, работния процес за субтитри в YouTube.

Кога вместо това да конвертирате в SRT

Конвертирането на ASS в SRT преди превод премахва стиловете, позициите, рисунките и караокето, което също така премахва повечето от проблемите по-горе. Това е разумна замяна, ако дестинацията ви показва само обикновени субтитри или ако стилизирането никога не е било важно за изданието. Това е грешна замяна за аниме и музикални издания, където надписите и караокето са част от произведението. Решете въз основа на това къде ще се показва файлът, а не кой формат е по-лесен за превод.

Вземете тестовите файлове

Всичко от този тест е свободно за използване:

  • sample-source.ass: английската извадка с 14 събития;
  • check_ass_translation.py: проверяващият скрипт (стандартна библиотека на Python; тестът --font изисква fontTools);
  • run_llm_ass_test.py: трите условия на подканата за всеки локален сървър, съвместим с OpenAI;
  • results.csv и check-results.txt: резултати за всяко изпълнение;
  • README.txt: списъкът с файлове и настройките на теста, с деветте нередактирани изхода в папката outputs.

Свързани публикации