feat(stream): HLS-copy — reemplazo resiliente del remux progresivo
Nuevo modo VideoCopy en el engine HLS: ffmpeg -c:v copy (el vídeo jamás se re-encodea — I/O puro, funciona en un NAS sin GPU), audio copy si ya es AAC o AAC 192k si no, muxeado a segmentos fMP4 con ffmpeg escribiendo SU PROPIO playlist (EVENT mientras corre, ENDLIST al acabar, EXTINF exactos en los keyframes del source). Sustituye al remux growing-fMP4 servido por HTTP Range artesanal, cuya fragilidad estructural produjo tres incidentes en un día (init malformado/delay_moov, loop de re-seek por total inventado, iOS rechazando total desconocido). Diferencias deliberadas respecto al modo encode: - playlist de ffmpeg servido desde disco (los cortes van a keyframe del source → duraciones imposibles de pre-renderizar; medido: probar keyframes antes cuesta 8-24s, inviable para TTFF) - sin seek-restart ni auto-restart (la copia va a velocidad de disco y adelanta a cualquier viewer; el -ss de segmentos uniformes corrompería la timeline de cortes variables) - sin caché HLS (regenerar no cuesta encode; cachear solo quema disco) - resume vía -ss (snap a keyframe) + -output_ts_offset - master playlist sin CODECS (un string hardcodeado equivocado hace que iOS rechace la variante; omitirlo es legal y universal) Validación: TTFB seg-0 510ms sobre el MKV real del incidente (HEVC Main10 + EAC3, 6.7GB). Suite de integración con ffmpeg real (tag smoke): h264+aac (copy total), h264+ac3 (re-encode de audio con priming dts — la clase delay_moov), hevc10+eac3 (la forma exacta del incidente, tag hvc1), resume con StartSec, y serving del playlist; asserts de codecs vía ffprobe sobre el playlist servido, suma EXTINF ≈ duración, segmentos completos en disco (+temp_file = rename atómico). El wiring web (plan remux→hls+videoCopy con gate de versión ≥1.0.10) va en el repo web. Plan: docs/plans/hls-copy-remux-replacement.md (web).
This commit is contained in:
parent
3fcfaaf234
commit
5a92df1e14
4 changed files with 499 additions and 12 deletions
|
|
@ -998,6 +998,7 @@ func runDaemonStart() error {
|
|||
BurnSubtitleIndex: sess.BurnSubtitleIndex,
|
||||
StartSec: sess.StartSec,
|
||||
Prewarm: sess.Prewarm,
|
||||
VideoCopy: sess.VideoCopy,
|
||||
Transcode: tcRuntime,
|
||||
Cache: hlsCache,
|
||||
}, hlsCtx, hlsCancel)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue