From d6280f3ce8baea2cc50d06ce06714c462b6cc2ec Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 5 Oct 2026 21:39:49 -0400 Subject: [PATCH] fix: built-in downloader prefers separate streams over 360p muxed (v1.0.0.16) When YouTube offered a muxed stream, it was always taken, but muxed streams are 360p only. Use muxed only when the separate video+audio streams are missing or not better. Co-Authored-By: Claude Opus 5.5 --- ...fin.Plugin.CinemaTrailers4Jellyfins.csproj | 4 +-- .../Services/TrailerDownloadService.cs | 36 +++++++++++-------- build.yaml | 9 +++-- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Jellyfin.Plugin.CinemaTrailers4Jellyfins.csproj b/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Jellyfin.Plugin.CinemaTrailers4Jellyfins.csproj index cf35637..55000da 100644 --- a/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Jellyfin.Plugin.CinemaTrailers4Jellyfins.csproj +++ b/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Jellyfin.Plugin.CinemaTrailers4Jellyfins.csproj @@ -3,8 +3,8 @@ net9.0 Jellyfin.Plugin.CinemaTrailers4Jellyfins - 1.0.0.15 - 1.0.0.15 + 1.0.0.16 + 1.0.0.16 enable false false diff --git a/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Services/TrailerDownloadService.cs b/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Services/TrailerDownloadService.cs index 561be97..b793b07 100644 --- a/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Services/TrailerDownloadService.cs +++ b/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Services/TrailerDownloadService.cs @@ -90,31 +90,37 @@ namespace Jellyfin.Plugin.CinemaTrailers4Jellyfins.Services .GetManifestAsync($"https://www.youtube.com/watch?v={key}", ct) .ConfigureAwait(false); - // Muxed streams include audio+video in one file. YouTube rarely serves them - // anymore, but use one when it exists since it needs no merge. + // Best video-only stream at or below the height limit. MP4 (H.264) is preferred for + // client compatibility; any container is the fallback. + var videoStreams = manifest.GetVideoOnlyStreams().ToList(); + var audioStreams = manifest.GetAudioOnlyStreams().ToList(); + var mp4Video = videoStreams.Where(s => s.Container == Container.Mp4).ToList(); + var video = videoStreams.Count > 0 + ? PickByHeight(mp4Video.Count > 0 ? mp4Video : videoStreams, preferredHeight) + : null; + + // Muxed streams (audio+video in one file) need no merge, but YouTube only serves + // them at 360p. Use one only when the separate streams can't do better. var muxedStreams = manifest.GetMuxedStreams().ToList(); if (muxedStreams.Count > 0) { var muxed = PickByHeight(muxedStreams, preferredHeight); - _logger.LogInformation( - "|CinemaTrailers4Jellyfins| Downloading {Key} at {Quality} (muxed) to {Path}", - key, muxed.VideoQuality.Label, outputPath); - await youtube.Videos.Streams.DownloadAsync(muxed, outputPath, cancellationToken: ct).ConfigureAwait(false); - return true; + if (video == null || audioStreams.Count == 0 + || muxed.VideoQuality.MaxHeight >= video.VideoQuality.MaxHeight) + { + _logger.LogInformation( + "|CinemaTrailers4Jellyfins| Downloading {Key} at {Quality} (muxed) to {Path}", + key, muxed.VideoQuality.Label, outputPath); + await youtube.Videos.Streams.DownloadAsync(muxed, outputPath, cancellationToken: ct).ConfigureAwait(false); + return true; + } } - // Otherwise download the best video-only and audio-only streams and merge them. - // MP4 (H.264/AAC) is preferred for client compatibility; any container is the fallback. - var videoStreams = manifest.GetVideoOnlyStreams().ToList(); - var audioStreams = manifest.GetAudioOnlyStreams().ToList(); - if (videoStreams.Count == 0 || audioStreams.Count == 0) + if (video == null || audioStreams.Count == 0) { _logger.LogWarning("|CinemaTrailers4Jellyfins| No usable video/audio streams for {Key}.", key); return false; } - - var mp4Video = videoStreams.Where(s => s.Container == Container.Mp4).ToList(); - var video = PickByHeight(mp4Video.Count > 0 ? mp4Video : videoStreams, preferredHeight); var mp4Audio = audioStreams.Where(s => s.Container == Container.Mp4).ToList(); var audio = (mp4Audio.Count > 0 ? mp4Audio : audioStreams).GetWithHighestBitrate(); diff --git a/build.yaml b/build.yaml index 00e7981..8d643ea 100644 --- a/build.yaml +++ b/build.yaml @@ -1,5 +1,5 @@ --- -version: 1.0.0.15 +version: 1.0.0.16 name: CinemaTrailers4Jellyfins guid: b581493e-1046-40ed-b6dc-cb8027624984 description: > @@ -12,10 +12,9 @@ category: General owner: 514mart targetAbi: 10.11.0.0 changelog: - - Trailer Languages now also checks the original language of the movie or - show. Before, only the trailer's own language tag was checked, and - TMDB often tags subtitled foreign trailers as English, so Korean, - Chinese or Japanese trailers got through + - The built-in downloader no longer picks YouTube's 360p combined file + when separate video and audio streams give a better picture. This + mostly showed up when yt-dlp failed and the built-in downloader took over dotnetProjects: - name: Jellyfin.Plugin.CinemaTrailers4Jellyfins