unarr/internal/engine
Deivid Soto 5a92df1e14 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).
2026-06-10 23:06:21 +02:00
..
debrid.go feat(downloads): pre-flight free-disk guard before each download (hueco medio) 2026-05-31 21:48:34 +02:00
debrid_test.go chore: rename module from torrentclaw-cli to unarr 2026-03-30 13:06:07 +02:00
diskspace.go feat(downloads): pre-flight free-disk guard before each download (hueco medio) 2026-05-31 21:48:34 +02:00
diskspace_test.go feat(downloads): pre-flight free-disk guard before each download (hueco medio) 2026-05-31 21:48:34 +02:00
encode_benchmark.go fix(stream): functional libplacebo probe + benchmark hardening 2026-06-03 09:57:48 +02:00
encode_benchmark_test.go feat(stream): benchmark software encode ceiling at startup 2026-06-03 09:30:03 +02:00
hls.go feat(stream): HLS-copy — reemplazo resiliente del remux progresivo 2026-06-10 23:06:21 +02:00
hls_cache.go feat(stream): burn bitmap (PGS/DVB) subtitles into the video via overlay 2026-06-01 09:51:27 +02:00
hls_cache_smoke_test.go feat(stream): burn bitmap (PGS/DVB) subtitles into the video via overlay 2026-06-01 09:51:27 +02:00
hls_cache_test.go feat(stream): burn bitmap (PGS/DVB) subtitles into the video via overlay 2026-06-01 09:51:27 +02:00
hls_copy_smoke_test.go feat(stream): HLS-copy — reemplazo resiliente del remux progresivo 2026-06-10 23:06:21 +02:00
hls_cudascale_test.go feat(hls): full-GPU scale_cuda for NVENC SDR downscales 2026-06-10 21:44:58 +02:00
hls_progress_test.go feat(stream): live transcode telemetry from ffmpeg speed= 2026-06-06 00:37:03 +02:00
hls_ratecontrol_test.go test(hls): cubrir -forced_idr de QSV en el rate-control 2026-06-10 12:00:33 +02:00
hls_registry_prewarm_test.go fix(hls): los prewarms ya no desalojan la sesión del espectador + trickplay 12x 2026-06-10 00:54:50 +02:00
hls_test.go feat(stream): serve embedded text subtitles as on-demand WebVTT 2026-06-01 23:50:39 +02:00
hls_url_args_test.go fix(stream): clamp out-of-range audio-track index to 0🅰️0 2026-06-03 18:55:42 +02:00
hwaccel.go fix(stream): derive H.264 level from frame macroblocks, not height 2026-06-01 08:29:10 +02:00
hwaccel_test.go fix(stream): derive H.264 level from frame macroblocks, not height 2026-06-01 08:29:10 +02:00
hwscale.go feat(hls): full-GPU scale_cuda for NVENC SDR downscales 2026-06-10 21:44:58 +02:00
manager.go feat(agent): event-driven uplink — sync on every state transition 2026-06-01 19:09:44 +02:00
manager_integration_test.go test: add comprehensive test suite for engine, agent and cmd packages 2026-04-08 23:36:00 +02:00
manager_resume_test.go feat(subtitles): subtitle-fetch jobs vía sync + auto-fetch opcional en scan 2026-06-10 14:48:35 +02:00
manager_test.go fix(ci): fix lint errors and pin CI to Go 1.25 2026-03-31 22:15:12 +02:00
method.go feat: initial commit — unarr CLI 2026-03-28 11:29:42 +01:00
method_test.go feat(cli): upgrade command, rich status, and version cache 2026-03-31 22:05:43 +02:00
notify.go feat: improve daemon resilience, streaming, and usenet downloads 2026-03-28 21:36:12 +01:00
notify_test.go feat: improve daemon resilience, streaming, and usenet downloads 2026-03-28 21:36:12 +01:00
organize.go feat(organize): use server metadata for file organization and subtitle handling 2026-04-05 23:36:01 +02:00
organize_expand_test.go feat(organize): use server metadata for file organization and subtitle handling 2026-04-05 23:36:01 +02:00
organize_test.go feat: improve daemon resilience, streaming, and usenet downloads 2026-03-28 21:36:12 +01:00
probe.go feat(subs): resilient subtitle extraction — sidecars, charset, torrent/debrid 2026-06-08 13:04:09 +02:00
probe_cache.go refactor(hls): critico-driven hardening of fase 3.2 2026-05-27 11:15:44 +02:00
probe_cache_test.go refactor(hls): critico-driven hardening of fase 3.2 2026-05-27 11:15:44 +02:00
probe_test.go feat(stream): pion-based WebRTC byte streamer for browser playback 2026-05-06 23:12:38 +02:00
progress.go fix(docker): three streaming/reliability bugs found in live docker test 2026-05-30 08:59:33 +02:00
progress_test.go fix(ci): fix lint errors and pin CI to Go 1.25 2026-03-31 22:15:12 +02:00
readahead.go feat(stream): bitrate-sized readahead for play-while-download 2026-05-31 23:23:39 +02:00
readahead_test.go feat(subtitles): subtitle-fetch jobs vía sync + auto-fetch opcional en scan 2026-06-10 14:48:35 +02:00
resolve.go feat: initial commit — unarr CLI 2026-03-28 11:29:42 +01:00
resolve_test.go feat: initial commit — unarr CLI 2026-03-28 11:29:42 +01:00
safepath.go feat: initial commit — unarr CLI 2026-03-28 11:29:42 +01:00
safepath_test.go feat: initial commit — unarr CLI 2026-03-28 11:29:42 +01:00
seed_lifecycle_smoke_test.go feat(seeding): wire seed ratio/time lifecycle into the torrent daemon 2026-06-01 10:30:39 +02:00
sockopt_unix.go fix(stream): use platform-specific socket options for Windows cross-compilation 2026-04-07 19:18:13 +02:00
sockopt_windows.go fix(stream): use platform-specific socket options for Windows cross-compilation 2026-04-07 19:18:13 +02:00
stream.go feat(stream): bitrate-sized readahead for play-while-download 2026-05-31 23:23:39 +02:00
stream_growing_test.go fix(stream): iOS exige total concreto en el Content-Range del remux 2026-06-10 22:37:02 +02:00
stream_player.go fix(security): CORS allowlist, URL scheme guard, state perms, ZIP slip, mirror docs 2026-05-15 18:48:59 +02:00
stream_server.go fix(stream): iOS exige total concreto en el Content-Range del remux 2026-06-10 22:37:02 +02:00
stream_server_extra_test.go test(coverage): raise engine+agent coverage above 50% 2026-05-12 11:21:59 +02:00
stream_server_test.go fix(stream): self-heal host→container path skew in HLS + sidecar handlers 2026-06-04 22:38:12 +02:00
stream_server_tls_test.go feat(stream): optional per-agent HTTPS listener with hot-reloadable cert 2026-06-01 13:03:35 +02:00
stream_source.go feat(stream): device-aware remux (HEVC/AV1 + non-aac audio) + TTFF timers 2026-05-31 12:44:12 +02:00
stream_source_debrid.go feat(stream): debrid passthrough for mode=stream tasks (external players) 2026-06-03 22:43:43 +02:00
stream_source_debrid_test.go feat(stream): refresh expired debrid links mid-stream (hueco #2/2c) 2026-05-31 17:02:59 +02:00
stream_source_test.go test(coverage): raise engine+agent coverage above 50% 2026-05-12 11:21:59 +02:00
stream_test.go fix(stream): fix black screen on remote/Tailscale streaming 2026-04-09 16:15:41 +02:00
stream_token.go feat(stream): serve embedded text subtitles as on-demand WebVTT 2026-06-01 23:50:39 +02:00
stream_token_test.go feat(stream): authenticate /stream and /hls with signed tokens 2026-05-31 01:19:14 +02:00
task.go feat(agent): event-driven uplink — sync on every state transition 2026-06-01 19:09:44 +02:00
task_test.go feat(agent): event-driven uplink — sync on every state transition 2026-06-01 19:09:44 +02:00
thumbnail_test.go fix(stream): retry thumbnail extraction with output-seek on seek-index failure 2026-06-03 18:55:49 +02:00
tonemap.go fix(stream): don't cache transient libplacebo probe timeouts 2026-06-03 10:48:30 +02:00
tonemap_test.go feat(stream): enable GPU libplacebo in prod image + gate to real GPU 2026-06-03 10:42:16 +02:00
torrent.go fix(torrent): suppress noisy UPnP AddPortMapping warnings 2026-06-05 17:18:57 +02:00
torrent_test.go fix(agent): surface par2/install/NFS failures instead of degrading silently 2026-06-01 15:52:54 +02:00
transcode_quality.go feat(hls): full-GPU scale_cuda for NVENC SDR downscales 2026-06-10 21:44:58 +02:00
transcoder.go fix(stream): delay_moov en el remux para audio AAC con dts negativo 2026-06-10 20:10:11 +02:00
transcoder_test.go test(coverage): raise engine+agent coverage above 50% 2026-05-12 11:21:59 +02:00
upnp.go fix: resolve deadlock, data races and path traversal vulnerabilities 2026-04-08 23:36:18 +02:00
upnp_debug_test.go feat(stream): add NAT-PMP port mapping for remote downloads 2026-04-06 10:09:07 +02:00
upnp_live_test.go feat(stream): add NAT-PMP port mapping for remote downloads 2026-04-06 10:09:07 +02:00
upnp_test.go feat(stream): add NAT-PMP port mapping for remote downloads 2026-04-06 10:09:07 +02:00
usenet.go fix(agent): surface par2/install/NFS failures instead of degrading silently 2026-06-01 15:52:54 +02:00
usenet_test.go test(coverage): raise engine+agent coverage above 50% 2026-05-12 11:21:59 +02:00
vaapi_args_test.go test(vaapi): dump full ffmpeg argv for smoke validation 2026-05-27 15:58:30 +02:00
validate.go fix(stream): allow unarr.app origins for /stream + /hls CORS 2026-05-31 14:20:49 +02:00
verify.go feat: initial commit — unarr CLI 2026-03-28 11:29:42 +01:00
verify_test.go feat: initial commit — unarr CLI 2026-03-28 11:29:42 +01:00
watch_reporter.go feat(stream): report duration and position in watch progress 2026-04-07 23:29:00 +02:00
watch_reporter_test.go fix(security): UPnP opt-in, bounded SSE reader, signed self-update 2026-05-15 17:29:22 +02:00