From bf3f37e3d0d10d77a99dfb38c868de26b3b4a05d Mon Sep 17 00:00:00 2001 From: jkhsjdhjs Date: Sun, 13 Jul 2025 23:28:14 +0200 Subject: [PATCH] Add fallback for keyframe-only trickplay extraction Keyframe-only trickplay image extraction can fail for some media files. The current behavior is to skip the media file and try again on the next run, which will fail again. This adds a fallback to regular non-keyframe-only extraction for failed runs, so the extraction can complete. --- .../Encoder/MediaEncoder.cs | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 2eb647e264..c69f8e97b7 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -827,7 +827,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } /// - public Task ExtractVideoImagesOnIntervalAccelerated( + public async Task ExtractVideoImagesOnIntervalAccelerated( string inputFile, string container, MediaSourceInfo mediaSource, @@ -918,18 +918,34 @@ namespace MediaBrowser.MediaEncoding.Encoder inputArg = "-hwaccel_flags +low_priority " + inputArg; } - if (enableKeyFrameOnlyExtraction) - { - inputArg = "-skip_frame nokey " + inputArg; - } - var filterParam = encodingHelper.GetVideoProcessingFilterParam(jobState, options, vidEncoder).Trim(); if (string.IsNullOrWhiteSpace(filterParam)) { throw new InvalidOperationException("EncodingHelper returned empty or invalid filter parameters."); } - return ExtractVideoImagesOnIntervalInternal(inputArg, filterParam, vidEncoder, threads, qualityScale, priority, cancellationToken); + try + { + return await ExtractVideoImagesOnIntervalInternal( + (enableKeyFrameOnlyExtraction ? "-skip_frame nokey " : string.Empty) + inputArg, + filterParam, + vidEncoder, + threads, + qualityScale, + priority, + cancellationToken).ConfigureAwait(false); + } + catch (FfmpegException ex) + { + if (!enableKeyFrameOnlyExtraction) + { + throw; + } + + _logger.LogWarning(ex, "I-frame trickplay extraction failed, will attempt standard way. Input: {InputFile}", inputFile); + } + + return await ExtractVideoImagesOnIntervalInternal(inputArg, filterParam, vidEncoder, threads, qualityScale, priority, cancellationToken).ConfigureAwait(false); } private async Task ExtractVideoImagesOnIntervalInternal(