From be8ba9618365eb83e0b42964a891309234973d5b Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 2 Apr 2020 16:49:58 +0200 Subject: [PATCH 01/13] Fix some warnings --- Emby.Dlna/Api/DlnaServerService.cs | 10 ++ Emby.Dlna/Api/DlnaService.cs | 3 + Emby.Dlna/ContentDirectory/ControlHandler.cs | 111 ++++++------ Emby.Dlna/Didl/DidlBuilder.cs | 166 ++++++++++-------- Emby.Dlna/Didl/StringWriterWithEncoding.cs | 2 +- Emby.Dlna/Emby.Dlna.csproj | 4 +- Emby.Dlna/PlayTo/Device.cs | 19 +- Emby.Dlna/PlayTo/PlayToController.cs | 150 ++++++++-------- Emby.Dlna/PlayTo/PlayToManager.cs | 6 +- Emby.Dlna/PlayTo/SsdpHttpClient.cs | 10 +- .../Api/NotificationsService.cs | 12 +- 11 files changed, 274 insertions(+), 219 deletions(-) diff --git a/Emby.Dlna/Api/DlnaServerService.cs b/Emby.Dlna/Api/DlnaServerService.cs index b7d0189210..7fba2184a7 100644 --- a/Emby.Dlna/Api/DlnaServerService.cs +++ b/Emby.Dlna/Api/DlnaServerService.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; using System.Threading.Tasks; @@ -151,6 +152,7 @@ namespace Emby.Dlna.Api return _resultFactory.GetStaticResult(Request, cacheKey, null, cacheLength, XMLContentType, () => Task.FromResult(new MemoryStream(bytes))); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetContentDirectory request) { var xml = ContentDirectory.GetServiceXml(); @@ -158,6 +160,7 @@ namespace Emby.Dlna.Api return _resultFactory.GetResult(Request, xml, XMLContentType); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetMediaReceiverRegistrar request) { var xml = MediaReceiverRegistrar.GetServiceXml(); @@ -165,6 +168,7 @@ namespace Emby.Dlna.Api return _resultFactory.GetResult(Request, xml, XMLContentType); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetConnnectionManager request) { var xml = ConnectionManager.GetServiceXml(); @@ -313,31 +317,37 @@ namespace Emby.Dlna.Api return _resultFactory.GetStaticResult(Request, cacheKey, null, cacheLength, contentType, () => Task.FromResult(_dlnaManager.GetIcon(request.Filename).Stream)); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Subscribe(ProcessContentDirectoryEventRequest request) { return ProcessEventRequest(ContentDirectory); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Subscribe(ProcessConnectionManagerEventRequest request) { return ProcessEventRequest(ConnectionManager); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Subscribe(ProcessMediaReceiverRegistrarEventRequest request) { return ProcessEventRequest(MediaReceiverRegistrar); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Unsubscribe(ProcessContentDirectoryEventRequest request) { return ProcessEventRequest(ContentDirectory); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Unsubscribe(ProcessConnectionManagerEventRequest request) { return ProcessEventRequest(ConnectionManager); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Unsubscribe(ProcessMediaReceiverRegistrarEventRequest request) { return ProcessEventRequest(MediaReceiverRegistrar); diff --git a/Emby.Dlna/Api/DlnaService.cs b/Emby.Dlna/Api/DlnaService.cs index 7d6b8f78ed..5f984bb335 100644 --- a/Emby.Dlna/Api/DlnaService.cs +++ b/Emby.Dlna/Api/DlnaService.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 +using System.Diagnostics.CodeAnalysis; using System.Linq; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Net; @@ -52,6 +53,7 @@ namespace Emby.Dlna.Api _dlnaManager = dlnaManager; } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetProfileInfos request) { return _dlnaManager.GetProfileInfos().ToArray(); @@ -62,6 +64,7 @@ namespace Emby.Dlna.Api return _dlnaManager.GetProfile(request.Id); } + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetDefaultProfile request) { return _dlnaManager.GetDefaultProfile(); diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 41f4fbbd31..28888f031a 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -78,7 +78,18 @@ namespace Emby.Dlna.ContentDirectory _profile = profile; _config = config; - _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, mediaEncoder); + _didlBuilder = new DidlBuilder( + profile, + user, + imageProcessor, + serverAddress, + accessToken, + userDataManager, + localization, + mediaSourceManager, + Logger, + mediaEncoder, + libraryManager); } /// @@ -153,7 +164,7 @@ namespace Emby.Dlna.ContentDirectory { var id = sparams["ObjectID"]; - var serverItem = GetItemFromObjectId(id, _user); + var serverItem = GetItemFromObjectId(id); var item = serverItem.Item; @@ -276,7 +287,7 @@ namespace Emby.Dlna.ContentDirectory DidlBuilder.WriteXmlRootAttributes(_profile, writer); - var serverItem = GetItemFromObjectId(id, _user); + var serverItem = GetItemFromObjectId(id); var item = serverItem.Item; @@ -293,7 +304,7 @@ namespace Emby.Dlna.ContentDirectory else { var dlnaOptions = _config.GetDlnaConfiguration(); - _didlBuilder.WriteItemElement(dlnaOptions, writer, item, _user, null, null, deviceId, filter); + _didlBuilder.WriteItemElement(writer, item, _user, null, null, deviceId, filter); } provided++; @@ -320,7 +331,7 @@ namespace Emby.Dlna.ContentDirectory } else { - _didlBuilder.WriteItemElement(dlnaOptions, writer, childItem, _user, item, serverItem.StubType, deviceId, filter); + _didlBuilder.WriteItemElement(writer, childItem, _user, item, serverItem.StubType, deviceId, filter); } } } @@ -387,7 +398,7 @@ namespace Emby.Dlna.ContentDirectory DidlBuilder.WriteXmlRootAttributes(_profile, writer); - var serverItem = GetItemFromObjectId(sparams["ContainerID"], _user); + var serverItem = GetItemFromObjectId(sparams["ContainerID"]); var item = serverItem.Item; @@ -406,7 +417,7 @@ namespace Emby.Dlna.ContentDirectory } else { - _didlBuilder.WriteItemElement(dlnaOptions, writer, i, _user, item, serverItem.StubType, deviceId, filter); + _didlBuilder.WriteItemElement(writer, i, _user, item, serverItem.StubType, deviceId, filter); } } @@ -512,11 +523,11 @@ namespace Emby.Dlna.ContentDirectory } else if (string.Equals(CollectionType.Folders, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase)) { - return GetFolders(item, user, stubType, sort, startIndex, limit); + return GetFolders(user, startIndex, limit); } else if (string.Equals(CollectionType.LiveTv, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase)) { - return GetLiveTvChannels(item, user, stubType, sort, startIndex, limit); + return GetLiveTvChannels(user, sort, startIndex, limit); } } @@ -547,7 +558,7 @@ namespace Emby.Dlna.ContentDirectory return ToResult(queryResult); } - private QueryResult GetLiveTvChannels(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit) + private QueryResult GetLiveTvChannels(User user, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) { @@ -579,7 +590,7 @@ namespace Emby.Dlna.ContentDirectory if (stubType.HasValue && stubType.Value == StubType.Playlists) { - return GetMusicPlaylists(item, user, query); + return GetMusicPlaylists(user, query); } if (stubType.HasValue && stubType.Value == StubType.Albums) @@ -707,7 +718,7 @@ namespace Emby.Dlna.ContentDirectory if (stubType.HasValue && stubType.Value == StubType.Collections) { - return GetMovieCollections(item, user, query); + return GetMovieCollections(user, query); } if (stubType.HasValue && stubType.Value == StubType.Favorites) @@ -720,46 +731,42 @@ namespace Emby.Dlna.ContentDirectory return GetGenres(item, user, query); } - var list = new List(); - - list.Add(new ServerItem(item) + var array = new ServerItem[] { - StubType = StubType.ContinueWatching - }); - - list.Add(new ServerItem(item) - { - StubType = StubType.Latest - }); - - list.Add(new ServerItem(item) - { - StubType = StubType.Movies - }); - - list.Add(new ServerItem(item) - { - StubType = StubType.Collections - }); - - list.Add(new ServerItem(item) - { - StubType = StubType.Favorites - }); - - list.Add(new ServerItem(item) - { - StubType = StubType.Genres - }); + new ServerItem(item) + { + StubType = StubType.ContinueWatching + }, + new ServerItem(item) + { + StubType = StubType.Latest + }, + new ServerItem(item) + { + StubType = StubType.Movies + }, + new ServerItem(item) + { + StubType = StubType.Collections + }, + new ServerItem(item) + { + StubType = StubType.Favorites + }, + new ServerItem(item) + { + StubType = StubType.Genres + } + }; return new QueryResult { - Items = list, - TotalRecordCount = list.Count + Items = array, + TotalRecordCount = array.Length }; } - private QueryResult GetFolders(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit) + private QueryResult GetFolders(User user, int? startIndex, int? limit) { var folders = _libraryManager.GetUserRootFolder().GetChildren(user, true) .OrderBy(i => i.SortName) @@ -792,7 +799,7 @@ namespace Emby.Dlna.ContentDirectory if (stubType.HasValue && stubType.Value == StubType.NextUp) { - return GetNextUp(item, user, query); + return GetNextUp(item, query); } if (stubType.HasValue && stubType.Value == StubType.Latest) @@ -910,7 +917,7 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } - private QueryResult GetMovieCollections(BaseItem parent, User user, InternalItemsQuery query) + private QueryResult GetMovieCollections(User user, InternalItemsQuery query) { query.Recursive = true; //query.Parent = parent; @@ -1105,7 +1112,7 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } - private QueryResult GetMusicPlaylists(BaseItem parent, User user, InternalItemsQuery query) + private QueryResult GetMusicPlaylists(User user, InternalItemsQuery query) { query.Parent = null; query.IncludeItemTypes = new[] { typeof(Playlist).Name }; @@ -1134,7 +1141,7 @@ namespace Emby.Dlna.ContentDirectory return ToResult(items); } - private QueryResult GetNextUp(BaseItem parent, User user, InternalItemsQuery query) + private QueryResult GetNextUp(BaseItem parent, InternalItemsQuery query) { query.OrderBy = Array.Empty<(string, SortOrder)>(); @@ -1289,15 +1296,15 @@ namespace Emby.Dlna.ContentDirectory return result; } - private ServerItem GetItemFromObjectId(string id, User user) + private ServerItem GetItemFromObjectId(string id) { return DidlBuilder.IsIdRoot(id) ? new ServerItem(_libraryManager.GetUserRootFolder()) - : ParseItemId(id, user); + : ParseItemId(id); } - private ServerItem ParseItemId(string id, User user) + private ServerItem ParseItemId(string id) { StubType? stubType = null; diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index efc86f333d..255f2c9882 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -45,6 +45,7 @@ namespace Emby.Dlna.Didl private readonly IMediaSourceManager _mediaSourceManager; private readonly ILogger _logger; private readonly IMediaEncoder _mediaEncoder; + private readonly ILibraryManager _libraryManager; public DidlBuilder( DeviceProfile profile, @@ -56,7 +57,8 @@ namespace Emby.Dlna.Didl ILocalizationManager localization, IMediaSourceManager mediaSourceManager, ILogger logger, - IMediaEncoder mediaEncoder) + IMediaEncoder mediaEncoder, + ILibraryManager libraryManager) { _profile = profile; _user = user; @@ -68,6 +70,7 @@ namespace Emby.Dlna.Didl _mediaSourceManager = mediaSourceManager; _logger = logger; _mediaEncoder = mediaEncoder; + _libraryManager = libraryManager; } public static string NormalizeDlnaMediaUrl(string url) @@ -75,7 +78,7 @@ namespace Emby.Dlna.Didl return url + "&dlnaheaders=true"; } - public string GetItemDidl(DlnaOptions options, BaseItem item, User user, BaseItem context, string deviceId, Filter filter, StreamInfo streamInfo) + public string GetItemDidl(BaseItem item, User user, BaseItem context, string deviceId, Filter filter, StreamInfo streamInfo) { var settings = new XmlWriterSettings { @@ -100,7 +103,7 @@ namespace Emby.Dlna.Didl WriteXmlRootAttributes(_profile, writer); - WriteItemElement(options, writer, item, user, context, null, deviceId, filter, streamInfo); + WriteItemElement(writer, item, user, context, null, deviceId, filter, streamInfo); writer.WriteFullEndElement(); //writer.WriteEndDocument(); @@ -127,7 +130,6 @@ namespace Emby.Dlna.Didl } public void WriteItemElement( - DlnaOptions options, XmlWriter writer, BaseItem item, User user, @@ -164,25 +166,23 @@ namespace Emby.Dlna.Didl // refID? // storeAttribute(itemNode, object, ClassProperties.REF_ID, false); - var hasMediaSources = item as IHasMediaSources; - - if (hasMediaSources != null) + if (item is IHasMediaSources) { if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) { - AddAudioResource(options, writer, item, deviceId, filter, streamInfo); + AddAudioResource(writer, item, deviceId, filter, streamInfo); } else if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) { - AddVideoResource(options, writer, item, deviceId, filter, streamInfo); + AddVideoResource(writer, item, deviceId, filter, streamInfo); } } - AddCover(item, context, null, writer); + AddCover(item, null, writer); writer.WriteFullEndElement(); } - private void AddVideoResource(DlnaOptions options, XmlWriter writer, BaseItem video, string deviceId, Filter filter, StreamInfo streamInfo = null) + private void AddVideoResource(XmlWriter writer, BaseItem video, string deviceId, Filter filter, StreamInfo streamInfo = null) { if (streamInfo == null) { @@ -226,7 +226,7 @@ namespace Emby.Dlna.Didl foreach (var contentFeature in contentFeatureList) { - AddVideoResource(writer, video, deviceId, filter, contentFeature, streamInfo); + AddVideoResource(writer, filter, contentFeature, streamInfo); } var subtitleProfiles = streamInfo.GetSubtitleProfiles(_mediaEncoder, false, _serverAddress, _accessToken); @@ -283,7 +283,10 @@ namespace Emby.Dlna.Didl else { writer.WriteStartElement(string.Empty, "res", NS_DIDL); - var protocolInfo = string.Format("http-get:*:text/{0}:*", info.Format.ToLowerInvariant()); + var protocolInfo = string.Format( + CultureInfo.InvariantCulture, + "http-get:*:text/{0}:*", + info.Format.ToLowerInvariant()); writer.WriteAttributeString("protocolInfo", protocolInfo); writer.WriteString(info.Url); @@ -293,7 +296,7 @@ namespace Emby.Dlna.Didl return true; } - private void AddVideoResource(XmlWriter writer, BaseItem video, string deviceId, Filter filter, string contentFeatures, StreamInfo streamInfo) + private void AddVideoResource(XmlWriter writer, Filter filter, string contentFeatures, StreamInfo streamInfo) { writer.WriteStartElement(string.Empty, "res", NS_DIDL); @@ -335,7 +338,13 @@ namespace Emby.Dlna.Didl { if (targetWidth.HasValue && targetHeight.HasValue) { - writer.WriteAttributeString("resolution", string.Format("{0}x{1}", targetWidth.Value, targetHeight.Value)); + writer.WriteAttributeString( + "resolution", + string.Format( + CultureInfo.InvariantCulture, + "{0}x{1}", + targetWidth.Value, + targetHeight.Value)); } } @@ -369,17 +378,19 @@ namespace Emby.Dlna.Didl streamInfo.TargetVideoCodecTag, streamInfo.IsTargetAVC); - var filename = url.Substring(0, url.IndexOf('?')); + var filename = url.Substring(0, url.IndexOf('?', StringComparison.Ordinal)); var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType) ? MimeTypes.GetMimeType(filename) : mediaProfile.MimeType; - writer.WriteAttributeString("protocolInfo", string.Format( - "http-get:*:{0}:{1}", - mimeType, - contentFeatures - )); + writer.WriteAttributeString( + "protocolInfo", + string.Format( + CultureInfo.InvariantCulture, + "http-get:*:{0}:{1}", + mimeType, + contentFeatures)); writer.WriteString(url); @@ -420,7 +431,10 @@ namespace Emby.Dlna.Didl if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0 && season.IndexNumber.HasValue && season.IndexNumber.Value != 0) { - return string.Format(_localization.GetLocalizedString("ValueSpecialEpisodeName"), item.Name); + return string.Format( + CultureInfo.InvariantCulture, + _localization.GetLocalizedString("ValueSpecialEpisodeName"), + item.Name); } if (item.IndexNumber.HasValue) @@ -439,7 +453,7 @@ namespace Emby.Dlna.Didl return item.Name; } - private void AddAudioResource(DlnaOptions options, XmlWriter writer, BaseItem audio, string deviceId, Filter filter, StreamInfo streamInfo = null) + private void AddAudioResource(XmlWriter writer, BaseItem audio, string deviceId, Filter filter, StreamInfo streamInfo = null) { writer.WriteStartElement(string.Empty, "res", NS_DIDL); @@ -505,7 +519,7 @@ namespace Emby.Dlna.Didl targetSampleRate, targetAudioBitDepth); - var filename = url.Substring(0, url.IndexOf('?')); + var filename = url.Substring(0, url.IndexOf('?', StringComparison.Ordinal)); var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType) ? MimeTypes.GetMimeType(filename) @@ -521,11 +535,13 @@ namespace Emby.Dlna.Didl streamInfo.RunTimeTicks ?? 0, streamInfo.TranscodeSeekInfo); - writer.WriteAttributeString("protocolInfo", string.Format( - "http-get:*:{0}:{1}", - mimeType, - contentFeatures - )); + writer.WriteAttributeString( + "protocolInfo", + string.Format( + CultureInfo.InvariantCulture, + "http-get:*:{0}:{1}", + mimeType, + contentFeatures)); writer.WriteString(url); @@ -548,7 +564,7 @@ namespace Emby.Dlna.Didl var clientId = GetClientId(folder, stubType); - if (string.Equals(requestedId, "0")) + if (string.Equals(requestedId, "0", StringComparison.Ordinal)) { writer.WriteAttributeString("id", "0"); writer.WriteAttributeString("parentID", "-1"); @@ -577,7 +593,7 @@ namespace Emby.Dlna.Didl AddGeneralProperties(folder, stubType, context, writer, filter); - AddCover(folder, context, stubType, writer); + AddCover(folder, stubType, writer); writer.WriteFullEndElement(); } @@ -610,7 +626,10 @@ namespace Emby.Dlna.Didl if (playbackPositionTicks > 0) { - var elementValue = string.Format("BM={0}", Convert.ToInt32(TimeSpan.FromTicks(playbackPositionTicks).TotalSeconds).ToString(_usCulture)); + var elementValue = string.Format( + CultureInfo.InvariantCulture, + "BM={0}", + Convert.ToInt32(TimeSpan.FromTicks(playbackPositionTicks).TotalSeconds)); AddValue(writer, "sec", "dcmInfo", elementValue, secAttribute.Value); } } @@ -763,37 +782,37 @@ namespace Emby.Dlna.Didl private void AddPeople(BaseItem item, XmlWriter writer) { - //var types = new[] - //{ - // PersonType.Director, - // PersonType.Writer, - // PersonType.Producer, - // PersonType.Composer, - // "Creator" - //}; + var types = new[] + { + PersonType.Director, + PersonType.Writer, + PersonType.Producer, + PersonType.Composer, + "Creator" + }; - //var people = _libraryManager.GetPeople(item); + var people = _libraryManager.GetPeople(item); - //var index = 0; + var index = 0; - //// Seeing some LG models locking up due content with large lists of people - //// The actual issue might just be due to processing a more metadata than it can handle - //var limit = 6; + // Seeing some LG models locking up due content with large lists of people + // The actual issue might just be due to processing a more metadata than it can handle + var limit = 6; - //foreach (var actor in people) - //{ - // var type = types.FirstOrDefault(i => string.Equals(i, actor.Type, StringComparison.OrdinalIgnoreCase) || string.Equals(i, actor.Role, StringComparison.OrdinalIgnoreCase)) - // ?? PersonType.Actor; + foreach (var actor in people) + { + var type = types.FirstOrDefault(i => string.Equals(i, actor.Type, StringComparison.OrdinalIgnoreCase) || string.Equals(i, actor.Role, StringComparison.OrdinalIgnoreCase)) + ?? PersonType.Actor; - // AddValue(writer, "upnp", type.ToLowerInvariant(), actor.Name, NS_UPNP); + AddValue(writer, "upnp", type.ToLowerInvariant(), actor.Name, NS_UPNP); - // index++; + index++; - // if (index >= limit) - // { - // break; - // } - //} + if (index >= limit) + { + break; + } + } } private void AddGeneralProperties(BaseItem item, StubType? itemStubType, BaseItem context, XmlWriter writer, Filter filter) @@ -870,7 +889,7 @@ namespace Emby.Dlna.Didl } } - private void AddCover(BaseItem item, BaseItem context, StubType? stubType, XmlWriter writer) + private void AddCover(BaseItem item, StubType? stubType, XmlWriter writer) { ImageDownloadInfo imageInfo = GetImageInfo(item); @@ -915,17 +934,8 @@ namespace Emby.Dlna.Didl } - private void AddEmbeddedImageAsCover(string name, XmlWriter writer) - { - writer.WriteStartElement("upnp", "albumArtURI", NS_UPNP); - writer.WriteAttributeString("dlna", "profileID", NS_DLNA, _profile.AlbumArtPn); - writer.WriteString(_serverAddress + "/Dlna/icons/people480.jpg"); - writer.WriteFullEndElement(); - - writer.WriteElementString("upnp", "icon", NS_UPNP, _serverAddress + "/Dlna/icons/people48.jpg"); - } - - private void AddImageResElement(BaseItem item, + private void AddImageResElement( + BaseItem item, XmlWriter writer, int maxWidth, int maxHeight, @@ -951,13 +961,17 @@ namespace Emby.Dlna.Didl var contentFeatures = new ContentFeatureBuilder(_profile) .BuildImageHeader(format, width, height, imageInfo.IsDirectStream, org_Pn); - writer.WriteAttributeString("protocolInfo", string.Format( - "http-get:*:{0}:{1}", - MimeTypes.GetMimeType("file." + format), - contentFeatures - )); + writer.WriteAttributeString( + "protocolInfo", + string.Format( + CultureInfo.InvariantCulture, + "http-get:*:{0}:{1}", + MimeTypes.GetMimeType("file." + format), + contentFeatures)); - writer.WriteAttributeString("resolution", string.Format("{0}x{1}", width, height)); + writer.WriteAttributeString( + "resolution", + string.Format(CultureInfo.InvariantCulture, "{0}x{1}", width, height)); writer.WriteString(albumartUrlInfo.Url); @@ -1096,7 +1110,9 @@ namespace Emby.Dlna.Didl private ImageUrlInfo GetImageUrl(ImageDownloadInfo info, int maxWidth, int maxHeight, string format) { - var url = string.Format("{0}/Items/{1}/Images/{2}/0/{3}/{4}/{5}/{6}/0/0", + var url = string.Format( + CultureInfo.InvariantCulture, + "{0}/Items/{1}/Images/{2}/0/{3}/{4}/{5}/{6}/0/0", _serverAddress, info.ItemId.ToString("N", CultureInfo.InvariantCulture), info.Type, diff --git a/Emby.Dlna/Didl/StringWriterWithEncoding.cs b/Emby.Dlna/Didl/StringWriterWithEncoding.cs index 67fc56ec0f..896fe992bf 100644 --- a/Emby.Dlna/Didl/StringWriterWithEncoding.cs +++ b/Emby.Dlna/Didl/StringWriterWithEncoding.cs @@ -53,6 +53,6 @@ namespace Emby.Dlna.Didl _encoding = encoding; } - public override Encoding Encoding => (null == _encoding) ? base.Encoding : _encoding; + public override Encoding Encoding => _encoding ?? base.Encoding; } } diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index 0cabe43d51..43c3c1384f 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -15,14 +15,14 @@ netstandard2.1 false true - true + true - + diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index b77a2bbac7..0d47dc929f 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -346,7 +346,12 @@ namespace Emby.Dlna.PlayTo throw new InvalidOperationException("Unable to find service"); } - return new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)); + return new SsdpHttpClient(_httpClient).SendCommandAsync( + Properties.BaseUrl, + service, + command.Name, + avCommands.BuildPost(command, service.ServiceType, 1), + cancellationToken: cancellationToken); } public async Task SetPlay(CancellationToken cancellationToken) @@ -588,8 +593,14 @@ namespace Emby.Dlna.PlayTo return null; } - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType), false) - .ConfigureAwait(false); + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + Properties.BaseUrl, + service, + command.Name, + avCommands.BuildPost(command, + service.ServiceType), + false, + cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null) { @@ -599,7 +610,7 @@ namespace Emby.Dlna.PlayTo var transportState = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetTransportInfoResponse").Select(i => i.Element("CurrentTransportState")).FirstOrDefault(i => i != null); - var transportStateValue = transportState == null ? null : transportState.Value; + var transportStateValue = transportState?.Value; if (transportStateValue != null && Enum.TryParse(transportStateValue, true, out TRANSPORTSTATE state)) diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index cf978d7420..9ee6986b43 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -27,6 +27,8 @@ namespace Emby.Dlna.PlayTo { public class PlayToController : ISessionController, IDisposable { + private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US")); + private Device _device; private readonly SessionInfo _session; private readonly ISessionManager _sessionManager; @@ -45,9 +47,10 @@ namespace Emby.Dlna.PlayTo private readonly string _serverAddress; private readonly string _accessToken; - public bool IsSessionActive => !_disposed && _device != null; + private readonly List _playlist = new List(); + private int _currentPlaylistIndex; - public bool SupportsMediaControl => IsSessionActive; + private bool _disposed; public PlayToController( SessionInfo session, @@ -83,18 +86,22 @@ namespace Emby.Dlna.PlayTo _mediaEncoder = mediaEncoder; } + public bool IsSessionActive => !_disposed && _device != null; + + public bool SupportsMediaControl => IsSessionActive; + public void Init(Device device) { _device = device; _device.OnDeviceUnavailable = OnDeviceUnavailable; - _device.PlaybackStart += _device_PlaybackStart; - _device.PlaybackProgress += _device_PlaybackProgress; - _device.PlaybackStopped += _device_PlaybackStopped; - _device.MediaChanged += _device_MediaChanged; + _device.PlaybackStart += OnDevicePlaybackStart; + _device.PlaybackProgress += OnDevicePlaybackProgress; + _device.PlaybackStopped += DevicePlaybackStopped; + _device.MediaChanged += OnDeviceMediaChanged; _device.Start(); - _deviceDiscovery.DeviceLeft += _deviceDiscovery_DeviceLeft; + _deviceDiscovery.DeviceLeft += OnDeviceDiscoveryDeviceLeft; } private void OnDeviceUnavailable() @@ -110,7 +117,7 @@ namespace Emby.Dlna.PlayTo } } - void _deviceDiscovery_DeviceLeft(object sender, GenericEventArgs e) + private void OnDeviceDiscoveryDeviceLeft(object sender, GenericEventArgs e) { var info = e.Argument; @@ -125,7 +132,7 @@ namespace Emby.Dlna.PlayTo } } - async void _device_MediaChanged(object sender, MediaChangedEventArgs e) + private async void OnDeviceMediaChanged(object sender, MediaChangedEventArgs e) { if (_disposed) { @@ -137,15 +144,15 @@ namespace Emby.Dlna.PlayTo var streamInfo = StreamParams.ParseFromUrl(e.OldMediaInfo.Url, _libraryManager, _mediaSourceManager); if (streamInfo.Item != null) { - var positionTicks = GetProgressPositionTicks(e.OldMediaInfo, streamInfo); + var positionTicks = GetProgressPositionTicks(streamInfo); - ReportPlaybackStopped(e.OldMediaInfo, streamInfo, positionTicks); + ReportPlaybackStopped(streamInfo, positionTicks); } streamInfo = StreamParams.ParseFromUrl(e.NewMediaInfo.Url, _libraryManager, _mediaSourceManager); if (streamInfo.Item == null) return; - var newItemProgress = GetProgressInfo(e.NewMediaInfo, streamInfo); + var newItemProgress = GetProgressInfo(streamInfo); await _sessionManager.OnPlaybackStart(newItemProgress).ConfigureAwait(false); } @@ -155,7 +162,7 @@ namespace Emby.Dlna.PlayTo } } - async void _device_PlaybackStopped(object sender, PlaybackStoppedEventArgs e) + private async void DevicePlaybackStopped(object sender, PlaybackStoppedEventArgs e) { if (_disposed) { @@ -168,9 +175,9 @@ namespace Emby.Dlna.PlayTo if (streamInfo.Item == null) return; - var positionTicks = GetProgressPositionTicks(e.MediaInfo, streamInfo); + var positionTicks = GetProgressPositionTicks(streamInfo); - ReportPlaybackStopped(e.MediaInfo, streamInfo, positionTicks); + ReportPlaybackStopped(streamInfo, positionTicks); var mediaSource = await streamInfo.GetMediaSource(CancellationToken.None).ConfigureAwait(false); @@ -194,7 +201,7 @@ namespace Emby.Dlna.PlayTo } else { - Playlist.Clear(); + _playlist.Clear(); } } catch (Exception ex) @@ -203,7 +210,7 @@ namespace Emby.Dlna.PlayTo } } - private async void ReportPlaybackStopped(uBaseObject mediaInfo, StreamParams streamInfo, long? positionTicks) + private async void ReportPlaybackStopped(StreamParams streamInfo, long? positionTicks) { try { @@ -222,7 +229,7 @@ namespace Emby.Dlna.PlayTo } } - async void _device_PlaybackStart(object sender, PlaybackStartEventArgs e) + private async void OnDevicePlaybackStart(object sender, PlaybackStartEventArgs e) { if (_disposed) { @@ -235,7 +242,7 @@ namespace Emby.Dlna.PlayTo if (info.Item != null) { - var progress = GetProgressInfo(e.MediaInfo, info); + var progress = GetProgressInfo(info); await _sessionManager.OnPlaybackStart(progress).ConfigureAwait(false); } @@ -246,7 +253,7 @@ namespace Emby.Dlna.PlayTo } } - async void _device_PlaybackProgress(object sender, PlaybackProgressEventArgs e) + private async void OnDevicePlaybackProgress(object sender, PlaybackProgressEventArgs e) { if (_disposed) { @@ -266,7 +273,7 @@ namespace Emby.Dlna.PlayTo if (info.Item != null) { - var progress = GetProgressInfo(e.MediaInfo, info); + var progress = GetProgressInfo(info); await _sessionManager.OnPlaybackProgress(progress).ConfigureAwait(false); } @@ -277,7 +284,7 @@ namespace Emby.Dlna.PlayTo } } - private long? GetProgressPositionTicks(uBaseObject mediaInfo, StreamParams info) + private long? GetProgressPositionTicks(StreamParams info) { var ticks = _device.Position.Ticks; @@ -289,13 +296,13 @@ namespace Emby.Dlna.PlayTo return ticks; } - private PlaybackStartInfo GetProgressInfo(uBaseObject mediaInfo, StreamParams info) + private PlaybackStartInfo GetProgressInfo(StreamParams info) { return new PlaybackStartInfo { ItemId = info.ItemId, SessionId = _session.Id, - PositionTicks = GetProgressPositionTicks(mediaInfo, info), + PositionTicks = GetProgressPositionTicks(info), IsMuted = _device.IsMuted, IsPaused = _device.IsPaused, MediaSourceId = info.MediaSourceId, @@ -310,9 +317,7 @@ namespace Emby.Dlna.PlayTo }; } - #region SendCommands - - public async Task SendPlayCommand(PlayRequest command, CancellationToken cancellationToken) + public Task SendPlayCommand(PlayRequest command, CancellationToken cancellationToken) { _logger.LogDebug("{0} - Received PlayRequest: {1}", this._session.DeviceName, command.PlayCommand); @@ -350,11 +355,12 @@ namespace Emby.Dlna.PlayTo if (command.PlayCommand == PlayCommand.PlayLast) { - Playlist.AddRange(playlist); + _playlist.AddRange(playlist); } + if (command.PlayCommand == PlayCommand.PlayNext) { - Playlist.AddRange(playlist); + _playlist.AddRange(playlist); } if (!command.ControllingUserId.Equals(Guid.Empty)) @@ -363,7 +369,7 @@ namespace Emby.Dlna.PlayTo _session.DeviceName, _session.RemoteEndPoint, user); } - await PlayItems(playlist).ConfigureAwait(false); + return PlayItems(playlist, cancellationToken); } private Task SendPlaystateCommand(PlaystateRequest command, CancellationToken cancellationToken) @@ -371,7 +377,7 @@ namespace Emby.Dlna.PlayTo switch (command.Command) { case PlaystateCommand.Stop: - Playlist.Clear(); + _playlist.Clear(); return _device.SetStop(CancellationToken.None); case PlaystateCommand.Pause: @@ -387,10 +393,10 @@ namespace Emby.Dlna.PlayTo return Seek(command.SeekPositionTicks ?? 0); case PlaystateCommand.NextTrack: - return SetPlaylistIndex(_currentPlaylistIndex + 1); + return SetPlaylistIndex(_currentPlaylistIndex + 1, cancellationToken); case PlaystateCommand.PreviousTrack: - return SetPlaylistIndex(_currentPlaylistIndex - 1); + return SetPlaylistIndex(_currentPlaylistIndex - 1, cancellationToken); } return Task.CompletedTask; @@ -426,14 +432,6 @@ namespace Emby.Dlna.PlayTo return info.IsDirectStream; } - #endregion - - #region Playlist - - private int _currentPlaylistIndex; - private readonly List _playlist = new List(); - private List Playlist => _playlist; - private void AddItemFromId(Guid id, List list) { var item = _libraryManager.GetItemById(id); @@ -451,7 +449,7 @@ namespace Emby.Dlna.PlayTo _dlnaManager.GetDefaultProfile(); var mediaSources = item is IHasMediaSources - ? (_mediaSourceManager.GetStaticMediaSources(item, true, user)) + ? _mediaSourceManager.GetStaticMediaSources(item, true, user) : new List(); var playlistItem = GetPlaylistItem(item, mediaSources, profile, _session.DeviceId, mediaSourceId, audioStreamIndex, subtitleStreamIndex); @@ -459,8 +457,19 @@ namespace Emby.Dlna.PlayTo playlistItem.StreamUrl = DidlBuilder.NormalizeDlnaMediaUrl(playlistItem.StreamInfo.ToUrl(_serverAddress, _accessToken)); - var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _mediaEncoder) - .GetItemDidl(_config.GetDlnaConfiguration(), item, user, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo); + var itemXml = new DidlBuilder( + profile, + user, + _imageProcessor, + _serverAddress, + _accessToken, + _userDataManager, + _localization, + _mediaSourceManager, + _logger, + _mediaEncoder, + _libraryManager) + .GetItemDidl(item, user, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo); playlistItem.Didl = itemXml; @@ -570,30 +579,31 @@ namespace Emby.Dlna.PlayTo /// Plays the items. /// /// The items. - /// - private async Task PlayItems(IEnumerable items) + /// The cancellation token. + /// true on success. + private async Task PlayItems(IEnumerable items, CancellationToken cancellationToken = default) { - Playlist.Clear(); - Playlist.AddRange(items); - _logger.LogDebug("{0} - Playing {1} items", _session.DeviceName, Playlist.Count); + _playlist.Clear(); + _playlist.AddRange(items); + _logger.LogDebug("{0} - Playing {1} items", _session.DeviceName, _playlist.Count); - await SetPlaylistIndex(0).ConfigureAwait(false); + await SetPlaylistIndex(0, cancellationToken).ConfigureAwait(false); return true; } - private async Task SetPlaylistIndex(int index) + private async Task SetPlaylistIndex(int index, CancellationToken cancellationToken = default) { - if (index < 0 || index >= Playlist.Count) + if (index < 0 || index >= _playlist.Count) { - Playlist.Clear(); - await _device.SetStop(CancellationToken.None); + _playlist.Clear(); + await _device.SetStop(cancellationToken).ConfigureAwait(false); return; } _currentPlaylistIndex = index; - var currentitem = Playlist[index]; + var currentitem = _playlist[index]; - await _device.SetAvTransport(currentitem.StreamUrl, GetDlnaHeaders(currentitem), currentitem.Didl, CancellationToken.None); + await _device.SetAvTransport(currentitem.StreamUrl, GetDlnaHeaders(currentitem), currentitem.Didl, cancellationToken).ConfigureAwait(false); var streamInfo = currentitem.StreamInfo; if (streamInfo.StartPositionTicks > 0 && EnableClientSideSeek(streamInfo)) @@ -602,10 +612,7 @@ namespace Emby.Dlna.PlayTo } } - #endregion - - private bool _disposed; - + /// public void Dispose() { Dispose(true); @@ -624,19 +631,17 @@ namespace Emby.Dlna.PlayTo _device.Dispose(); } - _device.PlaybackStart -= _device_PlaybackStart; - _device.PlaybackProgress -= _device_PlaybackProgress; - _device.PlaybackStopped -= _device_PlaybackStopped; - _device.MediaChanged -= _device_MediaChanged; - _deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft; + _device.PlaybackStart -= OnDevicePlaybackStart; + _device.PlaybackProgress -= OnDevicePlaybackProgress; + _device.PlaybackStopped -= DevicePlaybackStopped; + _device.MediaChanged -= OnDeviceMediaChanged; + _deviceDiscovery.DeviceLeft -= OnDeviceDiscoveryDeviceLeft; _device.OnDeviceUnavailable = null; _device = null; _disposed = true; } - private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US")); - private Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken) { if (Enum.TryParse(command.Name, true, out GeneralCommandType commandType)) @@ -713,7 +718,7 @@ namespace Emby.Dlna.PlayTo if (info.Item != null) { - var newPosition = GetProgressPositionTicks(media, info) ?? 0; + var newPosition = GetProgressPositionTicks(info) ?? 0; var user = !_session.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(_session.UserId) : null; var newItem = CreatePlaylistItem(info.Item, user, newPosition, info.MediaSourceId, newIndex, info.SubtitleStreamIndex); @@ -738,7 +743,7 @@ namespace Emby.Dlna.PlayTo if (info.Item != null) { - var newPosition = GetProgressPositionTicks(media, info) ?? 0; + var newPosition = GetProgressPositionTicks(info) ?? 0; var user = !_session.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(_session.UserId) : null; var newItem = CreatePlaylistItem(info.Item, user, newPosition, info.MediaSourceId, info.AudioStreamIndex, newIndex); @@ -852,8 +857,11 @@ namespace Emby.Dlna.PlayTo return request; } - var index = url.IndexOf('?'); - if (index == -1) return request; + var index = url.IndexOf('?', StringComparison.Ordinal); + if (index == -1) + { + return request; + } var query = url.Substring(index + 1); Dictionary values = QueryHelpers.ParseQuery(query).ToDictionary(kv => kv.Key, kv => kv.Value.ToString()); diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index b8a47c44cf..bbedd1485c 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -23,7 +23,7 @@ using Microsoft.Extensions.Logging; namespace Emby.Dlna.PlayTo { - public class PlayToManager : IDisposable + public sealed class PlayToManager : IDisposable { private readonly ILogger _logger; private readonly ISessionManager _sessionManager; @@ -231,6 +231,7 @@ namespace Emby.Dlna.PlayTo } } + /// public void Dispose() { _deviceDiscovery.DeviceDiscovered -= OnDeviceDiscoveryDeviceDiscovered; @@ -244,6 +245,9 @@ namespace Emby.Dlna.PlayTo } + _sessionLock.Dispose(); + _disposeCancellationTokenSource.Dispose(); + _disposed = true; } } diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs index dab5f29bd8..8c13620075 100644 --- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs +++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs @@ -32,18 +32,15 @@ namespace Emby.Dlna.PlayTo DeviceService service, string command, string postData, - bool logRequest = true, - string header = null) + string header = null, + CancellationToken cancellationToken = default) { - var cancellationToken = CancellationToken.None; - var url = NormalizeServiceUrl(baseUrl, service.ControlUrl); using (var response = await PostSoapDataAsync( url, $"\"{service.ServiceType}#{command}\"", postData, header, - logRequest, cancellationToken) .ConfigureAwait(false)) using (var stream = response.Content) @@ -63,7 +60,7 @@ namespace Emby.Dlna.PlayTo return serviceUrl; } - if (!serviceUrl.StartsWith("/")) + if (!serviceUrl.StartsWith("/", StringComparison.Ordinal)) { serviceUrl = "/" + serviceUrl; } @@ -127,7 +124,6 @@ namespace Emby.Dlna.PlayTo string soapAction, string postData, string header, - bool logRequest, CancellationToken cancellationToken) { if (soapAction[0] != '\"') diff --git a/Emby.Notifications/Api/NotificationsService.cs b/Emby.Notifications/Api/NotificationsService.cs index 67401c1f5b..788750796d 100644 --- a/Emby.Notifications/Api/NotificationsService.cs +++ b/Emby.Notifications/Api/NotificationsService.cs @@ -134,19 +134,19 @@ namespace Emby.Notifications.Api _userManager = userManager; } - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetNotificationTypes request) { return _notificationManager.GetNotificationTypes(); } - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetNotificationServices request) { return _notificationManager.GetNotificationServices().ToList(); } - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetNotificationsSummary request) { return new NotificationsSummary @@ -170,17 +170,17 @@ namespace Emby.Notifications.Api return _notificationManager.SendNotification(notification, CancellationToken.None); } - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public void Post(MarkRead request) { } - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public void Post(MarkUnread request) { } - [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request")] + [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "request", Justification = "Required for ServiceStack")] public object Get(GetNotifications request) { return new NotificationResult(); From 8a566dfe73a918bb234540d6def57cf4d32332c2 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 2 Apr 2020 17:07:37 +0200 Subject: [PATCH 02/13] Fix build --- Emby.Dlna/Emby.Dlna.csproj | 2 +- Emby.Dlna/PlayTo/Device.cs | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index 43c3c1384f..bc6df75720 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -15,7 +15,7 @@ netstandard2.1 false true - true + true diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 0d47dc929f..1611380663 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -520,8 +520,11 @@ namespace Emby.Dlna.PlayTo return; } - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true) - .ConfigureAwait(false); + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + Properties.BaseUrl, + service, + command.Name, + rendererCommands.BuildPost(command, service.ServiceType)).ConfigureAwait(false); if (result == null || result.Document == null) { @@ -566,8 +569,11 @@ namespace Emby.Dlna.PlayTo return; } - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), true) - .ConfigureAwait(false); + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + Properties.BaseUrl, + service, + command.Name, + rendererCommands.BuildPost(command, service.ServiceType)).ConfigureAwait(false); if (result == null || result.Document == null) return; @@ -599,7 +605,6 @@ namespace Emby.Dlna.PlayTo command.Name, avCommands.BuildPost(command, service.ServiceType), - false, cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null) @@ -637,8 +642,11 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false) - .ConfigureAwait(false); + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + Properties.BaseUrl, + service, + command.Name, + rendererCommands.BuildPost(command, service.ServiceType)).ConfigureAwait(false); if (result == null || result.Document == null) { @@ -700,8 +708,11 @@ namespace Emby.Dlna.PlayTo var rendererCommands = await GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); - var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, rendererCommands.BuildPost(command, service.ServiceType), false) - .ConfigureAwait(false); + var result = await new SsdpHttpClient(_httpClient).SendCommandAsync( + Properties.BaseUrl, + service, + command.Name, + rendererCommands.BuildPost(command, service.ServiceType)).ConfigureAwait(false); if (result == null || result.Document == null) { From 231c1e519fa7a1b4071a1742ff413a84ba025137 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 3 Apr 2020 16:44:40 +0200 Subject: [PATCH 03/13] Update Emby.Dlna.csproj --- Emby.Dlna/Emby.Dlna.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index bc6df75720..0cabe43d51 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -22,7 +22,7 @@ - + From f6c9a44703cfee7c99b333db8c06160c50c67754 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 3 Apr 2020 16:46:14 +0200 Subject: [PATCH 04/13] Update Device.cs --- Emby.Dlna/PlayTo/Device.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 1611380663..5ccf88be25 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -573,7 +573,8 @@ namespace Emby.Dlna.PlayTo Properties.BaseUrl, service, command.Name, - rendererCommands.BuildPost(command, service.ServiceType)).ConfigureAwait(false); + rendererCommands.BuildPost(command, service.ServiceType), + cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null) return; From 3161e85f7678aab603eb2f0180a2b911207e477e Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Fri, 3 Apr 2020 17:30:01 +0200 Subject: [PATCH 05/13] Address comments --- Emby.Dlna/Didl/DidlBuilder.cs | 27 +++++++++---------- Emby.Dlna/PlayTo/Device.cs | 6 ++--- Emby.Dlna/PlayTo/PlayToController.cs | 6 ++--- .../Data/SqliteItemRepository.cs | 10 +++++++ .../Entities/InternalPeopleQuery.cs | 7 +++++ 5 files changed, 35 insertions(+), 21 deletions(-) diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 255f2c9882..b37bc30610 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -782,22 +782,26 @@ namespace Emby.Dlna.Didl private void AddPeople(BaseItem item, XmlWriter writer) { + if (!item.SupportsPeople) + { + return; + } + var types = new[] { PersonType.Director, PersonType.Writer, PersonType.Producer, PersonType.Composer, - "Creator" + "creator" }; - var people = _libraryManager.GetPeople(item); - - var index = 0; - - // Seeing some LG models locking up due content with large lists of people - // The actual issue might just be due to processing a more metadata than it can handle - var limit = 6; + var people = _libraryManager.GetPeople( + new InternalPeopleQuery + { + ItemId = item.Id, + Limit = 6 + }); foreach (var actor in people) { @@ -805,13 +809,6 @@ namespace Emby.Dlna.Didl ?? PersonType.Actor; AddValue(writer, "upnp", type.ToLowerInvariant(), actor.Name, NS_UPNP); - - index++; - - if (index >= limit) - { - break; - } } } diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 5ccf88be25..a06c863fd0 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -604,8 +604,7 @@ namespace Emby.Dlna.PlayTo Properties.BaseUrl, service, command.Name, - avCommands.BuildPost(command, - service.ServiceType), + avCommands.BuildPost(command, service.ServiceType), cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null) @@ -647,7 +646,8 @@ namespace Emby.Dlna.PlayTo Properties.BaseUrl, service, command.Name, - rendererCommands.BuildPost(command, service.ServiceType)).ConfigureAwait(false); + rendererCommands.BuildPost(command, service.ServiceType), + cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null) { diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 9ee6986b43..43e9830540 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -96,7 +96,7 @@ namespace Emby.Dlna.PlayTo _device.OnDeviceUnavailable = OnDeviceUnavailable; _device.PlaybackStart += OnDevicePlaybackStart; _device.PlaybackProgress += OnDevicePlaybackProgress; - _device.PlaybackStopped += DevicePlaybackStopped; + _device.PlaybackStopped += OnDevicePlaybackStopped; _device.MediaChanged += OnDeviceMediaChanged; _device.Start(); @@ -162,7 +162,7 @@ namespace Emby.Dlna.PlayTo } } - private async void DevicePlaybackStopped(object sender, PlaybackStoppedEventArgs e) + private async void OnDevicePlaybackStopped(object sender, PlaybackStoppedEventArgs e) { if (_disposed) { @@ -633,7 +633,7 @@ namespace Emby.Dlna.PlayTo _device.PlaybackStart -= OnDevicePlaybackStart; _device.PlaybackProgress -= OnDevicePlaybackProgress; - _device.PlaybackStopped -= DevicePlaybackStopped; + _device.PlaybackStopped -= OnDevicePlaybackStopped; _device.MediaChanged -= OnDeviceMediaChanged; _deviceDiscovery.DeviceLeft -= OnDeviceDiscoveryDeviceLeft; _device.OnDeviceUnavailable = null; diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index e3242f7b4f..e360b790c6 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -5011,6 +5011,11 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type commandText += " order by ListOrder"; + if (query.Limit > 0) + { + commandText += "LIMIT " + query.Limit; + } + using (var connection = GetConnection(true)) { var list = new List(); @@ -5049,6 +5054,11 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type commandText += " order by ListOrder"; + if (query.Limit > 0) + { + commandText += "LIMIT " + query.Limit; + } + using (var connection = GetConnection(true)) { var list = new List(); diff --git a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs index 1613531b5c..41d8a4c83e 100644 --- a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs @@ -4,11 +4,18 @@ namespace MediaBrowser.Controller.Entities { public class InternalPeopleQuery { + public int Limit { get; set; } + public Guid ItemId { get; set; } + public string[] PersonTypes { get; set; } + public string[] ExcludePersonTypes { get; set; } + public int? MaxListOrder { get; set; } + public Guid AppearsInItemId { get; set; } + public string NameContains { get; set; } public InternalPeopleQuery() From cbb67970436e8fe073cbe28f7a2fb4217a2f2524 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 3 Apr 2020 22:41:14 +0200 Subject: [PATCH 06/13] Update SqliteItemRepository.cs --- Emby.Server.Implementations/Data/SqliteItemRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index e360b790c6..052c4ef8c9 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -5056,7 +5056,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type if (query.Limit > 0) { - commandText += "LIMIT " + query.Limit; + commandText += " LIMIT " + query.Limit; } using (var connection = GetConnection(true)) From d6224ddedab49c8a4c95176de4fece1c73348e09 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 3 Apr 2020 22:44:18 +0200 Subject: [PATCH 07/13] Update InternalPeopleQuery.cs --- MediaBrowser.Controller/Entities/InternalPeopleQuery.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs index 41d8a4c83e..79b4d9444b 100644 --- a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs @@ -4,6 +4,9 @@ namespace MediaBrowser.Controller.Entities { public class InternalPeopleQuery { + /// + /// Gets or sets the maximum of items the query should return. + /// public int Limit { get; set; } public Guid ItemId { get; set; } From 0b21494999f8a7e70cc137152e94c40a9b1c666b Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 3 Apr 2020 23:13:04 +0200 Subject: [PATCH 08/13] Update Emby.Server.Implementations/Data/SqliteItemRepository.cs Co-Authored-By: Vasily --- Emby.Server.Implementations/Data/SqliteItemRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 052c4ef8c9..46c6d55200 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -5013,7 +5013,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type if (query.Limit > 0) { - commandText += "LIMIT " + query.Limit; + commandText += " LIMIT " + query.Limit; } using (var connection = GetConnection(true)) From ad0e2e42e62e4fc5cc79bb5f53253b01b7c8b15a Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 3 Apr 2020 23:13:45 +0200 Subject: [PATCH 09/13] Update Device.cs --- Emby.Dlna/PlayTo/Device.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index a06c863fd0..b269869da4 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -524,7 +524,8 @@ namespace Emby.Dlna.PlayTo Properties.BaseUrl, service, command.Name, - rendererCommands.BuildPost(command, service.ServiceType)).ConfigureAwait(false); + rendererCommands.BuildPost(command, service.ServiceType), + cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null) { From 4cacfd5997c31c151bfa40edf8defb0a0ec60e61 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 3 Apr 2020 23:20:04 +0200 Subject: [PATCH 10/13] Update DidlBuilder.cs --- Emby.Dlna/Didl/DidlBuilder.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index b37bc30610..3be4efbc88 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -796,6 +796,8 @@ namespace Emby.Dlna.Didl "creator" }; + // Seeing some LG models locking up due content with large lists of people + // The actual issue might just be due to processing a more metadata than it can handle var people = _libraryManager.GetPeople( new InternalPeopleQuery { From 91b17e72894c2b078d13c88a6a73ba7935d38c06 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sat, 4 Apr 2020 00:21:26 +0200 Subject: [PATCH 11/13] Update Device.cs --- Emby.Dlna/PlayTo/Device.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index b269869da4..d940856aef 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -714,7 +714,8 @@ namespace Emby.Dlna.PlayTo Properties.BaseUrl, service, command.Name, - rendererCommands.BuildPost(command, service.ServiceType)).ConfigureAwait(false); + rendererCommands.BuildPost(command, service.ServiceType) + cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null) { From 0951dc632bf033ddd07462e0c6958e84e6d24627 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sat, 4 Apr 2020 00:21:54 +0200 Subject: [PATCH 12/13] Update MediaBrowser.Controller/Entities/InternalPeopleQuery.cs Co-Authored-By: Mark Monteiro --- MediaBrowser.Controller/Entities/InternalPeopleQuery.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs index 79b4d9444b..dfa5816713 100644 --- a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs @@ -5,7 +5,7 @@ namespace MediaBrowser.Controller.Entities public class InternalPeopleQuery { /// - /// Gets or sets the maximum of items the query should return. + /// Gets or sets the maximum number of items the query should return. /// public int Limit { get; set; } From 64692af1a23dafba2e67620478ffeae078244070 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sat, 4 Apr 2020 00:24:36 +0200 Subject: [PATCH 13/13] Update Device.cs --- Emby.Dlna/PlayTo/Device.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index d940856aef..6abc3a82c3 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -714,7 +714,7 @@ namespace Emby.Dlna.PlayTo Properties.BaseUrl, service, command.Name, - rendererCommands.BuildPost(command, service.ServiceType) + rendererCommands.BuildPost(command, service.ServiceType), cancellationToken: cancellationToken).ConfigureAwait(false); if (result == null || result.Document == null)