Envio de conteúdo ao vivo do YouTube pelo DASH

Este documento fornece diretrizes para usar o formato de entrega Dynamic Adaptive Streaming over HTTP (DASH) para transmitir dados ao vivo no YouTube de um codificador. Ele foi criado para ajudar os fornecedores de codificadores a adicionar suporte à entrega de DASH aos produtos deles.

Entender o DASH

A lista abaixo mostra alguns recursos e atributos principais do DASH:

  • Baseado em padrões abertos.
  • Baseado em HTTP. Como resultado, o DASH é compatível com a infraestrutura da Internet e pode atravessar firewalls.
  • Suporta alta taxa de bits de transferência. O DASH é compatível com várias sessões HTTP simultâneas e entrega de segmentos não sequenciais, oferecendo mais capacidade de recuperação do que protocolos que dependem de uma única conexão TCP.
  • Entrega segura por HTTPS.
  • Entrega sem perdas por HTTP e HTTPS.
  • Independente de codec.
  • Compatível com MP4 que contém H264 e AAC, além de WebM que contém VP8/VP9 e Vorbis/Opus.

Especificações

Requisitos

As subseções a seguir explicam os requisitos para usar o DASH e fazer transmissões ao vivo no YouTube.

Tempo

O endpoint DASH do YouTube se comporta como um servidor HTTP passivo, gravando chamadas do método PUT enviadas por um codificador.

  • O endpoint DASH é compatível com conexões TCP simultâneas. É possível reutilizar conexões de acordo com o HTTP/1.1.
  • O MPD e os segmentos de inicialização precisam ser PUT em até 3 segundos após o primeiro segmento de mídia. Recomendamos que você inclua o segmento de inicialização no MPD.
  • Cada segmento ou MPD precisa usar uma solicitação PUT separada. O upload de várias partes de vários segmentos não é compatível.
  • As operações PUT para segmentos de mídia podem se sobrepor no tempo para melhorar a largura de banda de upload.
  • Os segmentos podem ser fornecidos em ordem não sequencial em uma janela de tempo de aproximadamente 3 segundos.
  • Os segmentos MPD e de inicialização precisam ser atualizados pelo menos a cada 60 segundos com um availabilityStartTime e um startNumber atualizados. Como mencionado acima, o segmento de inicialização pode ser incluído no MPD. Nesse caso, uma solicitação PUT pode atualizar os dois segmentos.)

Estrutura do URL

O codificador precisa formar URLs PUT anexando uma string ao URL base do endpoint do YouTube. Você precisa criar o endpoint de ingestão DASH usando a API YouTube Live Streaming.

Em seguida, o codificador pode receber o URL de base do endpoint de maneira programática pela API YouTube Live Streaming. O URL base também fica visível na interface dos Eventos ao vivo do YouTube se você quiser fornecer o URL ao codificador manualmente.

A string anexada ao URL base pode conter o seguinte conjunto de caracteres ASCII:

  • Letras minúsculas: a-z
  • Letras maiúsculas: A-Z
  • Dígitos: 0 a 9
  • Caracteres especiais: _ (sublinhado), - (hífen), . (ponto)

URLs da MPD

Além do requisito acima, o URL da MPD precisa terminar com .mpd, permitindo que o servidor do YouTube identifique facilmente a MPD. Os URLs de outros segmentos não podem terminar com .mpd.

Inicialização e URLs de segmentos de mídia

O URL do segmento de inicialização e todos os URLs de segmento de mídia precisam terminar com .mp4 se os dados estiverem em um contêiner ISO BMFF ou com .webm se os dados estiverem em um contêiner WebM.

Conteúdo da MPD

O MPD precisa estar completo e em conformidade com o padrão DASH. Ele precisa conter exatamente um de cada um dos seguintes elementos. Essa lista identifica elementos especificamente exigidos pelo YouTube, e o padrão DASH pode identificar outros elementos necessários. Os elementos são representados usando a sintaxe XPath e são consistentes com o padrão DASH.

  • /mpd:MPD/attribute::type
  • /mpd:MPD/mpd:Period
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/attribute::mimeType (video/mp4 or video/webm)
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::media
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::initialization
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::startNumber

