Cómo configurar los subtítulos generados automáticamente

En esta página, se explica cómo agregar subtítulos generados automáticamente a tu salida con la API de Transcoder. Esta función te permite generar subtítulos a partir de pistas de audio, incluso si no se conoce el idioma, y traducir subtítulos a varios idiomas.

Para configurar esta función, proporciona metadatos adicionales sobre tus recursos de entrada con el campo attributes dentro de cada elemento del array inputs en la configuración del trabajo. Este campo ayuda a la API de Transcoder a comprender los idiomas presentes en tus pistas de audio y cómo procesarlos.

Antes de comenzar

En esta página, se supone que completaste los pasos que se indican en Antes de comenzar.

Limitaciones

Esta función tiene las siguientes limitaciones:

Ubicaciones admitidas

Esta función es compatible con us-central1 y europe-west4.

Formato de salida

El resultado de los subtítulos generados automáticamente debe estar en formato WebVTT (webvtt).

Cómo editar la unión de listas

Esta función no admite el uso de un editList para unir varios clips de video.

Ejemplos de configuración

En los siguientes ejemplos, se muestra cómo configurar los subtítulos automáticos para varios casos de uso.

Asignación proporcionada por el usuario

Este método proporciona control directo, ya que especifica exactamente qué pista de entrada se debe usar para generar subtítulos.

Asigna de forma explícita las pistas de entrada a los flujos de subtítulos de salida

En este ejemplo, se muestra cómo usar el campo mapping dentro de cada textStream para controlar con precisión qué pista de audio de entrada se usa para generar los subtítulos en inglés y francés.

{
  "config": {
    "inputs": [
      {
        "key": "input0",
        "uri": "gs://input-bucket/input.mp4",
        "attributes": {
          "trackDefinitions": [
            {
              "inputTrack": 1,
              "languages": [
                "en-US"
              ]
            },
            {
              "inputTrack": 2,
              "languages": [
                "fr-FR"
              ]
            }
          ]
        }
      }
    ],
    "editList": [
      {
        "key": "atom0",
        "inputs": [
          "input0"
        ]
      }
    ],
    "elementaryStreams": [
      {
        "key": "video-stream0",
        "videoStream": {
          "h264": {
            "frameRate": 30,
            "widthPixels": 1280,
            "heightPixels": 720,
            "bitrateBps": 3200000,
            "frameRateConversionStrategy": "DOWNSAMPLE"
          }
        }
      },
      {
        "key": "audio-stream0",
        "audioStream": {
          "codec": "aac",
          "bitrateBps": 64000,
          "sampleRateHertz": 48000,
          "channelCount": 2,
          "channelLayout": [
            "fl",
            "fr"
          ]
        }
      },
      {
        "key": "vtt-stream-english",
        "textStream": {
          "codec": "webvtt",
          "languageCode": "en-US",
          "displayName": "English",
          "mapping": [
            {
              "atomKey": "atom0",
              "inputKey": "input0",
              "inputTrack": 1
            }
          ]
        }
      },
      {
        "key": "vtt-stream-french",
        "textStream": {
          "codec": "webvtt",
          "languageCode": "fr-FR",
          "displayName": "French",
          "mapping": [
            {
              "atomKey": "atom0",
              "inputKey": "input0",
              "inputTrack": 2
            }
          ]
        }
      }
    ],
    "muxStreams": [
      {
        "container": "fmp4",
        "elementaryStreams": [
          "video-stream0"
        ],
        "fileName": "video-only.m4s",
        "key": "hd-video-only",
        "segmentSettings": {
          "segmentDuration": "6s"
        }
      },
      {
        "container": "fmp4",
        "elementaryStreams": [
          "audio-stream0"
        ],
        "fileName": "audio-only.m4s",
        "key": "audio-only",
        "segmentSettings": {
          "segmentDuration": "6s"
        }
      },
      {
        "key": "text-vtt-english",
        "container": "vtt",
        "elementaryStreams": [
          "vtt-stream-english"
        ],
        "segmentSettings": {
          "individualSegments": true,
          "segmentDuration": "6s"
        }
      },
      {
        "key": "text-vtt-french",
        "container": "vtt",
        "elementaryStreams": [
          "vtt-stream-french"
        ],
        "segmentSettings": {
          "individualSegments": true,
          "segmentDuration": "6s"
        }
      }
    ],
    "manifests": [
      {
        "fileName": "manifest.m3u8",
        "muxStreams": [
          "hd-video-only",
          "audio-only",
          "text-vtt-english",
          "text-vtt-french"
        ],
        "type": "HLS"
      }
    ],
    "output": {
      "uri": "gs://your-bucket/output/"
    }
  }
}

