From f3e992b82be4b23e33e6130d1495f2b5203d0576 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 01:10:33 -0400 Subject: support more profile features --- MediaBrowser.Controller/Dlna/TranscodingProfile.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Controller/Dlna/TranscodingProfile.cs') diff --git a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs index 1073f74aaf..32ffb91cf6 100644 --- a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs @@ -31,8 +31,9 @@ namespace MediaBrowser.Controller.Dlna public enum TranscodingSettingType { - Profile = 0, - MaxAudioChannels = 1 + VideoLevel = 0, + VideoProfile = 1, + MaxAudioChannels = 2 } public enum TranscodeSeekInfo -- cgit v1.2.3 From 85aa11e926ae9cba2ad58bf1087ad6efaff925a3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 12:42:02 -0400 Subject: separate profiles --- MediaBrowser.Controller/Dlna/CodecProfile.cs | 4 +- MediaBrowser.Controller/Dlna/ContainerProfile.cs | 22 + .../Dlna/DeviceIdentification.cs | 10 +- MediaBrowser.Controller/Dlna/DeviceProfile.cs | 9 +- MediaBrowser.Controller/Dlna/DirectPlayProfile.cs | 7 - MediaBrowser.Controller/Dlna/TranscodingProfile.cs | 9 +- .../MediaBrowser.Controller.csproj | 1 + MediaBrowser.Dlna/DlnaManager.cs | 1358 +++++--------------- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 10 + MediaBrowser.Dlna/PlayTo/DlnaController.cs | 5 +- MediaBrowser.Dlna/PlayTo/PlaylistItem.cs | 2 + MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs | 21 +- MediaBrowser.Dlna/PlayTo/StreamHelper.cs | 7 +- MediaBrowser.Dlna/Profiles/DefaultProfile.cs | 49 + MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs | 28 + .../Profiles/PanasonicVieraProfile.cs | 187 +++ .../Profiles/SonyBravia2010Profile.cs | 242 ++++ .../Profiles/SonyBravia2011Profile.cs | 260 ++++ .../Profiles/SonyBravia2012Profile.cs | 202 +++ .../Profiles/SonyBravia2013Profile.cs | 233 ++++ MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs | 242 ++++ MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 314 +++++ MediaBrowser.Dlna/Profiles/XboxOneProfile.cs | 60 + MediaBrowser.ServerApplication/ApplicationHost.cs | 2 +- 24 files changed, 2187 insertions(+), 1097 deletions(-) create mode 100644 MediaBrowser.Controller/Dlna/ContainerProfile.cs create mode 100644 MediaBrowser.Dlna/Profiles/DefaultProfile.cs create mode 100644 MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs create mode 100644 MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs create mode 100644 MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs create mode 100644 MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs create mode 100644 MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs create mode 100644 MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs create mode 100644 MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs create mode 100644 MediaBrowser.Dlna/Profiles/Xbox360Profile.cs create mode 100644 MediaBrowser.Dlna/Profiles/XboxOneProfile.cs (limited to 'MediaBrowser.Controller/Dlna/TranscodingProfile.cs') diff --git a/MediaBrowser.Controller/Dlna/CodecProfile.cs b/MediaBrowser.Controller/Dlna/CodecProfile.cs index 0d66d90ae8..1dc7f21396 100644 --- a/MediaBrowser.Controller/Dlna/CodecProfile.cs +++ b/MediaBrowser.Controller/Dlna/CodecProfile.cs @@ -6,12 +6,12 @@ namespace MediaBrowser.Controller.Dlna public class CodecProfile { public CodecType Type { get; set; } - public List Conditions { get; set; } + public ProfileCondition[] Conditions { get; set; } public string Codec { get; set; } public CodecProfile() { - Conditions = new List(); + Conditions = new ProfileCondition[] {}; } public List GetCodecs() diff --git a/MediaBrowser.Controller/Dlna/ContainerProfile.cs b/MediaBrowser.Controller/Dlna/ContainerProfile.cs new file mode 100644 index 0000000000..3bd3c9eaf6 --- /dev/null +++ b/MediaBrowser.Controller/Dlna/ContainerProfile.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Controller.Dlna +{ + public class ContainerProfile + { + public DlnaProfileType Type { get; set; } + public ProfileCondition[] Conditions { get; set; } + public string Container { get; set; } + + public ContainerProfile() + { + Conditions = new ProfileCondition[] { }; + } + + public List GetContainers() + { + return (Container ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + } + } +} diff --git a/MediaBrowser.Controller/Dlna/DeviceIdentification.cs b/MediaBrowser.Controller/Dlna/DeviceIdentification.cs index 20c94ad50b..461c77537c 100644 --- a/MediaBrowser.Controller/Dlna/DeviceIdentification.cs +++ b/MediaBrowser.Controller/Dlna/DeviceIdentification.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; - + namespace MediaBrowser.Controller.Dlna { public class DeviceIdentification @@ -55,11 +54,11 @@ namespace MediaBrowser.Controller.Dlna /// Gets or sets the headers. /// /// The headers. - public List Headers { get; set; } + public HttpHeaderInfo[] Headers { get; set; } public DeviceIdentification() { - Headers = new List(); + Headers = new HttpHeaderInfo[] {}; } } @@ -73,6 +72,7 @@ namespace MediaBrowser.Controller.Dlna public enum HeaderMatchType { Equals = 0, - Substring = 1 + Regex = 1, + Substring = 2 } } diff --git a/MediaBrowser.Controller/Dlna/DeviceProfile.cs b/MediaBrowser.Controller/Dlna/DeviceProfile.cs index 49568e7d43..83500e407b 100644 --- a/MediaBrowser.Controller/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Controller/Dlna/DeviceProfile.cs @@ -20,13 +20,15 @@ namespace MediaBrowser.Controller.Dlna /// /// The transcoding profiles. public TranscodingProfile[] TranscodingProfiles { get; set; } - + /// /// Gets or sets the direct play profiles. /// /// The direct play profiles. public DirectPlayProfile[] DirectPlayProfiles { get; set; } + public ContainerProfile[] ContainerProfiles { get; set; } + /// /// Gets or sets the identification. /// @@ -40,6 +42,8 @@ namespace MediaBrowser.Controller.Dlna public string ModelDescription { get; set; } public string ModelNumber { get; set; } public string ModelUrl { get; set; } + public bool IgnoreTranscodeByteRangeRequests { get; set; } + /// /// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace. /// @@ -62,13 +66,14 @@ namespace MediaBrowser.Controller.Dlna public bool RequiresPlainVideoItems { get; set; } public bool RequiresPlainFolders { get; set; } - + public DeviceProfile() { DirectPlayProfiles = new DirectPlayProfile[] { }; TranscodingProfiles = new TranscodingProfile[] { }; MediaProfiles = new MediaProfile[] { }; CodecProfiles = new CodecProfile[] { }; + ContainerProfiles = new ContainerProfile[] { }; } } } diff --git a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs index 56dd15ca32..686b31287e 100644 --- a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs +++ b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs @@ -11,13 +11,6 @@ namespace MediaBrowser.Controller.Dlna public DlnaProfileType Type { get; set; } - public List Conditions { get; set; } - - public DirectPlayProfile() - { - Conditions = new List(); - } - public List GetContainers() { return (Container ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); diff --git a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs index 32ffb91cf6..1ce2adb1ba 100644 --- a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; - + namespace MediaBrowser.Controller.Dlna { public class TranscodingProfile @@ -15,12 +14,14 @@ namespace MediaBrowser.Controller.Dlna public TranscodeSeekInfo TranscodeSeekInfo { get; set; } - public List Settings { get; set; } + public TranscodingSetting[] Settings { get; set; } public TranscodingProfile() { - Settings = new List(); + Settings = new TranscodingSetting[] { }; } + + public bool EnableMpegtsM2TsMode { get; set; } } public class TranscodingSetting diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index b51824bdb9..5e6297d060 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -79,6 +79,7 @@ + diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 7c3123b781..9588eb7b6f 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Dlna; +using MediaBrowser.Dlna.Profiles; using MediaBrowser.Model.Serialization; using System.Collections.Generic; using System.Linq; @@ -13,1035 +14,322 @@ namespace MediaBrowser.Dlna private IApplicationPaths _appPaths; private readonly IXmlSerializer _xmlSerializer; private readonly IFileSystem _fileSystem; + private readonly IJsonSerializer _jsonSerializer; - public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem) + public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IJsonSerializer jsonSerializer) { _xmlSerializer = xmlSerializer; _fileSystem = fileSystem; + _jsonSerializer = jsonSerializer; - //GetProfiles(); + GetProfiles(); } public IEnumerable GetProfiles() { var list = new List(); - list.Add(new DeviceProfile - { - Name = "Samsung TV (B Series)", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - FriendlyName = "^TV$", - ModelNumber = @"1\.0", - ModelName = "Samsung DTV DMR" - }, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio, - }, - new TranscodingProfile - { - Container = "ts", - Type = DlnaProfileType.Video - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio, - }, - new DirectPlayProfile - { - Container = "mkv", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "mp4", - Type = DlnaProfileType.Video - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="avi", - MimeType = "video/x-msvideo", - Type = DlnaProfileType.Video - }, - - new MediaProfile - { - Container ="mkv", - MimeType = "video/x-mkv", - Type = DlnaProfileType.Video - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Samsung TV (E/F-series)", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - FriendlyName = @"(^\[TV\][A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung|(^\[TV\]Samsung [A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)", - ModelNumber = @"(1\.0)|(AllShare1\.0)" - }, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new TranscodingProfile - { - Container = "ts", - Type = DlnaProfileType.Video - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "mkv", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "mp4", - Type = DlnaProfileType.Video - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="avi", - MimeType = "video/x-msvideo", - Type = DlnaProfileType.Video - }, - - new MediaProfile - { - Container ="mkv", - MimeType = "video/x-mkv", - Type = DlnaProfileType.Video - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Samsung TV (C/D-series)", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - FriendlyName = @"(^TV-\d{2}C\d{3}.*)|(^\[TV\][A-Z]{2}\d{2}(D)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung", - ModelNumber = @"(1\.0)|(AllShare1\.0)" - }, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new TranscodingProfile - { - Container = "ts", - Type = DlnaProfileType.Video - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "mkv", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "mp4", - Type = DlnaProfileType.Video - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="avi", - MimeType = "video/x-msvideo", - Type = DlnaProfileType.Video - }, - - new MediaProfile - { - Container ="mkv", - MimeType = "video/x-mkv", - Type = DlnaProfileType.Video - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Xbox 360", - ClientType = "DLNA", - - ModelName = "Windows Media Player Sharing", - ModelNumber = "12.0", - ModelUrl = "http://www.microsoft.com/", - Manufacturer = "Microsoft Corporation", - ManufacturerUrl = "http://www.microsoft.com/", - XDlnaDoc = "DMS-1.50", - - TimelineOffsetSeconds = 40, - RequiresPlainFolders = true, - RequiresPlainVideoItems = true, - - Identification = new DeviceIdentification - { - ModelName = "Xbox 360", - - Headers = new List - { - new HttpHeaderInfo{ Name="User-Agent", Value="Xbox", Match= HeaderMatchType.Substring}, - new HttpHeaderInfo{ Name="User-Agent", Value="Xenon", Match= HeaderMatchType.Substring} - } - }, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - AudioCodec = "mp3", - Type = DlnaProfileType.Audio - }, - new TranscodingProfile - { - Container = "asf", - VideoCodec = "wmv2", - AudioCodec = "wmav2", - Type = DlnaProfileType.Video, - TranscodeSeekInfo = TranscodeSeekInfo.Bytes, - EstimateContentLength = true, - - Settings = new List - { - new TranscodingSetting { Name = TranscodingSettingType.MaxAudioChannels, Value = "6" }, - new TranscodingSetting{ Name = TranscodingSettingType.VideoLevel, Value = "3"}, - new TranscodingSetting{ Name = TranscodingSettingType.VideoProfile, Value = "baseline"} - } - }, - new TranscodingProfile - { - Container = "jpeg", - Type = DlnaProfileType.Photo - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "avi", - VideoCodec = "mpeg4", - AudioCodec = "ac3,mp3", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "avi", - VideoCodec = "h264", - AudioCodec = "aac", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "mp4,mov", - VideoCodec = "h264,mpeg4", - AudioCodec = "aac,ac3", - Type = DlnaProfileType.Video, - - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Has64BitOffsets, Value = "false", IsRequired=false} - } - }, - new DirectPlayProfile - { - Container = "asf", - VideoCodec = "wmv2,wmv3,vc1", - AudioCodec = "wmav2,wmapro", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "asf", - AudioCodec = "wmav2,wmapro,wmavoice", - Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "mp3", - AudioCodec = "mp3", - Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "jpeg", - Type = DlnaProfileType.Photo, - - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Width, Value = "1920"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Height, Value = "1080"} - } - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="avi", - MimeType = "video/avi", - Type = DlnaProfileType.Video - } - }, - - CodecProfiles = new[] - { - new CodecProfile - { - Type = CodecType.VideoCodec, - Codec = "mpeg4", - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Width, Value = "1280"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Height, Value = "720"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.VideoFramerate, Value = "30", IsRequired=false}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.VideoBitrate, Value = "5120000", IsRequired=false} - } - }, - - new CodecProfile - { - Type = CodecType.VideoCodec, - Codec = "h264", - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Width, Value = "1920"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Height, Value = "1080"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.VideoLevel, Value = "41", IsRequired=false}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.VideoBitrate, Value = "10240000", IsRequired=false} - } - }, - - new CodecProfile - { - Type = CodecType.VideoCodec, - Codec = "wmv2,wmv3,vc1", - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Width, Value = "1920"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Height, Value = "1080"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.VideoFramerate, Value = "30", IsRequired=false}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.VideoBitrate, Value = "15360000", IsRequired=false} - } - }, - - new CodecProfile - { - Type = CodecType.VideoAudioCodec, - Codec = "ac3,wmav2,wmapro", - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.AudioChannels, Value = "6", IsRequired=false} - } - }, - - new CodecProfile - { - Type = CodecType.VideoAudioCodec, - Codec = "aac", - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.AudioChannels, Value = "6", IsRequired=false}, - new ProfileCondition{ Condition = ProfileConditionType.Equals, Property = ProfileConditionValue.AudioProfile, Value = "lc", IsRequired=false} - } - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Xbox One", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - ModelName = "Xbox One", - FriendlyName = "Xbox-SystemOS" - }, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new TranscodingProfile - { - Container = "ts", - Type = DlnaProfileType.Video - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="avi", - MimeType = "video/x-msvideo", - Type = DlnaProfileType.Video - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Sony Bravia (2012)", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - FriendlyName = @"BRAVIA KDL-\d{2}[A-Z]X\d5(\d|G).*" - }, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new TranscodingProfile - { - Container = "ts", - Type = DlnaProfileType.Video - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "asf", - Type = DlnaProfileType.Audio - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="avi", - MimeType = "video/avi", - Type = DlnaProfileType.Video - }, - - new MediaProfile - { - Container ="asf", - MimeType = "video/x-ms-wmv", - Type = DlnaProfileType.Audio - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Sony Bravia (2013)", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - FriendlyName = @"BRAVIA (KDL-\d{2}W[689]\d{2}A.*)|(KD-\d{2}X9\d{3}A.*)" - }, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new TranscodingProfile - { - Container = "ts", - Type = DlnaProfileType.Video - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "wma", - Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video - }, - new DirectPlayProfile - { - Container = "mp4", - Type = DlnaProfileType.Video - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="avi", - MimeType = "video/avi", - Type = DlnaProfileType.Video - }, - - new MediaProfile - { - Container ="mp4", - MimeType = "video/mp4", - Type = DlnaProfileType.Video - }, - - new MediaProfile - { - Container ="ts", - MimeType = "video/mpeg", - Type = DlnaProfileType.Video - }, - - new MediaProfile - { - Container ="wma", - MimeType = "video/x-ms-wma", - Type = DlnaProfileType.Audio - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Panasonic Viera", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - FriendlyName = @"VIERA", - Manufacturer = "Panasonic", - - Headers = new List - { - new HttpHeaderInfo{ Name= "User-Agent", Value = "Panasonic MIL DLNA", Match = HeaderMatchType.Substring} - } - }, - - TimelineOffsetSeconds = 10, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - AudioCodec = "mp3", - Type = DlnaProfileType.Audio - }, - new TranscodingProfile - { - Container = "ts", - AudioCodec = "ac3", - VideoCodec = "h264", - Type = DlnaProfileType.Video - }, - new TranscodingProfile - { - Container = "jpeg", - Type = DlnaProfileType.Photo - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mpeg", - VideoCodec = "mpeg2video,mpeg4", - AudioCodec = "ac3,mp3", - Type = DlnaProfileType.Video - }, - - new DirectPlayProfile - { - Container = "mkv", - VideoCodec = "h264", - AudioCodec = "aac,ac3,mp3,pcm", - Type = DlnaProfileType.Video - }, - - new DirectPlayProfile - { - Container = "ts", - VideoCodec = "h264", - AudioCodec = "aac,mp3", - Type = DlnaProfileType.Video - }, - - new DirectPlayProfile - { - Container = "mp4", - VideoCodec = "h264", - AudioCodec = "aac,ac3,mp3,pcm", - Type = DlnaProfileType.Video - }, - - new DirectPlayProfile - { - Container = "mov", - VideoCodec = "h264", - AudioCodec = "aac,pcm", - Type = DlnaProfileType.Video - }, - - new DirectPlayProfile - { - Container = "avi", - VideoCodec = "mpeg4", - AudioCodec = "pcm", - Type = DlnaProfileType.Video - }, - - new DirectPlayProfile - { - Container = "flv", - VideoCodec = "h264", - AudioCodec = "aac", - Type = DlnaProfileType.Video - }, - - new DirectPlayProfile - { - Container = "mp3", - AudioCodec = "mp3", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "mp4", - AudioCodec = "aac", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "jpeg", - Type = DlnaProfileType.Photo, - - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Width, Value = "1920"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Height, Value = "1080"} - } - } - }, - - CodecProfiles = new [] - { - new CodecProfile - { - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Width, Value = "1920"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Height, Value = "1080"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.VideoBitDepth, Value = "8", IsRequired = false} - } - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Philips (2010-)", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - FriendlyName = ".*PHILIPS.*", - ModelName = "WD TV HD Live" - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3,wma", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video - }, - - new DirectPlayProfile - { - Container = "mkv", - Type = DlnaProfileType.Video - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="avi", - MimeType = "video/avi", - Type = DlnaProfileType.Video - }, - - new MediaProfile - { - Container ="mkv", - MimeType = "video/x-matroska", - Type = DlnaProfileType.Video - } - } - }); - - list.Add(new DeviceProfile - { - Name = "WDTV Live", - ClientType = "DLNA", - - TimelineOffsetSeconds = 5, - - Identification = new DeviceIdentification - { - ModelName = "WD TV HD Live", - - Headers = new List - { - new HttpHeaderInfo{ Name="User-Agent", Value="alphanetworks", Match= HeaderMatchType.Substring}, - new HttpHeaderInfo{ Name="User-Agent", Value="ALPHA Networks", Match= HeaderMatchType.Substring} - } - }, - - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - Type = DlnaProfileType.Audio, - AudioCodec = "mp3" - }, - new TranscodingProfile - { - Container = "ts", - Type = DlnaProfileType.Video, - VideoCodec = "h264", - AudioCodec = "aac", - - Settings = new List - { - new TranscodingSetting{ Name = TranscodingSettingType.VideoLevel, Value = "3"}, - new TranscodingSetting{ Name = TranscodingSettingType.VideoProfile, Value = "baseline"} - } - }, - new TranscodingProfile - { - Container = "jpeg", - Type = DlnaProfileType.Photo - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video, - VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1", - AudioCodec = "ac3,dca,mp2,mp3,pcm" - }, - - new DirectPlayProfile - { - Container = "mpeg", - Type = DlnaProfileType.Video, - VideoCodec = "mpeg1video,mpeg2video", - AudioCodec = "ac3,dca,mp2,mp3,pcm" - }, - - new DirectPlayProfile - { - Container = "mkv", - Type = DlnaProfileType.Video, - VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1", - AudioCodec = "ac3,dca,aac,mp2,mp3,pcm" - }, - - new DirectPlayProfile - { - Container = "ts", - Type = DlnaProfileType.Video, - VideoCodec = "mpeg1video,mpeg2video,h264,vc1", - AudioCodec = "ac3,dca,mp2,mp3" - }, - - new DirectPlayProfile - { - Container = "mp4,mov", - Type = DlnaProfileType.Video, - VideoCodec = "h264,mpeg4", - AudioCodec = "ac3,aac,mp2,mp3" - }, - - new DirectPlayProfile - { - Container = "asf", - Type = DlnaProfileType.Video, - VideoCodec = "vc1", - AudioCodec = "wmav2,wmapro" - }, - - new DirectPlayProfile - { - Container = "asf", - Type = DlnaProfileType.Video, - VideoCodec = "mpeg2video", - AudioCodec = "mp2,ac3" - }, - - new DirectPlayProfile - { - Container = "mp3", - AudioCodec = "mp2,mp3", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "mp4", - AudioCodec = "mp4", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "flac", - AudioCodec = "flac", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "asf", - AudioCodec = "wmav2,wmapro,wmavoice", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "ogg", - AudioCodec = "vorbis", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Type = DlnaProfileType.Photo, - - Container = "jpeg,png,gif,bmp,tiff", - - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Width, Value = "1920"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Height, Value = "1080"} - } - } - }, - - MediaProfiles = new[] - { - new MediaProfile - { - Container ="ts", - OrgPn = "MPEG_TS_SD_NA", - Type = DlnaProfileType.Video - } - }, - - CodecProfiles = new[] - { - new CodecProfile - { - Type = CodecType.VideoCodec, - Codec= "h264", - - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Width, Value = "1920"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.Height, Value = "1080"}, - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.VideoLevel, Value = "41"} - } - }, - - new CodecProfile - { - Type = CodecType.VideoAudioCodec, - Codec= "aac", - - Conditions = new List - { - new ProfileCondition{ Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.AudioChannels, Value = "2"} - } - } - } - }); - - list.Add(new DeviceProfile - { - // Linksys DMA2100us does not need any transcoding of the formats we support statically - Name = "Linksys DMA2100", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - ModelName = "DMA2100us" - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3,flac,m4a,wma", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "avi,mp4,mkv,ts", - Type = DlnaProfileType.Video - } - } - }); - - list.Add(new DeviceProfile - { - Name = "Denon AVR", - ClientType = "DLNA", - - Identification = new DeviceIdentification - { - FriendlyName = @"Denon:\[AVR:.*", - Manufacturer = "Denon" - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3,flac,m4a,wma", - Type = DlnaProfileType.Audio - }, - } - }); + //list.Add(new DeviceProfile + //{ + // Name = "Samsung TV (B Series)", + // ClientType = "DLNA", + + // Identification = new DeviceIdentification + // { + // FriendlyName = "^TV$", + // ModelNumber = @"1\.0", + // ModelName = "Samsung DTV DMR" + // }, + + // TranscodingProfiles = new[] + // { + // new TranscodingProfile + // { + // Container = "mp3", + // Type = DlnaProfileType.Audio, + // }, + // new TranscodingProfile + // { + // Container = "ts", + // Type = DlnaProfileType.Video + // } + // }, + + // DirectPlayProfiles = new[] + // { + // new DirectPlayProfile + // { + // Container = "mp3", + // Type = DlnaProfileType.Audio, + // }, + // new DirectPlayProfile + // { + // Container = "mkv", + // Type = DlnaProfileType.Video + // }, + // new DirectPlayProfile + // { + // Container = "avi", + // Type = DlnaProfileType.Video + // }, + // new DirectPlayProfile + // { + // Container = "mp4", + // Type = DlnaProfileType.Video + // } + // }, + + // MediaProfiles = new[] + // { + // new MediaProfile + // { + // Container ="avi", + // MimeType = "video/x-msvideo", + // Type = DlnaProfileType.Video + // }, + + // new MediaProfile + // { + // Container ="mkv", + // MimeType = "video/x-mkv", + // Type = DlnaProfileType.Video + // } + // } + //}); + + //list.Add(new DeviceProfile + //{ + // Name = "Samsung TV (E/F-series)", + // ClientType = "DLNA", + + // Identification = new DeviceIdentification + // { + // FriendlyName = @"(^\[TV\][A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung|(^\[TV\]Samsung [A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)", + // ModelNumber = @"(1\.0)|(AllShare1\.0)" + // }, + + // TranscodingProfiles = new[] + // { + // new TranscodingProfile + // { + // Container = "mp3", + // Type = DlnaProfileType.Audio + // }, + // new TranscodingProfile + // { + // Container = "ts", + // Type = DlnaProfileType.Video + // } + // }, + + // DirectPlayProfiles = new[] + // { + // new DirectPlayProfile + // { + // Container = "mp3", + // Type = DlnaProfileType.Audio + // }, + // new DirectPlayProfile + // { + // Container = "mkv", + // Type = DlnaProfileType.Video + // }, + // new DirectPlayProfile + // { + // Container = "avi", + // Type = DlnaProfileType.Video + // }, + // new DirectPlayProfile + // { + // Container = "mp4", + // Type = DlnaProfileType.Video + // } + // }, + + // MediaProfiles = new[] + // { + // new MediaProfile + // { + // Container ="avi", + // MimeType = "video/x-msvideo", + // Type = DlnaProfileType.Video + // }, + + // new MediaProfile + // { + // Container ="mkv", + // MimeType = "video/x-mkv", + // Type = DlnaProfileType.Video + // } + // } + //}); + + //list.Add(new DeviceProfile + //{ + // Name = "Samsung TV (C/D-series)", + // ClientType = "DLNA", + + // Identification = new DeviceIdentification + // { + // FriendlyName = @"(^TV-\d{2}C\d{3}.*)|(^\[TV\][A-Z]{2}\d{2}(D)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung", + // ModelNumber = @"(1\.0)|(AllShare1\.0)" + // }, + + // TranscodingProfiles = new[] + // { + // new TranscodingProfile + // { + // Container = "mp3", + // Type = DlnaProfileType.Audio + // }, + // new TranscodingProfile + // { + // Container = "ts", + // Type = DlnaProfileType.Video + // } + // }, + + // DirectPlayProfiles = new[] + // { + // new DirectPlayProfile + // { + // Container = "mp3", + // Type = DlnaProfileType.Audio + // }, + // new DirectPlayProfile + // { + // Container = "mkv", + // Type = DlnaProfileType.Video + // }, + // new DirectPlayProfile + // { + // Container = "avi", + // Type = DlnaProfileType.Video + // }, + // new DirectPlayProfile + // { + // Container = "mp4", + // Type = DlnaProfileType.Video + // } + // }, + + // MediaProfiles = new[] + // { + // new MediaProfile + // { + // Container ="avi", + // MimeType = "video/x-msvideo", + // Type = DlnaProfileType.Video + // }, + + // new MediaProfile + // { + // Container ="mkv", + // MimeType = "video/x-mkv", + // Type = DlnaProfileType.Video + // } + // } + //}); + + list.Add(new Xbox360Profile()); + + list.Add(new XboxOneProfile()); + + list.Add(new SonyBravia2010Profile()); + + list.Add(new SonyBravia2011Profile()); + + list.Add(new SonyBravia2012Profile()); + + list.Add(new SonyBravia2013Profile()); + + list.Add(new PanasonicVieraProfile()); + + //list.Add(new DeviceProfile + //{ + // Name = "Philips (2010-)", + // ClientType = "DLNA", + + // Identification = new DeviceIdentification + // { + // FriendlyName = ".*PHILIPS.*", + // ModelName = "WD TV HD Live" + // }, + + // DirectPlayProfiles = new[] + // { + // new DirectPlayProfile + // { + // Container = "mp3,wma", + // Type = DlnaProfileType.Audio + // }, + + // new DirectPlayProfile + // { + // Container = "avi", + // Type = DlnaProfileType.Video + // }, + + // new DirectPlayProfile + // { + // Container = "mkv", + // Type = DlnaProfileType.Video + // } + // }, + + // MediaProfiles = new[] + // { + // new MediaProfile + // { + // Container ="avi", + // MimeType = "video/avi", + // Type = DlnaProfileType.Video + // }, + + // new MediaProfile + // { + // Container ="mkv", + // MimeType = "video/x-matroska", + // Type = DlnaProfileType.Video + // } + // } + //}); + + list.Add(new WdtvLiveProfile()); + + //list.Add(new DeviceProfile + //{ + // // Linksys DMA2100us does not need any transcoding of the formats we support statically + // Name = "Linksys DMA2100", + // ClientType = "DLNA", + + // Identification = new DeviceIdentification + // { + // ModelName = "DMA2100us" + // }, + + // DirectPlayProfiles = new[] + // { + // new DirectPlayProfile + // { + // Container = "mp3,flac,m4a,wma", + // Type = DlnaProfileType.Audio + // }, + + // new DirectPlayProfile + // { + // Container = "avi,mp4,mkv,ts", + // Type = DlnaProfileType.Video + // } + // } + //}); + + list.Add(new DenonAvrProfile()); foreach (var item in list) { - //_xmlSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name)); + //_xmlSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".xml"); + //_jsonSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".json"); } return list; @@ -1049,45 +337,7 @@ namespace MediaBrowser.Dlna public DeviceProfile GetDefaultProfile() { - return new DeviceProfile - { - TranscodingProfiles = new[] - { - new TranscodingProfile - { - Container = "mp3", - AudioCodec = "mp3", - Type = DlnaProfileType.Audio - }, - new TranscodingProfile - { - Container = "ts", - Type = DlnaProfileType.Video, - AudioCodec = "aac", - VideoCodec = "h264", - Settings = new List - { - new TranscodingSetting{ Name = TranscodingSettingType.VideoLevel, Value = "3"}, - new TranscodingSetting{ Name = TranscodingSettingType.VideoProfile, Value = "baseline"} - } - } - }, - - DirectPlayProfiles = new[] - { - new DirectPlayProfile - { - Container = "mp3,wma", - Type = DlnaProfileType.Audio - }, - - new DirectPlayProfile - { - Container = "avi,mp4", - Type = DlnaProfileType.Video - } - } - }; + return new DefaultProfile(); } public DeviceProfile GetProfile(DeviceIdentification deviceInfo) diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 800fb1b236..590d6378f6 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -81,6 +81,16 @@ + + + + + + + + + + diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs index 4f9c92da52..ecda07f0bc 100644 --- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs +++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs @@ -399,8 +399,11 @@ namespace MediaBrowser.Dlna.PlayTo var deviceInfo = _device.Properties; - var playlistItem = GetPlaylistItem(item, streams, _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification())); + var profile = _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification()); + + var playlistItem = GetPlaylistItem(item, streams, profile); playlistItem.StartPositionTicks = startPostionTicks; + playlistItem.DeviceProfileName = profile.Name; if (playlistItem.MediaType == DlnaProfileType.Audio) { diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs index 77b9085f75..3992fbfbf5 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs @@ -32,6 +32,8 @@ namespace MediaBrowser.Dlna.PlayTo public int? AudioStreamIndex { get; set; } public int? SubtitleStreamIndex { get; set; } + + public string DeviceProfileName { get; set; } public PlaylistItem() { diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs index a9a33ee3dc..31f15b1c31 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs @@ -47,6 +47,7 @@ namespace MediaBrowser.Dlna.PlayTo playlistItem.Transcode = true; playlistItem.TranscodingSettings = transcodingProfile.Settings.ToList(); playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.'); + playlistItem.AudioCodec = transcodingProfile.AudioCodec; } return playlistItem; @@ -118,6 +119,8 @@ namespace MediaBrowser.Dlna.PlayTo playlistItem.Transcode = true; playlistItem.TranscodingSettings = transcodingProfile.Settings.ToList(); playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.'); + playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',').FirstOrDefault(); + playlistItem.VideoCodec = transcodingProfile.VideoCodec; } return playlistItem; @@ -137,12 +140,6 @@ namespace MediaBrowser.Dlna.PlayTo } } - // Check additional conditions - if (!profile.Conditions.Any(i => IsConditionSatisfied(i, mediaPath, null, null))) - { - return false; - } - return true; } @@ -160,12 +157,6 @@ namespace MediaBrowser.Dlna.PlayTo } } - // Check additional conditions - if (!profile.Conditions.Any(i => IsConditionSatisfied(i, mediaPath, null, audioStream))) - { - return false; - } - return true; } @@ -210,12 +201,6 @@ namespace MediaBrowser.Dlna.PlayTo } } - // Check additional conditions - if (!profile.Conditions.Any(i => IsConditionSatisfied(i, mediaPath, videoStream, audioStream))) - { - return false; - } - return true; } diff --git a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs index 2a8e2d6170..6cd66c16ae 100644 --- a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs +++ b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Dlna.PlayTo /// System.String. internal static string GetAudioUrl(DeviceInfo deviceProperties, PlaylistItem item, List streams, string serverAddress) { - var dlnaCommand = BuildDlnaUrl(item.MediaSourceId, deviceProperties.UUID, !item.Transcode, null, item.AudioCodec, item.AudioStreamIndex, item.SubtitleStreamIndex, null, 128000, item.StartPositionTicks, item.TranscodingSettings); + var dlnaCommand = BuildDlnaUrl(item.DeviceProfileName, item.MediaSourceId, deviceProperties.UUID, !item.Transcode, null, item.AudioCodec, item.AudioStreamIndex, item.SubtitleStreamIndex, null, 128000, item.StartPositionTicks, item.TranscodingSettings); return string.Format("{0}/audio/{1}/stream{2}?{3}", serverAddress, item.ItemId, "." + item.Container.TrimStart('.'), dlnaCommand); } @@ -33,7 +33,7 @@ namespace MediaBrowser.Dlna.PlayTo /// The url to send to the device internal static string GetVideoUrl(DeviceInfo deviceProperties, PlaylistItem item, List streams, string serverAddress) { - var dlnaCommand = BuildDlnaUrl(item.MediaSourceId, deviceProperties.UUID, !item.Transcode, item.VideoCodec, item.AudioCodec, item.AudioStreamIndex, item.SubtitleStreamIndex, 1500000, 128000, item.StartPositionTicks, item.TranscodingSettings); + var dlnaCommand = BuildDlnaUrl(item.DeviceProfileName, item.MediaSourceId, deviceProperties.UUID, !item.Transcode, item.VideoCodec, item.AudioCodec, item.AudioStreamIndex, item.SubtitleStreamIndex, 1500000, 128000, item.StartPositionTicks, item.TranscodingSettings); return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.Container, dlnaCommand); } @@ -41,7 +41,7 @@ namespace MediaBrowser.Dlna.PlayTo /// /// Builds the dlna URL. /// - private static string BuildDlnaUrl(string mediaSourceId, string deviceID, bool isStatic, string videoCodec, string audioCodec, int? audiostreamIndex, int? subtitleIndex, int? videoBitrate, int? audioBitrate, long? startPositionTicks, List settings) + private static string BuildDlnaUrl(string deviceProfileName, string mediaSourceId, string deviceID, bool isStatic, string videoCodec, string audioCodec, int? audiostreamIndex, int? subtitleIndex, int? videoBitrate, int? audioBitrate, long? startPositionTicks, List settings) { var profile = settings.Where(i => i.Name == TranscodingSettingType.VideoProfile).Select(i => i.Value).FirstOrDefault(); var videoLevel = settings.Where(i => i.Name == TranscodingSettingType.VideoLevel).Select(i => i.Value).FirstOrDefault(); @@ -51,6 +51,7 @@ namespace MediaBrowser.Dlna.PlayTo var list = new List { + deviceProfileName ?? string.Empty, deviceID ?? string.Empty, mediaSourceId ?? string.Empty, isStatic.ToString().ToLower(), diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs new file mode 100644 index 0000000000..2580e8f8cf --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs @@ -0,0 +1,49 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class DefaultProfile : DeviceProfile + { + public DefaultProfile() + { + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + + new TranscodingProfile + { + Container = "ts", + Type = DlnaProfileType.Video, + AudioCodec = "aac", + VideoCodec = "h264", + + Settings = new [] + { + new TranscodingSetting {Name = TranscodingSettingType.VideoLevel, Value = "3"}, + new TranscodingSetting {Name = TranscodingSettingType.VideoProfile, Value = "baseline"} + } + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "mp3,wma", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "avi,mp4", + Type = DlnaProfileType.Video + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs b/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs new file mode 100644 index 0000000000..8029912d01 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs @@ -0,0 +1,28 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class DenonAvrProfile : DefaultProfile + { + public DenonAvrProfile() + { + Name = "Denon AVR"; + ClientType = "DLNA"; + + Identification = new DeviceIdentification + { + FriendlyName = @"Denon:\[AVR:.*", + Manufacturer = "Denon" + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "mp3,flac,m4a,wma", + Type = DlnaProfileType.Audio + }, + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs new file mode 100644 index 0000000000..ced648e5cc --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs @@ -0,0 +1,187 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class PanasonicVieraProfile : DefaultProfile + { + public PanasonicVieraProfile() + { + Name = "Panasonic Viera"; + ClientType = "DLNA"; + + Identification = new DeviceIdentification + { + FriendlyName = @"VIERA", + Manufacturer = "Panasonic", + + Headers = new[] + { + new HttpHeaderInfo + { + Name = "User-Agent", + Value = "Panasonic MIL DLNA", + Match = HeaderMatchType.Substring + } + } + }; + + TimelineOffsetSeconds = 10; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new TranscodingProfile + { + Container = "ts", + AudioCodec = "ac3", + VideoCodec = "h264", + Type = DlnaProfileType.Video + }, + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "mpeg", + VideoCodec = "mpeg2video,mpeg4", + AudioCodec = "ac3,mp3", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "mkv", + VideoCodec = "h264", + AudioCodec = "aac,ac3,mp3,pcm", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "aac,mp3", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "mp4", + VideoCodec = "h264", + AudioCodec = "aac,ac3,mp3,pcm", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "mov", + VideoCodec = "h264", + AudioCodec = "aac,pcm", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "avi", + VideoCodec = "mpeg4", + AudioCodec = "pcm", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "flv", + VideoCodec = "h264", + AudioCodec = "aac", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "mp4", + AudioCodec = "aac", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + ContainerProfiles = new[] + { + new ContainerProfile + { + Type = DlnaProfileType.Photo, + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + } + }; + + CodecProfiles = new[] + { + new CodecProfile + { + Type = CodecType.VideoCodec, + + Conditions = new[] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitDepth, + Value = "8", + IsRequired = false + } + } + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs new file mode 100644 index 0000000000..32eab4ae46 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs @@ -0,0 +1,242 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class SonyBravia2010Profile : DefaultProfile + { + public SonyBravia2010Profile() + { + Name = "Sony Bravia (2010)"; + ClientType = "DLNA"; + + Identification = new DeviceIdentification + { + FriendlyName = @"KDL-\d{2}[EHLNPB]X\d[01]\d.*", + Manufacturer = "Sony", + + Headers = new [] + { + new HttpHeaderInfo + { + Name = "X-AV-Client-Info", + Value = @".*KDL-\d{2}[EHLNPB]X\d[01]\d.*", + Match = HeaderMatchType.Regex + } + } + }; + + ModelName = "Windows Media Player Sharing"; + ModelNumber = "3.0"; + ModelUrl = "http://www.microsoft.com/"; + Manufacturer = "Microsoft Corporation"; + ManufacturerUrl = "http://www.microsoft.com/"; + SonyAggregationFlags = "10"; + ProtocolInfo = + "http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000"; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new TranscodingProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "ac3,aac", + Type = DlnaProfileType.Video, + EnableMpegtsM2TsMode = true + }, + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "ac3,aac,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "mpeg1video,mpeg2video", + AudioCodec = "mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mpeg", + VideoCodec = "mpeg2video,mpeg1video", + AudioCodec = "mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "avi", + MimeType = "video/avi", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "asf", + MimeType = "video/x-ms-wmv", + Type = DlnaProfileType.Audio + } + }; + + ContainerProfiles = new[] + { + new ContainerProfile + { + Type = DlnaProfileType.Photo, + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + } + }; + + CodecProfiles = new[] + { + new CodecProfile + { + Type = CodecType.VideoCodec, + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "h264", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoFramerate, + Value = "30" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "20000000" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "41" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "mpeg2video", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoFramerate, + Value = "30" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "20000000" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "aac", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "2" + }, + new ProfileCondition + { + Condition = ProfileConditionType.NotEquals, + Property = ProfileConditionValue.AudioProfile, + Value = "he-aac" + } + } + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs new file mode 100644 index 0000000000..c679dec21f --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs @@ -0,0 +1,260 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class SonyBravia2011Profile : DefaultProfile + { + public SonyBravia2011Profile() + { + Name = "Sony Bravia (2011)"; + ClientType = "DLNA"; + + Identification = new DeviceIdentification + { + FriendlyName = @"KDL-\d{2}([A-Z]X\d2\d|CX400).*", + Manufacturer = "Sony", + + Headers = new[] + { + new HttpHeaderInfo + { + Name = "X-AV-Client-Info", + Value = @".*KDL-\d{2}([A-Z]X\d2\d|CX400).*", + Match = HeaderMatchType.Regex + } + } + }; + + ModelName = "Windows Media Player Sharing"; + ModelNumber = "3.0"; + ModelUrl = "http://www.microsoft.com/"; + Manufacturer = "Microsoft Corporation"; + ManufacturerUrl = "http://www.microsoft.com/"; + SonyAggregationFlags = "10"; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new TranscodingProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "ac3,aac", + Type = DlnaProfileType.Video, + EnableMpegtsM2TsMode = true + }, + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "ac3,aac,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "mpeg2video", + AudioCodec = "mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp4", + VideoCodec = "h264,mpeg4", + AudioCodec = "ac3,aac,mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mpeg", + VideoCodec = "mpeg2video,mpeg1video", + AudioCodec = "mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "asf", + VideoCodec = "wmv2,wmv3,vc1", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "asf", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Audio + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "avi", + MimeType = "video/avi", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "asf", + MimeType = "video/x-ms-wmv", + Type = DlnaProfileType.Audio + } + }; + + ContainerProfiles = new[] + { + new ContainerProfile + { + Type = DlnaProfileType.Photo, + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + } + }; + + CodecProfiles = new[] + { + new CodecProfile + { + Type = CodecType.VideoCodec, + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "h264", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoFramerate, + Value = "30" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "20000000" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "41" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "mpeg2video", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoFramerate, + Value = "30" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "20000000" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "aac", + + Conditions = new[] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "2" + }, + new ProfileCondition + { + Condition = ProfileConditionType.NotEquals, + Property = ProfileConditionValue.AudioProfile, + Value = "he-aac" + } + } + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs new file mode 100644 index 0000000000..488b7f7406 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs @@ -0,0 +1,202 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class SonyBravia2012Profile : DefaultProfile + { + public SonyBravia2012Profile() + { + Name = "Sony Bravia (2012)"; + ClientType = "DLNA"; + + Identification = new DeviceIdentification + { + FriendlyName = @"KDL-\d{2}[A-Z]X\d5(\d|G).*", + Manufacturer = "Sony", + + Headers = new[] + { + new HttpHeaderInfo + { + Name = "X-AV-Client-Info", + Value = @".*KDL-\d{2}[A-Z]X\d5(\d|G).*", + Match = HeaderMatchType.Regex + } + } + }; + + ModelName = "Windows Media Player Sharing"; + ModelNumber = "3.0"; + ModelUrl = "http://www.microsoft.com/"; + Manufacturer = "Microsoft Corporation"; + ManufacturerUrl = "http://www.microsoft.com/"; + SonyAggregationFlags = "10"; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new TranscodingProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "ac3,aac", + Type = DlnaProfileType.Video, + EnableMpegtsM2TsMode = true + }, + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "ac3,aac,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "mpeg2video", + AudioCodec = "mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp4", + VideoCodec = "h264,mpeg4", + AudioCodec = "ac3,aac,mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "avi", + VideoCodec = "mpeg4", + AudioCodec = "ac3,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mpeg", + VideoCodec = "mpeg2video,mpeg1video", + AudioCodec = "mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "asf", + VideoCodec = "wmv2,wmv3,vc1", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "asf", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "avi", + MimeType = "video/avi", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "asf", + MimeType = "video/x-ms-wmv", + Type = DlnaProfileType.Audio + } + }; + + ContainerProfiles = new[] + { + new ContainerProfile + { + Type = DlnaProfileType.Photo, + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + } + }; + + CodecProfiles = new[] + { + new CodecProfile + { + Type = CodecType.VideoCodec, + Conditions = new[] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3", + + Conditions = new[] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6" + } + } + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs new file mode 100644 index 0000000000..21a6ad40ac --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs @@ -0,0 +1,233 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class SonyBravia2013Profile : DefaultProfile + { + public SonyBravia2013Profile() + { + Name = "Sony Bravia (2013)"; + ClientType = "DLNA"; + + Identification = new DeviceIdentification + { + FriendlyName = @"KDL-\d{2}[WR][5689]\d{2}A.*", + Manufacturer = "Sony", + + Headers = new[] + { + new HttpHeaderInfo + { + Name = "X-AV-Client-Info", + Value = @".*KDL-\d{2}[WR][5689]\d{2}A.*", + Match = HeaderMatchType.Regex + } + } + }; + + ModelName = "Windows Media Player Sharing"; + ModelNumber = "3.0"; + ModelUrl = "http://www.microsoft.com/"; + Manufacturer = "Microsoft Corporation"; + ManufacturerUrl = "http://www.microsoft.com/"; + SonyAggregationFlags = "10"; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + Type = DlnaProfileType.Audio + }, + new TranscodingProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "ac3,aac", + Type = DlnaProfileType.Video, + EnableMpegtsM2TsMode = true + }, + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "ac3,eac3,aac,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "mpeg2video", + AudioCodec = "mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp4", + VideoCodec = "h264,mpeg4", + AudioCodec = "ac3,eac3,aac,mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mov", + VideoCodec = "h264,mpeg4,mjpeg", + AudioCodec = "ac3,eac3,aac,mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mkv", + VideoCodec = "h264,mpeg4,vp8", + AudioCodec = "ac3,eac3,aac,mp3,mp2,pcm,vorbis", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "avi", + VideoCodec = "mpeg4", + AudioCodec = "ac3,eac3,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "avi", + VideoCodec = "mjpeg", + AudioCodec = "pcm", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mpeg", + VideoCodec = "mpeg2video,mpeg1video", + AudioCodec = "mp3,mp2", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "asf", + VideoCodec = "wmv2,wmv3,vc1", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "mp4", + AudioCodec = "aac", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "wav", + AudioCodec = "pcm", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "asf", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + ContainerProfiles = new[] + { + new ContainerProfile + { + Type = DlnaProfileType.Photo, + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "avi", + MimeType = "video/avi", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "mp4", + MimeType = "video/mp4", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "ts", + MimeType = "video/mpeg", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "wma", + MimeType = "video/x-ms-wma", + Type = DlnaProfileType.Audio + } + }; + + CodecProfiles = new[] + { + new CodecProfile + { + Type = CodecType.VideoCodec, + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs new file mode 100644 index 0000000000..3487044a97 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs @@ -0,0 +1,242 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class WdtvLiveProfile : DefaultProfile + { + public WdtvLiveProfile() + { + Name = "WDTV Live"; + ClientType = "DLNA"; + + TimelineOffsetSeconds = 5; + IgnoreTranscodeByteRangeRequests = true; + + Identification = new DeviceIdentification + { + ModelName = "WD TV HD Live", + + Headers = new [] + { + new HttpHeaderInfo {Name = "User-Agent", Value = "alphanetworks", Match = HeaderMatchType.Substring}, + new HttpHeaderInfo + { + Name = "User-Agent", + Value = "ALPHA Networks", + Match = HeaderMatchType.Substring + } + } + }; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + Type = DlnaProfileType.Audio, + AudioCodec = "mp3" + }, + new TranscodingProfile + { + Container = "ts", + Type = DlnaProfileType.Video, + VideoCodec = "h264", + AudioCodec = "aac", + + Settings = new [] + { + new TranscodingSetting {Name = TranscodingSettingType.VideoLevel, Value = "3"}, + new TranscodingSetting {Name = TranscodingSettingType.VideoProfile, Value = "baseline"} + } + }, + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "avi", + Type = DlnaProfileType.Video, + VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1", + AudioCodec = "ac3,dca,mp2,mp3,pcm" + }, + + new DirectPlayProfile + { + Container = "mpeg", + Type = DlnaProfileType.Video, + VideoCodec = "mpeg1video,mpeg2video", + AudioCodec = "ac3,dca,mp2,mp3,pcm" + }, + + new DirectPlayProfile + { + Container = "mkv", + Type = DlnaProfileType.Video, + VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1", + AudioCodec = "ac3,dca,aac,mp2,mp3,pcm" + }, + + new DirectPlayProfile + { + Container = "ts", + Type = DlnaProfileType.Video, + VideoCodec = "mpeg1video,mpeg2video,h264,vc1", + AudioCodec = "ac3,dca,mp2,mp3" + }, + + new DirectPlayProfile + { + Container = "mp4,mov", + Type = DlnaProfileType.Video, + VideoCodec = "h264,mpeg4", + AudioCodec = "ac3,aac,mp2,mp3" + }, + + new DirectPlayProfile + { + Container = "asf", + Type = DlnaProfileType.Video, + VideoCodec = "vc1", + AudioCodec = "wmav2,wmapro" + }, + + new DirectPlayProfile + { + Container = "asf", + Type = DlnaProfileType.Video, + VideoCodec = "mpeg2video", + AudioCodec = "mp2,ac3" + }, + + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp2,mp3", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "mp4", + AudioCodec = "mp4", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "flac", + AudioCodec = "flac", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "asf", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Container = "ogg", + AudioCodec = "vorbis", + Type = DlnaProfileType.Audio + }, + + new DirectPlayProfile + { + Type = DlnaProfileType.Photo, + + Container = "jpeg,png,gif,bmp,tiff" + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "ts", + OrgPn = "MPEG_TS_SD_NA", + Type = DlnaProfileType.Video + } + }; + + ContainerProfiles = new[] + { + new ContainerProfile + { + Type = DlnaProfileType.Photo, + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + } + }; + + CodecProfiles = new[] + { + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "h264", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "41" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "aac", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "2" + } + } + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs new file mode 100644 index 0000000000..82b70fe012 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -0,0 +1,314 @@ +using MediaBrowser.Controller.Dlna; +using System.Collections.Generic; + +namespace MediaBrowser.Dlna.Profiles +{ + public class Xbox360Profile : DefaultProfile + { + public Xbox360Profile() + { + Name = "Xbox 360"; + ClientType = "DLNA"; + + ModelName = "Windows Media Player Sharing"; + ModelNumber = "12.0"; + ModelUrl = "http://www.microsoft.com/"; + Manufacturer = "Microsoft Corporation"; + ManufacturerUrl = "http://www.microsoft.com/"; + XDlnaDoc = "DMS-1.50"; + + TimelineOffsetSeconds = 40; + RequiresPlainFolders = true; + RequiresPlainVideoItems = true; + + Identification = new DeviceIdentification + { + ModelName = "Xbox 360", + + Headers = new [] + { + new HttpHeaderInfo {Name = "User-Agent", Value = "Xbox", Match = HeaderMatchType.Substring}, + new HttpHeaderInfo {Name = "User-Agent", Value = "Xenon", Match = HeaderMatchType.Substring} + } + }; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new TranscodingProfile + { + Container = "asf", + VideoCodec = "wmv2", + AudioCodec = "wmav2", + Type = DlnaProfileType.Video, + TranscodeSeekInfo = TranscodeSeekInfo.Bytes, + EstimateContentLength = true, + + Settings = new [] + { + new TranscodingSetting {Name = TranscodingSettingType.MaxAudioChannels, Value = "6"}, + new TranscodingSetting {Name = TranscodingSettingType.VideoLevel, Value = "3"}, + new TranscodingSetting {Name = TranscodingSettingType.VideoProfile, Value = "baseline"} + } + }, + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "avi", + VideoCodec = "mpeg4", + AudioCodec = "ac3,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "avi", + VideoCodec = "h264", + AudioCodec = "aac", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp4,mov", + VideoCodec = "h264,mpeg4", + AudioCodec = "aac,ac3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "asf", + VideoCodec = "wmv2,wmv3,vc1", + AudioCodec = "wmav2,wmapro", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "asf", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "avi", + MimeType = "video/avi", + Type = DlnaProfileType.Video + } + }; + + ContainerProfiles = new[] + { + new ContainerProfile + { + Type = DlnaProfileType.Video, + Container = "mp4,mov", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Has64BitOffsets, + Value = "false", + IsRequired = false + } + } + }, + + new ContainerProfile + { + Type = DlnaProfileType.Photo, + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + } + } + } + }; + + CodecProfiles = new[] + { + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "mpeg4", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1280" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "720" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoFramerate, + Value = "30", + IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "5120000", + IsRequired = false + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "h264", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "41", + IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "10240000", + IsRequired = false + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "wmv2,wmv3,vc1", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Width, + Value = "1920" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.Height, + Value = "1080" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoFramerate, + Value = "30", + IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "15360000", + IsRequired = false + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3,wmav2,wmapro", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6", + IsRequired = false + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "aac", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6", + IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.Equals, + Property = ProfileConditionValue.AudioProfile, + Value = "lc", + IsRequired = false + } + } + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs new file mode 100644 index 0000000000..0a5203a9c8 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs @@ -0,0 +1,60 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class XboxOneProfile : DefaultProfile + { + public XboxOneProfile() + { + Name = "Xbox One"; + ClientType = "DLNA"; + + Identification = new DeviceIdentification + { + ModelName = "Xbox One", + FriendlyName = "Xbox-SystemOS" + }; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new TranscodingProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "aac", + Type = DlnaProfileType.Video + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "mp3", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "avi", + Type = DlnaProfileType.Video + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "avi", + MimeType = "video/x-msvideo", + Type = DlnaProfileType.Video + } + }; + } + } +} diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 879fbc1b69..dec1a10310 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -498,7 +498,7 @@ namespace MediaBrowser.ServerApplication var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger); RegisterSingleInstance(appThemeManager); - var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager); + var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, JsonSerializer); RegisterSingleInstance(dlnaManager); var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor); -- cgit v1.2.3 From a94a98dc6c1381c177a407139769e0cad566346b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 24 Mar 2014 13:54:45 -0400 Subject: apply codec profile conditions --- MediaBrowser.Api/ItemUpdateService.cs | 7 +- MediaBrowser.Api/Playback/BaseStreamingService.cs | 46 ++++-- MediaBrowser.Api/Playback/StreamRequest.cs | 3 + MediaBrowser.Controller/Dlna/CodecProfile.cs | 10 +- MediaBrowser.Controller/Dlna/TranscodingProfile.cs | 4 +- MediaBrowser.Dlna/PlayTo/PlaylistItem.cs | 15 +- MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs | 171 +++++++++++++++++---- MediaBrowser.Dlna/PlayTo/StreamHelper.cs | 43 +++--- MediaBrowser.Dlna/Profiles/DefaultProfile.cs | 19 ++- MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs | 4 +- MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs | 1 - MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 18 ++- MediaBrowser.Model/Dto/BaseItemDto.cs | 1 + MediaBrowser.Providers/Manager/MetadataService.cs | 3 +- .../Dto/DtoService.cs | 1 + 15 files changed, 267 insertions(+), 79 deletions(-) (limited to 'MediaBrowser.Controller/Dlna/TranscodingProfile.cs') diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 1e9f2f7a2f..8bc06b6577 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -211,12 +211,7 @@ namespace MediaBrowser.Api private void UpdateItem(BaseItemDto request, BaseItem item) { item.Name = request.Name; - - // Only set the forced value if they changed it, or there's already one - if (!string.Equals(item.SortName, request.SortName) || !string.IsNullOrEmpty(item.ForcedSortName)) - { - item.ForcedSortName = request.SortName; - } + item.ForcedSortName = request.ForcedSortName; var hasBudget = item as IHasBudget; if (hasBudget != null) diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index a6b3b72942..7dcb06f7b3 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1168,18 +1168,23 @@ namespace MediaBrowser.Api.Playback protected double? GetFramerateParam(StreamState state) { - if (state.VideoRequest != null && state.VideoRequest.Framerate.HasValue) + if (state.VideoRequest != null) { - return state.VideoRequest.Framerate.Value; - } + if (state.VideoRequest.Framerate.HasValue) + { + return state.VideoRequest.Framerate.Value; + } - if (state.VideoStream != null) - { - var contentRate = state.VideoStream.AverageFrameRate ?? state.VideoStream.RealFrameRate; + var maxrate = state.VideoRequest.MaxFramerate ?? 23.976; - if (contentRate.HasValue && contentRate.Value > 23.976) + if (state.VideoStream != null) { - return 23.976; + var contentRate = state.VideoStream.AverageFrameRate ?? state.VideoStream.RealFrameRate; + + if (contentRate.HasValue && contentRate.Value > maxrate) + { + return maxrate; + } } } @@ -1265,17 +1270,38 @@ namespace MediaBrowser.Api.Playback { if (videoRequest != null) { - request.StartTimeTicks = long.Parse(val, UsCulture); + videoRequest.MaxWidth = int.Parse(val, UsCulture); } } else if (i == 12) { if (videoRequest != null) { - videoRequest.Profile = val; + videoRequest.MaxHeight = int.Parse(val, UsCulture); } } else if (i == 13) + { + if (videoRequest != null) + { + videoRequest.Framerate = int.Parse(val, UsCulture); + } + } + else if (i == 14) + { + if (videoRequest != null) + { + request.StartTimeTicks = long.Parse(val, UsCulture); + } + } + else if (i == 15) + { + if (videoRequest != null) + { + videoRequest.Profile = val; + } + } + else if (i == 16) { if (videoRequest != null) { diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index 3439621e95..8db5920f6b 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -145,6 +145,9 @@ namespace MediaBrowser.Api.Playback [ApiMember(Name = "Framerate", Description = "Optional. A specific video framerate to encode to, e.g. 23.976. Generally this should be omitted unless the device has specific requirements.", IsRequired = false, DataType = "double", ParameterType = "query", Verb = "GET")] public double? Framerate { get; set; } + [ApiMember(Name = "MaxFramerate", Description = "Optional. A specific maximum video framerate to encode to, e.g. 23.976. Generally this should be omitted unless the device has specific requirements.", IsRequired = false, DataType = "double", ParameterType = "query", Verb = "GET")] + public double? MaxFramerate { get; set; } + /// /// Gets or sets the profile. /// diff --git a/MediaBrowser.Controller/Dlna/CodecProfile.cs b/MediaBrowser.Controller/Dlna/CodecProfile.cs index 5621c7ef23..2b9a40ea06 100644 --- a/MediaBrowser.Controller/Dlna/CodecProfile.cs +++ b/MediaBrowser.Controller/Dlna/CodecProfile.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; namespace MediaBrowser.Controller.Dlna @@ -18,6 +19,13 @@ namespace MediaBrowser.Controller.Dlna { return (Codec ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); } + + public bool ContainsCodec(string codec) + { + var codecs = GetCodecs(); + + return codecs.Count == 0 || codecs.Contains(codec, StringComparer.OrdinalIgnoreCase); + } } public enum CodecType diff --git a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs index 1ce2adb1ba..007cb632e4 100644 --- a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs @@ -32,9 +32,7 @@ namespace MediaBrowser.Controller.Dlna public enum TranscodingSettingType { - VideoLevel = 0, - VideoProfile = 1, - MaxAudioChannels = 2 + VideoProfile = 0 } public enum TranscodeSeekInfo diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs index 3992fbfbf5..20f31cf9da 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs @@ -34,7 +34,20 @@ namespace MediaBrowser.Dlna.PlayTo public int? SubtitleStreamIndex { get; set; } public string DeviceProfileName { get; set; } - + + public int? MaxAudioChannels { get; set; } + + public int? AudioBitrate { get; set; } + + public int? VideoBitrate { get; set; } + + public int? VideoLevel { get; set; } + + public int? MaxWidth { get; set; } + public int? MaxHeight { get; set; } + + public int? MaxFramerate { get; set; } + public PlaylistItem() { TranscodingSettings = new List(); diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs index e4c49a224c..1b2d791136 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs @@ -24,13 +24,16 @@ namespace MediaBrowser.Dlna.PlayTo var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); - if (profile.CodecProfiles.Where(i => i.Type == CodecType.AudioCodec) - .All(i => IsCodecProfileSupported(i, item.Path, null, audioStream))) + var directPlay = profile.DirectPlayProfiles + .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsSupported(i, item, audioStream)); + + if (directPlay != null) { - var directPlay = profile.DirectPlayProfiles - .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsSupported(i, item, audioStream)); + var audioCodec = audioStream == null ? null : audioStream.Codec; - if (directPlay != null) + // Make sure audio codec profiles are satisfied + if (!string.IsNullOrEmpty(audioCodec) && profile.CodecProfiles.Where(i => i.Type == CodecType.AudioCodec && i.ContainsCodec(audioCodec)) + .All(i => AreConditionsSatisfied(i.Conditions, item.Path, null, audioStream))) { playlistItem.Transcode = false; playlistItem.Container = Path.GetExtension(item.Path); @@ -48,8 +51,15 @@ namespace MediaBrowser.Dlna.PlayTo playlistItem.TranscodingSettings = transcodingProfile.Settings.ToList(); playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.'); playlistItem.AudioCodec = transcodingProfile.AudioCodec; + + var audioTranscodingConditions = profile.CodecProfiles + .Where(i => i.Type == CodecType.AudioCodec && i.ContainsCodec(transcodingProfile.AudioCodec)) + .Take(1) + .SelectMany(i => i.Conditions); + + ApplyTranscodingConditions(playlistItem, audioTranscodingConditions); } - + return playlistItem; } @@ -81,7 +91,7 @@ namespace MediaBrowser.Dlna.PlayTo playlistItem.TranscodingSettings = transcodingProfile.Settings.ToList(); playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.'); } - + return playlistItem; } @@ -96,18 +106,28 @@ namespace MediaBrowser.Dlna.PlayTo var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); - if (profile.CodecProfiles.Where(i => i.Type == CodecType.VideoCodec || i.Type == CodecType.VideoAudioCodec) - .All(i => IsCodecProfileSupported(i, item.Path, videoStream, audioStream))) + var directPlay = profile.DirectPlayProfiles + .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsSupported(i, item, videoStream, audioStream)); + + if (directPlay != null) { - var directPlay = profile.DirectPlayProfiles - .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsSupported(i, item, videoStream, audioStream)); + var videoCodec = videoStream == null ? null : videoStream.Codec; - if (directPlay != null) + // Make sure video codec profiles are satisfied + if (!string.IsNullOrEmpty(videoCodec) && profile.CodecProfiles.Where(i => i.Type == CodecType.VideoCodec && i.ContainsCodec(videoCodec)) + .All(i => AreConditionsSatisfied(i.Conditions, item.Path, videoStream, audioStream))) { - playlistItem.Transcode = false; - playlistItem.Container = Path.GetExtension(item.Path); + var audioCodec = audioStream == null ? null : audioStream.Codec; - return playlistItem; + // Make sure audio codec profiles are satisfied + if (string.IsNullOrEmpty(audioCodec) || profile.CodecProfiles.Where(i => i.Type == CodecType.VideoAudioCodec && i.ContainsCodec(audioCodec)) + .All(i => AreConditionsSatisfied(i.Conditions, item.Path, videoStream, audioStream))) + { + playlistItem.Transcode = false; + playlistItem.Container = Path.GetExtension(item.Path); + + return playlistItem; + } } } @@ -121,11 +141,113 @@ namespace MediaBrowser.Dlna.PlayTo playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.'); playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',').FirstOrDefault(); playlistItem.VideoCodec = transcodingProfile.VideoCodec; + + var videoTranscodingConditions = profile.CodecProfiles + .Where(i => i.Type == CodecType.VideoCodec && i.ContainsCodec(transcodingProfile.VideoCodec)) + .Take(1) + .SelectMany(i => i.Conditions); + + ApplyTranscodingConditions(playlistItem, videoTranscodingConditions); + + var audioTranscodingConditions = profile.CodecProfiles + .Where(i => i.Type == CodecType.VideoAudioCodec && i.ContainsCodec(transcodingProfile.AudioCodec)) + .Take(1) + .SelectMany(i => i.Conditions); + + ApplyTranscodingConditions(playlistItem, audioTranscodingConditions); } return playlistItem; } + private void ApplyTranscodingConditions(PlaylistItem item, IEnumerable conditions) + { + foreach (var condition in conditions.Where(i => !string.IsNullOrEmpty(i.Value))) + { + var value = condition.Value; + + switch (condition.Property) + { + case ProfileConditionValue.AudioBitrate: + { + var num = 0; + if (int.TryParse(value, NumberStyles.Any, _usCulture, out num)) + { + item.AudioBitrate = num; + } + break; + } + case ProfileConditionValue.AudioChannels: + { + var num = 0; + if (int.TryParse(value, NumberStyles.Any, _usCulture, out num)) + { + item.MaxAudioChannels = num; + } + break; + } + case ProfileConditionValue.Filesize: + case ProfileConditionValue.AudioProfile: + case ProfileConditionValue.Has64BitOffsets: + case ProfileConditionValue.VideoBitDepth: + case ProfileConditionValue.VideoPacketLength: + case ProfileConditionValue.VideoProfile: + case ProfileConditionValue.VideoTimestamp: + { + // Not supported yet + break; + } + case ProfileConditionValue.Height: + { + var num = 0; + if (int.TryParse(value, NumberStyles.Any, _usCulture, out num)) + { + item.MaxHeight = num; + } + break; + } + case ProfileConditionValue.VideoBitrate: + { + var num = 0; + if (int.TryParse(value, NumberStyles.Any, _usCulture, out num)) + { + item.VideoBitrate = num; + } + break; + } + case ProfileConditionValue.VideoFramerate: + { + var num = 0; + if (int.TryParse(value, NumberStyles.Any, _usCulture, out num)) + { + item.MaxFramerate = num; + } + break; + } + case ProfileConditionValue.VideoLevel: + { + var num = 0; + if (int.TryParse(value, NumberStyles.Any, _usCulture, out num)) + { + item.VideoLevel = num; + } + break; + } + case ProfileConditionValue.Width: + { + var num = 0; + if (int.TryParse(value, NumberStyles.Any, _usCulture, out num)) + { + item.MaxWidth = num; + } + break; + } + default: + throw new ArgumentException("Unrecognized ProfileConditionValue"); + } + } + } + private bool IsSupported(DirectPlayProfile profile, Photo item) { var mediaPath = item.Path; @@ -142,7 +264,7 @@ namespace MediaBrowser.Dlna.PlayTo return true; } - + private bool IsSupported(DirectPlayProfile profile, Audio item, MediaStream audioStream) { var mediaPath = item.Path; @@ -222,22 +344,9 @@ namespace MediaBrowser.Dlna.PlayTo return true; } - private bool IsCodecProfileSupported(CodecProfile profile, string mediaPath, MediaStream videoStream, MediaStream audioStream) + private bool AreConditionsSatisfied(IEnumerable conditions, string mediaPath, MediaStream videoStream, MediaStream audioStream) { - var codecs = profile.GetCodecs(); - var stream = profile.Type == CodecType.VideoCodec ? videoStream : audioStream; - var existingCodec = (stream == null ? null : stream.Codec) ?? string.Empty; - - if (codecs.Count == 0 || codecs.Contains(existingCodec, StringComparer.OrdinalIgnoreCase)) - { - // Check additional conditions - if (!profile.Conditions.Any(i => IsConditionSatisfied(i, mediaPath, videoStream, audioStream))) - { - return false; - } - } - - return true; + return conditions.All(i => IsConditionSatisfied(i, mediaPath, videoStream, audioStream)); } /// diff --git a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs index 6cd66c16ae..61c3bdd730 100644 --- a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs +++ b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Dlna.PlayTo /// System.String. internal static string GetAudioUrl(DeviceInfo deviceProperties, PlaylistItem item, List streams, string serverAddress) { - var dlnaCommand = BuildDlnaUrl(item.DeviceProfileName, item.MediaSourceId, deviceProperties.UUID, !item.Transcode, null, item.AudioCodec, item.AudioStreamIndex, item.SubtitleStreamIndex, null, 128000, item.StartPositionTicks, item.TranscodingSettings); + var dlnaCommand = BuildDlnaUrl(deviceProperties, item); return string.Format("{0}/audio/{1}/stream{2}?{3}", serverAddress, item.ItemId, "." + item.Container.TrimStart('.'), dlnaCommand); } @@ -33,7 +33,7 @@ namespace MediaBrowser.Dlna.PlayTo /// The url to send to the device internal static string GetVideoUrl(DeviceInfo deviceProperties, PlaylistItem item, List streams, string serverAddress) { - var dlnaCommand = BuildDlnaUrl(item.DeviceProfileName, item.MediaSourceId, deviceProperties.UUID, !item.Transcode, item.VideoCodec, item.AudioCodec, item.AudioStreamIndex, item.SubtitleStreamIndex, 1500000, 128000, item.StartPositionTicks, item.TranscodingSettings); + var dlnaCommand = BuildDlnaUrl(deviceProperties, item); return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.Container, dlnaCommand); } @@ -41,30 +41,33 @@ namespace MediaBrowser.Dlna.PlayTo /// /// Builds the dlna URL. /// - private static string BuildDlnaUrl(string deviceProfileName, string mediaSourceId, string deviceID, bool isStatic, string videoCodec, string audioCodec, int? audiostreamIndex, int? subtitleIndex, int? videoBitrate, int? audioBitrate, long? startPositionTicks, List settings) + private static string BuildDlnaUrl(DeviceInfo deviceProperties, PlaylistItem item) { - var profile = settings.Where(i => i.Name == TranscodingSettingType.VideoProfile).Select(i => i.Value).FirstOrDefault(); - var videoLevel = settings.Where(i => i.Name == TranscodingSettingType.VideoLevel).Select(i => i.Value).FirstOrDefault(); - var maxAudioChannels = settings.Where(i => i.Name == TranscodingSettingType.MaxAudioChannels).Select(i => i.Value).FirstOrDefault(); + 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 { - deviceProfileName ?? string.Empty, - deviceID ?? string.Empty, - mediaSourceId ?? string.Empty, - isStatic.ToString().ToLower(), - videoCodec ?? string.Empty, - audioCodec ?? string.Empty, - audiostreamIndex.HasValue ? audiostreamIndex.Value.ToString(usCulture) : string.Empty, - subtitleIndex.HasValue ? subtitleIndex.Value.ToString(usCulture) : string.Empty, - videoBitrate.HasValue ? videoBitrate.Value.ToString(usCulture) : string.Empty, - audioBitrate.HasValue ? audioBitrate.Value.ToString(usCulture) : string.Empty, - maxAudioChannels ?? string.Empty, - startPositionTicks.HasValue ? startPositionTicks.Value.ToString(usCulture) : string.Empty, + item.DeviceProfileName ?? string.Empty, + deviceProperties.UUID ?? string.Empty, + item.MediaSourceId ?? string.Empty, + (!item.Transcode).ToString().ToLower(), + item.VideoCodec ?? string.Empty, + item.AudioCodec ?? string.Empty, + item.AudioStreamIndex.HasValue ? item.AudioStreamIndex.Value.ToString(usCulture) : string.Empty, + item.SubtitleStreamIndex.HasValue ? item.SubtitleStreamIndex.Value.ToString(usCulture) : string.Empty, + item.VideoBitrate.HasValue ? item.VideoBitrate.Value.ToString(usCulture) : string.Empty, + item.AudioBitrate.HasValue ? item.AudioBitrate.Value.ToString(usCulture) : string.Empty, + item.MaxAudioChannels.HasValue ? item.MaxAudioChannels.Value.ToString(usCulture) : string.Empty, + item.MaxFramerate.HasValue ? item.MaxFramerate.Value.ToString(usCulture) : string.Empty, + 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, - videoLevel ?? string.Empty + item.VideoLevel.HasValue ? item.VideoLevel.Value.ToString(usCulture) : string.Empty }; return string.Format("Params={0}", string.Join(";", list.ToArray())); diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs index a1c6612753..710f02df2e 100644 --- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs @@ -34,7 +34,6 @@ namespace MediaBrowser.Dlna.Profiles Settings = new [] { - new TranscodingSetting {Name = TranscodingSettingType.VideoLevel, Value = "3"}, new TranscodingSetting {Name = TranscodingSettingType.VideoProfile, Value = "baseline"} } } @@ -54,6 +53,24 @@ namespace MediaBrowser.Dlna.Profiles Type = DlnaProfileType.Video } }; + + CodecProfiles = new[] + { + new CodecProfile + { + Type = CodecType.VideoCodec, + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "3", + IsRequired = false + } + } + } + }; } } } diff --git a/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs b/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs index e5fc1ed073..39490f8062 100644 --- a/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs @@ -6,10 +6,12 @@ namespace MediaBrowser.Dlna.Profiles { public SonyPs3Profile() { - Name = "Sony Bravia (2010)"; + Name = "Sony PlayStation 3"; Identification = new DeviceIdentification { + FriendlyName = "PLAYSTATION 3", + Headers = new[] { new HttpHeaderInfo diff --git a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs index 52d4a5f291..47c7b21cc8 100644 --- a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs +++ b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs @@ -44,7 +44,6 @@ namespace MediaBrowser.Dlna.Profiles Settings = new [] { - new TranscodingSetting {Name = TranscodingSettingType.VideoLevel, Value = "3"}, new TranscodingSetting {Name = TranscodingSettingType.VideoProfile, Value = "baseline"} } }, diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index 7216457a3f..660d821d34 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -49,8 +49,6 @@ namespace MediaBrowser.Dlna.Profiles Settings = new [] { - new TranscodingSetting {Name = TranscodingSettingType.MaxAudioChannels, Value = "6"}, - new TranscodingSetting {Name = TranscodingSettingType.VideoLevel, Value = "3"}, new TranscodingSetting {Name = TranscodingSettingType.VideoProfile, Value = "baseline"} } }, @@ -229,6 +227,13 @@ namespace MediaBrowser.Dlna.Profiles Property = ProfileConditionValue.VideoBitrate, Value = "10240000", IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "3", + IsRequired = false } } }, @@ -264,6 +269,13 @@ namespace MediaBrowser.Dlna.Profiles Property = ProfileConditionValue.VideoBitrate, Value = "15360000", IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "3", + IsRequired = false } } }, @@ -294,7 +306,7 @@ namespace MediaBrowser.Dlna.Profiles { Condition = ProfileConditionType.LessThanEqual, Property = ProfileConditionValue.AudioChannels, - Value = "6", + Value = "2", IsRequired = false }, new ProfileCondition diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 780f936be2..c13e1d2d08 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -69,6 +69,7 @@ namespace MediaBrowser.Model.Dto /// /// The name of the sort. public string SortName { get; set; } + public string ForcedSortName { get; set; } /// /// Gets or sets the video3 D format. diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index dfd13d8c32..dad716f6ad 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -107,7 +107,8 @@ namespace MediaBrowser.Providers.Manager // Next run metadata providers if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None) { - var providers = GetProviders(item, refreshResult.DateLastMetadataRefresh.HasValue, refreshOptions).ToList(); + var providers = GetProviders(item, refreshResult.DateLastMetadataRefresh.HasValue, refreshOptions) + .ToList(); if (providers.Count > 0 || !refreshResult.DateLastMetadataRefresh.HasValue) { diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 66a9284d73..1833b708fc 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -741,6 +741,7 @@ namespace MediaBrowser.Server.Implementations.Dto { dto.LockedFields = item.LockedFields; dto.LockData = item.IsLocked; + dto.ForcedSortName = item.ForcedSortName; } var hasBudget = item as IHasBudget; -- cgit v1.2.3