docs(roadmap): 3b approach = progressive fMP4 remux via /stream
This commit is contained in:
parent
5fa8455b21
commit
6e8bca2ac4
1 changed files with 32 additions and 7 deletions
|
|
@ -261,13 +261,38 @@ el orden de STREAMING (no el de descarga) prefiera debrid.
|
||||||
`MarkSessionReady` — requiere extender el payload + SSE + diferir el attach
|
`MarkSessionReady` — requiere extender el payload + SSE + diferir el attach
|
||||||
del player al evento ready). Diferido por mayor superficie.
|
del player al evento ready). Diferido por mayor superficie.
|
||||||
|
|
||||||
- **Fase 3b — remux HLS (`-c:v copy`) para contenedores no-mp4 compatibles.**
|
- **Fase 3b — remux fMP4 progresivo vía /stream (ENFOQUE ELEGIDO 2026-05-31).**
|
||||||
Caso `mkv` h264/aac (no direct-playable por contenedor). `-c:v copy` evita el
|
Caso `mkv` (u otro contenedor no-mp4) con h264 + aac + 8-bit + SDR: codecs ya
|
||||||
re-encode de vídeo. **Parte difícil:** con `-c copy` ffmpeg corta segmentos en
|
browser-native, solo el contenedor estorba. `-c copy` evita el re-encode de vídeo.
|
||||||
keyframes del GOP origen → duraciones variables que NO casan con el manifiesto
|
Descartado HLS-copy (duraciones de segmento variables vs manifiesto pre-render →
|
||||||
pre-renderizado uniforme (`renderVideoPlaylist`) → rompe seek/playback. Hay que
|
rompe seek; arreglarlo = probe de keyframes lento o reescribir el núcleo HLS).
|
||||||
servir el manifiesto que genera ffmpeg (no el pre-render) o reescribir el seek.
|
**Enfoque:** ffmpeg `-c copy -movflags +frag_keyframe+empty_moov+default_base_moof
|
||||||
Mayor que 3a.
|
-f mp4` mkv→fMP4 a fichero temporal **creciente**; servir ese fMP4 por **/stream**
|
||||||
|
(mismo path direct-play 3a, attach nativo, sin hls.js, sin manifiesto).
|
||||||
|
**Núcleo real (la parte no-trivial):** servir un fichero que **crece** mientras
|
||||||
|
ffmpeg escribe. El `/stream` actual usa `http.ServeContent` (asume fichero completo
|
||||||
|
y seekable). Hay que:
|
||||||
|
- Resucitar/adaptar el `transcodeSource` muerto (`engine/stream_source.go`):
|
||||||
|
ffmpeg→tmp creciente, `ReadAt` con bloqueo hasta que los bytes existan
|
||||||
|
(`readBlockTimeout`), `EstimatedSize` = bitrate×duración para que la barra del
|
||||||
|
player tenga timeline.
|
||||||
|
- Un **responder de Range manual** en /stream para fuentes no-finales (en vez de
|
||||||
|
`http.ServeContent`): leer `Range`, `ReadAt` la fuente, escribir 206 +
|
||||||
|
`Content-Range` con el tamaño estimado. El path mp4-completo (3a) sigue usando
|
||||||
|
ServeContent (rápido).
|
||||||
|
- Caveat: seek-adelante a zona no-remuxada bloquea hasta que el copy la alcanza
|
||||||
|
(copy es I/O-bound, rápido). Seek-atrás (bytes ya en disco) inmediato.
|
||||||
|
**Plan de incrementos seguros:**
|
||||||
|
- **3b-i (agente, dormido):** `remuxSource` + responder Range para fuentes
|
||||||
|
crecientes, gateado tras `PlayMethod=="remux"` (que el web aún no envía) →
|
||||||
|
commiteable sin romper nada, con tests.
|
||||||
|
- **3b-ii (web+player):** `decidePlayMethod` devuelve `"remux"` para
|
||||||
|
contenedor-no-mp4 + h264/aac/8-bit/SDR; player trata `playMethod != "hls"` igual
|
||||||
|
que direct (streamUrls + attach nativo). Activa 3b. Mismo gate de versión.
|
||||||
|
**Ficheros:** CLI `engine/stream_source.go` (remuxSource), `engine/stream_server.go`
|
||||||
|
(range responder + provider creciente), `cmd/daemon.go` (branch `remux`),
|
||||||
|
`engine/transcoder.go` (args `-c copy` fMP4). WEB `lib/stream/play-method.ts`
|
||||||
|
(+"remux"), `stream/session/route.ts`, `HlsStreamPlayer.tsx` (`!= "hls"`).
|
||||||
|
|
||||||
- **Fase 3c — capability negotiation (device-profile).** El web envía
|
- **Fase 3c — capability negotiation (device-profile).** El web envía
|
||||||
`{maxHeight, codecs:[h264,hevc,av1], containers}` (de UA + `canPlayType`).
|
`{maxHeight, codecs:[h264,hevc,av1], containers}` (de UA + `canPlayType`).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue