diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index ec6ca7737b..7289ac0862 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -714,8 +714,10 @@ namespace MediaBrowser.Api.Playback
/// true if the specified stream is H264; otherwise, false.
protected bool IsH264(MediaStream stream)
{
- return stream.Codec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 ||
- stream.Codec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1;
+ var codec = stream.Codec ?? string.Empty;
+
+ return codec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 ||
+ codec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1;
}
///
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index bea4ba37ed..30ba25ae47 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -367,16 +367,6 @@ namespace MediaBrowser.Api.Playback.Hls
{
var state = await GetState(request, CancellationToken.None).ConfigureAwait(false);
- if (string.Equals(request.AudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
- {
- throw new ArgumentException("Audio codec copy is not allowed here.");
- }
-
- if (string.Equals(request.VideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
- {
- throw new ArgumentException("Video codec copy is not allowed here.");
- }
-
if (string.IsNullOrEmpty(request.MediaSourceId))
{
throw new ArgumentException("MediaSourceId is required");
@@ -638,7 +628,7 @@ namespace MediaBrowser.Api.Playback.Hls
// See if we can save come cpu cycles by avoiding encoding
if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase))
{
- return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
+ return state.VideoStream != null && IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
}
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
index 02acf7e718..06fa4065c2 100644
--- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
@@ -139,7 +139,7 @@ namespace MediaBrowser.Api.Playback.Hls
// See if we can save come cpu cycles by avoiding encoding
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
{
- return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
+ return state.VideoStream != null && IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
}
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs
index 09bf6e2328..81f1d70d39 100644
--- a/MediaBrowser.Common/Net/HttpRequestOptions.cs
+++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs
@@ -94,6 +94,8 @@ namespace MediaBrowser.Common.Net
public CacheMode CacheMode { get; set; }
public TimeSpan CacheLength { get; set; }
+ public int TimeoutMs { get; set; }
+
private string GetHeaderValue(string name)
{
string value;
@@ -115,6 +117,8 @@ namespace MediaBrowser.Common.Net
LogRequest = true;
CacheMode = CacheMode.None;
+
+ TimeoutMs = 20000;
}
public void SetPostData(IDictionary values)
diff --git a/MediaBrowser.Controller/Library/IMetadataSaver.cs b/MediaBrowser.Controller/Library/IMetadataSaver.cs
index ce8feb4c6c..f13cf45879 100644
--- a/MediaBrowser.Controller/Library/IMetadataSaver.cs
+++ b/MediaBrowser.Controller/Library/IMetadataSaver.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Providers;
using System.Threading;
namespace MediaBrowser.Controller.Library
diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
index 3f9ce66c5c..b92a4174ef 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Common.Extensions;
+using System.Linq;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Dlna.Didl;
@@ -85,7 +87,9 @@ namespace MediaBrowser.Dlna.ContentDirectory
{
var id = sparams["ObjectID"];
- var item = GetItemFromObjectId(id, user);
+ var serverItem = GetItemFromObjectId(id, user);
+
+ var item = serverItem.Item;
var newbookmark = int.Parse(sparams["PosSecond"], _usCulture);
@@ -173,49 +177,48 @@ namespace MediaBrowser.Dlna.ContentDirectory
//didl.SetAttribute("xmlns:sec", NS_SEC);
result.AppendChild(didl);
- var item = GetItemFromObjectId(id, user);
+ var serverItem = GetItemFromObjectId(id, user);
+ var item = serverItem.Item;
var totalCount = 0;
if (string.Equals(flag, "BrowseMetadata"))
{
- var folder = item as Folder;
-
- if (folder == null)
+ if (item.IsFolder || serverItem.StubType.HasValue)
{
- result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, item, null, deviceId, filter));
+ var childrenResult = (await GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requested).ConfigureAwait(false));
+ totalCount = childrenResult.TotalRecordCount;
+
+ result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, item, serverItem.StubType, null, totalCount, filter, id));
}
else
{
- var childrenResult = (await GetUserItems(folder, user, sortCriteria, start, requested).ConfigureAwait(false));
- totalCount = childrenResult.TotalRecordCount;
-
- result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, folder, totalCount, filter, id));
+ result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, item, null, null, deviceId, filter));
}
+
provided++;
}
else
{
- var folder = (Folder)item;
-
- var childrenResult = (await GetUserItems(folder, user, sortCriteria, start, requested).ConfigureAwait(false));
+ var childrenResult = (await GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requested).ConfigureAwait(false));
totalCount = childrenResult.TotalRecordCount;
provided = childrenResult.Items.Length;
foreach (var i in childrenResult.Items)
{
- if (i.IsFolder)
+ var displayStubType = GetDisplayStubType(i, serverItem.Item);
+
+ if (i.IsFolder || displayStubType.HasValue)
{
- var f = (Folder)i;
- var childCount = (await GetUserItems(f, user, sortCriteria, null, 0).ConfigureAwait(false))
+ var childCount = (await GetUserItems(i, displayStubType, user, sortCriteria, null, 0).ConfigureAwait(false))
.TotalRecordCount;
- result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, f, childCount, filter));
+ result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, i, displayStubType, item, childCount, filter));
}
else
{
- result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, folder, deviceId, filter));
+ result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, item, serverItem.StubType, deviceId, filter));
}
}
}
@@ -231,6 +234,24 @@ namespace MediaBrowser.Dlna.ContentDirectory
};
}
+ private StubType? GetDisplayStubType(BaseItem item, BaseItem context)
+ {
+ if (context == null || context.IsFolder)
+ {
+ var movie = item as Movie;
+ if (movie != null)
+ {
+ if (movie.LocalTrailerIds.Count > 0 ||
+ movie.SpecialFeatureIds.Count > 0)
+ {
+ return StubType.Folder;
+ }
+ }
+ }
+
+ return null;
+ }
+
private async Task>> HandleSearch(Headers sparams, User user, string deviceId)
{
var searchCriteria = new SearchCriteria(sparams.GetValueOrDefault("SearchCriteria", ""));
@@ -269,9 +290,11 @@ namespace MediaBrowser.Dlna.ContentDirectory
result.AppendChild(didl);
- var folder = (Folder)GetItemFromObjectId(sparams["ContainerID"], user);
+ var serverItem = GetItemFromObjectId(sparams["ContainerID"], user);
- var childrenResult = (await GetChildrenSorted(folder, user, searchCriteria, sortCriteria, start, requested).ConfigureAwait(false));
+ var item = serverItem.Item;
+
+ var childrenResult = (await GetChildrenSorted(item, user, searchCriteria, sortCriteria, start, requested).ConfigureAwait(false));
var totalCount = childrenResult.TotalRecordCount;
@@ -281,15 +304,14 @@ namespace MediaBrowser.Dlna.ContentDirectory
{
if (i.IsFolder)
{
- var f = (Folder)i;
- var childCount = (await GetChildrenSorted(f, user, searchCriteria, sortCriteria, null, 0).ConfigureAwait(false))
+ var childCount = (await GetChildrenSorted(i, user, searchCriteria, sortCriteria, null, 0).ConfigureAwait(false))
.TotalRecordCount;
- result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, f, childCount, filter));
+ result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, i, null, item, childCount, filter));
}
else
{
- result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, folder, deviceId, filter));
+ result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, item, serverItem.StubType, deviceId, filter));
}
}
@@ -304,8 +326,10 @@ namespace MediaBrowser.Dlna.ContentDirectory
};
}
- private async Task> GetChildrenSorted(Folder folder, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit)
+ private async Task> GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit)
{
+ var folder = (Folder)item;
+
var sortOrders = new List();
if (!folder.IsPreSorted)
{
@@ -340,7 +364,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
//items = items.OfType();
isFolder = true;
}
-
+
return await folder.GetItems(new InternalItemsQuery
{
Limit = limit,
@@ -356,8 +380,20 @@ namespace MediaBrowser.Dlna.ContentDirectory
}).ConfigureAwait(false);
}
- private async Task> GetUserItems(Folder folder, User user, SortCriteria sort, int? startIndex, int? limit)
+ private async Task> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit)
{
+ if (stubType.HasValue)
+ {
+ var movie = item as Movie;
+
+ if (movie != null)
+ {
+ return await GetMovieItems(movie).ConfigureAwait(false);
+ }
+ }
+
+ var folder = (Folder)item;
+
var sortOrders = new List();
if (!folder.IsPreSorted)
{
@@ -376,6 +412,23 @@ namespace MediaBrowser.Dlna.ContentDirectory
}).ConfigureAwait(false);
}
+ private Task> GetMovieItems(Movie item)
+ {
+ var list = new List();
+
+ list.Add(item);
+
+ list.AddRange(item.LocalTrailerIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
+ list.AddRange(item.SpecialFeatureIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
+ list.AddRange(item.ThemeVideoIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
+
+ return Task.FromResult(new QueryResult
+ {
+ Items = list.ToArray(),
+ TotalRecordCount = list.Count
+ });
+ }
+
private bool FilterUnsupportedContent(BaseItem i, User user)
{
// Unplayable
@@ -399,26 +452,50 @@ namespace MediaBrowser.Dlna.ContentDirectory
return true;
}
- private BaseItem GetItemFromObjectId(string id, User user)
+ private ServerItem GetItemFromObjectId(string id, User user)
{
return DidlBuilder.IsIdRoot(id)
- ? user.RootFolder
+ ? new ServerItem { Item = user.RootFolder }
: ParseItemId(id, user);
}
- private BaseItem ParseItemId(string id, User user)
+ private ServerItem ParseItemId(string id, User user)
{
Guid itemId;
+ StubType? stubType = null;
+
+ if (id.StartsWith("folder_", StringComparison.OrdinalIgnoreCase))
+ {
+ stubType = StubType.Folder;
+ id = id.Split(new[] { '_' }, 2)[1];
+ }
if (Guid.TryParse(id, out itemId))
{
- return _libraryManager.GetItemById(itemId);
+ var item = _libraryManager.GetItemById(itemId);
+
+ return new ServerItem
+ {
+ Item = item,
+ StubType = stubType
+ };
}
Logger.Error("Error parsing item Id: {0}. Returning user root folder.", id);
- return user.RootFolder;
+ return new ServerItem { Item = user.RootFolder };
}
}
+
+ internal class ServerItem
+ {
+ public BaseItem Item { get; set; }
+ public StubType? StubType { get; set; }
+ }
+
+ public enum StubType
+ {
+ Folder = 0
+ }
}
diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
index 6bc50b1ea9..912612d299 100644
--- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs
+++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
@@ -9,6 +9,7 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Playlists;
+using MediaBrowser.Dlna.ContentDirectory;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
@@ -63,25 +64,31 @@ namespace MediaBrowser.Dlna.Didl
result.AppendChild(didl);
- result.DocumentElement.AppendChild(GetItemElement(result, item, context, deviceId, filter, streamInfo));
+ result.DocumentElement.AppendChild(GetItemElement(result, item, context, null, deviceId, filter, streamInfo));
return result.DocumentElement.OuterXml;
}
- public XmlElement GetItemElement(XmlDocument doc, BaseItem item, BaseItem context, string deviceId, Filter filter, StreamInfo streamInfo = null)
+ public XmlElement GetItemElement(XmlDocument doc, BaseItem item, BaseItem context, StubType? contextStubType, string deviceId, Filter filter, StreamInfo streamInfo = null)
{
+ var clientId = GetClientId(item, null);
+
var element = doc.CreateElement(string.Empty, "item", NS_DIDL);
element.SetAttribute("restricted", "1");
- element.SetAttribute("id", item.Id.ToString("N"));
+ element.SetAttribute("id", clientId);
- if (item.Parent != null)
+ if (context != null)
{
- element.SetAttribute("parentID", item.Parent.Id.ToString("N"));
+ element.SetAttribute("parentID", GetClientId(context, contextStubType));
+ }
+ else if (item.Parent != null)
+ {
+ element.SetAttribute("parentID", GetClientId(item.Parent, null));
}
//AddBookmarkInfo(item, user, element);
- AddGeneralProperties(item, context, element, filter);
+ AddGeneralProperties(item, null, context, element, filter);
// refID?
// storeAttribute(itemNode, object, ClassProperties.REF_ID, false);
@@ -111,14 +118,14 @@ namespace MediaBrowser.Dlna.Didl
{
var sources = _user == null ? video.GetMediaSources(true).ToList() : video.GetMediaSources(true, _user).ToList();
- streamInfo = new StreamBuilder().BuildVideoItem(new VideoOptions
- {
- ItemId = video.Id.ToString("N"),
- MediaSources = sources,
- Profile = _profile,
- DeviceId = deviceId,
- MaxBitrate = _profile.MaxStreamingBitrate
- });
+ streamInfo = new StreamBuilder().BuildVideoItem(new VideoOptions
+ {
+ ItemId = GetClientId(video),
+ MediaSources = sources,
+ Profile = _profile,
+ DeviceId = deviceId,
+ MaxBitrate = _profile.MaxStreamingBitrate
+ });
}
var targetWidth = streamInfo.TargetWidth;
@@ -311,7 +318,7 @@ namespace MediaBrowser.Dlna.Didl
return item.Name;
}
-
+
private void AddAudioResource(XmlElement container, IHasMediaSources audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
{
var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
@@ -322,7 +329,7 @@ namespace MediaBrowser.Dlna.Didl
streamInfo = new StreamBuilder().BuildAudioItem(new AudioOptions
{
- ItemId = audio.Id.ToString("N"),
+ ItemId = GetClientId(audio),
MediaSources = sources,
Profile = _profile,
DeviceId = deviceId
@@ -403,8 +410,8 @@ namespace MediaBrowser.Dlna.Didl
public static bool IsIdRoot(string id)
{
- if (string.IsNullOrWhiteSpace(id) ||
-
+ if (string.IsNullOrWhiteSpace(id) ||
+
string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
// Samsung sometimes uses 1 as root
@@ -416,13 +423,15 @@ namespace MediaBrowser.Dlna.Didl
return false;
}
- public XmlElement GetFolderElement(XmlDocument doc, BaseItem folder, int childCount, Filter filter, string requestedId = null)
+ public XmlElement GetFolderElement(XmlDocument doc, BaseItem folder, StubType? stubType, BaseItem context, int childCount, Filter filter, string requestedId = null)
{
var container = doc.CreateElement(string.Empty, "container", NS_DIDL);
container.SetAttribute("restricted", "0");
container.SetAttribute("searchable", "1");
container.SetAttribute("childCount", childCount.ToString(_usCulture));
+ var clientId = GetClientId(folder, stubType);
+
if (string.Equals(requestedId, "0"))
{
container.SetAttribute("id", "0");
@@ -430,20 +439,20 @@ namespace MediaBrowser.Dlna.Didl
}
else
{
- container.SetAttribute("id", folder.Id.ToString("N"));
+ container.SetAttribute("id", clientId);
- var parent = folder.Parent;
+ var parent = context ?? folder.Parent;
if (parent == null)
{
container.SetAttribute("parentID", "0");
}
else
{
- container.SetAttribute("parentID", parent.Id.ToString("N"));
+ container.SetAttribute("parentID", GetClientId(parent, null));
}
}
- AddCommonFields(folder, null, container, filter);
+ AddCommonFields(folder, stubType, null, container, filter);
AddCover(folder, container);
@@ -466,10 +475,11 @@ namespace MediaBrowser.Dlna.Didl
/// Adds fields used by both items and folders
///
/// The item.
+ /// Type of the item stub.
/// The context.
/// The element.
/// The filter.
- private void AddCommonFields(BaseItem item, BaseItem context, XmlElement element, Filter filter)
+ private void AddCommonFields(BaseItem item, StubType? itemStubType, BaseItem context, XmlElement element, Filter filter)
{
// Don't filter on dc:title because not all devices will include it in the filter
// MediaMonkey for example won't display content without a title
@@ -478,7 +488,7 @@ namespace MediaBrowser.Dlna.Didl
AddValue(element, "dc", "title", GetDisplayName(item, context), NS_DC);
}
- element.AppendChild(CreateObjectClass(element.OwnerDocument, item));
+ element.AppendChild(CreateObjectClass(element.OwnerDocument, item, itemStubType));
if (filter.Contains("dc:date"))
{
@@ -539,14 +549,14 @@ namespace MediaBrowser.Dlna.Didl
AddPeople(item, element);
}
- private XmlElement CreateObjectClass(XmlDocument result, BaseItem item)
+ private XmlElement CreateObjectClass(XmlDocument result, BaseItem item, StubType? stubType)
{
// More types here
// http://oss.linn.co.uk/repos/Public/LibUpnpCil/DidlLite/UpnpAv/Test/TestDidlLite.cs
var objectClass = result.CreateElement("upnp", "class", NS_UPNP);
- if (item.IsFolder)
+ if (item.IsFolder || stubType.HasValue)
{
string classType = null;
@@ -560,7 +570,7 @@ namespace MediaBrowser.Dlna.Didl
{
classType = "object.container.person.musicArtist";
}
- else if (item is Series || item is Season || item is BoxSet)
+ else if (item is Series || item is Season || item is BoxSet || item is Video)
{
classType = "object.container.album.videoAlbum";
}
@@ -628,9 +638,9 @@ namespace MediaBrowser.Dlna.Didl
}
}
- private void AddGeneralProperties(BaseItem item, BaseItem context, XmlElement element, Filter filter)
+ private void AddGeneralProperties(BaseItem item, StubType? itemStubType, BaseItem context, XmlElement element, Filter filter)
{
- AddCommonFields(item, context, element, filter);
+ AddCommonFields(item, itemStubType, context, element, filter);
var audio = item as Audio;
@@ -773,20 +783,26 @@ namespace MediaBrowser.Dlna.Didl
}
}
- AddImageResElement(item, element, 4096, 4096, playbackPercentage, "jpg", "JPEG_LRG");
- AddImageResElement(item, element, 4096, 4096, playbackPercentage, "png", "PNG_LRG");
- AddImageResElement(item, element, 1024, 768, playbackPercentage, "jpg", "JPEG_MED");
- AddImageResElement(item, element, 640, 480, playbackPercentage, "jpg", "JPEG_SM");
+ var imageLimit = _profile.DidlAlbumArtLimit ?? 100;
+
AddImageResElement(item, element, 160, 160, playbackPercentage, "jpg", "JPEG_TN");
- AddImageResElement(item, element, 160, 160, playbackPercentage, "png", "PNG_TN");
+
+ if (imageLimit > 1)
+ {
+ AddImageResElement(item, element, 4096, 4096, playbackPercentage, "jpg", "JPEG_LRG");
+ AddImageResElement(item, element, 1024, 768, playbackPercentage, "jpg", "JPEG_MED");
+ AddImageResElement(item, element, 640, 480, playbackPercentage, "jpg", "JPEG_SM");
+ AddImageResElement(item, element, 4096, 4096, playbackPercentage, "png", "PNG_LRG");
+ AddImageResElement(item, element, 160, 160, playbackPercentage, "png", "PNG_TN");
+ }
}
- private void AddImageResElement(BaseItem item,
- XmlElement element,
- int maxWidth,
- int maxHeight,
+ private void AddImageResElement(BaseItem item,
+ XmlElement element,
+ int maxWidth,
+ int maxHeight,
int playbackPercentage,
- string format,
+ string format,
string org_Pn)
{
var imageInfo = GetImageInfo(item);
@@ -920,6 +936,25 @@ namespace MediaBrowser.Dlna.Didl
internal int? Height;
}
+ public static string GetClientId(BaseItem item, StubType? stubType)
+ {
+ var id = item.Id.ToString("N");
+
+ if (stubType.HasValue)
+ {
+ id = stubType.Value.ToString().ToLower() + "_" + id;
+ }
+
+ return id;
+ }
+
+ public static string GetClientId(IHasMediaSources item)
+ {
+ var id = item.Id.ToString("N");
+
+ return id;
+ }
+
private ImageUrlInfo GetImageUrl(ImageDownloadInfo info, int maxWidth, int maxHeight, int playbackPercentage, string format)
{
var url = string.Format("{0}/Items/{1}/Images/{2}/0/{3}/{4}/{5}/{6}/{7}",
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index c4a79c22d0..f4578eca7c 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -528,7 +528,8 @@ namespace MediaBrowser.Dlna
new AndroidProfile(),
new DirectTvProfile(),
new DishHopperJoeyProfile(),
- new DefaultProfile()
+ new DefaultProfile(),
+ new PopcornHourProfile()
};
foreach (var item in list)
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index 761ce52c88..bc6e4f32a6 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -75,6 +75,7 @@
+
@@ -194,6 +195,9 @@
+
+
+