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 quehttp://;hlss://host/path.m3u8— lo mismo quehttps://.
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:
- cabeceras —
headers, por ejemploAuthorization: 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 |
sí |
Playlist master: selección de variante, representaciones EXT-X-MEDIA |
sí |
Segmentos fMP4 (EXT-X-MAP) y MPEG-TS |
sí |
EXT-X-BYTERANGE |
sí |
EXT-X-DISCONTINUITY, recreación de la playlist, retraso respecto a la ventana |
sí |
EXT-X-GAP |
sí, se salta sin error |
EXT-X-PROGRAM-DATE-TIME — anclaje del tiempo de media a UTC |
sí |
Cifrado AES-128 y SAMPLE-AES (H.264, AAC) |
sí |
| Escalera: captura de todas las variantes, medición del desfase | sí |
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.