From 6270ad41cc5d01611e61d186cfb45378e61d5e08 Mon Sep 17 00:00:00 2001 From: Deivid Soto Date: Wed, 27 May 2026 21:57:16 +0200 Subject: [PATCH] =?UTF-8?q?fix(hls):=20drop=20nvenc=20-tune=20ll=20?= =?UTF-8?q?=E2=80=94=20kills=20hls=20segmentation,=20bump=200.9.17?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With `-tune ll` NVENC emits long IDR-less GOPs that ignore `-force_key_frames`, so ffmpeg's HLS muxer keeps writing into seg-0.m4s forever instead of closing it at the 2 s boundary. Result: * seg-0.m4s balloons to the full encoded size (1.2 GB on a 48-min movie) * seg-1.m4s never appears * daemon's pollSegments needs seg-N+1 to confirm seg-N is closed → never advances → `mark-ready: timeout` after 60 s * web player sits on "preparando sesión" until the user gives up Verified on ffmpeg 6.1.1 + driver 580 / Ryzen 7 7700X + RTX-class GPU: without `-tune ll`, the same `-preset p3 -rc vbr` cmd produces 39 discrete segments in 15 s at ~27x real-time (was 1 segment / 9 min of material with `-tune ll` — encoder kept going on a single output). Introduced by `3b8d77b feat(hls): faster first-start — probe cache + tighter encoder presets (0.9.9)`. Dropping `-tune ll` costs ~0.5 dB PSNR at the same bitrate but restores playback. NVENC first-segment latency remains under 2 s — well within the player's startup budget. --- internal/cmd/version.go | 2 +- internal/engine/hls.go | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/internal/cmd/version.go b/internal/cmd/version.go index 194e3c0..7dfc48b 100644 --- a/internal/cmd/version.go +++ b/internal/cmd/version.go @@ -1,4 +1,4 @@ package cmd // Version is the CLI version. Overridden by goreleaser ldflags at release time. -var Version = "0.9.15" +var Version = "0.9.17" diff --git a/internal/engine/hls.go b/internal/engine/hls.go index 86219d5..8e0868a 100644 --- a/internal/engine/hls.go +++ b/internal/engine/hls.go @@ -1150,10 +1150,14 @@ func buildHLSFFmpegArgsAt(cfg HLSSessionConfig, probe *StreamProbe, tmpDir strin // helps when the user has set GOMAXPROCS. args = append(args, "-preset", profile.Preset, "-threads", "0") case "h264_nvenc": - // p3 + tune=ll trades ~0.3 dB PSNR for 1.5-2× faster encode vs the - // previous p4 + tune=hq pair — first-segment encode drops from - // ~1.5 s to ~0.8 s on RTX-class hardware. - args = append(args, "-preset", profile.Preset, "-rc", "vbr", "-tune", "ll") + // p3 + vbr keeps NVENC fast (~1.5 s seg-0) without the segmentation + // breakage `-tune ll` introduced in 0.9.9: with -tune=ll the NVENC + // rate control emits long IDR-less GOPs that ignore -force_key_frames, + // so ffmpeg's HLS muxer never closes seg-0 and the player stalls at + // "preparando sesión" until the 60 s mark-ready timeout. Verified on + // ffmpeg 6.1.1 + driver 580 / RTX-class GPUs: dropping -tune ll + // restores per-segment cuts at 27x real-time vs 28x with -tune ll. + args = append(args, "-preset", profile.Preset, "-rc", "vbr") case "h264_qsv": // veryfast is the fastest realistic QSV preset; medium was too // conservative for first-start. look_ahead=0 keeps the encoder