From 19b756a5073d33f31181eef2c47212aed3b2abf4 Mon Sep 17 00:00:00 2001 From: MBR#0001 Date: Fri, 17 Apr 2026 15:17:30 +0200 Subject: [PATCH] Fix FFProbeVideoInfo downloading subtitles without considering internal streams Currently "Skip if the video already contains embedded subtitles" and "Skip if the default audio track matches the download language" are ignored because the internal tracks are not loaded before downloading This method is also triggered by the missing subtitles task (whenever a subtitle is downloaded) so if there are multiple languages configured, after first one is downloaded (valid) it runs it for other languages which might be internal --- .../MediaInfo/FFProbeVideoInfo.cs | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index fdc2f36469..e79f69dd28 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -194,20 +194,11 @@ namespace MediaBrowser.Providers.MediaInfo IReadOnlyList mediaAttachments; ChapterInfo[] chapters; - // Add external streams before adding the streams from the file to preserve stream IDs on remote videos - await AddExternalSubtitlesAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); - await AddExternalAudioAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); - var startIndex = mediaStreams.Count == 0 ? 0 : (mediaStreams.Max(i => i.Index) + 1); - if (mediaInfo is not null) { - foreach (var mediaStream in mediaInfo.MediaStreams) - { - mediaStream.Index = startIndex++; - mediaStreams.Add(mediaStream); - } + mediaStreams.AddRange(mediaInfo.MediaStreams); mediaAttachments = mediaInfo.MediaAttachments; video.TotalBitrate = mediaInfo.Bitrate; @@ -231,7 +222,6 @@ namespace MediaBrowser.Providers.MediaInfo { if (!mediaStream.IsExternal) { - mediaStream.Index = startIndex++; mediaStreams.Add(mediaStream); } } @@ -240,6 +230,14 @@ namespace MediaBrowser.Providers.MediaInfo chapters = []; } + // Download and insert external streams before the streams from the file to preserve stream IDs on remote videos + await AddExternalSubtitlesAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); + + for (var i = 0; i < mediaStreams.Count; i++) + { + mediaStreams[i].Index = i; + } + var libraryOptions = _libraryManager.GetLibraryOptions(video); if (mediaInfo is not null) @@ -542,8 +540,7 @@ namespace MediaBrowser.Providers.MediaInfo MetadataRefreshOptions options, CancellationToken cancellationToken) { - var startIndex = currentStreams.Count == 0 ? 0 : (currentStreams.Select(i => i.Index).Max() + 1); - var externalSubtitleStreams = await _subtitleResolver.GetExternalStreamsAsync(video, startIndex, options.DirectoryService, false, cancellationToken).ConfigureAwait(false); + var externalSubtitleStreams = await _subtitleResolver.GetExternalStreamsAsync(video, 0, options.DirectoryService, false, cancellationToken).ConfigureAwait(false); var enableSubtitleDownloading = options.MetadataRefreshMode == MetadataRefreshMode.Default || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh; @@ -569,13 +566,13 @@ namespace MediaBrowser.Providers.MediaInfo // Rescan if (downloadedLanguages.Count > 0) { - externalSubtitleStreams = await _subtitleResolver.GetExternalStreamsAsync(video, startIndex, options.DirectoryService, true, cancellationToken).ConfigureAwait(false); + externalSubtitleStreams = await _subtitleResolver.GetExternalStreamsAsync(video, 0, options.DirectoryService, true, cancellationToken).ConfigureAwait(false); } } video.SubtitleFiles = externalSubtitleStreams.Select(i => i.Path).Distinct().ToArray(); - currentStreams.AddRange(externalSubtitleStreams); + currentStreams.InsertRange(0, externalSubtitleStreams); } /// @@ -591,8 +588,7 @@ namespace MediaBrowser.Providers.MediaInfo MetadataRefreshOptions options, CancellationToken cancellationToken) { - var startIndex = currentStreams.Count == 0 ? 0 : currentStreams.Max(i => i.Index) + 1; - var externalAudioStreams = await _audioResolver.GetExternalStreamsAsync(video, startIndex, options.DirectoryService, false, cancellationToken).ConfigureAwait(false); + var externalAudioStreams = await _audioResolver.GetExternalStreamsAsync(video, 0, options.DirectoryService, false, cancellationToken).ConfigureAwait(false); video.AudioFiles = externalAudioStreams.Select(i => i.Path).Distinct().ToArray();