diff --git a/src/Jellyfin.Plugin.Dlna/Didl/DidlBuilder.cs b/src/Jellyfin.Plugin.Dlna/Didl/DidlBuilder.cs index 150fb49..9160d8a 100644 --- a/src/Jellyfin.Plugin.Dlna/Didl/DidlBuilder.cs +++ b/src/Jellyfin.Plugin.Dlna/Didl/DidlBuilder.cs @@ -239,6 +239,17 @@ public class DidlBuilder writer.WriteFullEndElement(); } + private string sanitize(string input) + { + var valid = input.Where(ch => System.Xml.XmlConvert.IsXmlChar(ch)).ToArray(); + if (valid.Length == input.Length) + { + return input; + } + _logger.LogInformation("Sanitized: {0} (was: {1})", valid, input.Where(ch => true).ToArray()); + return new string(valid); + } + private void AddVideoResource(XmlWriter writer, BaseItem video, string deviceId, Filter filter, StreamInfo? streamInfo = null) { if (streamInfo is null) @@ -1009,7 +1020,7 @@ public class DidlBuilder writer.WriteStartElement("upnp", "artist", NsUpnp); writer.WriteAttributeString("role", "AlbumArtist"); - writer.WriteString(name); + writer.WriteString(sanitize(name)); writer.WriteFullEndElement(); } @@ -1023,7 +1034,7 @@ public class DidlBuilder { try { - writer.WriteElementString(prefix, name, namespaceUri, value); + writer.WriteElementString(prefix, name, namespaceUri, sanitize(value)); } catch (XmlException ex) { diff --git a/src/Jellyfin.Plugin.Dlna/PlayTo/PlayToController.cs b/src/Jellyfin.Plugin.Dlna/PlayTo/PlayToController.cs index 4d822e2..9105d46 100644 --- a/src/Jellyfin.Plugin.Dlna/PlayTo/PlayToController.cs +++ b/src/Jellyfin.Plugin.Dlna/PlayTo/PlayToController.cs @@ -386,34 +386,38 @@ public class PlayToController : ISessionController, IDisposable ? null : _userManager.GetUserById(command.ControllingUserId); - var items = new List(); - foreach (var id in command.ItemIds) - { - AddItemFromId(id, items); - } - var startIndex = command.StartIndex ?? 0; - int len = items.Count - startIndex; - if (startIndex > 0) - { - items = items.GetRange(startIndex, len); - } - - var playlist = new PlaylistItem[len]; - - // Not nullable enabled - so this is required. - playlist[0] = CreatePlaylistItem( - items[0], - user, - command.StartPositionTicks ?? 0, - command.MediaSourceId ?? string.Empty, - command.AudioStreamIndex, - command.SubtitleStreamIndex); + var playlist = new List(); + var first = true; + foreach (var id in command.ItemIds) { + var item = _libraryManager.GetItemById(id); + if (item?.MediaType != MediaType.Audio && item?.MediaType != MediaType.Video) + { + continue; + } - for (int i = 1; i < len; i++) - { - playlist[i] = CreatePlaylistItem(items[i], user, 0, string.Empty, null, null); - } + if (startIndex > 0) { + startIndex -= 1; + continue; + } + + PlaylistItem? playlistItem = null; + try { + playlistItem = CreatePlaylistItem(item, user, + first ? (command.StartPositionTicks ?? 0) : 0, + first ? (command.MediaSourceId ?? string.Empty) : string.Empty, + first ? command.AudioStreamIndex : null, + first ? command.SubtitleStreamIndex : null); + } catch (System.NullReferenceException) { + _logger.LogError("{0}: could not create playlist item.", item.Path ?? ""); + } + first = false; + + if (playlistItem != null) + { + playlist.Add(playlistItem); + } + } _logger.LogDebug("{0} - Playlist created", _session.DeviceName); @@ -509,15 +513,6 @@ public class PlayToController : ISessionController, IDisposable return info.IsDirectStream; } - private void AddItemFromId(Guid id, List list) - { - var item = _libraryManager.GetItemById(id); - if (item?.MediaType == MediaType.Audio || item?.MediaType == MediaType.Video) - { - list.Add(item); - } - } - private PlaylistItem CreatePlaylistItem( BaseItem item, User? user,