Observe os seguintes requisitos para valores de elementos:

  • O atributo minimumUpdatePeriod do elemento <MPD> precisa ser definido como um valor igual ou menor que 60 segundos (PT60S).
  • O atributo media do elemento <SegmentTemplate> precisa especificar que os URLs de segmento de mídia são gerados usando $Number$. O atributo startNumber identifica o número que será atribuído ao primeiro segmento de mídia.

Duração do segmento de inicialização

O segmento de inicialização não pode ter mais de 100 KB. Normalmente, um segmento de inicialização é muito menor do que isso. Se o segmento de inicialização estiver incluído no MPD, o URL data:, que contém o segmento, não poderá ter mais de 100 KB.

Saída do codificador

O segmento de inicialização e os segmentos de mídia precisam constituir um fluxo de arquivos ISO BMFF ou WebM multiplexado com GOPs (grupos de imagens) fechados.

  • O tamanho do GOP precisa ser de cerca de 2 segundos e não pode ultrapassar 8 segundos.
  • O stream multiplexado precisa conter faixas de áudio e vídeo.

Práticas recomendadas adicionais

Criptografia

O YouTube oferece suporte à criptografia de stream via HTTPS. Recomendamos muito que você use esse recurso.

Segmentos de inicialização em MPD

É possível representar o segmento de inicialização diretamente no MPD usando um URL data:, conforme a RFC 2397. Isso simplifica a configuração do stream e reduz a possibilidade de que o segmento de inicialização não corresponda ao restante do stream.

O XPath para esse elemento é:

/mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute:data

Durações de segmento de destino

Para uma boa performance de ingestão e uma boa compensação entre capacidade e latência, a duração dos segmentos de mídia precisa estar entre 1 e 5 segundos. Recomendamos informar a duração desejada desses segmentos no MPD usando estes dois elementos:

  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::duration
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::timescale

A duração calculada com base nesses atributos precisa estar dentro de um fator de 2 de todas as durações reais de segmento. Caso contrário, o desempenho do streaming pode ser afetado.

A duração da ingestão não é igual à duração do bloco da transmissão ao vivo produzida pelo YouTube. O YouTube transcodifica e refragmenta a entrada, e a duração desejada da saída depende se um stream é otimizado para qualidade ou para latência.

Novas tentativas e espera exponencial

Todas as solicitações HTTP PUT devem ser realizadas com um tempo limite, que recomendamos definir como um valor 500 milissegundos maior que a duração do segmento.

Uma solicitação PUT de segmento de mídia que falha, seja por tempo limite ou outros erros, corresponde a uma lacuna no fluxo de vídeo. Portanto, repita qualquer solicitação desse tipo usando uma espera exponencial binária aleatória:

  1. Após uma falha, aguarde um período aleatório entre [0 ... 100] milissegundos e tente novamente.
  2. Se a solicitação falhar novamente, aguarde um período aleatório entre [0 ... 200] milissegundos e tente de novo.
  3. Se a solicitação falhar novamente, aguarde um período aleatório entre [0 ... 400] milissegundos e tente de novo.
  4. etc.

Falhas repetidas precisam ser sinalizadas ao operador do codificador, já que correspondem a uma transmissão com falha.

Códigos de resposta HTTP

As seções a seguir explicam os códigos de resposta que o YouTube retorna em resposta a segmentos entregues via DASH.

200 (OK)

Uma resposta HTTP 200 (OK) indica que o servidor do YouTube recebeu uma operação esperada e a processou com êxito.

202 (Aceito)

Uma resposta HTTP 202 (Aceita) a qualquer operação PUT ou POST indica que a operação foi inesperada e aceita para processamento adiado. No entanto, a operação adiada pode ser concluída ou falhar. Portanto, a resposta não garante que o YouTube vai conseguir processar a operação.

Essa resposta ocorre com mais frequência quando um segmento é entregue de forma não sequencial. Normalmente, o YouTube consegue processar corretamente o segmento aceito depois de receber os anteriores, e não é necessário reenviar o segmento.

