From 0bef4eef872c39fc9f747db7648b86f475c4a643 Mon Sep 17 00:00:00 2001 From: randrey Date: Fri, 17 Apr 2020 14:45:56 -0700 Subject: [PATCH] Fix InvalidOperationException while browsing via DLNA client. --- Emby.Dlna/Didl/DidlBuilder.cs | 114 +++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 36 deletions(-) diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 88cc00e30a..f9e9de8ff2 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -425,57 +425,99 @@ namespace Emby.Dlna.Didl } } - if (item is Episode episode && context is Season season) + return item is Episode episode + ? GetEpisodeDisplayName(episode, context) + : item.Name; + } + + /// + /// Gets episode display name appropriate for the given context. + /// + /// + /// If context is a season, this will return a string containing just episode number and name. + /// Otherwise the result will include series nams and season number. + /// + /// The episode. + /// Current context. + /// Formatted name of the episode. + private string GetEpisodeDisplayName(Episode episode, BaseItem context) + { + string[] components; + + if (context is Season season) { // This is a special embedded within a season - if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0 + if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value == 0 && season.IndexNumber.HasValue && season.IndexNumber.Value != 0) { return string.Format( CultureInfo.InvariantCulture, _localization.GetLocalizedString("ValueSpecialEpisodeName"), - item.Name); + episode.Name); } - if (item.IndexNumber.HasValue) - { - var number = item.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture); - - if (episode.IndexNumberEnd.HasValue) - { - number += "-" + episode.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture); - } - - return number + " - " + item.Name; - } + // inside a season use simple format (ex. '12 - Episode Name') + var epNumberName = GetEpisodeIndexFullName(episode); + components = new[] { epNumberName, episode.Name }; } - else if (item is Episode ep) + else { - var parent = ep.GetParent(); - var name = parent.Name + " - "; - - if (ep.ParentIndexNumber.HasValue) - { - name += "S" + ep.ParentIndexNumber.Value.ToString("00", CultureInfo.InvariantCulture); - } - else if (!item.IndexNumber.HasValue) - { - return name + " - " + item.Name; - } - - name += "E" + ep.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture); - if (ep.IndexNumberEnd.HasValue) - { - name += "-" + ep.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture); - } - - name += " - " + item.Name; - return name; + // outside a season include series and season details (ex. 'TV Show - S05E11 - Episode Name') + var epNumberName = GetEpisodeNumberDisplayName(episode); + components = new[] { episode.SeriesName, epNumberName, episode.Name }; } - return item.Name; + return string.Join(" - ", components.Where(NotNullOrWhiteSpace)); } + /// + /// Gets complete episode number. + /// + /// The episode. + /// For single episodes returns just the number. For double episodes - current and ending numbers. + private string GetEpisodeIndexFullName(Episode episode) + { + var name = string.Empty; + if (episode.IndexNumber.HasValue) + { + name += episode.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture); + + if (episode.IndexNumberEnd.HasValue) + { + name += "-" + episode.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture); + } + } + + return name; + } + + /// + /// Gets episode number formatted as 'S##E##'. + /// + /// The episode. + /// Formatted episode number. + private string GetEpisodeNumberDisplayName(Episode episode) + { + var name = string.Empty; + var seasonNumber = episode.Season?.IndexNumber; + + if (seasonNumber.HasValue) + { + name = "S" + seasonNumber.Value.ToString("00", CultureInfo.InvariantCulture); + } + + var indexName = GetEpisodeIndexFullName(episode); + + if (!string.IsNullOrWhiteSpace(indexName)) + { + name += "E" + indexName; + } + + return name; + } + + private bool NotNullOrWhiteSpace(string s) => !string.IsNullOrWhiteSpace(s); + private void AddAudioResource(XmlWriter writer, BaseItem audio, string deviceId, Filter filter, StreamInfo streamInfo = null) { writer.WriteStartElement(string.Empty, "res", NS_DIDL);