Commit: 1df32d1
Parent: 95e7269

Only look for text based subtitles

Mårten Åsberg committed on 2026-05-09 at 18:15
src/Api/appsettings.json +8 -1
diff --git a/src/Api/appsettings.json b/src/Api/appsettings.json
index 10f68b8..ef211be 100644
@@ -5,5 +5,12 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"MediaRepository": {
"SubtitleCodecs": [
"ass",
"move_text",
"subrip"
]
}
}
src/Cli/appsettings.json +7 -0
diff --git a/src/Cli/appsettings.json b/src/Cli/appsettings.json
index 960be50..7e40cb9 100644
@@ -3,5 +3,12 @@
"LogLevel": {
"Default": "Information"
}
},
"MediaRepository": {
"SubtitleCodecs": [
"ass",
"move_text",
"subrip"
]
}
}
src/Infrastructure/Database/Jellyfin/MediaRepository.cs +14 -2
diff --git a/src/Infrastructure/Database/Jellyfin/MediaRepository.cs b/src/Infrastructure/Database/Jellyfin/MediaRepository.cs
index 60bd7d0..a0e1e66 100644
@@ -1,21 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Database.Implementations;
using Jellyfin.Database.Implementations.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Slopper.Domain;
namespace Slopper.Infrastructure.Database.Jellyfin;
internal sealed class MediaRepository(JellyfinDbContext jellyfinDbContext, Random random) : IMediaRepository
internal sealed class MediaRepository(
IOptions<MediaRepositoryOptions> options,
JellyfinDbContext jellyfinDbContext,
Random random
) : IMediaRepository
{
private readonly IReadOnlyCollection<string> subtitleCodecs = options.Value.SubtitleCodecs;
public async Task<MediaItem> GetRandomMediaItem(CancellationToken cancellationToken)
{
var query = jellyfinDbContext
.MediaStreamInfos.AsNoTracking()
.Where(s => s.StreamType == MediaStreamTypeEntity.Subtitle && s.Language == "eng" && s.Codec != "PGSSUB");
.Where(s =>
s.StreamType == MediaStreamTypeEntity.Subtitle
&& s.Language == "eng"
&& subtitleCodecs.Contains(s.Codec)
);
var count = await query.CountAsync(cancellationToken);
var index = random.Next(count);
src/Infrastructure/Database/Jellyfin/MediaRepositoryOptions.cs +14 -0
diff --git a/src/Infrastructure/Database/Jellyfin/MediaRepositoryOptions.cs b/src/Infrastructure/Database/Jellyfin/MediaRepositoryOptions.cs
new file mode 100644
index 0000000..0fb7cb3
@@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.Extensions.Options;
namespace Slopper.Infrastructure.Database.Jellyfin;
internal sealed class MediaRepositoryOptions
{
[Required, MinLength(1)]
public required IReadOnlyCollection<string> SubtitleCodecs { get; set; }
}
[OptionsValidator]
internal sealed partial class MediaRepositoryOptionsValidator : IValidateOptions<MediaRepositoryOptions>;
src/Infrastructure/Database/ServiceCollectionExtensions.cs +6 -0
diff --git a/src/Infrastructure/Database/ServiceCollectionExtensions.cs b/src/Infrastructure/Database/ServiceCollectionExtensions.cs
index f61a648..68c6151 100644
@@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Slopper.Domain;
using Slopper.Infrastructure.Database.Jellyfin;
using Slopper.Infrastructure.Database.Slopper;
@@ -23,7 +24,12 @@ public static class ServiceCollectionExtensions
(sp, options) =>
options.UseSqlite(sp.GetRequiredService<IConfiguration>().GetConnectionString("jellyfin"))
);
services.TryAddSingleton(Random.Shared);
services.AddOptions<MediaRepositoryOptions>().BindConfiguration("MediaRepository").ValidateOnStart();
services.AddTransient<IValidateOptions<MediaRepositoryOptions>, MediaRepositoryOptionsValidator>();
services.AddTransient<IMediaRepository, MediaRepository>();
return services;
}