La transmisión vtt-stream-english se genera a partir del segmento 1 de input0 debido a la asignación explícita. La transmisión vtt-stream-french se genera a partir de la pista 2 de input0.

Asignación predeterminada de la API de Transcoder

Estos ejemplos se basan en la API para inferir qué pista de audio usar según el attributes proporcionado en el inputs. Se supone que las otras partes de la configuración (muxStreams, manifests, output) son similares al ejemplo completo.

Una sola pista de audio con un idioma conocido

Si tu video de entrada tiene una pista de audio (p.ej., la pista 1) y sabes que está en inglés (en-US), puedes generar subtítulos en inglés. También puedes solicitar subtítulos en otros idiomas, como francés (fr-FR), y la API traducirá la transcripción en inglés.

{
  "inputs": [
    {
      "key": "input0",
      "uri": "gs://input-bucket/input.mp4",
      "attributes": {
        "trackDefinitions": [
          {
            "inputTrack": 1,
            "languages": [
              "en-US"
            ]
          }
        ]
      }
    }
  ],
  "elementaryStreams": [
    { "key": "video-stream0", "videoStream": { ... } },
    { "key": "audio-stream0", "audioStream": { ... } },
    {
      "key": "vtt-stream-english",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "en-US",
        "displayName": "English"
      }
    },
    {
      "key": "vtt-stream-french",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "fr-FR",
        "displayName": "French"
      }
    }
  ]
}

La pista de subtítulos en inglés (vtt-stream-english) se genera directamente a partir de la pista de audio 1 definida, ya que los códigos de idioma coinciden. El flujo de subtítulos en francés (vtt-stream-french) se produce primero transcribiendo el audio en inglés de la pista 1 y, luego, traduciendo el texto resultante al francés.

Varias pistas de audio con idiomas conocidos

Cuando tu archivo de entrada contiene varias pistas de audio con diferentes idiomas (p.ej., francés en la pista 1 e inglés en la pista 2), puedes especificar los idiomas para cada pista.

{
  "inputs": [
    {
      "key": "input0",
      "uri": "gs://input-bucket/input.mp4",
      "attributes": {
        "trackDefinitions": [
          {
            "inputTrack": 1,
            "languages": ["fr-FR"]
          },
          {
            "inputTrack": 2,
            "languages": ["en-US"]
          }
        ]
      }
    }
  ],
  "elementaryStreams": [
    { "key": "video-stream0", "videoStream": { ... } },
    { "key": "audio-stream0", "audioStream": { ... } },
    {
      "key": "vtt-stream-english",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "en-US",
        "displayName": "English"
      }
    },
    {
      "key": "vtt-stream-french",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "fr-FR",
        "displayName": "French"
      }
    }
  ]
}

En esta configuración, los subtítulos en vtt-stream-english se generan a partir de la pista de audio 2, y los subtítulos en vtt-stream-french se generan a partir de la pista de audio 1, según los códigos de idioma proporcionados en attributes.

El idioma de salida no coincide con ninguna pista de audio de entrada

Si el idioma de subtítulos solicitado no coincide con ningún idioma de pista definido, la API usa la pista de audio disponible primero para la transcripción y la traducción.

{
  "inputs": [
    {
      "key": "input0",
      "uri": "gs://input-bucket/input.mp4",
      "attributes": {
        "trackDefinitions": [
          {
            "inputTrack": 1,
            "languages": ["fr-FR"]
          },
          {
            "inputTrack": 2,
            "languages": ["en-US"]
          }
        ]
      }
    }
  ],
  "elementaryStreams": [
    { "key": "video-stream0", "videoStream": { ... } },
    { "key": "audio-stream0", "audioStream": { ... } },
    {
      "key": "vtt-stream-hindi",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "hi-IN",
        "displayName": "Hindi"
      }
    }
  ]
}

Como no se define ninguna pista de audio en hindi, los subtítulos vtt-stream-hindi se generan transcribiendo la primera pista de audio (pista 1, francés) y, luego, traduciendo la transcripción al hindi.

Una sola pista de audio con idiomas combinados

Si una sola pista de audio contiene varios idiomas, enuméralos todos en el array languages.

