From 4a9565ab52c19be8798e622a3d238c3238b01c07 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Wed, 3 Apr 2024 14:56:56 +0200 Subject: Fix some spelling mistakes --- .../Library/MediaSourceManager.cs | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'Emby.Server.Implementations/Library/MediaSourceManager.cs') diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 18ada6aeb..9658bd566 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -191,7 +191,7 @@ namespace Emby.Server.Implementations.Library if (user is not null) { - SetDefaultAudioAndSubtitleStreamIndexes(item, source, user); + SetDefaultAudioAndSubtitleStreamIndices(item, source, user); if (item.MediaType == MediaType.Audio) { @@ -296,7 +296,7 @@ namespace Emby.Server.Implementations.Library catch (Exception ex) { _logger.LogError(ex, "Error getting media sources"); - return Enumerable.Empty(); + return []; } } @@ -339,7 +339,7 @@ namespace Emby.Server.Implementations.Library { foreach (var source in sources) { - SetDefaultAudioAndSubtitleStreamIndexes(item, source, user); + SetDefaultAudioAndSubtitleStreamIndices(item, source, user); if (item.MediaType == MediaType.Audio) { @@ -360,7 +360,7 @@ namespace Emby.Server.Implementations.Library { if (string.IsNullOrEmpty(language)) { - return Array.Empty(); + return []; } var culture = _localizationManager.FindLanguageInfo(language); @@ -369,14 +369,15 @@ namespace Emby.Server.Implementations.Library return culture.ThreeLetterISOLanguageNames; } - return new string[] { language }; + return [language]; } private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection) { if (userData.SubtitleStreamIndex.HasValue && user.RememberSubtitleSelections - && user.SubtitleMode != SubtitlePlaybackMode.None && allowRememberingSelection) + && user.SubtitleMode != SubtitlePlaybackMode.None + && allowRememberingSelection) { var index = userData.SubtitleStreamIndex.Value; // Make sure the saved index is still valid @@ -390,7 +391,7 @@ namespace Emby.Server.Implementations.Library var preferredSubs = NormalizeLanguage(user.SubtitleLanguagePreference); var defaultAudioIndex = source.DefaultAudioStreamIndex; - var audioLangage = defaultAudioIndex is null + var audioLanguage = defaultAudioIndex is null ? null : source.MediaStreams.Where(i => i.Type == MediaStreamType.Audio && i.Index == defaultAudioIndex).Select(i => i.Language).FirstOrDefault(); @@ -398,9 +399,9 @@ namespace Emby.Server.Implementations.Library source.MediaStreams, preferredSubs, user.SubtitleMode, - audioLangage); + audioLanguage); - MediaStreamSelector.SetSubtitleStreamScores(source.MediaStreams, preferredSubs, user.SubtitleMode, audioLangage); + MediaStreamSelector.SetSubtitleStreamScores(source.MediaStreams, preferredSubs, user.SubtitleMode, audioLanguage); } private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection) @@ -421,7 +422,7 @@ namespace Emby.Server.Implementations.Library source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.PlayDefaultAudioTrack); } - public void SetDefaultAudioAndSubtitleStreamIndexes(BaseItem item, MediaSourceInfo source, User user) + public void SetDefaultAudioAndSubtitleStreamIndices(BaseItem item, MediaSourceInfo source, User user) { // Item would only be null if the app didn't supply ItemId as part of the live stream open request var mediaType = item?.MediaType ?? MediaType.Video; @@ -526,7 +527,7 @@ namespace Emby.Server.Implementations.Library var item = request.ItemId.IsEmpty() ? null : _libraryManager.GetItemById(request.ItemId); - SetDefaultAudioAndSubtitleStreamIndexes(item, clone, user); + SetDefaultAudioAndSubtitleStreamIndices(item, clone, user); } return new Tuple(new LiveStreamResponse(clone), liveStream as IDirectStreamProvider); -- cgit v1.2.3 From d29b85a134ba4630178a48424b7eb54402c5c574 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Thu, 25 Apr 2024 15:02:01 +0200 Subject: Fix multiple intro providers and remove unneeded ToLists (#11431) --- Emby.Server.Implementations/Library/LibraryManager.cs | 9 ++++++--- Emby.Server.Implementations/Library/MediaSourceManager.cs | 2 +- MediaBrowser.Providers/Manager/ProviderManager.cs | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'Emby.Server.Implementations/Library/MediaSourceManager.cs') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 7b3871a9b..3e41a5048 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -44,7 +44,6 @@ using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Tasks; using Microsoft.Extensions.Logging; -using TMDbLib.Objects.Authentication; using Episode = MediaBrowser.Controller.Entities.TV.Episode; using EpisodeInfo = Emby.Naming.TV.EpisodeInfo; using Genre = MediaBrowser.Controller.Entities.Genre; @@ -1612,14 +1611,18 @@ namespace Emby.Server.Implementations.Library /// IEnumerable{System.String}. public async Task> GetIntros(BaseItem item, User user) { + if (IntroProviders.Length == 0) + { + return []; + } + var tasks = IntroProviders - .Take(1) .Select(i => GetIntros(i, item, user)); var items = await Task.WhenAll(tasks).ConfigureAwait(false); return items - .SelectMany(i => i.ToArray()) + .SelectMany(i => i) .Select(ResolveIntro) .Where(i => i is not null)!; // null values got filtered out } diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 9658bd566..5ec333cb1 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -274,7 +274,7 @@ namespace Emby.Server.Implementations.Library var tasks = _providers.Select(i => GetDynamicMediaSources(item, i, cancellationToken)); var results = await Task.WhenAll(tasks).ConfigureAwait(false); - return results.SelectMany(i => i.ToList()); + return results.SelectMany(i => i); } private async Task> GetDynamicMediaSources(BaseItem item, IMediaSourceProvider provider, CancellationToken cancellationToken) diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 844989a0b..275f4028d 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -286,7 +286,7 @@ namespace MediaBrowser.Providers.Manager var results = await Task.WhenAll(tasks).ConfigureAwait(false); - return results.SelectMany(i => i.ToList()); + return results.SelectMany(i => i); } /// -- cgit v1.2.3 From fc1bee30a62e2e31682809c8245a117f7ecbddd5 Mon Sep 17 00:00:00 2001 From: David Schulte Date: Mon, 15 Jul 2024 14:48:09 +0200 Subject: Allow streaming of raw PGS subtitles without transcoding (#12056) --- .../Library/MediaSourceManager.cs | 5 ++ .../Subtitles/SubtitleEncoder.cs | 54 ++++++++++++++++------ MediaBrowser.Model/Entities/MediaStream.cs | 33 +++++++++++++ 3 files changed, 79 insertions(+), 13 deletions(-) (limited to 'Emby.Server.Implementations/Library/MediaSourceManager.cs') diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 5ec333cb1..bb22ca82f 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -113,6 +113,11 @@ namespace Emby.Server.Implementations.Library return true; } + if (stream.IsPgsSubtitleStream) + { + return true; + } + return false; } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 16837d98b..9ecbfa9cf 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -198,10 +198,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (!subtitleStream.IsExternal || subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)) { - await ExtractAllTextSubtitles(mediaSource, cancellationToken).ConfigureAwait(false); + await ExtractAllExtractableSubtitles(mediaSource, cancellationToken).ConfigureAwait(false); - var outputFormat = GetTextSubtitleFormat(subtitleStream); - var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + outputFormat); + var outputFileExtension = GetExtractableSubtitleFileExtension(subtitleStream); + var outputFormat = GetExtractableSubtitleFormat(subtitleStream); + var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + outputFileExtension); return new SubtitleInfo() { @@ -215,6 +216,18 @@ namespace MediaBrowser.MediaEncoding.Subtitles var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec) .TrimStart('.'); + // Handle PGS subtitles as raw streams for the client to render + if (MediaStream.IsPgsFormat(currentFormat)) + { + return new SubtitleInfo() + { + Path = subtitleStream.Path, + Protocol = _mediaSourceManager.GetPathProtocol(subtitleStream.Path), + Format = "pgssub", + IsExternal = true + }; + } + // Fallback to ffmpeg conversion if (!_subtitleParser.SupportsFileExtension(currentFormat)) { @@ -428,10 +441,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles _logger.LogInformation("ffmpeg subtitle conversion succeeded for {Path}", inputPath); } - private string GetTextSubtitleFormat(MediaStream subtitleStream) + private string GetExtractableSubtitleFormat(MediaStream subtitleStream) { if (string.Equals(subtitleStream.Codec, "ass", StringComparison.OrdinalIgnoreCase) - || string.Equals(subtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase)) + || string.Equals(subtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase) + || string.Equals(subtitleStream.Codec, "pgssub", StringComparison.OrdinalIgnoreCase)) { return subtitleStream.Codec; } @@ -441,21 +455,35 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } + private string GetExtractableSubtitleFileExtension(MediaStream subtitleStream) + { + // Using .pgssub as file extension is not allowed by ffmpeg. The file extension for pgs subtitles is .sup. + if (string.Equals(subtitleStream.Codec, "pgssub", StringComparison.OrdinalIgnoreCase)) + { + return "sup"; + } + else + { + return GetExtractableSubtitleFormat(subtitleStream); + } + } + private bool IsCodecCopyable(string codec) { return string.Equals(codec, "ass", StringComparison.OrdinalIgnoreCase) || string.Equals(codec, "ssa", StringComparison.OrdinalIgnoreCase) || string.Equals(codec, "srt", StringComparison.OrdinalIgnoreCase) - || string.Equals(codec, "subrip", StringComparison.OrdinalIgnoreCase); + || string.Equals(codec, "subrip", StringComparison.OrdinalIgnoreCase) + || string.Equals(codec, "pgssub", StringComparison.OrdinalIgnoreCase); } /// - /// Extracts all text subtitles. + /// Extracts all extractable subtitles (text and pgs). /// /// The mediaSource. /// The cancellation token. /// Task. - private async Task ExtractAllTextSubtitles(MediaSourceInfo mediaSource, CancellationToken cancellationToken) + private async Task ExtractAllExtractableSubtitles(MediaSourceInfo mediaSource, CancellationToken cancellationToken) { var locks = new List(); var extractableStreams = new List(); @@ -463,11 +491,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles try { var subtitleStreams = mediaSource.MediaStreams - .Where(stream => stream is { IsTextSubtitleStream: true, SupportsExternalStream: true, IsExternal: false }); + .Where(stream => stream is { IsExtractableSubtitleStream: true, SupportsExternalStream: true, IsExternal: false }); foreach (var subtitleStream in subtitleStreams) { - var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetTextSubtitleFormat(subtitleStream)); + var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetExtractableSubtitleFileExtension(subtitleStream)); var releaser = await _semaphoreLocks.LockAsync(outputPath, cancellationToken).ConfigureAwait(false); @@ -483,7 +511,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles if (extractableStreams.Count > 0) { - await ExtractAllTextSubtitlesInternal(mediaSource, extractableStreams, cancellationToken).ConfigureAwait(false); + await ExtractAllExtractableSubtitlesInternal(mediaSource, extractableStreams, cancellationToken).ConfigureAwait(false); } } catch (Exception ex) @@ -496,7 +524,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } - private async Task ExtractAllTextSubtitlesInternal( + private async Task ExtractAllExtractableSubtitlesInternal( MediaSourceInfo mediaSource, List subtitleStreams, CancellationToken cancellationToken) @@ -510,7 +538,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles foreach (var subtitleStream in subtitleStreams) { - var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetTextSubtitleFormat(subtitleStream)); + var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetExtractableSubtitleFileExtension(subtitleStream)); var outputCodec = IsCodecCopyable(subtitleStream.Codec) ? "copy" : "srt"; var streamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, subtitleStream); diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index e1082adea..9044c0524 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -585,6 +585,31 @@ namespace MediaBrowser.Model.Entities } } + public bool IsPgsSubtitleStream + { + get + { + if (Type != MediaStreamType.Subtitle) + { + return false; + } + + if (string.IsNullOrEmpty(Codec) && !IsExternal) + { + return false; + } + + return IsPgsFormat(Codec); + } + } + + /// + /// Gets a value indicating whether this is a subtitle steam that is extractable by ffmpeg. + /// All text-based and pgs subtitles can be extracted. + /// + /// true if this is a extractable subtitle steam otherwise, false. + public bool IsExtractableSubtitleStream => IsTextSubtitleStream || IsPgsSubtitleStream; + /// /// Gets or sets a value indicating whether [supports external stream]. /// @@ -666,6 +691,14 @@ namespace MediaBrowser.Model.Entities && !string.Equals(codec, "sub", StringComparison.OrdinalIgnoreCase)); } + public static bool IsPgsFormat(string format) + { + string codec = format ?? string.Empty; + + return codec.Contains("pgs", StringComparison.OrdinalIgnoreCase) + || string.Equals(codec, "sup", StringComparison.OrdinalIgnoreCase); + } + public bool SupportsSubtitleConversionTo(string toCodec) { if (!IsTextSubtitleStream) -- cgit v1.2.3