# General Translation Knowledge Base: Как перевести субтитры SRT, не нарушив тайминг?
URL: https://generaltranslation.com/ru/kb/translate-srt-subtitles.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Переводите в файле SRT только текст реплик, а номера реплик, таймкоды, пустые строки-разделители и теги форматирования оставляйте такими же, как в источнике. Затем проверьте длину строк и скорость чтения на соответствие требованиям целевой платформы: например, англоязычное руководство Netflix допускает 42 символа в строке и 20 символов в секунду для программ для взрослой аудитории.
Category: Перевод
Last updated: 2026-10-20
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-20

У формата SRT (SubRip) нет формальной спецификации. Библиотека Конгресса США называет его [«плохо стандартизированным»](https://www.loc.gov/preservation/digital/formats/fdd/fdd000569.shtml), поэтому плееры и платформы поддерживают его по-разному, и надёжнее всего, если переведённый файл останется таким же простым, как источник.

## Что содержит файл SRT

Файл SRT — это список реплик, разделённых пустыми строками. Каждая реплика состоит из порядкового номера, строки тайминга в формате `HH:MM:SS,mmm --> HH:MM:SS,mmm` (перед миллисекундами ставится запятая) и одной или нескольких строк текста:

```text title="subtitles/en/intro.srt"
1
00:00:01,000 --> 00:00:03,500
Welcome back to the channel.

2
00:00:03,600 --> 00:00:06,200
Today we're looking at
<i>how subtitles are timed</i>.

3
00:00:06,400 --> 00:00:08,000
Let's get started.
```

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

* **Номера реплик** — по порядку, по одному на реплику.
* **Строки таймингов** — символ в символ. Из-за точки вместо запятой или сдвига на одну миллисекунду плеер может отклонить реплику или показать её не в тот момент.
* **Пустая строка между репликами.** Если разделителей нет, плеер может объединить, неверно прочитать или пропустить затронутые реплики. Временные метки последующих реплик абсолютные, поэтому их тайминги автоматически не сдвигаются.
* **Переносы строк внутри реплики**, благодаря которым каждая строка остаётся достаточно короткой для чтения. В переводе можно перенести строку в другом месте, но третью строку добавлять не стоит.
* **Теги** — например, `<i>`, `<b>` и `<font>`, а также теги позиционирования, например `{\an8}`, которые плееры воспринимают как форматирование. Будут ли они отображаться, зависит от плеера: например, YouTube принимает только базовые SRT-файлы, не распознаёт разметку и требует обычную кодировку UTF-8 ([поддерживаемые файлы субтитров](https://support.google.com/youtube/answer/2734698)).
* **Кодировка текста.** Стандартной кодировки для SRT не существует, поэтому сохраняйте переводы в UTF-8, если вашему плееру не требуется другая.

## Длина строки и скорость чтения

Тайминг остаётся прежним, а длина переведённого текста меняется, поэтому субтитр, который комфортно читался на английском, на другом языке может промелькнуть слишком быстро. Netflix публикует такие ограничения отдельно для каждого языка. Его [English (USA) Timed Text Style Guide](https://partnerhelp.netflixstudios.com/hc/en-us/articles/217350977-English-USA-Timed-Text-Style-Guide) допускает 42 символа в строке, не более двух строк и скорость чтения до 20 символов в секунду для взрослых программ (17 — для детских). В [руководстве для немецкого языка](https://partnerhelp.netflixstudios.com/hc/en-us/articles/217351587-German-Timed-Text-Style-Guide) лимит в 42 символа на строку сохраняется, но скорость чтения снижена до 17 символов в секунду для взрослых и до 13 — для детей.

Переводу может понадобиться больше символов, чем исходному тексту, а доступное время при этом не меняется. Рассчитывайте количество символов в секунду по каждой переведённой реплике и её длительности; ширина отрендеренного текста — это совсем другой показатель. Если реплика выходит за рамки спецификации поставки, перефразируйте её без потери смысла и проверьте результат на видео.

## По одной реплике или с учётом всего файла как контекста

Фраза в диалоге часто растягивается на две-три реплики. Если переводить каждую реплику отдельно, структура гарантированно сохранится, но переводиться будут лишь фрагменты: например, в немецком языке глагол стоит в конце придаточного предложения и может попасть уже в следующую реплику. Перевод с учётом соседних реплик как контекста получается естественнее — при условии, что текст возвращается в те же реплики с тем же таймингом.

## Способы перевести SRT-файл

| Подход                                                | Работа со структурой SRT                                                                       | Машинный перевод                                          | Проверка скорости чтения                                                     | Когда подходит                                                                  |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Subtitle Edit (бесплатный, с открытым исходным кодом) | Читает и записывает SRT                                                                        | Google Translate, DeepL, API LLM и локальные модели       | Проверки в стиле Netflix: символы в секунду, длина строки и количество строк | Один человек переводит и вычитывает файл вручную                                |
| Перевод документов в DeepL                            | Принимает загрузку `.srt`                                                                      | DeepL                                                     | Нет                                                                          | Нужен быстрый черновой перевод одного файла                                     |
| Google Translate                                      | Загрузка SRT не поддерживается ни в потребительском приложении, ни в Cloud-переводе документов | Только текстовый API; файл собираете вы сами              | Нет                                                                          | Вы готовы написать скрипт и взять обработку файлов на себя                      |
| General Translation CLI                               | Специальная обработка SRT сохраняет тайминг реплик и защищённую разметку                       | Сервис GT с общими Glossary и пользовательскими промптами | Выполните проверки ниже и сверьте с видео                                    | Субтитры версионируются вместе с регулярными релизами продукта или документации |
| Передать файл LLM в промпте                           | Читает файл как обычный текст; сохранность структуры ничем не гарантирована                    | Любая модель на ваш выбор                                 | Только по запросу и без гарантий                                             | Разовый файл, который вы проверите построчно                                    |

Несколько пояснений к таблице. YouTube Studio в ней нет, потому что этот сервис публикует субтитры, а не переводит их: когда переведённый файл готов, откройте **Субтитры**, выберите видео, нажмите **Добавить язык**, выберите язык и загрузите файл ([добавление субтитров](https://support.google.com/youtube/answer/2734796)). То есть к моменту загрузки перевод уже должен быть готов. В [Subtitle Edit](https://github.com/SubtitleEdit/subtitleedit) (лицензия MIT, для Windows, macOS и Linux) есть диалоговое окно **Translate &gt; Auto-translate** с движками, среди которых Google Translate, DeepL, ChatGPT, Claude, Gemini и локальные модели через Ollama, а также средство проверки **Tools &gt; Check and fix Netflix errors**. В [API документов](https://developers.deepl.com/api-reference/document) DeepL формат `srt` указан среди поддерживаемых. [Перевод документов](https://docs.cloud.google.com/translate/docs/advanced/translate-documents) Google принимает файлы Office и PDF, а [потребительский сайт](https://support.google.com/translate/answer/2534559?co=GENIE.Platform%3DDesktop) — только `.docx`, `.pdf`, `.pptx` и `.xlsx`.

Используйте Subtitle Edit, когда один человек переводит и вычитывает файл вручную: в нём машинный перевод сочетается с проверками тайминга и скорости чтения. Для быстрого чернового перевода одного файла подойдёт перевод документов в DeepL. Выбирайте General Translation, если одни и те же файлы субтитров меняются с каждым релизом и в них нужна та же терминология, что в вашем приложении и документации; финальную проверку по видео выполняйте в редакторе субтитров.

## Проверка переведённого файла

Этот скрипт на Node.js проверяет, что в переведённом файле столько же реплик, сколько в источнике, и что их номера и таймкоды совпадают, а также что среди них нет пустых. Чтобы пометить реплики, превышающие заданную скорость чтения (например, 17 символов в секунду для немецкого языка), передайте третий аргумент:

```js title="check-srt.mjs"
// Использование: node check-srt.mjs <source.srt> <translated.srt> [макс. число символов в секунду]
import { readFileSync } from 'node:fs';

const TIMING = /^(\d{2}:[0-5]\d:[0-5]\d,\d{3}) --> (\d{2}:[0-5]\d:[0-5]\d,\d{3})$/;
const cues = (file) =>
  readFileSync(file, 'utf8')
    .replace(/^﻿/, '')
    .split(/\r?\n\s*\r?\n/)
    .map((block) => block.trim().split(/\r?\n/))
    .filter((lines) => lines[0])
    .map(([number, timing = '', ...text]) => ({ number, timing, text }));

const [srcFile, outFile, maxCps] = process.argv.slice(2);
if (!srcFile || !outFile || (maxCps !== undefined && !(Number(maxCps) > 0 && Number.isFinite(Number(maxCps))))) {
  throw new Error('Provide source and translated files, and an optional positive reading-speed limit.');
}
const [source, target] = [srcFile, outFile].map(cues);
const seconds = (tc) => tc.split(/[:,]/).reduce((acc, n, i) => acc + n * [3600, 60, 1, 0.001][i], 0);
const problems = [];
if (!source.length) problems.push('source has no cues');
if (source.length !== target.length) problems.push(`cue count: ${source.length} in source, ${target.length} translated`);

source.forEach((cue, i) => {
  const t = target[i];
  if (!t) return;
  if (cue.number !== t.number) problems.push(`cue ${i + 1}: number "${cue.number}" became "${t.number}"`);
  if (!TIMING.test(t.timing)) problems.push(`cue ${cue.number}: invalid timing line "${t.timing}"`);
  else if (cue.timing !== t.timing) problems.push(`cue ${cue.number}: timing changed to "${t.timing}"`);
  if (!t.text.join('').trim()) problems.push(`cue ${cue.number}: empty text`);
  const [, start, end] = TIMING.exec(t.timing) ?? [];
  const duration = start ? seconds(end) - seconds(start) : 0;
  if (start && duration <= 0) problems.push(`cue ${cue.number}: end must be after start`);
  if (maxCps && duration > 0) {
    // Учитываем пробелы и знаки препинания, но не разметку вроде <i> или {\an8}
    const chars = t.text.join(' ').replace(/<[^>]+>|\{\\an\d\}/g, '').length;
    const cps = chars / duration;
    if (cps > maxCps) problems.push(`cue ${cue.number}: ${cps.toFixed(1)} characters per second`);
  }
});

console.log(problems.length ? problems.join('\n') : `OK: ${source.length} cues, numbers and timecodes match`);
process.exitCode = problems.length ? 1 : 0;
```

Ниже приведены два перевода файла из примера. В испанском сохранены все реплики. В немецком три реплики втиснуты в две, а в таймкоде запятая заменена точкой:

```text title="subtitles/es/intro.srt"
1
00:00:01,000 --> 00:00:03,500
Bienvenidos de nuevo al canal.

2
00:00:03,600 --> 00:00:06,200
Hoy veremos
<i>cómo se sincronizan los subtítulos</i>.

3
00:00:06,400 --> 00:00:08,000
¡Empecemos!
```

```text title="subtitles/de/intro.srt"
1
00:00:01,000 --> 00:00:03,500
Willkommen zurück auf dem Kanal.
Heute sehen wir uns an,

2
00:00:03,600 --> 00:00:06.200
<i>wie Untertitel getimt werden</i>.
Los geht's!
```

При запуске в Node.js 24 испанский файл проходит проверку скрипта, а немецкий — нет. Теперь в реплике 1 — 56 символов на 2,5 секунды:

```bash
$ node check-srt.mjs subtitles/en/intro.srt subtitles/es/intro.srt 20
OK: 3 cues, numbers and timecodes match

$ node check-srt.mjs subtitles/en/intro.srt subtitles/de/intro.srt 17
cue count: 3 in source, 2 translated
cue 1: 22.4 characters per second
cue 2: invalid timing line "00:00:03,600 --> 00:00:06.200"
```

При любой ошибке скрипт завершается с кодом 1, поэтому его можно запускать в CI после перевода. Он принимает простые строки таймингов в показанном здесь формате, без необязательных координат позиции. Скрипт проверяет соответствие реплик, корректность таймингов, наличие текста и, если задано, ограничение скорости чтения. Сохранность тегов, длину и количество строк, а также смысл он не проверяет: для этого используйте средство проверки субтитров целевой платформы и просмотрите результат вместе с рецензентом — носителем языка. Подсчёт символов средствами JavaScript — лишь предварительная проверка, а не замена собственным правилам подсчёта платформы.

## Как переводить SRT-файлы с помощью General Translation

Если файлы субтитров хранятся в репозитории и их нужно переводить на несколько языков после каждого изменения, воспользуйтесь CLI General Translation — `gt`: начиная с версии 2.22.2 он умеет переводить файлы `.srt`. Установите CLI и войдите в систему (см. [Быстрый старт CLI](/docs/cli/quickstart)), а затем добавьте запись `srt` в раздел `files` файла `gt.config.json`, указав в пути плейсхолдер `[locale]`:

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "de"],
  "files": {
    "srt": {
      "include": ["subtitles/[locale]/**/*.srt"]
    }
  }
}
```

Затем выполните [`npx gt translate`](/docs/cli/reference/commands/translate). CLI считывает исходные субтитры из `subtitles/en/` и записывает переводы в `subtitles/es/` и `subtitles/de/`. Чтобы переводить на английский, укажите язык-источник в `defaultLocale` и добавьте `"en"` в `locales`.

Переводится только текст реплик. Номера реплик, строки тайминга (включая данные о позиции после временных меток), пустые строки-разделители, разметка вроде `<i>` и `<font>`, а также начальные теги позиции от `{\an1}` до `{\an9}` остаются без изменений — как и любой блок без корректной строки тайминга. В переведённых строках сохраняются окончания строк исходной реплики, а скачиваемые файлы получают кодировку исходного файла. Для неизменённых реплик могут повторно использоваться прежние переводы, а Glossary и пользовательские промпты вашего проекта действуют и для субтитров. (См. [справочник по формату SRT](/docs/cli/reference/formats/srt-files) и [Определение контекста для переводов](/docs/platform/dashboard/guides/defining-context-for-translations)).

Строки тайминга остаются в точности такими же, как в исходном файле, поэтому запустите приведённый выше скрипт проверки для каждого переведённого файла — особенно для языков, на которых текст получается длиннее, чем в оригинале.

## Основные выводы

* При переводе с фиксированным таймингом меняйте только текст реплик, сохраняя их номера, строки тайминга, разделители и теги форматирования. Намеренные изменения тайминга или границ реплик проверяйте отдельно, сверяясь с видео.
* Netflix допускает не более двух строк по 42 символа; скорость чтения во взрослых программах — до 20 символов в секунду для английского языка и до 17 — для немецкого.
* Перевод документов в DeepL и Subtitle Edit поддерживают файлы SRT, а загрузка документов в Google Translate — нет.
* CLI `gt` (версии 2.22.2 или новее) переводит SRT, если добавить `files.srt.include` с путём, содержащим `[locale]`, и выполнить [`npx gt translate`](/docs/cli/reference/commands/translate). Переводится только текст реплик, а тайминг остаётся таким же, как в источнике.

## Related questions

- [Как перевести Markdown и MDX, не нарушив синтаксис?](https://generaltranslation.com/ru/kb/translate-markdown-files.mdx): Переводите текст, alt-текст изображений, заголовки и описания во frontmatter, а также пропсы компонентов с отображаемым текстом. Блоки кода, встроенный код, импорты, имена JSX-компонентов, ключи frontmatter и URL ссылок оставляйте без изменений, если только их не переписывает сопоставление локалей. Заключайте переведённые значения YAML в кавычки, а затем запустите сборку сайта.
- [Как перевести JSON-файлы i18n?](https://generaltranslation.com/ru/kb/translate-json-files.mdx): Переводите только строковые значения в JSON-файле локали. Ключи, не связанные с множественным числом, заполнители вроде {{name}} и теги оставляйте без изменений, но учтите, что ключи для форм множественного числа зависят от языка: например, для польского нужны inbox_few и inbox_many. Используйте инструмент или API с поддержкой формата, а затем разберите и проверьте результат перед вычиткой.
- [Достаточно ли точен ИИ-перевод для приложения в рабочей среде?](https://generaltranslation.com/ru/kb/is-ai-translation-accurate.mdx): Для распространённых языков — зачастую да, но только после проверки на ваших языках, строках UI и контенте с повышенными рисками. На WMT25 Gemini 2.5 Pro не уступил эталонным переводам, выполненным людьми, или превзошёл их в 10 из 16 языковых пар, однако бенчмарк на документах не показывает, готовы ли к выпуску короткие строки интерфейса.
- [Альтернативы Google Translate: General Translation и Google Translate](https://generaltranslation.com/ru/kb/general-translation-vs-google-translate.mdx): Google Translate — быстрый способ перевести разовый текст, но чтобы выпустить продукт на другом языке, нужно переводить каждую строку с учётом контекста, соблюдать единую терминологию, правильно обрабатывать переменные и формы множественного числа, проводить ревью и выстроить процесс релизов. General Translation понимает контекст каждой строки в вашем коде и автоматизирует весь рабочий процесс локализации — от кода до ревью и каждого релиза.

## Previous and next questions

- Previous question: [Как перевести Markdown и MDX, не нарушив синтаксис?](https://generaltranslation.com/ru/kb/translate-markdown-files.mdx)
- Next question: [Как поддержать RTL-языки (right-to-left) в CSS?](https://generaltranslation.com/ru/kb/right-to-left-css.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/ru/kb/sitemap.md) for every article.
