From 857e7301686a4645e218020b8bf141143b84242e Mon Sep 17 00:00:00 2001 From: ExpctING Date: Sat, 25 Apr 2026 03:30:55 +0800 Subject: [PATCH 1/4] Fix dummy chapter handling for videos with a single chapter. --- Emby.Server.Implementations/Chapters/ChapterManager.cs | 2 +- MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs | 8 ++------ .../MediaInfo/FFProbeVideoInfoTests.cs | 5 +++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Emby.Server.Implementations/Chapters/ChapterManager.cs b/Emby.Server.Implementations/Chapters/ChapterManager.cs index d09ed30ae3..a2d7d7d7fb 100644 --- a/Emby.Server.Implementations/Chapters/ChapterManager.cs +++ b/Emby.Server.Implementations/Chapters/ChapterManager.cs @@ -128,7 +128,7 @@ public class ChapterManager : IChapterManager var averageChapterDuration = GetAverageDurationBetweenChapters(chapters); var threshold = TimeSpan.FromSeconds(1).Ticks; - if (averageChapterDuration < threshold) + if (chapters.Count >= 2 && averageChapterDuration < threshold) { _logger.LogInformation("Skipping chapter image extraction for {Video} as the average chapter duration {AverageDuration} was lower than the minimum threshold {Threshold}", video.Name, averageChapterDuration, threshold); extractImages = false; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index fdc2f36469..a41d03839f 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -278,7 +278,7 @@ namespace MediaBrowser.Providers.MediaInfo if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || options.MetadataRefreshMode == MetadataRefreshMode.Default) { - if (_config.Configuration.DummyChapterDuration > 0 && chapters.Length == 0 && mediaStreams.Any(i => i.Type == MediaStreamType.Video)) + if (_config.Configuration.DummyChapterDuration > 0 && chapters.Length <= 1 && mediaStreams.Any(i => i.Type == MediaStreamType.Video)) { chapters = CreateDummyChapters(video); } @@ -620,12 +620,8 @@ namespace MediaBrowser.Providers.MediaInfo } long dummyChapterDuration = TimeSpan.FromSeconds(_config.Configuration.DummyChapterDuration).Ticks; - if (runtime <= dummyChapterDuration) - { - return []; - } - int chapterCount = (int)(runtime / dummyChapterDuration); + int chapterCount = Math.Max(1, (int)(runtime / dummyChapterDuration)); var chapters = new ChapterInfo[chapterCount]; long currentChapterTicks = 0; diff --git a/tests/Jellyfin.Providers.Tests/MediaInfo/FFProbeVideoInfoTests.cs b/tests/Jellyfin.Providers.Tests/MediaInfo/FFProbeVideoInfoTests.cs index 76922af8d5..7cb3e61724 100644 --- a/tests/Jellyfin.Providers.Tests/MediaInfo/FFProbeVideoInfoTests.cs +++ b/tests/Jellyfin.Providers.Tests/MediaInfo/FFProbeVideoInfoTests.cs @@ -45,8 +45,9 @@ public class FFProbeVideoInfoTests [Theory] [InlineData(null, 0)] [InlineData(0L, 0)] - [InlineData(1L, 0)] - [InlineData(TimeSpan.TicksPerMinute * 5, 0)] + [InlineData(1L, 1)] + [InlineData(TimeSpan.TicksPerMinute * 3, 1)] + [InlineData(TimeSpan.TicksPerMinute * 5, 1)] [InlineData((TimeSpan.TicksPerMinute * 5) + 1, 1)] [InlineData(TimeSpan.TicksPerMinute * 50, 10)] public void CreateDummyChapters_ValidRuntime_CorrectChaptersCount(long? runtime, int chaptersCount) From d86a4d681572cdabc79efe47f5719d2761d84a3e Mon Sep 17 00:00:00 2001 From: ExpctING Date: Sat, 25 Apr 2026 16:38:21 +0800 Subject: [PATCH 2/4] fix chapter average calculation to avoid division by zero error. Co-authored-by: Copilot --- Emby.Server.Implementations/Chapters/ChapterManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Chapters/ChapterManager.cs b/Emby.Server.Implementations/Chapters/ChapterManager.cs index a2d7d7d7fb..f24c975c14 100644 --- a/Emby.Server.Implementations/Chapters/ChapterManager.cs +++ b/Emby.Server.Implementations/Chapters/ChapterManager.cs @@ -108,7 +108,7 @@ public class ChapterManager : IChapterManager sum += chapters[i].StartPositionTicks - chapters[i - 1].StartPositionTicks; } - return sum / chapters.Count; + return sum / (chapters.Count - 1); } /// From 1dd8541ed5832414c326f0c2662a899e1ec96259 Mon Sep 17 00:00:00 2001 From: ExpctING Date: Sat, 25 Apr 2026 21:10:47 +0800 Subject: [PATCH 3/4] fix ci failed Co-authored-by: Copilot --- MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index a41d03839f..33115901ef 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -621,6 +621,11 @@ namespace MediaBrowser.Providers.MediaInfo long dummyChapterDuration = TimeSpan.FromSeconds(_config.Configuration.DummyChapterDuration).Ticks; + if (runtime <= 0) + { + return []; + } + int chapterCount = Math.Max(1, (int)(runtime / dummyChapterDuration)); var chapters = new ChapterInfo[chapterCount]; From 127d924c5bd004cb61bebc47a6474453408dcd5e Mon Sep 17 00:00:00 2001 From: ExpctING Date: Sun, 3 May 2026 02:06:13 +0800 Subject: [PATCH 4/4] fix Co-authored-by: Copilot --- .../Chapters/ChapterManager.cs | 2 +- .../MediaInfo/FFProbeVideoInfoTests.cs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Chapters/ChapterManager.cs b/Emby.Server.Implementations/Chapters/ChapterManager.cs index f24c975c14..a2d7d7d7fb 100644 --- a/Emby.Server.Implementations/Chapters/ChapterManager.cs +++ b/Emby.Server.Implementations/Chapters/ChapterManager.cs @@ -108,7 +108,7 @@ public class ChapterManager : IChapterManager sum += chapters[i].StartPositionTicks - chapters[i - 1].StartPositionTicks; } - return sum / (chapters.Count - 1); + return sum / chapters.Count; } /// diff --git a/tests/Jellyfin.Providers.Tests/MediaInfo/FFProbeVideoInfoTests.cs b/tests/Jellyfin.Providers.Tests/MediaInfo/FFProbeVideoInfoTests.cs index 7cb3e61724..a7491f42e9 100644 --- a/tests/Jellyfin.Providers.Tests/MediaInfo/FFProbeVideoInfoTests.cs +++ b/tests/Jellyfin.Providers.Tests/MediaInfo/FFProbeVideoInfoTests.cs @@ -59,4 +59,20 @@ public class FFProbeVideoInfoTests Assert.Equal(chaptersCount, chapters.Length); } + + [Theory] + [InlineData(1L)] + [InlineData(TimeSpan.TicksPerMinute * 3)] + [InlineData(TimeSpan.TicksPerMinute * 5)] + [InlineData((TimeSpan.TicksPerMinute * 5) + 1)] + [InlineData((TimeSpan.TicksPerMinute * 50) + 1)] + public void CreateDummyChapters_PositiveRuntime_NoChapterBeyondRuntime(long runtime) + { + var chapters = _fFProbeVideoInfo.CreateDummyChapters(new Video() + { + RunTimeTicks = runtime + }); + + Assert.All(chapters, chapter => Assert.True(chapter.StartPositionTicks < runtime)); + } }