feat: skip trailers/pre-rolls inaccessible to the current user (v1.0.0.9)
All checks were successful
Publish Release / release (push) Successful in 12s

Filters trailer pool items and pre-roll/feature pre-roll bumpers using
BaseItem.IsVisibleStandalone(user), so users without access to the
relevant library are never handed an item they can't actually play —
some Cinema Mode clients hang indefinitely in that case.
This commit is contained in:
Martin
2026-06-10 13:07:11 -04:00
parent 5f7a76feb5
commit 6bb23dc9c4
3 changed files with 16 additions and 13 deletions

View File

@@ -3,8 +3,8 @@
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Jellyfin.Plugin.CinemaTrailers4Jellyfins</RootNamespace>
<AssemblyVersion>1.0.0.8</AssemblyVersion>
<FileVersion>1.0.0.8</FileVersion>
<AssemblyVersion>1.0.0.9</AssemblyVersion>
<FileVersion>1.0.0.9</FileVersion>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>

View File

@@ -111,7 +111,7 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
if (preRollEnabled)
{
var preRoll = GetRandomLibraryMovieIntro("Trailer Pre-Roll", config.TrailerPreRollLibraryId, item.Id);
var preRoll = GetRandomLibraryMovieIntro("Trailer Pre-Roll", config.TrailerPreRollLibraryId, item.Id, user);
if (preRoll != null)
intros.Add(preRoll);
}
@@ -129,6 +129,9 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
.Where(m =>
m.Path?.StartsWith(outputFolder, StringComparison.OrdinalIgnoreCase) == true
&& m.LocalTrailers.Count > 0
// Skip items the user can't actually play (e.g. library not in their access list) —
// some clients hang indefinitely trying to play an inaccessible item.
&& m.IsVisibleStandalone(user)
// Keep TV show trailers for episodes and movie trailers for movies separate.
&& m.Tags.Contains(TrailerTags.TvShow, StringComparer.OrdinalIgnoreCase) == isEpisode)
.SelectMany(m => m.LocalTrailers.Select(t => (Movie: m, Trailer: t)))
@@ -165,7 +168,7 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
if (featurePreRollEnabled)
{
var featureRoll = GetRandomLibraryMovieIntro("Feature Pre-Roll", config.FeaturePreRollLibraryId, item.Id);
var featureRoll = GetRandomLibraryMovieIntro("Feature Pre-Roll", config.FeaturePreRollLibraryId, item.Id, user);
if (featureRoll != null)
intros.Add(featureRoll);
}
@@ -182,7 +185,7 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
/// Picks a random Movie from the given Jellyfin library (VirtualFolder ItemId) to use as a
/// pre-roll/post-roll bumper, excluding the item currently being played.
/// </summary>
private IntroInfo? GetRandomLibraryMovieIntro(string label, string libraryId, Guid excludeId)
private IntroInfo? GetRandomLibraryMovieIntro(string label, string libraryId, Guid excludeId, User user)
{
if (!Guid.TryParse(libraryId, out var parsedId))
{
@@ -204,14 +207,14 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services
var movies = folder.GetRecursiveChildren()
.OfType<Movie>()
.Where(m => m.Id != excludeId)
.Where(m => m.Id != excludeId && m.IsVisibleStandalone(user))
.ToList();
if (movies.Count == 0)
{
_logger.LogInformation(
"|CinemaTrailers4Jellyfins| {Label} library {LibraryId} has no eligible Movie items. "
+ "Ensure the library has been scanned and contains at least one other Movie.",
"|CinemaTrailers4Jellyfins| {Label} library {LibraryId} has no eligible Movie items visible to this user. "
+ "Ensure the library has been scanned, contains at least one other Movie, and is in this user's library access list.",
label,
parsedId);
return null;