diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 7dcb06f7b3..f65949ac7d 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
@@ -65,6 +66,7 @@ namespace MediaBrowser.Api.Playback
protected IItemRepository ItemRepository { get; private set; }
protected ILiveTvManager LiveTvManager { get; private set; }
+ protected IDlnaManager DlnaManager { get; private set; }
///
/// Initializes a new instance of the class.
@@ -77,8 +79,9 @@ namespace MediaBrowser.Api.Playback
/// The dto service.
/// The file system.
/// The item repository.
- protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager)
+ protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager)
{
+ DlnaManager = dlnaManager;
EncodingManager = encodingManager;
LiveTvManager = liveTvManager;
ItemRepository = itemRepository;
@@ -774,29 +777,24 @@ namespace MediaBrowser.Api.Playback
{
var codec = request.AudioCodec;
- if (!string.IsNullOrEmpty(codec))
+ if (string.Equals(codec, "aac", StringComparison.OrdinalIgnoreCase))
{
- if (string.Equals(codec, "aac", StringComparison.OrdinalIgnoreCase))
- {
- return "aac -strict experimental";
- }
- if (string.Equals(codec, "mp3", StringComparison.OrdinalIgnoreCase))
- {
- return "libmp3lame";
- }
- if (string.Equals(codec, "vorbis", StringComparison.OrdinalIgnoreCase))
- {
- return "libvorbis";
- }
- if (string.Equals(codec, "wma", StringComparison.OrdinalIgnoreCase))
- {
- return "wmav2";
- }
-
- return codec.ToLower();
+ return "aac -strict experimental";
+ }
+ if (string.Equals(codec, "mp3", StringComparison.OrdinalIgnoreCase))
+ {
+ return "libmp3lame";
+ }
+ if (string.Equals(codec, "vorbis", StringComparison.OrdinalIgnoreCase))
+ {
+ return "libvorbis";
+ }
+ if (string.Equals(codec, "wma", StringComparison.OrdinalIgnoreCase))
+ {
+ return "wmav2";
}
- return "copy";
+ return codec.ToLower();
}
///
@@ -1212,96 +1210,85 @@ namespace MediaBrowser.Api.Playback
if (i == 0)
{
- // Device profile name
+ request.DeviceId = val;
}
else if (i == 1)
{
- request.DeviceId = val;
+ request.MediaSourceId = val;
}
else if (i == 2)
- {
- request.MediaSourceId = val;
- }
- else if (i == 3)
{
request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
}
- else if (i == 4)
+ else if (i == 3)
{
if (videoRequest != null)
{
videoRequest.VideoCodec = val;
}
}
- else if (i == 5)
+ else if (i == 4)
{
request.AudioCodec = val;
}
- else if (i == 6)
+ else if (i == 5)
{
if (videoRequest != null)
{
videoRequest.AudioStreamIndex = int.Parse(val, UsCulture);
}
}
- else if (i == 7)
+ else if (i == 6)
{
if (videoRequest != null)
{
videoRequest.SubtitleStreamIndex = int.Parse(val, UsCulture);
}
}
- else if (i == 8)
+ else if (i == 7)
{
if (videoRequest != null)
{
videoRequest.VideoBitRate = int.Parse(val, UsCulture);
}
}
- else if (i == 9)
+ else if (i == 8)
{
request.AudioBitRate = int.Parse(val, UsCulture);
}
- else if (i == 10)
+ else if (i == 9)
{
request.MaxAudioChannels = int.Parse(val, UsCulture);
}
- else if (i == 11)
+ else if (i == 10)
{
if (videoRequest != null)
{
videoRequest.MaxWidth = int.Parse(val, UsCulture);
}
}
- else if (i == 12)
+ else if (i == 11)
{
if (videoRequest != null)
{
videoRequest.MaxHeight = int.Parse(val, UsCulture);
}
}
- else if (i == 13)
+ else if (i == 12)
{
if (videoRequest != null)
{
videoRequest.Framerate = int.Parse(val, UsCulture);
}
}
- else if (i == 14)
+ else if (i == 13)
{
if (videoRequest != null)
{
request.StartTimeTicks = long.Parse(val, UsCulture);
}
}
- else if (i == 15)
- {
- if (videoRequest != null)
- {
- videoRequest.Profile = val;
- }
- }
- else if (i == 16)
+ else if (i == 14)
{
if (videoRequest != null)
{
@@ -1487,9 +1474,172 @@ namespace MediaBrowser.Api.Playback
state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 10;
state.HlsListSize = state.ReadInputAtNativeFramerate ? 100 : 1440;
+ ApplyDeviceProfileSettings(state);
+
return state;
}
+ private void ApplyDeviceProfileSettings(StreamState state)
+ {
+ var headers = new Dictionary();
+
+ foreach (var key in Request.Headers.AllKeys)
+ {
+ headers[key] = Request.Headers[key];
+ }
+
+ var profile = DlnaManager.GetProfile(headers);
+
+ var container = Path.GetExtension(state.RequestedUrl);
+
+ if (string.IsNullOrEmpty(container))
+ {
+ container = Path.GetExtension(GetOutputFilePath(state));
+ }
+
+ var audioCodec = state.Request.AudioCodec;
+
+ if (string.Equals(audioCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.AudioStream != null)
+ {
+ audioCodec = state.AudioStream.Codec;
+ }
+
+ var videoCodec = state.VideoRequest == null ? null : state.VideoRequest.VideoCodec;
+
+ if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.VideoStream != null)
+ {
+ videoCodec = state.VideoStream.Codec;
+ }
+
+ var mediaProfile = state.VideoRequest == null ?
+ profile.GetAudioMediaProfile(container, audioCodec, state.AudioStream) :
+ profile.GetVideoMediaProfile(container, audioCodec, videoCodec, state.AudioStream, state.VideoStream);
+
+ if (mediaProfile != null)
+ {
+ state.MimeType = mediaProfile.MimeType;
+ state.OrgPn = mediaProfile.OrgPn;
+ }
+
+ var transcodingProfile = state.VideoRequest == null ?
+ profile.GetAudioTranscodingProfile(container, audioCodec) :
+ profile.GetVideoTranscodingProfile(container, audioCodec, videoCodec);
+
+ if (transcodingProfile != null)
+ {
+ state.EstimateContentLength = transcodingProfile.EstimateContentLength;
+ state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
+ state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
+
+ foreach (var setting in transcodingProfile.Settings)
+ {
+ switch (setting.Name)
+ {
+ case TranscodingSettingType.VideoProfile:
+ {
+ if (state.VideoRequest != null && string.IsNullOrWhiteSpace(state.VideoRequest.Profile))
+ {
+ state.VideoRequest.Profile = setting.Value;
+ }
+ break;
+ }
+ default:
+ throw new ArgumentException("Unrecognized TranscodingSettingType");
+ }
+ }
+ }
+ }
+
+
+ ///
+ /// Adds the dlna headers.
+ ///
+ /// The state.
+ /// The response headers.
+ /// if set to true [is statically streamed].
+ /// true if XXXX, false otherwise
+ protected void AddDlnaHeaders(StreamState state, IDictionary responseHeaders, bool isStaticallyStreamed)
+ {
+ var timeSeek = GetHeader("TimeSeekRange.dlna.org");
+
+ if (!string.IsNullOrEmpty(timeSeek))
+ {
+ ResultFactory.ThrowError(406, "Time seek not supported during encoding.", responseHeaders);
+ return;
+ }
+
+ var transferMode = GetHeader("transferMode.dlna.org");
+ responseHeaders["transferMode.dlna.org"] = string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode;
+ responseHeaders["realTimeInfo.dlna.org"] = "DLNA.ORG_TLAG=*";
+
+ var contentFeatures = string.Empty;
+ var extension = GetOutputFileExtension(state);
+
+ // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
+ var orgOp = isStaticallyStreamed || state.TranscodeSeekInfo == TranscodeSeekInfo.Bytes ? ";DLNA.ORG_OP=01" : ";DLNA.ORG_OP=00";
+
+ // 0 = native, 1 = transcoded
+ var orgCi = isStaticallyStreamed ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
+
+ const string dlnaflags = ";DLNA.ORG_FLAGS=01500000000000000000000000000000";
+
+ if (!string.IsNullOrWhiteSpace(state.OrgPn))
+ {
+ contentFeatures = "DLNA.ORG_PN=" + state.OrgPn;
+ }
+ else if (string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase))
+ {
+ contentFeatures = "DLNA.ORG_PN=MP3";
+ }
+ else if (string.Equals(extension, ".aac", StringComparison.OrdinalIgnoreCase))
+ {
+ contentFeatures = "DLNA.ORG_PN=AAC_ISO";
+ }
+ else if (string.Equals(extension, ".wma", StringComparison.OrdinalIgnoreCase))
+ {
+ contentFeatures = "DLNA.ORG_PN=WMABASE";
+ }
+ else if (string.Equals(extension, ".avi", StringComparison.OrdinalIgnoreCase))
+ {
+ contentFeatures = "DLNA.ORG_PN=AVI";
+ }
+ else if (string.Equals(extension, ".mkv", StringComparison.OrdinalIgnoreCase))
+ {
+ contentFeatures = "DLNA.ORG_PN=MATROSKA";
+ }
+ else if (string.Equals(extension, ".mp4", StringComparison.OrdinalIgnoreCase))
+ {
+ contentFeatures = "DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC";
+ }
+ else if (string.Equals(extension, ".mpeg", StringComparison.OrdinalIgnoreCase))
+ {
+ contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL";
+ }
+ else if (string.Equals(extension, ".ts", StringComparison.OrdinalIgnoreCase))
+ {
+ contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL";
+ }
+ //else if (string.Equals(extension, ".wmv", StringComparison.OrdinalIgnoreCase))
+ //{
+ // contentFeatures = "DLNA.ORG_PN=WMVHIGH_BASE";
+ //}
+ //else if (string.Equals(extension, ".asf", StringComparison.OrdinalIgnoreCase))
+ //{
+ // // ??
+ // contentFeatures = "DLNA.ORG_PN=WMVHIGH_BASE";
+ //}
+
+ if (!string.IsNullOrEmpty(contentFeatures))
+ {
+ responseHeaders["contentFeatures.dlna.org"] = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
+ }
+
+ foreach (var item in responseHeaders)
+ {
+ Request.Response.AddHeader(item.Key, item.Value);
+ }
+ }
+
///
/// Enforces the resolution limit.
///
@@ -1605,7 +1755,7 @@ namespace MediaBrowser.Api.Playback
return "vorbis";
}
- return null;
+ return "copy";
}
///
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index eb8f415e0d..198376d6a1 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -2,13 +2,13 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using System;
using System.Collections.Generic;
@@ -24,7 +24,7 @@ namespace MediaBrowser.Api.Playback.Hls
///
public abstract class BaseHlsService : BaseStreamingService
{
- protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager)
+ protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager)
{
}
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 66e8b0d149..ab0cd8871f 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -1,12 +1,12 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using ServiceStack;
using System;
@@ -60,7 +60,7 @@ namespace MediaBrowser.Api.Playback.Hls
public class DynamicHlsService : BaseHlsService
{
- public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager)
+ public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager)
{
}
diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
index a2080995d0..1bca4cae9a 100644
--- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
@@ -52,7 +53,7 @@ namespace MediaBrowser.Api.Playback.Hls
///
public class VideoHlsService : BaseHlsService
{
- public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager)
+ public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager)
{
}
diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
index 4d8d3a5816..ca206c0125 100644
--- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
@@ -43,7 +44,7 @@ namespace MediaBrowser.Api.Playback.Progressive
///
public class AudioService : BaseProgressiveStreamingService
{
- public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IHttpClient httpClient, IImageProcessor imageProcessor) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, httpClient, imageProcessor)
+ public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager, IHttpClient httpClient, IImageProcessor imageProcessor) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager, httpClient, imageProcessor)
{
}
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 9cb989fc21..dad8a51bd7 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -1,13 +1,13 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using ServiceStack.Web;
using System;
@@ -26,8 +26,7 @@ namespace MediaBrowser.Api.Playback.Progressive
protected readonly IImageProcessor ImageProcessor;
protected readonly IHttpClient HttpClient;
- protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IHttpClient httpClient, IImageProcessor imageProcessor)
- : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager)
+ protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager, IHttpClient httpClient, IImageProcessor imageProcessor) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager)
{
HttpClient = httpClient;
ImageProcessor = imageProcessor;
@@ -100,92 +99,6 @@ namespace MediaBrowser.Api.Playback.Progressive
return null;
}
- ///
- /// Adds the dlna headers.
- ///
- /// The state.
- /// The response headers.
- /// if set to true [is statically streamed].
- /// true if XXXX, false otherwise
- private void AddDlnaHeaders(StreamState state, IDictionary responseHeaders, bool isStaticallyStreamed)
- {
- var timeSeek = GetHeader("TimeSeekRange.dlna.org");
-
- if (!string.IsNullOrEmpty(timeSeek))
- {
- ResultFactory.ThrowError(406, "Time seek not supported during encoding.", responseHeaders);
- return;
- }
-
- var transferMode = GetHeader("transferMode.dlna.org");
- responseHeaders["transferMode.dlna.org"] = string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode;
- responseHeaders["realTimeInfo.dlna.org"] = "DLNA.ORG_TLAG=*";
-
- var contentFeatures = string.Empty;
- var extension = GetOutputFileExtension(state);
-
- // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
- var orgOp = isStaticallyStreamed ? ";DLNA.ORG_OP=01" : ";DLNA.ORG_OP=00";
-
- // 0 = native, 1 = transcoded
- var orgCi = isStaticallyStreamed ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
-
- const string dlnaflags = ";DLNA.ORG_FLAGS=01500000000000000000000000000000";
-
- if (string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase))
- {
- contentFeatures = "DLNA.ORG_PN=MP3";
- }
- else if (string.Equals(extension, ".aac", StringComparison.OrdinalIgnoreCase))
- {
- contentFeatures = "DLNA.ORG_PN=AAC_ISO";
- }
- else if (string.Equals(extension, ".wma", StringComparison.OrdinalIgnoreCase))
- {
- contentFeatures = "DLNA.ORG_PN=WMABASE";
- }
- else if (string.Equals(extension, ".avi", StringComparison.OrdinalIgnoreCase))
- {
- contentFeatures = "DLNA.ORG_PN=AVI";
- }
- else if (string.Equals(extension, ".mkv", StringComparison.OrdinalIgnoreCase))
- {
- contentFeatures = "DLNA.ORG_PN=MATROSKA";
- }
- else if (string.Equals(extension, ".mp4", StringComparison.OrdinalIgnoreCase))
- {
- contentFeatures = "DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC";
- }
- else if (string.Equals(extension, ".mpeg", StringComparison.OrdinalIgnoreCase))
- {
- contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL";
- }
- else if (string.Equals(extension, ".ts", StringComparison.OrdinalIgnoreCase))
- {
- contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL";
- }
- //else if (string.Equals(extension, ".wmv", StringComparison.OrdinalIgnoreCase))
- //{
- // contentFeatures = "DLNA.ORG_PN=WMVHIGH_BASE";
- //}
- //else if (string.Equals(extension, ".asf", StringComparison.OrdinalIgnoreCase))
- //{
- // // ??
- // contentFeatures = "DLNA.ORG_PN=WMVHIGH_BASE";
- //}
-
-
- if (!string.IsNullOrEmpty(contentFeatures))
- {
- responseHeaders["contentFeatures.dlna.org"] = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
- }
-
- foreach (var item in responseHeaders)
- {
- Request.Response.AddHeader(item.Key, item.Value);
- }
- }
-
///
/// Gets the type of the transcoding job.
///
diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
index 43dc6f0d49..0fc78f0e3d 100644
--- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
@@ -58,7 +59,7 @@ namespace MediaBrowser.Api.Playback.Progressive
///
public class VideoService : BaseProgressiveStreamingService
{
- public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IHttpClient httpClient, IImageProcessor imageProcessor) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, httpClient, imageProcessor)
+ public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager, IHttpClient httpClient, IImageProcessor imageProcessor) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager, httpClient, imageProcessor)
{
}
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index ecc5c93ef2..504d7d921b 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using System.Collections.Generic;
@@ -77,8 +78,21 @@ namespace MediaBrowser.Api.Playback
public string InputAudioCodec { get; set; }
+ public string MimeType { get; set; }
+ public string OrgPn { get; set; }
+
+ // DLNA Settings
+ public bool EstimateContentLength { get; set; }
+ public bool EnableMpegtsM2TsMode { get; set; }
+ public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
+
public string GetMimeType(string outputPath)
{
+ if (!string.IsNullOrEmpty(MimeType))
+ {
+ return MimeType;
+ }
+
return MimeTypes.GetMimeType(outputPath);
}
}
diff --git a/MediaBrowser.Controller/Dlna/DeviceIdentification.cs b/MediaBrowser.Controller/Dlna/DeviceIdentification.cs
index 461c77537c..7b8e3a1e72 100644
--- a/MediaBrowser.Controller/Dlna/DeviceIdentification.cs
+++ b/MediaBrowser.Controller/Dlna/DeviceIdentification.cs
@@ -41,9 +41,7 @@ namespace MediaBrowser.Controller.Dlna
///
/// Gets or sets the manufacturer.
///
- ///
- /// The manufacturer.
- ///
+ /// The manufacturer.
public string Manufacturer { get; set; }
///
/// Gets or sets the manufacturer URL.
diff --git a/MediaBrowser.Controller/Dlna/DeviceProfile.cs b/MediaBrowser.Controller/Dlna/DeviceProfile.cs
index f3de1bc34a..f34c4bf645 100644
--- a/MediaBrowser.Controller/Dlna/DeviceProfile.cs
+++ b/MediaBrowser.Controller/Dlna/DeviceProfile.cs
@@ -1,4 +1,7 @@
-
+using MediaBrowser.Model.Entities;
+using System;
+using System.Linq;
+
namespace MediaBrowser.Controller.Dlna
{
public class DeviceProfile
@@ -9,12 +12,6 @@ namespace MediaBrowser.Controller.Dlna
/// The name.
public string Name { get; set; }
- ///
- /// Gets or sets the type of the client.
- ///
- /// The type of the client.
- public string ClientType { get; set; }
-
///
/// Gets or sets the transcoding profiles.
///
@@ -76,5 +73,141 @@ namespace MediaBrowser.Controller.Dlna
CodecProfiles = new CodecProfile[] { };
ContainerProfiles = new ContainerProfile[] { };
}
+
+ public TranscodingProfile GetAudioTranscodingProfile(string container, string audioCodec)
+ {
+ container = (container ?? string.Empty).TrimStart('.');
+
+ return TranscodingProfiles.FirstOrDefault(i =>
+ {
+ if (i.Type != DlnaProfileType.Audio)
+ {
+ return false;
+ }
+
+ if (!string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
+ if (!i.GetAudioCodecs().Contains(audioCodec ?? string.Empty))
+ {
+ return false;
+ }
+
+ return true;
+ });
+ }
+
+ public TranscodingProfile GetVideoTranscodingProfile(string container, string audioCodec, string videoCodec)
+ {
+ container = (container ?? string.Empty).TrimStart('.');
+
+ return TranscodingProfiles.FirstOrDefault(i =>
+ {
+ if (i.Type != DlnaProfileType.Video)
+ {
+ return false;
+ }
+
+ if (!string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
+ if (!i.GetAudioCodecs().Contains(audioCodec ?? string.Empty))
+ {
+ return false;
+ }
+
+ if (!string.Equals(videoCodec, i.VideoCodec, StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
+ return true;
+ });
+ }
+
+ public MediaProfile GetAudioMediaProfile(string container, string audioCodec, MediaStream audioStream)
+ {
+ container = (container ?? string.Empty).TrimStart('.');
+
+ return MediaProfiles.FirstOrDefault(i =>
+ {
+ if (i.Type != DlnaProfileType.Audio)
+ {
+ return false;
+ }
+
+ var containers = i.GetContainers().ToList();
+ if (containers.Count > 0 && !containers.Contains(container))
+ {
+ return false;
+ }
+
+ var audioCodecs = i.GetAudioCodecs().ToList();
+ if (audioCodecs.Count > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty))
+ {
+ return false;
+ }
+
+ return true;
+ });
+ }
+
+ public MediaProfile GetVideoMediaProfile(string container, string audioCodec, string videoCodec, MediaStream audioStream, MediaStream videoStream)
+ {
+ container = (container ?? string.Empty).TrimStart('.');
+
+ return MediaProfiles.FirstOrDefault(i =>
+ {
+ if (i.Type != DlnaProfileType.Video)
+ {
+ return false;
+ }
+
+ var containers = i.GetContainers().ToList();
+ if (containers.Count > 0 && !containers.Contains(container))
+ {
+ return false;
+ }
+
+ var audioCodecs = i.GetAudioCodecs().ToList();
+ if (audioCodecs.Count > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty))
+ {
+ return false;
+ }
+
+ var videoCodecs = i.GetVideoCodecs().ToList();
+ if (videoCodecs.Count > 0 && !videoCodecs.Contains(videoCodec ?? string.Empty))
+ {
+ return false;
+ }
+
+ return true;
+ });
+ }
+
+ public MediaProfile GetPhotoMediaProfile(string container)
+ {
+ container = (container ?? string.Empty).TrimStart('.');
+
+ return MediaProfiles.FirstOrDefault(i =>
+ {
+ if (i.Type != DlnaProfileType.Photo)
+ {
+ return false;
+ }
+
+ var containers = i.GetContainers().ToList();
+ if (containers.Count > 0 && !containers.Contains(container))
+ {
+ return false;
+ }
+
+ return true;
+ });
+ }
}
}
diff --git a/MediaBrowser.Controller/Dlna/IDlnaManager.cs b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
index 6de17e5511..22d13fc3ad 100644
--- a/MediaBrowser.Controller/Dlna/IDlnaManager.cs
+++ b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
@@ -16,6 +16,13 @@ namespace MediaBrowser.Controller.Dlna
/// DlnaProfile.
DeviceProfile GetDefaultProfile();
+ ///
+ /// Gets the profile.
+ ///
+ /// The headers.
+ /// DeviceProfile.
+ DeviceProfile GetProfile(IDictionary headers);
+
///
/// Gets the profile.
///
diff --git a/MediaBrowser.Controller/Dlna/MediaProfile.cs b/MediaBrowser.Controller/Dlna/MediaProfile.cs
index 1d2613face..9a9b56ddd5 100644
--- a/MediaBrowser.Controller/Dlna/MediaProfile.cs
+++ b/MediaBrowser.Controller/Dlna/MediaProfile.cs
@@ -19,6 +19,11 @@ namespace MediaBrowser.Controller.Dlna
{
Conditions = new ProfileCondition[] {};
}
+
+ public List GetContainers()
+ {
+ return (Container ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+ }
public List GetAudioCodecs()
{
diff --git a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs
index 007cb632e4..d4cfae9893 100644
--- a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs
+++ b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs
@@ -1,4 +1,6 @@
-
+using System.Collections.Generic;
+using System.Linq;
+
namespace MediaBrowser.Controller.Dlna
{
public class TranscodingProfile
@@ -11,7 +13,7 @@ namespace MediaBrowser.Controller.Dlna
public string AudioCodec { get; set; }
public bool EstimateContentLength { get; set; }
-
+ public bool EnableMpegtsM2TsMode { get; set; }
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
public TranscodingSetting[] Settings { get; set; }
@@ -21,7 +23,11 @@ namespace MediaBrowser.Controller.Dlna
Settings = new TranscodingSetting[] { };
}
- public bool EnableMpegtsM2TsMode { get; set; }
+
+ public List GetAudioCodecs()
+ {
+ return (AudioCodec ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+ }
}
public class TranscodingSetting
diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
index d71c7af323..70b49efece 100644
--- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
+++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -284,22 +283,6 @@ namespace MediaBrowser.Controller.Providers
break;
}
- case "TagLine":
- {
- var tagline = reader.ReadElementContentAsString();
-
- var hasTaglines = item as IHasTaglines;
- if (hasTaglines != null)
- {
- if (!string.IsNullOrWhiteSpace(tagline))
- {
- hasTaglines.AddTagline(tagline);
- }
- }
-
- break;
- }
-
case "Language":
{
var val = reader.ReadElementContentAsString();
@@ -380,9 +363,7 @@ namespace MediaBrowser.Controller.Providers
}
case "ContentRating":
- case "certification":
case "MPAARating":
- case "ESRBRating":
{
var rating = reader.ReadElementContentAsString();
@@ -415,7 +396,6 @@ namespace MediaBrowser.Controller.Providers
break;
}
- case "Runtime":
case "RunningTime":
{
var text = reader.ReadElementContentAsString();
@@ -431,19 +411,6 @@ namespace MediaBrowser.Controller.Providers
break;
}
- case "Genre":
- {
- foreach (var name in SplitNames(reader.ReadElementContentAsString()))
- {
- if (string.IsNullOrWhiteSpace(name))
- {
- continue;
- }
- item.AddGenre(name);
- }
- break;
- }
-
case "AspectRatio":
{
var val = reader.ReadElementContentAsString();
@@ -587,7 +554,6 @@ namespace MediaBrowser.Controller.Providers
break;
}
- case "ReleaseYear":
case "ProductionYear":
{
var val = reader.ReadElementContentAsString();
@@ -606,7 +572,6 @@ namespace MediaBrowser.Controller.Providers
case "Rating":
case "IMDBrating":
- case "TGDBRating":
{
var rating = reader.ReadElementContentAsString();
@@ -683,22 +648,6 @@ namespace MediaBrowser.Controller.Providers
}
break;
}
- case "MusicbrainzId":
- {
- var mbz = reader.ReadElementContentAsString();
- if (!string.IsNullOrWhiteSpace(mbz))
- {
- if (item is MusicAlbum)
- {
- item.SetProviderId(MetadataProviders.MusicBrainzAlbum, mbz);
- }
- else if (item is MusicArtist)
- {
- item.SetProviderId(MetadataProviders.MusicBrainzArtist, mbz);
- }
- }
- break;
- }
case "MusicBrainzAlbumId":
{
var mbz = reader.ReadElementContentAsString();
@@ -802,9 +751,7 @@ namespace MediaBrowser.Controller.Providers
}
break;
- case "IMDB_ID":
case "IMDB":
- case "IMDbId":
var imDbId = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(imDbId))
{
@@ -856,15 +803,6 @@ namespace MediaBrowser.Controller.Providers
break;
}
- case "ParentalRating":
- {
- using (var subtree = reader.ReadSubtree())
- {
- FetchFromParentalRatingNode(subtree, item);
- }
- break;
- }
-
case "Studios":
{
using (var subtree = reader.ReadSubtree())
@@ -1227,32 +1165,6 @@ namespace MediaBrowser.Controller.Providers
}
}
- ///
- /// Fetches from parental rating node.
- ///
- /// The reader.
- /// The item.
- private void FetchFromParentalRatingNode(XmlReader reader, T item)
- {
- reader.MoveToContent();
-
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- // Removed support for "Value" tag as it conflicted with MPAA rating but leaving this function for possible
- // future support of "Description" -ebr
-
- default:
- reader.Skip();
- break;
- }
- }
- }
- }
-
///
/// Gets the persons from XML node.
///
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index c6da865cd7..78876d239c 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Dlna.Profiles;
using MediaBrowser.Model.Serialization;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
@@ -43,7 +44,8 @@ namespace MediaBrowser.Dlna
new WdtvLiveProfile(),
new DenonAvrProfile(),
new LinksysDMA2100Profile(),
- new LgTvProfile()
+ new LgTvProfile(),
+ new Foobar2000Profile()
};
foreach (var item in list)
@@ -124,5 +126,38 @@ namespace MediaBrowser.Dlna
return true;
}
+
+ public DeviceProfile GetProfile(IDictionary headers)
+ {
+ return GetProfiles().FirstOrDefault(i => IsMatch(headers, i.Identification)) ??
+ GetDefaultProfile();
+ }
+
+ private bool IsMatch(IDictionary headers, DeviceIdentification profileInfo)
+ {
+ return profileInfo.Headers.Any(i => IsMatch(headers, i));
+ }
+
+ private bool IsMatch(IDictionary headers, HttpHeaderInfo header)
+ {
+ string value;
+
+ if (headers.TryGetValue(header.Name, out value))
+ {
+ switch (header.Match)
+ {
+ case HeaderMatchType.Equals:
+ return string.Equals(value, header.Value, StringComparison.OrdinalIgnoreCase);
+ case HeaderMatchType.Substring:
+ return value.IndexOf(header.Value, StringComparison.OrdinalIgnoreCase) != -1;
+ case HeaderMatchType.Regex:
+ return Regex.IsMatch(value, header.Value, RegexOptions.IgnoreCase);
+ default:
+ throw new ArgumentException("Unrecognized HeaderMatchType");
+ }
+ }
+
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index bea281b614..bdfcae39b6 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -61,7 +61,6 @@
-
Code
@@ -70,7 +69,8 @@
-
+
+
@@ -100,7 +100,6 @@
-
diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs
index 2b43c019c0..a677cf5dd7 100644
--- a/MediaBrowser.Dlna/PlayTo/Device.cs
+++ b/MediaBrowser.Dlna/PlayTo/Device.cs
@@ -607,7 +607,7 @@ namespace MediaBrowser.Dlna.PlayTo
url = "/" + url;
var httpClient = new SsdpHttpClient(_httpClient, _config);
- var document = await httpClient.GetDataAsync(new Uri(Properties.BaseUrl + url));
+ var document = await httpClient.GetDataAsync(Properties.BaseUrl + url);
AvCommands = TransportCommands.Create(document);
}
@@ -625,7 +625,7 @@ namespace MediaBrowser.Dlna.PlayTo
url = "/" + url;
var httpClient = new SsdpHttpClient(_httpClient, _config);
- var document = await httpClient.GetDataAsync(new Uri(Properties.BaseUrl + url));
+ var document = await httpClient.GetDataAsync(Properties.BaseUrl + url);
RendererCommands = TransportCommands.Create(document);
}
@@ -646,7 +646,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
var ssdpHttpClient = new SsdpHttpClient(httpClient, config);
- var document = await ssdpHttpClient.GetDataAsync(url).ConfigureAwait(false);
+ var document = await ssdpHttpClient.GetDataAsync(url.ToString()).ConfigureAwait(false);
var deviceProperties = new DeviceInfo();
@@ -681,10 +681,18 @@ namespace MediaBrowser.Dlna.PlayTo
var presentationUrl = document.Descendants(uPnpNamespaces.ud.GetName("presentationURL")).FirstOrDefault();
if (presentationUrl != null)
deviceProperties.PresentationUrl = presentationUrl.Value;
+
var modelUrl = document.Descendants(uPnpNamespaces.ud.GetName("modelURL")).FirstOrDefault();
if (modelUrl != null)
deviceProperties.ModelUrl = modelUrl.Value;
-
+
+ var serialNumber = document.Descendants(uPnpNamespaces.ud.GetName("serialNumber")).FirstOrDefault();
+ if (serialNumber != null)
+ deviceProperties.SerialNumber = serialNumber.Value;
+
+ var modelDescription = document.Descendants(uPnpNamespaces.ud.GetName("modelDescription")).FirstOrDefault();
+ if (modelDescription != null)
+ deviceProperties.ModelDescription = modelDescription.Value;
deviceProperties.BaseUrl = String.Format("http://{0}:{1}", url.Host, url.Port);
@@ -724,7 +732,6 @@ namespace MediaBrowser.Dlna.PlayTo
if (isRenderer)
{
-
var device = new Device(deviceProperties, httpClient, logger, config);
await device.GetRenderingProtocolAsync().ConfigureAwait(false);
diff --git a/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs b/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs
index c57e95c194..122549c7d3 100644
--- a/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs
+++ b/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs
@@ -1,5 +1,5 @@
-using System.Collections.Generic;
-using MediaBrowser.Controller.Dlna;
+using MediaBrowser.Controller.Dlna;
+using System.Collections.Generic;
namespace MediaBrowser.Dlna.PlayTo
{
@@ -17,27 +17,18 @@ namespace MediaBrowser.Dlna.PlayTo
public string ClientType { get; set; }
- private string _displayName = string.Empty;
- public string DisplayName
- {
- get
- {
- return string.IsNullOrEmpty(_displayName) ? Name : _displayName;
- }
- set
- {
- _displayName = value;
- }
- }
-
public string ModelName { get; set; }
public string ModelNumber { get; set; }
+ public string ModelDescription { get; set; }
+
public string ModelUrl { get; set; }
public string Manufacturer { get; set; }
+ public string SerialNumber { get; set; }
+
public string ManufacturerUrl { get; set; }
public string PresentationUrl { get; set; }
@@ -75,7 +66,9 @@ namespace MediaBrowser.Dlna.PlayTo
ModelNumber = ModelNumber,
FriendlyName = Name,
ManufacturerUrl = ManufacturerUrl,
- ModelUrl = ModelUrl
+ ModelUrl = ModelUrl,
+ ModelDescription = ModelDescription,
+ SerialNumber = SerialNumber
};
}
}
diff --git a/MediaBrowser.Dlna/PlayTo/DidlBuilder.cs b/MediaBrowser.Dlna/PlayTo/DidlBuilder.cs
index 04f9a4644c..1327da1480 100644
--- a/MediaBrowser.Dlna/PlayTo/DidlBuilder.cs
+++ b/MediaBrowser.Dlna/PlayTo/DidlBuilder.cs
@@ -9,31 +9,27 @@ namespace MediaBrowser.Dlna.PlayTo
{
internal class DidlBuilder
{
- #region Constants
+ const string CRLF = "\r\n";
+ const string UNKNOWN = "Unknown";
- internal const string CRLF = "\r\n";
- internal const string UNKNOWN = "Unknown";
-
- internal const string DIDL_START = @"- " + CRLF;
- internal const string DIDL_TITLE = @" {0}" + CRLF;
- internal const string DIDL_ARTIST = @"{0}" + CRLF;
- internal const string DIDL_ALBUM = @"{0}" + CRLF;
- internal const string DIDL_TRACKNUM = @"0" + CRLF;
- internal const string DIDL_VIDEOCLASS = @" object.item.videoItem" + CRLF;
- internal const string DIDL_AUDIOCLASS = @" object.item.audioItem.musicTrack" + CRLF;
- internal const string DIDL_IMAGE = @" {0}" + CRLF +
- @" {0}" + CRLF;
- internal const string DIDL_RELEASEDATE = @" {0}" + CRLF;
- internal const string DIDL_GENRE = @" {0}" + CRLF;
- internal const string DESCRIPTION = @" {0}" + CRLF;
- internal const string DIDL_VIDEO_RES = @" {4}" + CRLF;
- internal const string DIDL_AUDIO_RES = @" {3}" + CRLF;
- internal const string DIDL_IMAGE_RES = @" {0}" + CRLF;
- internal const string DIDL_ALBUMIMAGE_RES = @" {0}" + CRLF;
- internal const string DIDL_RATING = @" {0}" + CRLF;
- internal const string DIDL_END = "
";
-
- #endregion
+ const string DIDL_START = @"- " + CRLF;
+ const string DIDL_TITLE = @" {0}" + CRLF;
+ const string DIDL_ARTIST = @"{0}" + CRLF;
+ const string DIDL_ALBUM = @"{0}" + CRLF;
+ const string DIDL_TRACKNUM = @"{0}" + CRLF;
+ const string DIDL_VIDEOCLASS = @" object.item.videoItem" + CRLF;
+ const string DIDL_AUDIOCLASS = @" object.item.audioItem.musicTrack" + CRLF;
+ const string DIDL_IMAGE = @" {0}" + CRLF +
+ @" {0}" + CRLF;
+ const string DIDL_RELEASEDATE = @" {0}" + CRLF;
+ const string DIDL_GENRE = @" {0}" + CRLF;
+ const string DESCRIPTION = @" {0}" + CRLF;
+ const string DIDL_VIDEO_RES = @" {4}" + CRLF;
+ const string DIDL_AUDIO_RES = @" {3}" + CRLF;
+ const string DIDL_IMAGE_RES = @" {0}" + CRLF;
+ const string DIDL_ALBUMIMAGE_RES = @" {0}" + CRLF;
+ const string DIDL_RATING = @" {0}" + CRLF;
+ const string DIDL_END = "
";
///
/// Builds a Didl MetaData object for the specified dto.
@@ -44,7 +40,7 @@ namespace MediaBrowser.Dlna.PlayTo
/// The stream URL.
/// The streams.
/// System.String.
- internal static string Build(BaseItem dto, string userId, string serverAddress, string streamUrl, IEnumerable streams)
+ public static string Build(BaseItem dto, string userId, string serverAddress, string streamUrl, IEnumerable streams)
{
string response = string.Format(DIDL_START, dto.Id, userId);
response += string.Format(DIDL_TITLE, dto.Name.Replace("&", "and"));
@@ -53,7 +49,12 @@ namespace MediaBrowser.Dlna.PlayTo
else
response += DIDL_AUDIOCLASS;
- response += string.Format(DIDL_IMAGE, GetImageUrl(dto, serverAddress));
+ var imageUrl = GetImageUrl(dto, serverAddress);
+
+ if (!string.IsNullOrEmpty(imageUrl))
+ {
+ response += string.Format(DIDL_IMAGE, imageUrl);
+ }
response += string.Format(DIDL_RELEASEDATE, GetDateString(dto.PremiereDate));
//TODO Add genres to didl;
@@ -63,7 +64,11 @@ namespace MediaBrowser.Dlna.PlayTo
{
response += string.Format(DESCRIPTION, UNKNOWN);
response += GetVideoDIDL(dto, streamUrl, streams);
- response += string.Format(DIDL_IMAGE_RES, GetImageUrl(dto, serverAddress));
+
+ if (!string.IsNullOrEmpty(imageUrl))
+ {
+ response += string.Format(DIDL_IMAGE_RES, imageUrl);
+ }
}
else
{
@@ -74,25 +79,25 @@ namespace MediaBrowser.Dlna.PlayTo
response += string.Format(DIDL_ARTIST, audio.Artists.FirstOrDefault() ?? UNKNOWN);
response += string.Format(DIDL_ALBUM, audio.Album);
- // TODO: Bad format string?
response += string.Format(DIDL_TRACKNUM, audio.IndexNumber ?? 0);
}
response += GetAudioDIDL(dto, streamUrl, streams);
- response += string.Format(DIDL_ALBUMIMAGE_RES, GetImageUrl(dto, serverAddress));
+
+ if (!string.IsNullOrEmpty(imageUrl))
+ {
+ response += string.Format(DIDL_ALBUMIMAGE_RES, imageUrl);
+ }
}
response += DIDL_END;
return response;
-
}
- #region Private methods
-
private static string GetVideoDIDL(BaseItem dto, string streamUrl, IEnumerable streams)
{
- var videostream = streams.Where(stream => stream.Type == Model.Entities.MediaStreamType.Video).OrderBy(s => s.IsDefault).FirstOrDefault();
+ var videostream = streams.Where(stream => stream.Type == MediaStreamType.Video).OrderBy(s => s.IsDefault ? 0 : 1).FirstOrDefault();
if (videostream == null)
{
@@ -105,7 +110,7 @@ namespace MediaBrowser.Dlna.PlayTo
private static string GetAudioDIDL(BaseItem dto, string streamUrl, IEnumerable streams)
{
- var audiostream = streams.Where(stream => stream.Type == MediaStreamType.Audio).OrderBy(s => s.IsDefault).FirstOrDefault();
+ var audiostream = streams.Where(stream => stream.Type == MediaStreamType.Audio).OrderBy(s => s.IsDefault ? 0 : 1).FirstOrDefault();
if (audiostream == null)
{
@@ -118,14 +123,14 @@ namespace MediaBrowser.Dlna.PlayTo
private static string GetImageUrl(BaseItem dto, string serverAddress)
{
- var imageType = ImageType.Primary;
+ const ImageType imageType = ImageType.Primary;
- if (!dto.HasImage(ImageType.Primary))
+ if (!dto.HasImage(imageType))
{
- dto = dto.Parents.FirstOrDefault(i => i.HasImage(ImageType.Primary));
+ dto = dto.Parents.FirstOrDefault(i => i.HasImage(imageType));
}
- return string.Format("{0}/Items/{1}/Images/{2}", serverAddress, dto.Id, imageType);
+ return dto == null ? null : string.Format("{0}/Items/{1}/Images/{2}", serverAddress, dto.Id, imageType);
}
private static string GetDurationString(BaseItem dto)
@@ -148,7 +153,5 @@ namespace MediaBrowser.Dlna.PlayTo
{
return string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
}
-
- #endregion
}
}
diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
index ecda07f0bc..0b0c03fcd4 100644
--- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs
+++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
@@ -140,8 +140,15 @@ namespace MediaBrowser.Dlna.PlayTo
{
_updateTimer.Change(Timeout.Infinite, Timeout.Infinite);
- //Session is inactive, mark it for Disposal and don't start the elapsed timer.
- await _sessionManager.ReportSessionEnded(_session.Id);
+ try
+ {
+ // Session is inactive, mark it for Disposal and don't start the elapsed timer.
+ await _sessionManager.ReportSessionEnded(_session.Id);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in ReportSessionEnded", ex);
+ }
}
}
@@ -156,7 +163,15 @@ namespace MediaBrowser.Dlna.PlayTo
if (!_playbackStarted)
{
- await _sessionManager.OnPlaybackStart(new PlaybackInfo { Item = _currentItem, SessionId = _session.Id, CanSeek = true, QueueableMediaTypes = new List { "Audio", "Video" } }).ConfigureAwait(false);
+ await _sessionManager.OnPlaybackStart(new PlaybackInfo
+ {
+ Item = _currentItem,
+ SessionId = _session.Id,
+ CanSeek = true,
+ QueueableMediaTypes = new List { "Audio", "Video" }
+
+ }).ConfigureAwait(false);
+
_playbackStarted = true;
}
@@ -403,7 +418,6 @@ namespace MediaBrowser.Dlna.PlayTo
var playlistItem = GetPlaylistItem(item, streams, profile);
playlistItem.StartPositionTicks = startPostionTicks;
- playlistItem.DeviceProfileName = profile.Name;
if (playlistItem.MediaType == DlnaProfileType.Audio)
{
@@ -414,8 +428,7 @@ namespace MediaBrowser.Dlna.PlayTo
playlistItem.StreamUrl = StreamHelper.GetVideoUrl(_device.Properties, playlistItem, streams, serverAddress);
}
- var didl = DidlBuilder.Build(item, _session.UserId.ToString(), serverAddress, playlistItem.StreamUrl, streams);
- playlistItem.Didl = didl;
+ playlistItem.Didl = DidlBuilder.Build(item, _session.UserId.ToString(), serverAddress, playlistItem.StreamUrl, streams);
return playlistItem;
}
diff --git a/MediaBrowser.Dlna/PlayTo/DlnaControllerFactory.cs b/MediaBrowser.Dlna/PlayTo/DlnaControllerFactory.cs
deleted file mode 100644
index 720dc200b4..0000000000
--- a/MediaBrowser.Dlna/PlayTo/DlnaControllerFactory.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Dlna.PlayTo
-{
- public class PlayToControllerFactory : ISessionControllerFactory
- {
- private readonly ISessionManager _sessionManager;
- private readonly IItemRepository _itemRepository;
- private readonly ILibraryManager _libraryManager;
- private readonly ILogger _logger;
- private readonly INetworkManager _networkManager;
-
- public PlayToControllerFactory(ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, ILogManager logManager, INetworkManager networkManager)
- {
- _itemRepository = itemRepository;
- _sessionManager = sessionManager;
- _libraryManager = libraryManager;
- _networkManager = networkManager;
- _logger = logManager.GetLogger("PlayTo");
- }
-
- public ISessionController GetSessionController(SessionInfo session)
- {
- return null;
- }
- }
-}
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
index ca76116feb..297f7a696b 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
@@ -5,16 +5,17 @@ using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Session;
+using MediaBrowser.Dlna.Ssdp;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Session;
using System;
using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -126,10 +127,9 @@ namespace MediaBrowser.Dlna.PlayTo
if (receivedBytes > 0)
{
- var rawData = Encoding.UTF8.GetString(receiveBuffer, 0, receivedBytes);
- var uri = SsdpHelper.ParseSsdpResponse(rawData);
+ var headers = SsdpHelper.ParseSsdpResponse(receiveBuffer);
- TryCreateController(uri);
+ TryCreateController(headers);
}
}
@@ -146,13 +146,20 @@ namespace MediaBrowser.Dlna.PlayTo
}, _tokenSource.Token, TaskCreationOptions.LongRunning);
}
- private void TryCreateController(Uri uri)
+ private void TryCreateController(IDictionary headers)
{
+ string location;
+
+ if (!headers.TryGetValue("Location", out location))
+ {
+ return;
+ }
+
Task.Run(async () =>
{
try
{
- await CreateController(uri).ConfigureAwait(false);
+ await CreateController(new Uri(location)).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
@@ -221,46 +228,25 @@ namespace MediaBrowser.Dlna.PlayTo
if (device != null && device.RendererCommands != null && !_sessionManager.Sessions.Any(s => string.Equals(s.DeviceId, device.Properties.UUID) && s.IsActive))
{
- GetProfileSettings(device.Properties);
-
- var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, device.Properties.Name, device.Properties.UUID, device.Properties.DisplayName, uri.OriginalString, null)
+ var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null)
.ConfigureAwait(false);
- _sessionManager.ReportCapabilities(sessionInfo.Id, new SessionCapabilities
- {
- PlayableMediaTypes = new[] { MediaType.Audio, MediaType.Video, MediaType.Photo },
- SupportsFullscreenToggle = false
- });
-
var controller = sessionInfo.SessionController as PlayToController;
if (controller == null)
{
sessionInfo.SessionController = controller = new PlayToController(sessionInfo, _sessionManager, _itemRepository, _libraryManager, _logger, _networkManager, _dlnaManager, _userManager, _appHost);
+
+ controller.Init(device);
+
+ _sessionManager.ReportCapabilities(sessionInfo.Id, new SessionCapabilities
+ {
+ PlayableMediaTypes = new[] { MediaType.Audio, MediaType.Video, MediaType.Photo },
+ SupportsFullscreenToggle = false
+ });
+
+ _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
}
-
- controller.Init(device);
-
- _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
- }
- }
-
- ///
- /// Gets the profile settings.
- ///
- /// The device properties.
- /// The TranscodeSettings for the device
- private void GetProfileSettings(DeviceInfo deviceProperties)
- {
- var profile = _dlnaManager.GetProfile(deviceProperties.ToDeviceIdentification());
-
- if (!string.IsNullOrWhiteSpace(profile.Name))
- {
- deviceProperties.DisplayName = profile.Name;
- }
- if (!string.IsNullOrWhiteSpace(profile.ClientType))
- {
- deviceProperties.ClientType = profile.ClientType;
}
}
diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
index 20f31cf9da..e1eea08240 100644
--- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
@@ -33,8 +33,6 @@ namespace MediaBrowser.Dlna.PlayTo
public int? SubtitleStreamIndex { get; set; }
- public string DeviceProfileName { get; set; }
-
public int? MaxAudioChannels { get; set; }
public int? AudioBitrate { get; set; }
diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
index 1b2d791136..0dec9bbf3f 100644
--- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
@@ -162,7 +162,8 @@ namespace MediaBrowser.Dlna.PlayTo
private void ApplyTranscodingConditions(PlaylistItem item, IEnumerable conditions)
{
- foreach (var condition in conditions.Where(i => !string.IsNullOrEmpty(i.Value)))
+ foreach (var condition in conditions
+ .Where(i => !string.IsNullOrEmpty(i.Value)))
{
var value = condition.Value;
@@ -170,7 +171,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
case ProfileConditionValue.AudioBitrate:
{
- var num = 0;
+ int num;
if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
{
item.AudioBitrate = num;
@@ -179,7 +180,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
case ProfileConditionValue.AudioChannels:
{
- var num = 0;
+ int num;
if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
{
item.MaxAudioChannels = num;
@@ -199,7 +200,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
case ProfileConditionValue.Height:
{
- var num = 0;
+ int num;
if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
{
item.MaxHeight = num;
@@ -208,7 +209,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
case ProfileConditionValue.VideoBitrate:
{
- var num = 0;
+ int num;
if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
{
item.VideoBitrate = num;
@@ -217,7 +218,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
case ProfileConditionValue.VideoFramerate:
{
- var num = 0;
+ int num;
if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
{
item.MaxFramerate = num;
@@ -226,7 +227,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
case ProfileConditionValue.VideoLevel:
{
- var num = 0;
+ int num;
if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
{
item.VideoLevel = num;
@@ -235,7 +236,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
case ProfileConditionValue.Width:
{
- var num = 0;
+ int num;
if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
{
item.MaxWidth = num;
diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
index f540a80041..b1ae21a437 100644
--- a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
+++ b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
@@ -2,7 +2,6 @@
using MediaBrowser.Controller.Configuration;
using System;
using System.IO;
-using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
@@ -14,8 +13,6 @@ namespace MediaBrowser.Dlna.PlayTo
private const string USERAGENT = "Microsoft-Windows/6.2 UPnP/1.0 Microsoft-DLNA DLNADOC/1.50";
private const string FriendlyName = "MediaBrowser";
- private static readonly CookieContainer Container = new CookieContainer();
-
private readonly IHttpClient _httpClient;
private readonly IServerConfigurationManager _config;
@@ -31,7 +28,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (!serviceUrl.StartsWith("/"))
serviceUrl = "/" + serviceUrl;
- var response = await PostSoapDataAsync(new Uri(baseUrl + serviceUrl), "\"" + service.ServiceType + "#" + command + "\"", postData, header)
+ var response = await PostSoapDataAsync(baseUrl + serviceUrl, "\"" + service.ServiceType + "#" + command + "\"", postData, header)
.ConfigureAwait(false);
using (var stream = response.Content)
@@ -43,11 +40,11 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- public async Task SubscribeAsync(Uri url, string ip, int port, string localIp, int eventport, int timeOut = 3600)
+ public async Task SubscribeAsync(string url, string ip, int port, string localIp, int eventport, int timeOut = 3600)
{
var options = new HttpRequestOptions
{
- Url = url.ToString(),
+ Url = url,
UserAgent = USERAGENT,
LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging
};
@@ -56,7 +53,6 @@ namespace MediaBrowser.Dlna.PlayTo
options.RequestHeaders["CALLBACK"] = "<" + localIp + ":" + eventport + ">";
options.RequestHeaders["NT"] = "upnp:event";
options.RequestHeaders["TIMEOUT"] = "Second - " + timeOut;
- //request.CookieContainer = Container;
using (await _httpClient.Get(options).ConfigureAwait(false))
{
@@ -75,24 +71,22 @@ namespace MediaBrowser.Dlna.PlayTo
options.RequestHeaders["CALLBACK"] = "<" + localIp + ":" + eventport + ">";
options.RequestHeaders["NT"] = "upnp:event";
options.RequestHeaders["TIMEOUT"] = "Second - 3600";
- //request.CookieContainer = Container;
using (await _httpClient.Get(options).ConfigureAwait(false))
{
}
}
- public async Task GetDataAsync(Uri url)
+ public async Task GetDataAsync(string url)
{
var options = new HttpRequestOptions
{
- Url = url.ToString(),
+ Url = url,
UserAgent = USERAGENT,
LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging
};
options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
- //request.CookieContainer = Container;
using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
{
@@ -103,14 +97,14 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- private Task PostSoapDataAsync(Uri url, string soapAction, string postData, string header = null, int timeOut = 20000)
+ private Task PostSoapDataAsync(string url, string soapAction, string postData, string header = null)
{
if (!soapAction.StartsWith("\""))
soapAction = "\"" + soapAction + "\"";
var options = new HttpRequestOptions
{
- Url = url.ToString(),
+ Url = url,
UserAgent = USERAGENT,
LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging
};
diff --git a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
index 61c3bdd730..a4855c94f2 100644
--- a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
+++ b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
@@ -43,15 +43,10 @@ namespace MediaBrowser.Dlna.PlayTo
///
private static string BuildDlnaUrl(DeviceInfo deviceProperties, PlaylistItem item)
{
- var profile = item.TranscodingSettings.Where(i => i.Name == TranscodingSettingType.VideoProfile)
- .Select(i => i.Value)
- .FirstOrDefault();
-
var usCulture = new CultureInfo("en-US");
var list = new List
{
- item.DeviceProfileName ?? string.Empty,
deviceProperties.UUID ?? string.Empty,
item.MediaSourceId ?? string.Empty,
(!item.Transcode).ToString().ToLower(),
@@ -66,7 +61,6 @@ namespace MediaBrowser.Dlna.PlayTo
item.MaxWidth.HasValue ? item.MaxWidth.Value.ToString(usCulture) : string.Empty,
item.MaxHeight.HasValue ? item.MaxHeight.Value.ToString(usCulture) : string.Empty,
item.StartPositionTicks.ToString(usCulture),
- profile ?? string.Empty,
item.VideoLevel.HasValue ? item.VideoLevel.Value.ToString(usCulture) : string.Empty
};
diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
index 710f02df2e..214b6f814d 100644
--- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
@@ -6,9 +6,10 @@ namespace MediaBrowser.Dlna.Profiles
{
public DefaultProfile()
{
+ Name = "Generic Device";
+
ProtocolInfo = "DLNA";
- ClientType = "DLNA";
Manufacturer = "Media Browser";
ModelDescription = "Media Browser";
ModelName = "Media Browser";
diff --git a/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs b/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs
new file mode 100644
index 0000000000..877f1a6665
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs
@@ -0,0 +1,27 @@
+using MediaBrowser.Controller.Dlna;
+
+namespace MediaBrowser.Dlna.Profiles
+{
+ public class Foobar2000Profile : DefaultProfile
+ {
+ public Foobar2000Profile()
+ {
+ Name = "foobar2000";
+
+ Identification = new DeviceIdentification
+ {
+ FriendlyName = @"foobar",
+
+ Headers = new[]
+ {
+ new HttpHeaderInfo
+ {
+ Name = "User-Agent",
+ Value = "foobar",
+ Match = HeaderMatchType.Substring
+ }
+ }
+ };
+ }
+ }
+}
diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
index fa6b1201ab..fbbb7a594a 100644
--- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -302,6 +302,13 @@ namespace MediaBrowser.Dlna.Profiles
MediaProfiles = new[]
{
+ new MediaProfile
+ {
+ Container = "avi",
+ MimeType = "video/x-msvideo",
+ Type = DlnaProfileType.Video
+ },
+
new MediaProfile
{
Container = "mkv",
diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs
index 49aa47027a..cec29b4182 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs
@@ -6,6 +6,8 @@ namespace MediaBrowser.Dlna.Profiles
{
public SonyBlurayPlayer2013Profile()
{
+ Name = "Sony Blu-ray Player 2013";
+
Identification = new DeviceIdentification
{
FriendlyName = @"Blu-ray Disc Player",
diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs
index 5121726706..2c678b11f0 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs
@@ -6,6 +6,8 @@ namespace MediaBrowser.Dlna.Profiles
{
public SonyBlurayPlayerProfile()
{
+ Name = "Sony Blu-ray Player";
+
Identification = new DeviceIdentification
{
FriendlyName = @"Blu-ray Disc Player",
diff --git a/MediaBrowser.Dlna/Server/Headers.cs b/MediaBrowser.Dlna/Server/Headers.cs
index 859ae7fbf2..2bd1a72f7b 100644
--- a/MediaBrowser.Dlna/Server/Headers.cs
+++ b/MediaBrowser.Dlna/Server/Headers.cs
@@ -13,7 +13,7 @@ namespace MediaBrowser.Dlna.Server
private readonly Dictionary _dict = new Dictionary();
private readonly static Regex Validator = new Regex(@"^[a-z\d][a-z\d_.-]+$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
- protected Headers(bool asIs)
+ public Headers(bool asIs)
{
_asIs = asIs;
}
diff --git a/MediaBrowser.Dlna/Server/RawHeaders.cs b/MediaBrowser.Dlna/Server/RawHeaders.cs
deleted file mode 100644
index f57e6b9f3d..0000000000
--- a/MediaBrowser.Dlna/Server/RawHeaders.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Dlna.Server
-{
- public class RawHeaders : Headers
- {
- public RawHeaders()
- : base(true)
- {
- }
- }
-}
diff --git a/MediaBrowser.Dlna/Server/SsdpHandler.cs b/MediaBrowser.Dlna/Server/SsdpHandler.cs
index 63c2abbec4..64c1118196 100644
--- a/MediaBrowser.Dlna/Server/SsdpHandler.cs
+++ b/MediaBrowser.Dlna/Server/SsdpHandler.cs
@@ -96,7 +96,7 @@ namespace MediaBrowser.Dlna.Server
{
break;
}
- var parts = line.Split(new char[] { ':' }, 2);
+ var parts = line.Split(new[] { ':' }, 2);
headers[parts[0]] = parts[1].Trim();
}
@@ -148,7 +148,7 @@ namespace MediaBrowser.Dlna.Server
private void SendSearchResponse(IPEndPoint endpoint, UpnpDevice dev)
{
- var headers = new RawHeaders();
+ var headers = new Headers(true);
headers.Add("CACHE-CONTROL", "max-age = 600");
headers.Add("DATE", DateTime.Now.ToString("R"));
headers.Add("EXT", "");
@@ -188,7 +188,7 @@ namespace MediaBrowser.Dlna.Server
private void NotifyDevice(UpnpDevice dev, string type, bool sticky)
{
_logger.Debug("NotifyDevice");
- var headers = new RawHeaders();
+ var headers = new Headers(true);
headers.Add("HOST", "239.255.255.250:1900");
headers.Add("CACHE-CONTROL", "max-age = 600");
headers.Add("LOCATION", dev.Descriptor.ToString());
diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHelper.cs b/MediaBrowser.Dlna/Ssdp/SsdpHelper.cs
similarity index 57%
rename from MediaBrowser.Dlna/PlayTo/SsdpHelper.cs
rename to MediaBrowser.Dlna/Ssdp/SsdpHelper.cs
index d07a7679f0..b22db781ad 100644
--- a/MediaBrowser.Dlna/PlayTo/SsdpHelper.cs
+++ b/MediaBrowser.Dlna/Ssdp/SsdpHelper.cs
@@ -1,8 +1,9 @@
using System;
-using System.Linq;
+using System.Collections.Generic;
+using System.IO;
using System.Text;
-namespace MediaBrowser.Dlna.PlayTo
+namespace MediaBrowser.Dlna.Ssdp
{
public class SsdpHelper
{
@@ -29,28 +30,29 @@ namespace MediaBrowser.Dlna.PlayTo
///
/// The data.
///
- public static Uri ParseSsdpResponse(string data)
+ public static Dictionary ParseSsdpResponse(byte[] data)
{
- var res = (from line in data.Split(new[] { '\r', '\n' })
- where line.ToLowerInvariant().StartsWith("location:")
- select line).FirstOrDefault();
+ var headers = new Dictionary(StringComparer.OrdinalIgnoreCase);
- return !string.IsNullOrEmpty(res) ? new Uri(res.Substring(9).Trim()) : null;
- }
+ using (var reader = new StreamReader(new MemoryStream(data), Encoding.ASCII))
+ {
+ for (var line = reader.ReadLine(); line != null; line = reader.ReadLine())
+ {
+ line = line.Trim();
+ if (string.IsNullOrEmpty(line))
+ {
+ break;
+ }
+ var parts = line.Split(new[] { ':' }, 2);
- ///
- /// Parses data into SSDP event.
- ///
- /// The data.
- ///
- [Obsolete("Not yet used", true)]
- public static string ParseSsdpEvent(string data)
- {
- var sid = (from line in data.Split(new[] { '\r', '\n' })
- where line.ToLowerInvariant().StartsWith("sid:")
- select line).FirstOrDefault();
-
- return data;
+ if (parts.Length == 2)
+ {
+ headers[parts[0]] = parts[1].Trim();
+ }
+ }
+ }
+
+ return headers;
}
}
}
diff --git a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
index 5957938543..9a31fd0912 100644
--- a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
@@ -3,7 +3,6 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Entities;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
@@ -75,16 +74,6 @@ namespace MediaBrowser.Providers.Savers
XmlSaverHelpers.AddCommonNodes(video, builder);
- if (video.CommunityRating.HasValue)
- {
- builder.Append("" + SecurityElement.Escape(video.CommunityRating.Value.ToString(UsCulture)) + "");
- }
-
- if (!string.IsNullOrEmpty(video.Overview))
- {
- builder.Append("");
- }
-
var musicVideo = item as MusicVideo;
if (musicVideo != null)
@@ -117,8 +106,12 @@ namespace MediaBrowser.Providers.Savers
XmlSaverHelpers.Save(builder, xmlFilePath, new List
{
+ // Deprecated. No longer saving in this field.
"IMDBrating",
+
+ // Deprecated. No longer saving in this field.
"Description",
+
"Artist",
"Album",
"TmdbCollectionName"
diff --git a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
index e69f2e0850..a7ed55e5dd 100644
--- a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
@@ -60,11 +60,6 @@ namespace MediaBrowser.Providers.Savers
builder.Append("" + SecurityElement.Escape(tvdb) + "");
}
- if (!string.IsNullOrEmpty(item.Name))
- {
- builder.Append("" + SecurityElement.Escape(item.Name) + "");
- }
-
if (series.Status.HasValue)
{
builder.Append("" + SecurityElement.Escape(series.Status.Value.ToString()) + "");
@@ -111,7 +106,6 @@ namespace MediaBrowser.Providers.Savers
XmlSaverHelpers.Save(builder, xmlFilePath, new List
{
"id",
- "SeriesName",
"Status",
"Network",
"Airs_Time",
@@ -120,6 +114,10 @@ namespace MediaBrowser.Providers.Savers
// Don't preserve old series node
"Series",
+
+ "SeriesName",
+
+ // Deprecated. No longer saving in this field.
"AnimeSeriesIndex"
});
}
diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
index 391ab7cfd9..6d681197e5 100644
--- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
@@ -28,7 +28,10 @@ namespace MediaBrowser.Providers.Savers
"AwardSummary",
"BirthDate",
"Budget",
+
+ // Deprecated. No longer saving in this field.
"certification",
+
"Chapters",
"ContentRating",
"CustomRating",
@@ -40,22 +43,31 @@ namespace MediaBrowser.Providers.Savers
"Genres",
"Genre",
"GamesDbId",
+
+ // Deprecated. No longer saving in this field.
"IMDB_ID",
+
"IMDB",
+
+ // Deprecated. No longer saving in this field.
"IMDbId",
+
"Language",
"LocalTitle",
"LockData",
"LockedFields",
"Format3D",
"Metascore",
+
+ // Deprecated. No longer saving in this field.
"MPAARating",
+
"MusicBrainzArtistId",
"MusicBrainzAlbumArtistId",
"MusicBrainzAlbumId",
"MusicBrainzReleaseGroupId",
- // Old - not used anymore
+ // Deprecated. No longer saving in this field.
"MusicbrainzId",
"Overview",
@@ -67,15 +79,24 @@ namespace MediaBrowser.Providers.Savers
"Revenue",
"RottenTomatoesId",
"RunningTime",
+
+ // Deprecated. No longer saving in this field.
"Runtime",
+
"SortTitle",
"Studios",
"Tags",
+
+ // Deprecated. No longer saving in this field.
"TagLine",
+
"Taglines",
"TMDbCollectionId",
"TMDbId",
+
+ // Deprecated. No longer saving in this field.
"Trailer",
+
"Trailers",
"TVcomId",
"TvDbId",
@@ -207,8 +228,6 @@ namespace MediaBrowser.Providers.Savers
if (!string.IsNullOrEmpty(item.OfficialRating))
{
builder.Append("" + SecurityElement.Escape(item.OfficialRating) + "");
- builder.Append("" + SecurityElement.Escape(item.OfficialRating) + "");
- builder.Append("" + SecurityElement.Escape(item.OfficialRating) + "");
}
builder.Append("" + SecurityElement.Escape(item.DateCreated.ToLocalTime().ToString("G")) + "");
@@ -376,16 +395,13 @@ namespace MediaBrowser.Providers.Savers
var timespan = TimeSpan.FromTicks(runTimeTicks.Value);
builder.Append("" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "");
- builder.Append("" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "");
}
var imdb = item.GetProviderId(MetadataProviders.Imdb);
if (!string.IsNullOrEmpty(imdb))
{
- builder.Append("" + SecurityElement.Escape(imdb) + "");
builder.Append("" + SecurityElement.Escape(imdb) + "");
- builder.Append("" + SecurityElement.Escape(imdb) + "");
}
var tmdb = item.GetProviderId(MetadataProviders.Tmdb);
diff --git a/MediaBrowser.Providers/TV/SeriesXmlParser.cs b/MediaBrowser.Providers/TV/SeriesXmlParser.cs
index 0c220031c1..9f68ad7a4e 100644
--- a/MediaBrowser.Providers/TV/SeriesXmlParser.cs
+++ b/MediaBrowser.Providers/TV/SeriesXmlParser.cs
@@ -90,6 +90,8 @@ namespace MediaBrowser.Providers.TV
break;
}
case "SeriesName":
+ // TODO: Deprecate in mid-2014
+ // No longer saving this tag but will still read it for a while
item.Name = reader.ReadElementContentAsString();
break;
diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
index 02c629906c..fcfe98a46e 100644
--- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
+++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
@@ -851,7 +851,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
// Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case.
- var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=20\" -f image2 \"{1}\"", inputPath, "-", vf) :
+ var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"thumbnail,{2}\" -f image2 \"{1}\"", inputPath, "-", vf) :
string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf);
var probeSize = GetProbeSizeArgument(type);