yt-dlp removes its separate video/audio files after a successful merge, but
a failed run (e.g. HTTP 403 mid-download) left "<name>.f137.mp4.part" etc.
in the trailer folder, even when the built-in fallback then succeeded.
Always remove files sharing the output's "<name>." prefix after yt-dlp runs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Format string prefers avc1 video + m4a audio, then any codec. The RTX 2070
host can hardware-transcode H.264 but not AV1.
- Pass Jellyfin's ffmpeg via --ffmpeg-location instead of relying on PATH.
- If yt-dlp fails, retry with the built-in YoutubeExplode downloader.
- Read stdout/stderr while yt-dlp runs (and add --no-progress); before,
stdout was never read, so a full pipe buffer could block yt-dlp forever.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1.0.0.11 kept every animated trailer away from non-animated content, which
also blocked Western animation (Pixar, Disney...). Only anime should be
restricted.
At download, a trailer is tagged ct4j-anime when TMDB has the "anime" or
"based on manga" keyword, or it is Animation in ja/zh/ko (keywords are now
appended to the details request). At playback, anime trailers are dropped
unless the feature is anime (genre "Anime", or those keywords as tags).
Western animation follows the normal genre/rating filters again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An anime trailer could play before live-action content: the genre filter
accepts any single shared genre (anime is tagged Animation + Drama/Action/...),
and when nothing matched it fell back to the whole pool. Trailers tagged
Animation or Anime are now dropped for non-animated features before the
filters and the fallback run, so a live-action feature gets no trailer
rather than an animated one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
YouTube stopped serving muxed streams and YoutubeExplode 6.6.0 failed on
every video ("Video is not available"), so no trailer downloaded. Bump
YoutubeExplode to 6.6.2, download the best video-only + audio-only streams
and stream-copy them into one MP4 with ffmpeg. The separate files are
always deleted afterwards, merge or not.
Also delete the trailer folder when a download fails. Empty folders were
treated as "already downloaded" (never retried) and counted toward
MaxTotalTrailers, so over time they pushed out every real trailer. The
skip check now requires the trailer file itself.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
TopParentIds-based queries could fail to match Movie items in the
configured pre-roll library even when they appear correctly in the
Jellyfin UI. Look up the library Folder by ID and walk its recursive
children directly instead, matching the path-based approach already
used for the trailer pool.
Logs every GetIntros call (item, path, enabled features), why an item
is skipped, and pre-roll/post-roll lookup outcomes, without depending
on a Debug logging.json override.
Helps diagnose why a Trailer Pre-Roll/Feature Pre-Roll bumper isn't
playing by logging invalid library IDs, empty library results, and
the movie picked.
Adds two optional IIntroProvider bumper slots, mirroring CherryFloors'
cinema mode plugin: a "Trailer Pre-Roll" played before the trailer block
and a "Feature Pre-Roll" played right before the movie/episode. Each is
configured by picking an existing Jellyfin Movie library, from which a
random Movie is injected as the bumper.
Bump version to 1.0.0.5.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Download trailers for TV shows from TMDB with separate sources and an
independent max-count cap (0 disables a category)
- Play trailers before TV episodes via IIntroProvider, limited to the first
episode a user watches each day
- Tag TV show trailers in their NFO so movies only get movie trailers and
episodes only get TV show trailers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Trailer selection now supports three optional filters:
- Genre match: prefer trailers whose fake-movie genre overlaps with the
feature being played (requires TMDB genres in NFO)
- Age rating ceiling: exclude trailers rated higher than the feature
(requires TMDB certification in NFO)
- Avoid repeats: cycle through all trailers before replaying any;
resets per-user once the pool is exhausted
Genre and certification are fetched from TMDB at download time via a
single /movie/{id}?append_to_response=release_dates call and written
into the fake-movie NFO as <genre> and <mpaa> tags. All filters fall
back to the full unfiltered pool when no match is found.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Registers TrailerIntroProvider as IIntroProvider. Queries fake-movie
items in the output folder and returns their local trailer extras
(LocalTrailers) as IntroInfo — mirroring jellyfin-plugin-cinemamode's
proven pattern so Wholphin plays the actual trailer, not the 3-second
black placeholder.
Recursion guard: items whose path starts with the output folder are
excluded from intro injection, so Wholphin's getIntros call on the
intro item itself returns empty. Server-scoped query bypasses library
visibility restrictions so hidden trailer libraries still work.
Adds TrailersPerMovie config option (default 1, 0 = disabled).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two issues prevented fake-movie generation:
- ffmpeg was invoked by bare name, but only /usr/lib/jellyfin-ffmpeg/ffmpeg
exists on the host (Jellyfin's bundled copy, not on PATH). Now probing that
path first with fallback to PATH.
- The temp file extension .tmp caused ffmpeg to fail with "Unable to choose an
output format" since it auto-detects the container from the extension. Added
-f mp4 to specify the format explicitly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adapted from Trailers4Jellyfin: keeps TMDB/YouTube trailer downloading,
the scheduled task, language/source/date filters, and trailer rotation,
but drops cinema-mode/IIntroProvider entirely. Each trailer now ships in
its own fake-movie folder (placeholder video + locked NFO + trailer) for
use with a Cinema Mode / trailer pre-roll plugin.