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 quehttp://;hlss://host/path.m3u8— o mesmo quehttps://.
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çalhos —
headers, por exemploAuthorization: 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.