From cd2988205d9baaeb9dda9b292997e05db2083d38 Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:18:32 -0500 Subject: [PATCH] fix: don't extract embedded subtitles that have already been extracted (#2873) --- CHANGELOG.md | 4 ++- .../ExtractEmbeddedSubtitlesHandlerBase.cs | 25 ++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1a51607d..648b4ace4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Add `Streaming Engine` setting to Channel - `Legacy` - (default) uses existing streaming engine - - `Next` - will use ErsatzTV Next streaming engine, when it is compatible with ErsatzTV Legacy + - `Next` - uses ErsatzTV Next streaming engine ### Fixed - Fix `Add Playout` button not opening drop down menu (regression from v26.4.0) - Consistently apply playout offset when generating XMLTV +- Schedule all required fallback filler in classic schedules +- Don't extract embedded subtitles that have already been extracted ## [26.4.0] - 2026-04-18 ### Changed diff --git a/ErsatzTV.Application/Subtitles/Commands/ExtractEmbeddedSubtitlesHandlerBase.cs b/ErsatzTV.Application/Subtitles/Commands/ExtractEmbeddedSubtitlesHandlerBase.cs index 99d08b768..52776461e 100644 --- a/ErsatzTV.Application/Subtitles/Commands/ExtractEmbeddedSubtitlesHandlerBase.cs +++ b/ErsatzTV.Application/Subtitles/Commands/ExtractEmbeddedSubtitlesHandlerBase.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO.Abstractions; using System.Security.Cryptography; @@ -11,6 +12,7 @@ using ErsatzTV.Core.Domain; using ErsatzTV.Core.Extensions; using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Extensions; +using Humanizer; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -97,6 +99,8 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem { foreach (List allSubtitles in GetSubtitles(mediaItem)) { + var sw = Stopwatch.StartNew(); + var subtitlesToExtract = new List(); // find each subtitle that needs extraction @@ -129,6 +133,11 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem .Add("-hide_banner") .Add("-i").Add(mediaItemPath); + var subtitleIndexes = subtitlesToExtract + .OrderBy(s => s.Subtitle.StreamIndex) + .Select(s => s.Subtitle.StreamIndex) + .ToList(); + foreach (SubtitleToExtract subtitle in subtitlesToExtract) { string fullOutputPath = Path.Combine(FileSystemLayout.SubtitleCacheFolder, subtitle.OutputPath); @@ -138,7 +147,7 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem File.Delete(fullOutputPath); } - args.Add("-map").Add($"0:{subtitle.Subtitle.StreamIndex}") + args.Add("-map").Add($"0:s:{subtitleIndexes.IndexOf(subtitle.Subtitle.StreamIndex)}") .Add("-c:s").Add(subtitle.Subtitle.Codec == "mov_text" ? "text" : "copy") .Add(fullOutputPath); } @@ -148,6 +157,8 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem .WithValidation(CommandResultValidation.None) .ExecuteBufferedAsync(cancellationToken); + sw.Stop(); + if (result.ExitCode == 0) { foreach (SubtitleToExtract subtitle in subtitlesToExtract) @@ -157,11 +168,17 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem new { SubtitleId = subtitle.Subtitle.Id, Path = subtitle.OutputPath }); } - logger.LogDebug("Successfully extracted {Count} subtitles", subtitlesToExtract.Count); + logger.LogDebug( + "Successfully extracted {Count} subtitles in {Duration}", + subtitlesToExtract.Count, + sw.Elapsed.Humanize()); } else { - logger.LogError("Failed to extract subtitles. {Error}", result.StandardError); + logger.LogError( + "Failed to extract subtitles in {Duration}. {Error}", + sw.Elapsed.Humanize(), + result.StandardError); } } } @@ -300,7 +317,7 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem { foreach (string path in GetRelativeOutputPath(mediaItemId, subtitle)) { - return !fileSystem.File.Exists(path); + return !fileSystem.File.Exists(Path.Combine(FileSystemLayout.SubtitleCacheFolder, path)); } return false;