{
  "inputs": [
    {
      "key": "input0",
      "uri": "gs://input-bucket/input.mp4",
      "attributes": {
        "trackDefinitions": [
          {
            "inputTrack": 1,
            "languages": ["en-US", "fr-FR"]
          }
        ]
      }
    }
  ],
  "elementaryStreams": [
    { "key": "video-stream0", "videoStream": { ... } },
    { "key": "audio-stream0", "audioStream": { ... } },
    {
      "key": "vtt-stream-english",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "en-US",
        "displayName": "English"
      }
    },
    {
      "key": "vtt-stream-french",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "fr-FR",
        "displayName": "French"
      }
    },
    {
      "key": "vtt-stream-hindi",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "hi-IN",
        "displayName": "Hindi"
      }
    }
  ]
}

Los tres flujos de VTT (inglés, francés y hindi) se generan a partir de la pista de audio 1. La API transcribirá el audio en varios idiomas y proporcionará cada flujo de salida en el único idioma especificado por el campo languageCode.

La API transcribe el audio y puede detectar varios idiomas en la pista 1. Para cada textStream de salida, genera subtítulos solo en el idioma especificado por el campo languageCode de ese flujo.

Detección de idioma en una pista de audio específica

Usa detectLanguages": true cuando se desconozca el idioma de un segmento específico.

{
  "inputs": [
    {
      "key": "input0",
      "uri": "gs://input-bucket/input.mp4",
      "attributes": {
        "trackDefinitions": [
          {
            "inputTrack": 1,
            "detectLanguages": true
          }
        ]
      }
    }
  ],
  "elementaryStreams": [
    { "key": "video-stream0", "videoStream": { ... } },
    { "key": "audio-stream0", "audioStream": { ... } },
    {
      "key": "vtt-stream-english",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "en-US",
        "displayName": "English"
      }
    }
  ]
}

Primero, la API detecta los idiomas presentes en la pista de audio 1. Luego, genera los subtítulos en inglés, incluida la traducción si el idioma detectado no es inglés.

Detección de idioma en la pista de audio predeterminada

Si se desconocen tanto el idioma como el número de pista, la API usará de forma predeterminada la primera pista de audio disponible.

{
  "inputs": [
    {
      "key": "input0",
      "uri": "gs://input-bucket/input.mp4",
      "attributes": {
        "trackDefinitions": [
          {
            "detectLanguages": true
          }
        ]
      }
    }
  ],
  "elementaryStreams": [
    { "key": "video-stream0", "videoStream": { ... } },
    { "key": "audio-stream0", "audioStream": { ... } },
    {
      "key": "vtt-stream-english",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "en-US",
        "displayName": "English"
      }
    }
  ]
}

La API analiza la primera pista de audio para detectar los idiomas y, luego, genera los subtítulos en inglés, traduciéndolos si es necesario.

Especifica el idioma de la pista de audio predeterminada

Si conoces el idioma, pero no el número de pista específico, la API supone que la primera pista de audio disponible coincide con el idioma proporcionado.

{
  "inputs": [
    {
      "key": "input0",
      "uri": "gs://input-bucket/input.mp4",
      "attributes": {
        "trackDefinitions": [
          {
            "languages": ["en-US"]
          }
        ]
      }
    }
  ],
  "elementaryStreams": [
    { "key": "video-stream0", "videoStream": { ... } },
    { "key": "audio-stream0", "audioStream": { ... } },
    {
      "key": "vtt-stream-english",
      "textStream": {
        "codec": "webvtt",
        "languageCode": "en-US",
        "displayName": "English"
      }
    }
  ]
}

Los subtítulos en inglés (vtt-stream-english) se generan a partir de la primera pista de audio de la entrada, con la suposición de que esta pista está en inglés.

Preguntas frecuentes

¿Qué sucede si especifico languages y detectLanguages en el mismo trackDefinition?

Solo puedes especificar uno de los campos languages o detectLanguages dentro de un solo trackDefinition. Proporcionar ambos en la misma definición es una configuración no válida y generará un error.

¿Cómo elige la API qué pista de audio usar si varios trackDefinitions coinciden con el idioma de un textStream?

Si tienes varios trackDefinitions en el array inputs.attributes.trackDefinitions que podrían coincidir con el languageCode de un textStream solicitado, la API usará la pista de audio del trackDefinition coincidente primero en el orden del array. Esto solo se aplica cuando no usas el campo mapping explícito dentro de textStream.