Skip to content

Captura por HLS

O Sapsan segue uma playlist HLS de terceiros em modo cliente (pull): sonda a playlist, baixa os segmentos e entrega quadros ao pipeline tal como RTSP, SRT ou MPEG-TS. É assim que entrega o stream quase todo agregador, toda CDN de terceiros e todo parceiro a quem não foi permitido abrir UDP ou SRT.

Configuração

streams:
  - name: chan1
    inputs:
    - hls:
        url: https://cdn.example.com/live/index.m3u8
Parâmetro Por padrão Descrição
url endereço da playlist exatamente como o operador o escreveu
headers nenhum cabeçalhos adicionados a cada requisição à fonte: playlist, segmentos, chaves
variant_mode single single — uma variante do master, ladder — a escada inteira
variant_bandwidth nenhum com qual bitrate casar a variante (o mais próximo abaixo); sem ele vence o maior BANDWIDTH
skew_threshold_ms 500 o desvio a partir do qual a escada é declarada fora de sincronia
skew_policy report o que fazer diante de um veredito skewed: report — continuar e mostrar, fallback_to_single — recuar para uma variante só
connect_timeout_ms 5000 tempo limite de estabelecimento da conexão
read_timeout_ms 15000 tempo limite do corpo: playlist, segmento, chave
max_body_bytes 64 MiB limite de tamanho de uma única resposta
peer_timeout_ms global quanto esperar quadros antes de considerar a fonte perdida

Um campo omitido significa o padrão do servidor, não «desativado».

O esquema pode ser escrito de três formas, todas equivalentes:

  • https://host/path.m3u8 — reconhecido pela extensão do caminho, uma query não atrapalha;
  • hls://host/path.m3u8 — o mesmo que http://;
  • hlss://host/path.m3u8 — o mesmo que https://.

Regra de início

Tudo o que já estava na playlist no momento da conexão é história. A captura começa pelo primeiro segmento que aparece depois da conexão, e numa reconexão ela se comporta igual.

Não existe de propósito ajuste de profundidade de início: caso contrário, a cada queda de conexão o stream despejaria no pipeline, em segundos, a janela acumulada, em vez de transmitir.

Autenticação

Duas formas, e elas se combinam:

  • cabeçalhosheaders, por exemplo Authorization: Bearer <token>; vão com a playlist, as variantes, os segmentos init, os segmentos e as chaves do mesmo origin, e nunca seguem um redirecionamento para um origin de terceiros;
  • credenciais na própria URL — autenticação Basic comum feita pelo cliente HTTP.

Os valores dos cabeçalhos nunca chegam ao log: só os nomes são impressos. O endereço da entrada é escrito inteiro nos logs e devolvido como está pela API de gerenciamento — qual parte desse endereço é o segredo, só o operador sabe, e uma máscara às cegas ou deixaria o token na query, ou cortaria justamente aquilo pelo que a entrada é reconhecida no log.

Escada de qualidades e desvio das renditions

Com variant_mode: ladder captura-se toda variante do master. A de maior BANDWIDTH passa a ser a referência, e as demais são comparadas com ela segmento a segmento, pelo número de sequência de mídia. O veredito fica exposto na estatística da entrada, campo hls_ladder:

  • synced — as renditions andam juntas, comutar entre elas é seguro;
  • skewed — o desvio passou do limite ou a estrutura está quebrada: a comutação dará trancos ou dessincronizará;
  • unmeasurable — não há com o que comparar, nenhum par de segmentos compartilha número.

O desvio é medido de duas maneiras ao mesmo tempo. O declarado é a diferença de EXT-X-PROGRAM-DATE-TIME na marcação; o real é a diferença do tempo de mídia dos primeiros quadros. Quando os dois discordam, o doente é a marcação, não o stream, e quem conserta é o dono da fonte.

Note

O Sapsan não traz as variantes da escada para uma escala de tempos comum, e não conserta de jeito nenhum um conteúdo ruim: um conserto silencioso não torna a escada comutável, apenas esconde o defeito. Por isso o desvio é mostrado como número, e quem decide é o operador.

A política fallback_to_single derruba a captura para uma variante só diante de um veredito skewed — para algumas fontes é o único modo viável. O recuo dura até a entrada ser reiniciada.

Criptografia

São suportados AES-128 (o segmento inteiro) e SAMPLE-AES (por quadro, para H.264 e AAC). A chave é buscada pelo mesmo cliente e com os mesmos cabeçalhos que todo o resto, e fica em cache por endereço, de modo que a rotação de chaves no meio de uma playlist funciona sozinha — uma chave nova tem outro endereço.

Um servidor de chaves calado é um erro de entrada com o endereço da chave e o código de resposta; o corpo do segmento não é baixado de forma alguma, já que não haveria com o que descriptografá-lo.

CENC/DRM (Widevine, PlayReady, FairPlay) não é suportado e é rejeitado pelo nome do KEYFORMAT.

O que é suportado

Funcionalidade Estado
Playlist de mídia: EXT-X-MEDIA-SEQUENCE, EXTINF, EXT-X-ENDLIST sim
Playlist master: seleção de variante, renditions EXT-X-MEDIA sim
Segmentos fMP4 (EXT-X-MAP) e MPEG-TS sim
EXT-X-BYTERANGE sim
EXT-X-DISCONTINUITY, recriação da playlist, ficar atrás da janela sim
EXT-X-GAP sim, pulado sem erro
EXT-X-PROGRAM-DATE-TIME — ancoragem do tempo de mídia ao UTC sim
Criptografia AES-128 e SAMPLE-AES (H.264, AAC) sim
Escada: captura de toda variante, medição do desvio sim
LL-HLS: EXT-X-PART, blocking reload não, as partes são ignoradas
CENC/DRM não
Áudio «empacotado»: ADTS puro ou ID3+AAC em vez de um contêiner não, o formato é nomeado no erro
Legendas TTML e segmentos WebVTT não, a faixa é reconhecida e pulada
Captura MPEG-DASH não

Aplicação das mudanças

Só uma mudança de url, headers ou dos ajustes HTTP (connect_timeout_ms, read_timeout_ms, max_body_bytes) reinicia a entrada: uma fonte nova tem sua própria numeração de faixas, seu próprio init e sua própria posição na playlist. Todo o resto — modo de variante, limite e política de desvio, peer_timeout_ms — é aplicado em tempo real, sem interromper a transmissão.

Verificação

Abra http://server/streaming/v/chan1/index.m3u8 num reprodutor ou peça uma captura de tela em http://server/streaming/live-preview-jpeg/chan1.

Vá além de «os quadros estão fluindo» e olhe três coisas:

  • o quanto a saída atrasa em relação à borda da playlist — sem isso, a reclamação «o stream está atrasado» é indistinguível de «a fonte está atrasada», e as duas se consertam em lugares diferentes;
  • os segmentos pulados e seu detalhamento: lavados para fora da janela, cancelados em voo, declarados com EXT-X-GAP. O último não é um erro da fonte, e sim a sua declaração honesta;
  • a emenda entre fragmentos vizinhos — um defeito silencioso: todos os segmentos foram baixados, sem erros de análise, mas a mídia dentro deles não se encaixa, e o arquivo guarda o buraco.

Próximos passos