# General Translation Knowledge Base: ¿Cómo traduzco subtítulos SRT sin alterar la sincronización?
URL: https://generaltranslation.com/es/kb/translate-srt-subtitles.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Traduce solo el texto de los subtítulos de un archivo SRT; conserva los números de subtítulo, los códigos de tiempo, las líneas en blanco que los separan y las etiquetas de formato tal como aparecen en el origen. Después, comprueba que la longitud de línea y la velocidad de lectura cumplan los requisitos de tu destino: la guía de Netflix para inglés, por ejemplo, admite 42 caracteres por línea y 20 caracteres por segundo en programas para adultos.
Category: Traducción
Last updated: 2026-10-20
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-20

SRT (SubRip) no tiene una especificación formal. La Biblioteca del Congreso de EE. UU. lo describe como un formato [&quot;poco estandarizado&quot;](https://www.loc.gov/preservation/digital/formats/fdd/fdd000569.shtml), así que cada reproductor y plataforma acepta cosas distintas. Por eso, lo más seguro es que el archivo traducido sea tan sencillo como el original.

## Qué contiene un archivo SRT

Un archivo SRT es una lista de subtítulos separados por líneas en blanco. Cada subtítulo consta de un número de secuencia, una línea de tiempo con el formato `HH:MM:SS,mmm --> HH:MM:SS,mmm` (con una coma antes de los milisegundos) y una o varias líneas de texto:

```text title="subtitles/en/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.
```

Esta guía usa un flujo de trabajo de tiempos fijos: traduce el texto conservando la estructura de subtítulos existente. Si el idioma de destino necesita otros tiempos o límites de subtítulo, haz esos cambios en un editor de subtítulos sincronizando con el video y valida el resultado editado por separado.

* **Números de subtítulo**, en orden, uno por subtítulo.
* **Líneas de tiempo**, carácter por carácter. Un punto en lugar de la coma, o un milisegundo desplazado, puede hacer que un reproductor rechace el subtítulo o lo muestre en el momento equivocado.
* **La línea en blanco entre subtítulos.** Si faltan separadores, un reproductor puede fusionar, interpretar mal u omitir los subtítulos afectados. Los subtítulos posteriores tienen marcas de tiempo absolutas, así que sus tiempos no se desplazan automáticamente.
* **Saltos de línea dentro de un subtítulo**, que mantienen cada línea lo bastante corta como para leerse con comodidad. Una traducción puede redistribuir dónde se corta una línea, pero no debería añadir una tercera.
* **Etiquetas** como `<i>`, `<b>` y `<font>`, y etiquetas de posición como `{\an8}`, que los reproductores interpretan como formato. Que se rendericen o no depende del reproductor: YouTube, por ejemplo, solo acepta archivos SRT básicos, no reconoce ningún marcado y requiere UTF-8 sin formato ([archivos de subtítulos compatibles](https://support.google.com/youtube/answer/2734698)).
* **La codificación del texto.** SRT no tiene un estándar de codificación, así que guarda las traducciones en UTF-8, salvo que tu reproductor requiera otra.

## Longitud de línea y velocidad de lectura

Los tiempos no cambian, pero la longitud del texto traducido sí, por lo que un subtítulo que se leía con comodidad en inglés puede pasar demasiado rápido en otro idioma. Netflix publica límites específicos para cada idioma. Su [English (USA) Timed Text Style Guide](https://partnerhelp.netflixstudios.com/hc/en-us/articles/217350977-English-USA-Timed-Text-Style-Guide) permite 42 caracteres por línea, un máximo de dos líneas y una velocidad de lectura de hasta 20 caracteres por segundo en programas para adultos (17 en programas infantiles). La [guía para alemán](https://partnerhelp.netflixstudios.com/hc/en-us/articles/217351587-German-Timed-Text-Style-Guide) mantiene los 42 caracteres por línea, pero reduce la velocidad de lectura a 17 caracteres por segundo para adultos y a 13 para niños.

Una traducción puede necesitar más caracteres que el texto de origen, aunque el tiempo disponible siga siendo el mismo. Calcula los caracteres por segundo a partir de cada subtítulo traducido y su duración; el ancho del texto renderizado es una medida distinta. Si un subtítulo supera lo establecido en la especificación de entrega, reformúlalo sin perder el significado y revísalo en el video.

## Subtítulo por subtítulo o con todo el archivo como contexto

Es habitual que un diálogo se reparta entre dos o tres subtítulos. Traducir cada subtítulo por separado mantiene la estructura a salvo, pero obliga a traducir fragmentos: en alemán, por ejemplo, el verbo va al final de la oración subordinada, y puede acabar en el subtítulo siguiente. Traducir usando los subtítulos contiguos como contexto da un resultado más natural, siempre que el texto vuelva a los mismos subtítulos y con los mismos tiempos.

## Formas de traducir un archivo SRT

| Enfoque                                     | Gestiona la estructura SRT                                                                       | Traducción automática                                               | Comprobaciones de velocidad de lectura                                                              | Ideal cuando                                                                          |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Subtitle Edit (gratuito, de código abierto) | Analiza y genera archivos SRT                                                                    | Google Translate, DeepL, API de LLM y modelos locales               | Comprobaciones al estilo de Netflix de caracteres por segundo, longitud de línea y número de líneas | Una sola persona traduce y pule un archivo a mano                                     |
| Traducción de documentos de DeepL           | Permite subir archivos `.srt`                                                                    | DeepL                                                               | Ninguna                                                                                             | Quieres un primer borrador rápido de un archivo                                       |
| Google Translate                            | No permite subir SRT ni en la app para consumidores ni en la traducción de documentos de Cloud   | Solo la API de texto; tú reconstruyes el archivo                    | Ninguna                                                                                             | Vas a automatizarlo con un script y te encargas de gestionar los archivos             |
| CLI de General Translation                  | El procesamiento específico de SRT conserva los tiempos de los subtítulos y el marcado protegido | El servicio de GT con glosario y prompts personalizados compartidos | Ejecuta las comprobaciones que se indican más abajo y revisa con el video                           | Subtítulos versionados con lanzamientos periódicos del producto o de la documentación |
| Pasar el archivo a un LLM con un prompt     | Lee el archivo como texto sin formato; nada garantiza que la estructura se mantenga              | Cualquier modelo que elijas                                         | Solo si lo pides, y sin verificar                                                                   | Un archivo puntual que revisarás línea por línea                                      |

Algunos detalles sobre la tabla. YouTube Studio no aparece porque publica subtítulos, no los traduce: cuando tengas un archivo traducido, abre **Subtítulos**, selecciona el video, haz clic en **Añadir idioma**, elige el idioma y sube el archivo ([añadir subtítulos](https://support.google.com/youtube/answer/2734796)). Esa subida da por hecho que la traducción ya existe. [Subtitle Edit](https://github.com/SubtitleEdit/subtitleedit) (con licencia MIT, para Windows, macOS y Linux) incluye un cuadro de diálogo **Translate &gt; Auto-translate** con motores como Google Translate, DeepL, ChatGPT, Claude, Gemini y modelos locales a través de Ollama, además de un verificador **Tools &gt; Check and fix Netflix errors**. La [API de documentos](https://developers.deepl.com/api-reference/document) de DeepL incluye `srt` entre sus formatos compatibles. La [traducción de documentos](https://docs.cloud.google.com/translate/docs/advanced/translate-documents) de Google admite archivos de Office y PDF, y el [sitio para consumidores](https://support.google.com/translate/answer/2534559?co=GENIE.Platform%3DDesktop) solo admite `.docx`, `.pdf`, `.pptx` y `.xlsx`.

Usa Subtitle Edit cuando una sola persona traduzca y pula un archivo a mano, ya que combina la traducción automática con comprobaciones de tiempos y velocidad de lectura. Usa la traducción de documentos de DeepL para obtener un primer borrador rápido de un único archivo. Elige General Translation cuando los mismos archivos de subtítulos cambien con cada lanzamiento y necesiten compartir terminología con tu app y tu documentación; usa un editor de subtítulos para la revisión final con el video.

## Comprobar el archivo traducido

Este script de Node.js comprueba que un archivo traducido tenga el mismo número de subtítulos, la misma numeración y los mismos códigos de tiempo que el archivo de origen, y que ningún subtítulo esté vacío. Si pasas un tercer argumento, marcará los subtítulos que superen una velocidad de lectura determinada, como 17 caracteres por segundo para el alemán:

```js title="check-srt.mjs"
// Uso: node check-srt.mjs <source.srt> <translated.srt> [máximo de caracteres por segundo]
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) {
    // Cuenta los espacios y la puntuación, pero no el marcado como <i> o {\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;
```

Estas son dos traducciones del archivo de ejemplo. La española conserva todos los subtítulos. La alemana reduce tres subtítulos a dos y escribe un punto en un código de tiempo:

```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!
```

Al ejecutarlo con Node.js 24, el script da por válido el archivo en español y rechaza el alemán. El subtítulo 1 ahora contiene 56 caracteres en 2,5 segundos:

```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"
```

El script termina con el código 1 ante cualquier problema, así que puede ejecutarse en CI después de la traducción. Acepta las líneas de tiempo simples que se muestran aquí, sin coordenadas de posición opcionales. Comprueba que los subtítulos se correspondan, que los tiempos sean válidos, que el texto no esté vacío y, opcionalmente, un límite de velocidad. No comprueba la conservación de etiquetas, la longitud de las líneas, el número de líneas ni el significado; usa el validador de subtítulos de la plataforma de destino y visualiza el resultado junto con un revisor que hable el idioma. Su recuento de caracteres en JavaScript es una comprobación preliminar y no sustituye las reglas de recuento propias de cada plataforma.

## Cómo traducir archivos SRT con General Translation

Si tienes archivos de subtítulos en un repositorio y necesitas traducirlos a varios idiomas cada vez que cambian, la CLI de General Translation, `gt`, admite archivos `.srt` a partir de la versión 2.22.2. Una vez que la hayas instalado e iniciado sesión (consulta el [Inicio rápido de la CLI](/docs/cli/quickstart)), agrega una entrada `srt` en `files` dentro de `gt.config.json`, con un marcador de posición `[locale]` en la ruta:

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

Después, ejecuta [`npx gt translate`](/docs/cli/reference/commands/translate). La CLI lee los subtítulos de origen de `subtitles/en/` y escribe las traducciones en `subtitles/es/` y `subtitles/de/`. Para traducir al inglés, establece `defaultLocale` en el idioma de origen e incluye `"en"` en `locales`.

Solo se traduce el texto de los subtítulos. Los números de subtítulo, las líneas de tiempo (incluidos los datos de posición que siguen a las marcas de tiempo), las líneas en blanco que separan los bloques, el marcado como `<i>` y `<font>` y las etiquetas de posición iniciales de `{\an1}` a `{\an9}` se mantienen sin cambios, al igual que cualquier bloque que no tenga una línea de tiempo válida. Las líneas traducidas conservan los finales de línea del subtítulo original, y las descargas usan la codificación del archivo de origen. Los subtítulos sin cambios pueden reutilizar traducciones anteriores, y el glosario y los prompts personalizados de tu proyecto también se aplican a los subtítulos. (Consulta la [referencia del formato SRT](/docs/cli/reference/formats/srt-files) y [Definir el contexto para las traducciones](/docs/platform/dashboard/guides/defining-context-for-translations)).

Las líneas de tiempo se conservan exactamente igual que en el origen, así que ejecuta el script de verificación anterior en cada archivo traducido, sobre todo en idiomas cuyos textos suelen ser más largos que los de tu idioma de origen.

## Conclusiones clave

* En una traducción con tiempos fijos, cambia el texto de los subtítulos sin tocar los números de subtítulo, las líneas de tiempo, los separadores ni las etiquetas de formato. Si cambias deliberadamente los tiempos o los límites entre subtítulos, revísalos aparte cotejándolos con el vídeo.
* Netflix permite dos líneas de 42 caracteres como máximo, con una velocidad de lectura de hasta 20 caracteres por segundo en inglés y 17 en alemán en programas para adultos.
* La traducción de documentos de DeepL y Subtitle Edit admiten archivos SRT; la subida de documentos de Google Translate, no.
* La CLI `gt` (2.22.2 o posterior) traduce archivos SRT si añades `files.srt.include` con una ruta que incluya `[locale]` y ejecutas [`npx gt translate`](/docs/cli/reference/commands/translate). Solo traduce el texto de los subtítulos y mantiene los tiempos del archivo de origen.

## Related questions

- [¿Cómo traduzco Markdown y MDX sin romper la sintaxis?](https://generaltranslation.com/es/kb/translate-markdown-files.mdx): Traduce la prosa, el texto alt de las imágenes, los títulos y las descripciones del frontmatter, y las props de componentes que muestran texto. No modifiques los bloques de código, el código inline, las importaciones, los nombres de componentes JSX, las claves del frontmatter ni las URL de los enlaces, salvo que un mapeo de configuraciones regionales las reescriba. Pon entre comillas los valores YAML traducidos y, después, ejecuta la compilación de tu sitio.
- [¿Cómo traduzco archivos JSON de i18n?](https://generaltranslation.com/es/kb/translate-json-files.mdx): Traduce solo los valores de cadena de un archivo JSON de configuración regional. No modifiques las claves no plurales, los marcadores de posición como {{name}} ni las etiquetas, pero ten en cuenta que las claves plurales varían según el idioma: el polaco necesita inbox_few e inbox_many. Usa una herramienta o API que reconozca el formato y, después, analiza y valida el resultado antes de revisarlo.
- [¿Es la traducción con IA lo bastante precisa para una aplicación en producción?](https://generaltranslation.com/es/kb/is-ai-translation-accurate.mdx): A menudo sí, en los idiomas más hablados, pero solo después de superar una evaluación con tus propios idiomas, cadenas de UI y contenido de mayor riesgo. En WMT25, Gemini 2.5 Pro igualó o superó a las traducciones humanas de referencia en 10 de 16 pares de idiomas; aun así, un benchmark basado en documentos no demuestra si las cadenas cortas de interfaz están listas para publicarse.
- [Alternativas a Google Translate: General Translation vs. Google Translate](https://generaltranslation.com/es/kb/general-translation-vs-google-translate.mdx): Google Translate es una forma rápida de traducir textos puntuales, pero lanzar un producto en otro idioma también exige traducir cada cadena en su contexto, mantener una terminología coherente, gestionar correctamente las variables y los plurales, revisar las traducciones y contar con un proceso de lanzamiento. General Translation entiende el contexto de cada cadena en tu código y automatiza todo el flujo de trabajo de localización, desde el código hasta la revisión y cada lanzamiento.

## Previous and next questions

- Previous question: [¿Cómo traduzco Markdown y MDX sin romper la sintaxis?](https://generaltranslation.com/es/kb/translate-markdown-files.mdx)
- Next question: [¿Es la traducción con IA lo bastante precisa para una aplicación en producción?](https://generaltranslation.com/es/kb/is-ai-translation-accurate.mdx)

## Sitemap

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