Browse Source

ignore embedded text subtitles that have not been extracted (#2479)

* ignore text subtitles that have not been extracted

* fix bug with channel paging
pull/2483/head
Jason Dove 10 months ago committed by GitHub
parent
commit
a0788532a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 227
      ErsatzTV.Core.Tests/FFmpeg/CustomStreamSelectorTests.cs
  3. 11
      ErsatzTV.Core/FFmpeg/CustomStreamSelector.cs
  4. 2
      ErsatzTV/Pages/Channels.razor

1
CHANGELOG.md

@ -100,6 +100,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Note that looping is relative to the start of the content, so this works best with permanent watermarks - Note that looping is relative to the start of the content, so this works best with permanent watermarks
- Fix some more hls.js warnings by adding codec information to multi-variant playlists - Fix some more hls.js warnings by adding codec information to multi-variant playlists
- Fix hardware decode of h264 constrained baseline content using VAAPI accel - Fix hardware decode of h264 constrained baseline content using VAAPI accel
- Custom stream selector: ignore embedded text subtitles that have not been extracted
### Changed ### Changed
- Filler presets: use separate text fields for `hours`, `minutes` and `seconds` duration - Filler presets: use separate text fields for `hours`, `minutes` and `seconds` duration

227
ErsatzTV.Core.Tests/FFmpeg/CustomStreamSelectorTests.cs

@ -1,9 +1,11 @@
using Destructurama;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.FFmpeg; using ErsatzTV.Core.FFmpeg;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Tests.Fakes; using ErsatzTV.Core.Tests.Fakes;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging;
using NUnit.Framework; using NUnit.Framework;
using Serilog;
using Shouldly; using Shouldly;
namespace ErsatzTV.Core.Tests.FFmpeg; namespace ErsatzTV.Core.Tests.FFmpeg;
@ -14,6 +16,21 @@ public class CustomStreamSelectorTests
[TestFixture] [TestFixture]
public class SelectStreams public class SelectStreams
{ {
private readonly ILogger<CustomStreamSelector> _logger;
public SelectStreams()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.Destructure.UsingAttributes()
.CreateLogger();
ILoggerFactory loggerFactory = new LoggerFactory().AddSerilog(Log.Logger);
_logger = loggerFactory.CreateLogger<CustomStreamSelector>();
}
[SetUp] [SetUp]
public void SetUp() public void SetUp()
{ {
@ -27,11 +44,34 @@ public class CustomStreamSelectorTests
_subtitles = _subtitles =
[ [
new Subtitle { Id = 1, Language = "eng", Title = "Words", SubtitleKind = SubtitleKind.Embedded }, new Subtitle
new Subtitle { Id = 2, Language = "en", Title = "Signs" }, {
new Subtitle { Id = 3, Language = "en", Title = "Songs" }, Id = 1,
new Subtitle { Id = 4, Language = "en", Forced = true, SubtitleKind = SubtitleKind.Sidecar }, Language = "eng",
new Subtitle { Id = 5, Language = "jp" } Title = "Words",
SubtitleKind = SubtitleKind.Embedded,
IsExtracted = false,
Codec = "srt"
},
new Subtitle
{
Id = 2,
Language = "eng",
Title = "Words",
SubtitleKind = SubtitleKind.Embedded,
IsExtracted = true,
Codec = "srt"
},
new Subtitle
{
Id = 3, Language = "en", Title = "Signs", SubtitleKind = SubtitleKind.Embedded, IsExtracted = true
},
new Subtitle
{
Id = 4, Language = "en", Title = "Songs", SubtitleKind = SubtitleKind.Embedded, IsExtracted = true
},
new Subtitle { Id = 5, Language = "en", Forced = true, SubtitleKind = SubtitleKind.Sidecar },
new Subtitle { Id = 6, Language = "jp", SubtitleKind = SubtitleKind.Embedded, IsExtracted = true }
]; ];
} }
@ -46,7 +86,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_eng_Audio_Exact_Match() public async Task Should_Select_eng_Audio_Exact_Match()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -55,8 +95,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -76,7 +116,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_und_Audio_Missing_Language() public async Task Should_Select_und_Audio_Missing_Language()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -84,8 +124,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -105,7 +145,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_eng_Audio_Exact_Match_Multiple_Audio_Languages() public async Task Should_Select_eng_Audio_Exact_Match_Multiple_Audio_Languages()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -113,8 +153,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -134,7 +174,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_eng_Audio_Exact_Match_Multiple_Items() public async Task Should_Select_eng_Audio_Exact_Match_Multiple_Items()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -148,8 +188,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -169,7 +209,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_eng_Audio_Pattern_Match() public async Task Should_Select_eng_Audio_Pattern_Match()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -178,8 +218,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -199,7 +239,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_en_Audio_Pattern_Match() public async Task Should_Select_en_Audio_Pattern_Match()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -209,8 +249,8 @@ public class CustomStreamSelectorTests
_audioVersion = GetTestAudioVersion("en"); _audioVersion = GetTestAudioVersion("en");
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -230,7 +270,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task disable_subtitles_Should_Select_No_Subtitles() public async Task disable_subtitles_Should_Select_No_Subtitles()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -240,8 +280,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -253,9 +293,9 @@ public class CustomStreamSelectorTests
} }
[Test] [Test]
public async Task Should_Select_eng_Subtitle_Exact_Match() public async Task Should_Select_eng_Subtitle_Exact_Match_Extracted()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -266,8 +306,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -279,7 +319,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(1); subtitle.Id.ShouldBe(2);
subtitle.Language.ShouldBe("eng"); subtitle.Language.ShouldBe("eng");
} }
} }
@ -287,7 +327,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_eng_Subtitle_Pattern_Match() public async Task Should_Select_eng_Subtitle_Pattern_Match()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -298,8 +338,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -311,7 +351,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(1); subtitle.Id.ShouldBe(2);
subtitle.Language.ShouldBe("eng"); subtitle.Language.ShouldBe("eng");
} }
} }
@ -319,7 +359,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_en_Subtitle_Pattern_Match() public async Task Should_Select_en_Subtitle_Pattern_Match()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -332,12 +372,15 @@ public class CustomStreamSelectorTests
_subtitles = _subtitles =
[ [
new Subtitle { Id = 1, Language = "en", Title = "Words" } new Subtitle
{
Id = 1, Language = "en", Title = "Words", SubtitleKind = SubtitleKind.Embedded, IsExtracted = true
}
]; ];
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -357,7 +400,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_No_Subtitle_Exact_Match_Multiple_Items() public async Task Should_Select_No_Subtitle_Exact_Match_Multiple_Items()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -371,8 +414,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -394,7 +437,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Foreign_Audio_And_English_Subtitle_Multiple_Items() public async Task Should_Select_Foreign_Audio_And_English_Subtitle_Multiple_Items()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -408,8 +451,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -429,7 +472,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(1); subtitle.Id.ShouldBe(2);
subtitle.Language.ShouldBe("eng"); subtitle.Language.ShouldBe("eng");
} }
} }
@ -437,7 +480,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_English_Audio_No_Subtitles_Time_Of_Day_Content_Condition_Fail() public async Task Should_Select_English_Audio_No_Subtitles_Time_Of_Day_Content_Condition_Fail()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -450,8 +493,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -473,7 +516,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Foreign_Audio_And_English_Subtitle_Time_Of_Day_Content_Condition_Match() public async Task Should_Select_Foreign_Audio_And_English_Subtitle_Time_Of_Day_Content_Condition_Match()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -486,8 +529,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -507,7 +550,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(1); subtitle.Id.ShouldBe(2);
subtitle.Language.ShouldBe("eng"); subtitle.Language.ShouldBe("eng");
} }
} }
@ -515,7 +558,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Ignore_Blocked_Audio_Title() public async Task Should_Ignore_Blocked_Audio_Title()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -526,8 +569,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -547,7 +590,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Allowed_Audio_Title() public async Task Should_Select_Allowed_Audio_Title()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -558,8 +601,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -579,7 +622,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Ignore_Blocked_Subtitle_Title() public async Task Should_Ignore_Blocked_Subtitle_Title()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -592,8 +635,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -605,7 +648,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(3); subtitle.Id.ShouldBe(4);
subtitle.Language.ShouldBe("en"); subtitle.Language.ShouldBe("en");
} }
} }
@ -613,7 +656,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Allowed_Subtitle_Title() public async Task Should_Select_Allowed_Subtitle_Title()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -626,8 +669,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -639,7 +682,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(3); subtitle.Id.ShouldBe(4);
subtitle.Language.ShouldBe("en"); subtitle.Language.ShouldBe("en");
} }
} }
@ -647,7 +690,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Condition_Forced_Subtitle() public async Task Should_Select_Condition_Forced_Subtitle()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -657,8 +700,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -670,7 +713,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(4); subtitle.Id.ShouldBe(5);
subtitle.Language.ShouldBe("en"); subtitle.Language.ShouldBe("en");
} }
} }
@ -678,7 +721,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Condition_External_Subtitle() public async Task Should_Select_Condition_External_Subtitle()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -688,8 +731,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -701,7 +744,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(4); subtitle.Id.ShouldBe(5);
subtitle.Language.ShouldBe("en"); subtitle.Language.ShouldBe("en");
} }
} }
@ -709,7 +752,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Condition_Audio_Title() public async Task Should_Select_Condition_Audio_Title()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -719,8 +762,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -740,7 +783,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Condition_Audio_Channels() public async Task Should_Select_Condition_Audio_Channels()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -750,8 +793,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -771,7 +814,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Prioritized_Audio_Language() public async Task Should_Select_Prioritized_Audio_Language()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -780,8 +823,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -801,7 +844,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_Prioritized_Subtitle_Language() public async Task Should_Select_Prioritized_Subtitle_Language()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -811,8 +854,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,
@ -824,7 +867,7 @@ public class CustomStreamSelectorTests
foreach (Subtitle subtitle in result.Subtitle) foreach (Subtitle subtitle in result.Subtitle)
{ {
subtitle.Id.ShouldBe(5); subtitle.Id.ShouldBe(6);
subtitle.Language.ShouldBe("jp"); subtitle.Language.ShouldBe("jp");
} }
} }
@ -832,7 +875,7 @@ public class CustomStreamSelectorTests
[Test] [Test]
public async Task Should_Select_No_Streams_When_Languages_Do_Not_Match() public async Task Should_Select_No_Streams_When_Languages_Do_Not_Match()
{ {
const string yaml = const string YAML =
""" """
--- ---
items: items:
@ -843,8 +886,8 @@ public class CustomStreamSelectorTests
"""; """;
var streamSelector = new CustomStreamSelector( var streamSelector = new CustomStreamSelector(
new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = yaml }]), new FakeLocalFileSystem([new FakeFileEntry(TestFileName) { Contents = YAML }]),
new NullLogger<CustomStreamSelector>()); _logger);
StreamSelectorResult result = await streamSelector.SelectStreams( StreamSelectorResult result = await streamSelector.SelectStreams(
_channel, _channel,

11
ErsatzTV.Core/FFmpeg/CustomStreamSelector.cs

@ -205,7 +205,16 @@ public class CustomStreamSelector(ILocalFileSystem localFileSystem, ILogger<Cust
} }
} }
if (!matches) if (subtitle.SubtitleKind is SubtitleKind.Embedded && !subtitle.IsImage &&
!subtitle.IsExtracted)
{
candidateSubtitles.Remove(subtitle);
logger.LogDebug(
"Subtitle {@Subtitle} is embedded text subtitle and NOT extracted; ignoring",
new { Language = safeLanguage, Title = safeTitle });
}
else if (!matches)
{ {
candidateSubtitles.Remove(subtitle); candidateSubtitles.Remove(subtitle);

2
ErsatzTV/Pages/Channels.razor

@ -83,7 +83,7 @@
</MudIconButton> </MudIconButton>
</MudTooltip> </MudTooltip>
} }
else if (CanPreviewChannel(context) && !_ffmpegProfilesThatCanPreview[context.FFmpegProfileId]) else if (CanPreviewChannel(context) && _ffmpegProfilesThatCanPreview.ContainsKey(context.FFmpegProfileId) && !_ffmpegProfilesThatCanPreview[context.FFmpegProfileId])
{ {
<MudTooltip Text="Channel preview requires FFmpeg Profile compatible with this browser"> <MudTooltip Text="Channel preview requires FFmpeg Profile compatible with this browser">
<div style="height: 48px; width: 48px; align-items: center; display: flex; justify-content: center"> <div style="height: 48px; width: 48px; align-items: center; display: flex; justify-content: center">

Loading…
Cancel
Save