From dec2032e13dbd96a7c9277fbb32be5f596a43039 Mon Sep 17 00:00:00 2001 From: gnattu Date: Fri, 17 May 2024 12:12:45 +0800 Subject: [PATCH] Workaround ffmpeg keyframe seeking for external subtitles We seek to the exact position of the keyframe for direct stream/remuxing, but FFmpeg seeks to the previous keyframe when the exact time is provided as input. To work around this, add a 0.5 second offset to the seeking time. Signed-off-by: gnattu --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index d6907fdf9e..49c208b77f 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2771,7 +2771,13 @@ namespace MediaBrowser.Controller.MediaEncoding if (time > 0) { - seekParam += string.Format(CultureInfo.InvariantCulture, "-ss {0}", _mediaEncoder.GetTimeParameter(time)); + // For direct streaming/remuxing, we seek at the exact position of the keyframe + // However, ffmpeg will seek to previous keyframe when the exact time is the input + // Workaround this by adding 0.5s offset to the seeking time to get the exact keyframe on most videos. + // This will help subtitle syncing. + var isHlsRemuxing = state.IsVideoRequest && state.TranscodingType is TranscodingJobType.Hls && IsCopyCodec(state.OutputVideoCodec); + var seekTick = isHlsRemuxing ? time + 5000000L : time; + seekParam += string.Format(CultureInfo.InvariantCulture, "-ss {0}", _mediaEncoder.GetTimeParameter(seekTick)); if (state.IsVideoRequest) {