Configurar legendas geradas automaticamente

Esta página explica como adicionar legendas geradas automaticamente à saída usando a API Transcoder. Com esse recurso, é possível gerar legendas de faixas de áudio, mesmo que o idioma não seja conhecido, e traduzir legendas para vários idiomas.

Para configurar esse recurso, forneça mais metadados sobre os recursos de entrada usando o campo attributes em cada item da matriz inputs na configuração do job. Esse campo ajuda a API Transcoder a entender os idiomas presentes nas suas faixas de áudio e como processá-los.

Antes de começar

Nesta página, pressupomos que você concluiu as etapas em Antes de começar.

Limitações

Este recurso tem as seguintes limitações:

Locais suportados

Esse recurso está disponível no us-central1 e no europe-west4.

Formato da saída

A saída das legendas geradas automaticamente precisa estar no formato WebVTT (webvtt).

Editar junção de listas

Esse recurso não é compatível com o uso de um editList para juntar vários videoclipes.

Exemplos de configuração

Os exemplos a seguir demonstram como configurar legendas automáticas para vários casos de uso.

Mapeamento fornecido pelo usuário

Esse método oferece controle direto ao especificar exatamente qual faixa de entrada usar para gerar legendas.

Mapear explicitamente as faixas de entrada para os fluxos de legendas de saída

Este exemplo mostra como usar o campo mapping em cada textStream para controlar com precisão qual faixa de áudio de entrada é usada para gerar as legendas em inglês e 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/"
    }
  }
}

O stream vtt-stream-english é gerado da faixa 1 de input0 devido ao mapeamento explícito. O stream vtt-stream-french é gerado da faixa 2 de input0.

Mapeamento padrão pela API Transcoder

Esses exemplos dependem da API para inferir qual faixa de áudio usar com base no attributes fornecido no inputs. As outras partes da configuração (muxStreams, manifests, output) são consideradas semelhantes ao exemplo completo.

Uma única faixa de áudio em um idioma conhecido

Se o vídeo de entrada tiver uma faixa de áudio (por exemplo, faixa 1) e você souber que ela está em inglês (en-US), gere legendas em inglês. Você também pode pedir legendas em outros idiomas, como francês (fr-FR), e a API vai traduzir a transcrição em 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"
      }
    }
  ]
}

A transmissão de legendas em inglês (vtt-stream-english) é gerada diretamente da faixa de áudio 1 definida, já que os códigos de idioma correspondem. O fluxo de legendas em francês (vtt-stream-french) é produzido primeiro transcrevendo o áudio em inglês da faixa 1 e depois traduzindo o texto resultante para francês.

Várias faixas de áudio com idiomas conhecidos

Quando o arquivo de entrada contém várias faixas de áudio com idiomas diferentes (por exemplo, francês na faixa 1 e inglês na faixa 2, por exemplo, é possível especificar os idiomas de cada faixa.

{
  "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"
      }
    }
  ]
}

Nessa configuração, as legendas vtt-stream-english são geradas da faixa de áudio 2, e as legendas vtt-stream-french são geradas da faixa de áudio 1, com base nos códigos de idioma fornecidos no attributes.

O idioma de saída não corresponde a nenhuma faixa de áudio de entrada

Se o idioma da legenda solicitada não corresponder a nenhum idioma de faixa definido, a API usará a primeira faixa de áudio disponível para transcrição e tradução.

{
  "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 nenhuma faixa de áudio em hindi está definida, as legendas vtt-stream-hindi são geradas transcrevendo a primeira faixa de áudio (faixa 1, francês) e traduzindo a transcrição para hindi.

Faixa de áudio única com idiomas mistos

Se uma única faixa de áudio tiver vários idiomas, liste todos eles na matriz 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"
      }
    }
  ]
}

Todos os três fluxos VTT (inglês, francês e hindi) são gerados da faixa de áudio 1. A API vai transcrever o áudio em vários idiomas e fornecer cada fluxo de saída no único idioma especificado pelo campo languageCode.

A API transcreve o áudio, detectando vários idiomas na faixa 1. Para cada textStream de saída, ele gera legendas apenas no idioma especificado pelo campo languageCode desse fluxo.

Detecção de idioma em uma faixa de áudio específica

Use detectLanguages": true quando o idioma de uma faixa específica for desconhecido.

{
  "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"
      }
    }
  ]
}

Primeiro, a API detecta os idiomas presentes na faixa de áudio 1. Em seguida, ele gera as legendas em inglês, incluindo a tradução se o idioma detectado não for o inglês.

Detecção de idioma na faixa de áudio padrão

Se o idioma e o número da faixa forem desconhecidos, a API usará a primeira faixa de áudio disponível por padrão.

{
  "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"
      }
    }
  ]
}

A API analisa a primeira faixa de áudio para detectar os idiomas e gera as legendas em inglês, traduzindo se necessário.

Especificar o idioma da faixa de áudio padrão

Se você souber o idioma, mas não o número da faixa específica, a API vai presumir que a primeira faixa de áudio disponível corresponde ao idioma fornecido.

{
  "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"
      }
    }
  ]
}

As legendas em inglês (vtt-stream-english) são geradas com base na primeira faixa de áudio da entrada, presumindo que ela esteja em inglês.

Perguntas frequentes

O que acontece se eu especificar languages e detectLanguages no mesmo trackDefinition?

Só é possível especificar um dos campos languages ou detectLanguages em um único trackDefinition. Fornecer os dois na mesma definição é uma configuração inválida e vai resultar em um erro.

Como a API escolhe qual faixa de áudio usar se vários trackDefinitions corresponderem ao idioma de um textStream?

Se você tiver vários trackDefinitions na matriz inputs.attributes.trackDefinitions que possam corresponder ao languageCode de um textStream solicitado, a API usará a faixa de áudio do trackDefinition primeiro correspondente na ordem da matriz. Isso só se aplica quando você não está usando o campo mapping explícito no textStream.