Skip to content

Captura por HLS

Sapsan sigue una playlist HLS ajena en modo cliente (pull): sondea la playlist, descarga los segmentos y entrega fotogramas al pipeline igual que RTSP, SRT o MPEG-TS. Así entrega el stream casi todo agregador, toda CDN ajena y todo socio al que no le han permitido abrir UDP o SRT.

Configuración

streams:
  - name: chan1
    inputs:
    - hls:
        url: https://cdn.example.com/live/index.m3u8
Parámetro Por defecto Descripción
url dirección de la playlist exactamente tal como la escribió el operador
headers ninguno cabeceras añadidas a cada petición a la fuente: playlist, segmentos, claves
variant_mode single single — una variante del master, ladder — toda la escalera
variant_bandwidth ninguno con qué bitrate casar la variante (el más cercano por debajo); sin él gana el mayor BANDWIDTH
skew_threshold_ms 500 el desfase a partir del cual la escalera se declara desincronizada
skew_policy report qué hacer ante un veredicto skewed: report — continuar y mostrarlo, fallback_to_single — retroceder a una sola variante
connect_timeout_ms 5000 tiempo de espera del establecimiento de la conexión
read_timeout_ms 15000 tiempo de espera del cuerpo: playlist, segmento, clave
max_body_bytes 64 MiB límite de tamaño de una única respuesta
peer_timeout_ms global cuánto esperar fotogramas antes de dar la fuente por perdida

Un campo omitido significa el valor por defecto del servidor, no «desactivado».

El esquema se puede escribir de tres formas equivalentes:

  • https://host/path.m3u8 — se reconoce por la extensión de la ruta, una query no estorba;
  • hls://host/path.m3u8 — lo mismo que http://;
  • hlss://host/path.m3u8 — lo mismo que https://.

Regla de inicio

Todo lo que ya había en la playlist en el momento de conectar es historia. La captura empieza con el primer segmento que aparece después de la conexión, y en una reconexión se comporta igual.

No existe a propósito un ajuste de profundidad de inicio: de lo contrario, cada caída de conexión haría que el stream vaciase por el pipeline, en segundos, la ventana acumulada, en lugar de emitir.

Autenticación

Dos formas, y se pueden combinar:

  • cabecerasheaders, por ejemplo Authorization: Bearer <token>; van con la playlist, las variantes, los segmentos init, los segmentos y las claves del mismo origin, y nunca siguen una redirección a un origin ajeno;
  • credenciales en la propia URL — autenticación Basic corriente hecha por el cliente HTTP.

Los valores de las cabeceras jamás llegan al log: solo se imprimen sus nombres. La dirección de la entrada se escribe entera en los logs y la API de gestión la devuelve tal cual: qué parte de esa dirección es el secreto lo sabe solo el operador, y enmascarar a ciegas o dejaría el token en la query o recortaría justo aquello por lo que la entrada se reconoce en el log.

Escalera de calidades y desfase de representaciones

Con variant_mode: ladder se capturan todas las variantes del master. La de mayor BANDWIDTH pasa a ser la referencia, y las demás se comparan con ella segmento a segmento, por número de secuencia de media. El veredicto queda expuesto en la estadística de la entrada, campo hls_ladder:

  • synced — las representaciones van juntas, conmutar entre ellas es seguro;
  • skewed — el desfase superó el umbral o la estructura está rota: la conmutación dará tirones o desincronizará;
  • unmeasurable — no hay con qué comparar, ningún par de segmentos comparte número.

El desfase se mide de dos maneras a la vez. El declarado es la diferencia de EXT-X-PROGRAM-DATE-TIME en el marcado; el real es la diferencia del tiempo de media de los primeros fotogramas. Si los dos no coinciden, lo enfermo es el marcado y no el stream, y quien lo arregla es el dueño de la fuente.

Note

Sapsan no lleva las variantes de la escalera a una escala de tiempos común, y no repara en absoluto el contenido defectuoso: una reparación silenciosa no hace conmutable la escalera, solo esconde el defecto. Por eso el desfase se muestra como número y decide el operador.

La política fallback_to_single baja la captura a una sola variante ante un veredicto skewed — para algunas fuentes es el único modo viable. El retroceso dura hasta que la entrada se reinicia.

Cifrado

Se admiten AES-128 (el segmento entero) y SAMPLE-AES (por fotograma, para H.264 y AAC). La clave la recoge el mismo cliente y con las mismas cabeceras que todo lo demás, y se guarda en caché por dirección, de modo que la rotación de claves en medio de una playlist funciona sola: una clave nueva tiene otra dirección.

Un servidor de claves que calla es un error de entrada con la dirección de la clave y el código de respuesta; el cuerpo del segmento no se descarga en absoluto, pues no habría con qué descifrarlo.

CENC/DRM (Widevine, PlayReady, FairPlay) no está admitido y se rechaza por el nombre de KEYFORMAT.

Qué se admite

Posibilidad Estado
Playlist de media: EXT-X-MEDIA-SEQUENCE, EXTINF, EXT-X-ENDLIST
Playlist master: selección de variante, representaciones EXT-X-MEDIA
Segmentos fMP4 (EXT-X-MAP) y MPEG-TS
EXT-X-BYTERANGE
EXT-X-DISCONTINUITY, recreación de la playlist, retraso respecto a la ventana
EXT-X-GAP sí, se salta sin error
EXT-X-PROGRAM-DATE-TIME — anclaje del tiempo de media a UTC
Cifrado AES-128 y SAMPLE-AES (H.264, AAC)
Escalera: captura de todas las variantes, medición del desfase
LL-HLS: EXT-X-PART, blocking reload no, las partes se ignoran
CENC/DRM no
Audio «empaquetado»: ADTS puro o ID3+AAC en lugar de un contenedor no, el formato se nombra en el error
Subtítulos TTML y segmentos WebVTT no, la pista se reconoce y se salta
Captura MPEG-DASH no

Aplicación de los cambios

Solo un cambio de url, headers o de los ajustes HTTP (connect_timeout_ms, read_timeout_ms, max_body_bytes) reinicia la entrada: una fuente nueva tiene su propia numeración de pistas, su propio init y su propia posición en la playlist. Todo lo demás — modo de variante, umbral y política de desfase, peer_timeout_ms — se aplica en caliente, sin interrumpir la emisión.

Comprobación

Abra http://server/streaming/v/chan1/index.m3u8 en un reproductor o pida una captura en http://server/streaming/live-preview-jpeg/chan1.

Más allá de «ya fluyen fotogramas», mire tres cosas:

  • cuánto se retrasa la salida respecto al borde de la playlist — sin eso, la queja «el stream va con retraso» es indistinguible de «la fuente va con retraso», y las dos se arreglan en sitios distintos;
  • los segmentos saltados y su desglose: lavados fuera de la ventana, cancelados en vuelo, declarados con EXT-X-GAP. Lo último no es un error de la fuente, sino su declaración honesta;
  • la costura entre fragmentos vecinos — un defecto silencioso: todos los segmentos se descargaron, sin errores de análisis, y sin embargo el medio de dentro no se une, y el archivo conserva el agujero.

Siguientes pasos