Por exemplo, o YouTube pode retornar uma resposta 202 em qualquer um dos seguintes casos:

  • Um segmento de inicialização é recebido antes do MPD.
  • Os segmentos de mídia são recebidos antes dos segmentos de MPD e de inicialização.
  • Um segmento de mídia é recebido antes de um segmento anterior, como o segmento 3 sendo recebido antes do segmento 2.

No entanto, uma resposta 202 também pode indicar que o identificador do item está incorreto se o YouTube não conseguir validar totalmente o identificador ao receber a solicitação POST ou PUT. Por exemplo, isso acontece quando o YouTube recebe e aceita um segmento de inicialização antes de receber o MPD, mas o segmento de inicialização acaba sendo inválido. Nesse caso, o YouTube aceita o segmento de inicialização e retorna um 202. Depois, ele determina se o segmento é válido ao receber o MPD. Para evitar esse cenário específico, inclua o segmento de inicialização no MPD.

400 (Solicitação inválida)

Uma resposta HTTP 400 (Solicitação inválida) indica que ocorreu um dos seguintes problemas:

  • O URL está malformado.
  • A postagem é muito grande (mais de 10 MB).
  • Não é possível analisar a MPD.
  • O segmento de inicialização na MPD está corrompido.

401 (Não autorizado)

Uma resposta HTTP 401 (Não autorizado) indica que o URL de base do endpoint DASH do YouTube está corrompido ou expirou.

405 (Método não permitido)

Uma resposta HTTP 405 (Method Not Allowed) indica que uma solicitação diferente de POST ou PUT foi enviada.

409 (Conflito)

Uma resposta HTTP 409 (conflito) a qualquer operação PUT ou POST indica que o YouTube não pode processar a solicitação. Por exemplo, essa resposta pode ocorrer se o solicitante tiver enviado vários segmentos de mídia, mas o YouTube ainda não tiver o MPD, o segmento de inicialização ou ambos. Nesse exemplo, o codificador precisaria retransmitir o MPD e os segmentos de inicialização antes de tentar novamente a solicitação com falha.

500 (erro interno do servidor)

Uma resposta HTTP 500 (erro interno do servidor) indica que o servidor não conseguiu processar a solicitação. Para esse erro, recomendamos que você repita a solicitação com espera exponencial.

Exemplos

Sequência de URL

A sequência de URLs abaixo mostra uma série de solicitações PUT que seriam feitas para entregar conteúdo via DASH. A sequência pressupõe que o URL base do endpoint DASH do YouTube seja:

http://upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=

A sequência mostra o MPD e os segmentos de inicialização enviados separadamente. No entanto, o segmento de inicialização pode ser representado diretamente na MPD, e essa prática é recomendada. Além disso, os segmentos de MPD e inicialização precisam ser atualizados pelo menos a cada 60 segundos. Assim, eventualmente, os URLs desses segmentos apareceriam novamente nessa sequência, seguidos por URLs de mais segmentos de mídia.

PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=dash.mpd
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media001.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media002.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media003.mp4
...

Segmentos WebM

MPD com segmento de inicialização incorporado

O exemplo de MPD a seguir tem um segmento de inicialização incorporado em um URL de dados RFC 2397. Recomendamos que você incorpore o segmento de inicialização dessa maneira, em vez de enviá-lo separadamente.

Este exemplo está em conformidade com a ingestão de WebM (VP8 ou VP9, Opus) no YouTube. A maior parte do URL de dados foi omitida para facilitar a leitura:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic" 
     profiles="urn:mpeg:dash:profile:isoff-live:2011" 
     minimumUpdatePeriod="PT60S"
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:52:58" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/webm">
      <ContentComponent contentType="video" id="1"/>
      <SegmentTemplate timescale="1000"
           duration="2000"
           startNumber="1"
           initialization="data:video/mp4;base64,AAAAGGZ0eXBpc...AAA"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media-$Number%09d$.webm"/>
      <Representation id="1" width="1920" height="1080">
        <SubRepresentation contentComponent="1"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

MPD

O exemplo de MPD a seguir, que não tem um segmento de inicialização incorporado, também está em conformidade com o processamento de WebM (VP8 ou VP9, Opus) para o YouTube:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic" 
     profiles="urn:mpeg:dash:profile:isoff-live:2011" 
     minimumUpdatePeriod="PT60S"
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:52:58" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/webm">
      <ContentComponent contentType="video" id="1"/>
      <SegmentTemplate timescale="1000"
           duration="2000"
           startNumber="1"
           initialization="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.webm"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media-$Number%09d$.webm"/>
      <Representation id="1" width="1920" height="1080">
        <SubRepresentation contentComponent="1"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

