Browse Source

fix: don't extract embedded subtitles that have already been extracted (#2873)

pull/2874/head
Jason Dove 3 weeks ago committed by GitHub
parent
commit
cd2988205d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 25
      ErsatzTV.Application/Subtitles/Commands/ExtractEmbeddedSubtitlesHandlerBase.cs

4
CHANGELOG.md

@ -7,11 +7,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added ### Added
- Add `Streaming Engine` setting to Channel - Add `Streaming Engine` setting to Channel
- `Legacy` - (default) uses existing streaming engine - `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 ### Fixed
- Fix `Add Playout` button not opening drop down menu (regression from v26.4.0) - Fix `Add Playout` button not opening drop down menu (regression from v26.4.0)
- Consistently apply playout offset when generating XMLTV - 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 ## [26.4.0] - 2026-04-18
### Changed ### Changed

25
ErsatzTV.Application/Subtitles/Commands/ExtractEmbeddedSubtitlesHandlerBase.cs

@ -1,3 +1,4 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO.Abstractions; using System.IO.Abstractions;
using System.Security.Cryptography; using System.Security.Cryptography;
@ -11,6 +12,7 @@ using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Extensions; using ErsatzTV.Core.Extensions;
using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions; using ErsatzTV.Infrastructure.Extensions;
using Humanizer;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -97,6 +99,8 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem
{ {
foreach (List<Subtitle> allSubtitles in GetSubtitles(mediaItem)) foreach (List<Subtitle> allSubtitles in GetSubtitles(mediaItem))
{ {
var sw = Stopwatch.StartNew();
var subtitlesToExtract = new List<SubtitleToExtract>(); var subtitlesToExtract = new List<SubtitleToExtract>();
// find each subtitle that needs extraction // find each subtitle that needs extraction
@ -129,6 +133,11 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem
.Add("-hide_banner") .Add("-hide_banner")
.Add("-i").Add(mediaItemPath); .Add("-i").Add(mediaItemPath);
var subtitleIndexes = subtitlesToExtract
.OrderBy(s => s.Subtitle.StreamIndex)
.Select(s => s.Subtitle.StreamIndex)
.ToList();
foreach (SubtitleToExtract subtitle in subtitlesToExtract) foreach (SubtitleToExtract subtitle in subtitlesToExtract)
{ {
string fullOutputPath = Path.Combine(FileSystemLayout.SubtitleCacheFolder, subtitle.OutputPath); string fullOutputPath = Path.Combine(FileSystemLayout.SubtitleCacheFolder, subtitle.OutputPath);
@ -138,7 +147,7 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem
File.Delete(fullOutputPath); 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("-c:s").Add(subtitle.Subtitle.Codec == "mov_text" ? "text" : "copy")
.Add(fullOutputPath); .Add(fullOutputPath);
} }
@ -148,6 +157,8 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem
.WithValidation(CommandResultValidation.None) .WithValidation(CommandResultValidation.None)
.ExecuteBufferedAsync(cancellationToken); .ExecuteBufferedAsync(cancellationToken);
sw.Stop();
if (result.ExitCode == 0) if (result.ExitCode == 0)
{ {
foreach (SubtitleToExtract subtitle in subtitlesToExtract) foreach (SubtitleToExtract subtitle in subtitlesToExtract)
@ -157,11 +168,17 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem
new { SubtitleId = subtitle.Subtitle.Id, Path = subtitle.OutputPath }); 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 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)) foreach (string path in GetRelativeOutputPath(mediaItemId, subtitle))
{ {
return !fileSystem.File.Exists(path); return !fileSystem.File.Exists(Path.Combine(FileSystemLayout.SubtitleCacheFolder, path));
} }
return false; return false;

Loading…
Cancel
Save