diff --git a/MediaBrowser.Api/PlaylistService.cs b/MediaBrowser.Api/PlaylistService.cs
index b4d2e2f0f2..2e3d38f465 100644
--- a/MediaBrowser.Api/PlaylistService.cs
+++ b/MediaBrowser.Api/PlaylistService.cs
@@ -41,6 +41,9 @@ namespace MediaBrowser.Api
{
[ApiMember(Name = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get; set; }
+
+ [ApiMember(Name = "EntryIds", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
+ public string EntryIds { get; set; }
}
[Route("/Playlists/{Id}/Items", "GET", Summary = "Gets the original items of a playlist")]
@@ -122,9 +125,9 @@ namespace MediaBrowser.Api
public void Delete(RemoveFromPlaylist request)
{
- //var task = _playlistManager.RemoveFromPlaylist(request.Id, request.Ids.Split(',').Select(i => new Guid(i)));
+ var task = _playlistManager.RemoveFromPlaylist(request.Id, request.EntryIds.Split(','));
- //Task.WaitAll(task);
+ Task.WaitAll(task);
}
public object Get(GetPlaylistItems request)
diff --git a/MediaBrowser.Controller/Entities/LinkedChild.cs b/MediaBrowser.Controller/Entities/LinkedChild.cs
index c77fe18c45..eb94b37dbc 100644
--- a/MediaBrowser.Controller/Entities/LinkedChild.cs
+++ b/MediaBrowser.Controller/Entities/LinkedChild.cs
@@ -13,6 +13,9 @@ namespace MediaBrowser.Controller.Entities
public string ItemType { get; set; }
public int? ItemYear { get; set; }
+ [IgnoreDataMember]
+ public string Id { get; set; }
+
///
/// Serves as a cache
///
@@ -27,6 +30,11 @@ namespace MediaBrowser.Controller.Entities
Type = LinkedChildType.Manual
};
}
+
+ public LinkedChild()
+ {
+ Id = Guid.NewGuid().ToString("N");
+ }
}
public enum LinkedChildType
diff --git a/MediaBrowser.Controller/Playlists/IPlaylistManager.cs b/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
index 2923c11c51..f5939ad969 100644
--- a/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
+++ b/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
@@ -32,9 +32,9 @@ namespace MediaBrowser.Controller.Playlists
/// Removes from playlist.
///
/// The playlist identifier.
- /// The indeces.
+ /// The entry ids.
/// Task.
- Task RemoveFromPlaylist(string playlistId, IEnumerable indeces);
+ Task RemoveFromPlaylist(string playlistId, IEnumerable entryIds);
///
/// Gets the playlists folder.
diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
index cbdd427afb..a5a97567a9 100644
--- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs
+++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Net;
+using System.IO;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
@@ -13,6 +14,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml;
+using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Dlna.Didl
{
@@ -615,9 +617,11 @@ namespace MediaBrowser.Dlna.Didl
}
AddImageResElement(item, element, 4096, 4096, "jpg");
+ AddImageResElement(item, element, 4096, 4096, "png");
AddImageResElement(item, element, 1024, 768, "jpg");
AddImageResElement(item, element, 640, 480, "jpg");
AddImageResElement(item, element, 160, 160, "jpg");
+ AddImageResElement(item, element, 160, 160, "png");
}
private void AddImageResElement(BaseItem item, XmlElement element, int maxWidth, int maxHeight, string format)
@@ -640,7 +644,7 @@ namespace MediaBrowser.Dlna.Didl
var width = albumartUrlInfo.Width;
var height = albumartUrlInfo.Height;
- var contentFeatures = new ContentFeatureBuilder(_profile).BuildImageHeader(format, width, height);
+ var contentFeatures = new ContentFeatureBuilder(_profile).BuildImageHeader(format, width, height, imageInfo.IsDirectStream);
res.SetAttribute("protocolInfo", String.Format(
"http-get:*:{0}:{1}",
@@ -648,6 +652,14 @@ namespace MediaBrowser.Dlna.Didl
contentFeatures
));
+ res.SetAttribute("colorDepth", "24");
+
+ if (imageInfo.IsDirectStream)
+ {
+ // TODO: Add file size
+ //res.SetAttribute("size", imageInfo.Size.Value.ToString(_usCulture));
+ }
+
if (width.HasValue && height.HasValue)
{
res.SetAttribute("resolution", string.Format("{0}x{1}", width.Value, height.Value));
@@ -722,7 +734,8 @@ namespace MediaBrowser.Dlna.Didl
Type = type,
ImageTag = tag,
Width = width,
- Height = height
+ Height = height,
+ File = imageInfo.Path
};
}
@@ -734,6 +747,10 @@ namespace MediaBrowser.Dlna.Didl
internal int? Width;
internal int? Height;
+
+ internal bool IsDirectStream;
+
+ internal string File;
}
class ImageUrlInfo
@@ -758,6 +775,8 @@ namespace MediaBrowser.Dlna.Didl
var width = info.Width;
var height = info.Height;
+ info.IsDirectStream = false;
+
if (width.HasValue && height.HasValue)
{
var newSize = DrawingUtils.Resize(new ImageSize
@@ -769,6 +788,18 @@ namespace MediaBrowser.Dlna.Didl
width = Convert.ToInt32(newSize.Width);
height = Convert.ToInt32(newSize.Height);
+
+ var inputFormat = (Path.GetExtension(info.File) ?? string.Empty)
+ .TrimStart('.')
+ .Replace("jpeg", "jpg", StringComparison.OrdinalIgnoreCase);
+
+ var normalizedFormat = format
+ .Replace("jpeg", "jpg", StringComparison.OrdinalIgnoreCase);
+
+ if (string.Equals(inputFormat, normalizedFormat, StringComparison.OrdinalIgnoreCase))
+ {
+ info.IsDirectStream = maxWidth >= width.Value && maxHeight >= height.Value;
+ }
}
return new ImageUrlInfo
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
index 5417c5b82c..c25e93c388 100644
--- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
+++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
@@ -14,12 +14,13 @@ namespace MediaBrowser.Model.Dlna
public string BuildImageHeader(string container,
int? width,
- int? height)
+ int? height,
+ bool isDirectStream)
{
string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetImageOrgOpValue();
// 0 = native, 1 = transcoded
- const string orgCi = ";DLNA.ORG_CI=0";
+ var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
DlnaFlags flagValue = DlnaFlags.StreamingTransferMode |
DlnaFlags.BackgroundTransferMode |
diff --git a/MediaBrowser.Model/Dlna/DlnaMaps.cs b/MediaBrowser.Model/Dlna/DlnaMaps.cs
index 036c1fc749..9a84eb1952 100644
--- a/MediaBrowser.Model/Dlna/DlnaMaps.cs
+++ b/MediaBrowser.Model/Dlna/DlnaMaps.cs
@@ -48,7 +48,7 @@
orgOp += "0";
// Byte-based seeking only possible when not transcoding
- orgOp += "1";
+ orgOp += "0";
return orgOp;
}
diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
index 3b4cc30acd..5101bbe5af 100644
--- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
+++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
@@ -385,7 +385,7 @@ namespace MediaBrowser.Model.Dlna
return ResolveImageJPGFormat(width, height);
if (StringHelper.EqualsIgnoreCase(container, "png"))
- return MediaFormatProfile.PNG_LRG;
+ return ResolveImagePNGFormat(width, height);
if (StringHelper.EqualsIgnoreCase(container, "gif"))
return MediaFormatProfile.GIF_LRG;
@@ -401,7 +401,7 @@ namespace MediaBrowser.Model.Dlna
if (width.HasValue && height.HasValue)
{
if ((width.Value <= 160) && (height.Value <= 160))
- return MediaFormatProfile.JPEG_SM;
+ return MediaFormatProfile.JPEG_TN;
if ((width.Value <= 640) && (height.Value <= 480))
return MediaFormatProfile.JPEG_SM;
@@ -416,5 +416,16 @@ namespace MediaBrowser.Model.Dlna
return MediaFormatProfile.JPEG_SM;
}
+
+ private MediaFormatProfile ResolveImagePNGFormat(int? width, int? height)
+ {
+ if (width.HasValue && height.HasValue)
+ {
+ if ((width.Value <= 160) && (height.Value <= 160))
+ return MediaFormatProfile.PNG_TN;
+ }
+
+ return MediaFormatProfile.PNG_LRG;
+ }
}
}
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index a38a6aff8c..563a2f19af 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -133,14 +133,21 @@ namespace MediaBrowser.Model.Dlna
public List GetExternalSubtitles(string baseUrl)
{
+ if (string.IsNullOrEmpty(baseUrl))
+ {
+ throw new ArgumentNullException(baseUrl);
+ }
+
+ List list = new List();
+
if (SubtitleDeliveryMethod != SubtitleDeliveryMethod.External)
{
- return null;
+ return list;
}
if (!SubtitleStreamIndex.HasValue)
{
- return null;
+ return list;
}
// HLS will preserve timestamps so we can just grab the full subtitle stream
@@ -156,8 +163,6 @@ namespace MediaBrowser.Model.Dlna
StringHelper.ToStringCultureInvariant(startPositionTicks),
SubtitleFormat);
- List list = new List();
-
foreach (MediaStream stream in MediaSource.MediaStreams)
{
if (stream.Type == MediaStreamType.Subtitle && stream.Index == SubtitleStreamIndex.Value)
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
index ad4ba7dc0f..1c207b0a2c 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
@@ -334,5 +334,6 @@
"OptionNewPlaylist": "New playlist...",
"MessageAddedToPlaylistSuccess": "Ok",
"ButtonViewSeriesRecording": "View series recording",
- "ValueOriginalAirDate": "Original air date: {0}"
+ "ValueOriginalAirDate": "Original air date: {0}",
+ "ButtonRemoveFromPlaylist": "Remove from playlist"
}
diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
index 79b673283d..6ab306c0ba 100644
--- a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
+++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
@@ -190,9 +190,29 @@ namespace MediaBrowser.Server.Implementations.Playlists
}, CancellationToken.None).ConfigureAwait(false);
}
- public Task RemoveFromPlaylist(string playlistId, IEnumerable indeces)
+ public async Task RemoveFromPlaylist(string playlistId, IEnumerable entryIds)
{
- throw new NotImplementedException();
+ var playlist = _libraryManager.GetItemById(playlistId) as Playlist;
+
+ if (playlist == null)
+ {
+ throw new ArgumentException("No Playlist exists with the supplied Id");
+ }
+
+ var children = playlist.LinkedChildren.ToList();
+
+ var idList = entryIds.ToList();
+
+ var removals = children.Where(i => idList.Contains(i.Id));
+
+ playlist.LinkedChildren = children.Except(removals)
+ .ToList();
+
+ await playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
+ await playlist.RefreshMetadata(new MetadataRefreshOptions
+ {
+ ForceSave = true
+ }, CancellationToken.None).ConfigureAwait(false);
}
public Folder GetPlaylistsFolder(string userId)
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index ce34a1b309..78218d9ce7 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common.Internal
- 3.0.422
+ 3.0.423
MediaBrowser.Common.Internal
Luke
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.
Copyright © Media Browser 2013
-
+
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 5f09afa688..2a0fbc9af9 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.422
+ 3.0.423
MediaBrowser.Common
Media Browser Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec
index df036cc98f..2724c2088f 100644
--- a/Nuget/MediaBrowser.Model.Signed.nuspec
+++ b/Nuget/MediaBrowser.Model.Signed.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Model.Signed
- 3.0.422
+ 3.0.423
MediaBrowser.Model - Signed Edition
Media Browser Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index ee54f248ba..0f48a19769 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.422
+ 3.0.423
Media Browser.Server.Core
Media Browser Team
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains core components required to build plugins for Media Browser Server.
Copyright © Media Browser 2013
-
+