Inicialização

A seguir, mostramos o layout de um exemplo de segmento de inicialização WebM. Ela consiste na parte do fluxo WebM até o primeiro cluster, mas não o inclui.

Mídia

A seguir, mostramos o layout de um exemplo de segmento de mídia WebM. Ele consiste em um único cluster WebM. Assim como em um fluxo ISO BMFF, o segmento de inicialização adicionado a uma série de clusters precisa gerar um fluxo WebM válido.

Segmentos ISO BMFF

MPD com segmento de inicialização incorporado

O exemplo de MPD a seguir tem um segmento de inicialização incorporado em um URL de dados RFC 2397. Recomendamos que você incorpore o segmento de inicialização dessa maneira, em vez de enviá-lo separadamente.

Este exemplo está em conformidade com a ingestão ISO BMFF (H.264, AAC) no YouTube. A maior parte do URL de dados foi omitida para facilitar a leitura:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="urn:mpeg:dash:schema:mpd:2011"   
    xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" 
    type="dynamic"
    minimumUpdatePeriod="PT30S" 
    availabilityStartTime="2016-05-04T20:47:25" 
    minBufferTime="PT12S" 
    profiles="urn:mpeg:dash:profile:isoff-live:2011">
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/mp4" codecs="avc1.4d401e,mp4a.40.2">
      <ContentComponent contentType="video" id="1"/>
      <ContentComponent contentType="audio" id="2"/>
      <SegmentTemplate timescale="600"
             media="/dash_upload?cid=ug50-xg26-cbc1-2p0h&staging=1&copy=0&file=media$Number%09d$.mp4"
             initialization="data:video/mp4;base64,AAAAGGZ0eXBpc281AA...AA"
             duration="306"
             startNumber="1"/>
      <Representation id="1" width="640" height="360" bandwidth="526952">
        <SubRepresentation contentComponent="1" bandwidth="526952" 
codecs="avc1.4d401e"/>
        <SubRepresentation contentComponent="2" bandwidth="125584" codecs="mp4a.40.2"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

MPD

O exemplo de MPD a seguir, que não tem um segmento de inicialização incorporado, também está em conformidade com a ingestão ISO BMFF (H.264, AAC) no YouTube:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic"
     profiles="urn:mpeg:dash:profile:isoff-live:2011"
     minimumUpdatePeriod="PT60S" 
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:51:31" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/mp4" codecs="avc1.4d401e,mp4a.40.2">
      <ContentComponent contentType="video" id="1"/>
      <ContentComponent contentType="audio" id="2"/>
      <SegmentTemplate timescale="600"
           duration="1200"
           startNumber="1"
           initialization="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.mp4"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media$Number%09d$.mp4"/>
      <Representation id="1" width="640" height="360" bandwidth="526952">
        <SubRepresentation contentComponent="1" bandwidth="526952" codecs="avc1.4d401e"/>
        <SubRepresentation contentComponent="2" bandwidth="125584" codecs="mp4a.40.2"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

Inicialização

O diagrama a seguir mostra o layout de um exemplo de segmento de inicialização ISO BMFF multiplexado. O YouTube não usa necessariamente os átomos, mas este é um exemplo adequado. Em particular, as faixas de áudio e vídeo são representadas.

Mídia

O diagrama a seguir mostra o layout de um exemplo de segmento de mídia ISO BMFF multiplexado. O YouTube não usa necessariamente todos os átomos, mas este é um exemplo compatível. Em particular, as faixas de áudio e vídeo são representadas. Uma série desses segmentos pode ser anexada a um segmento de inicialização para produzir um fluxo ISO BMFF multiplexado válido e completo.

Limitações conhecidas

Ingestões RTMP e DASH

Não é possível misturar ingestões RTMP e DASH no YouTube. Isso se aplica à troca entre os dois durante uma transmissão e ao uso de um como método principal de ingestão e do outro para ingestão de backup.