From 0ffb2e2efa360e6b03e18cbffbe9b353e30e9e02 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 22 Mar 2014 20:48:34 -0400 Subject: [PATCH 01/12] enforce codec profiles --- MediaBrowser.Controller/Dlna/CodecProfile.cs | 11 +- MediaBrowser.Controller/Dlna/DeviceProfile.cs | 3 + .../Dlna/TranscodingProfile.cs | 13 +- MediaBrowser.Dlna/DlnaManager.cs | 152 +++++++++++++++++- .../PlayTo/PlaylistItemFactory.cs | 116 ++++++++++--- 5 files changed, 262 insertions(+), 33 deletions(-) diff --git a/MediaBrowser.Controller/Dlna/CodecProfile.cs b/MediaBrowser.Controller/Dlna/CodecProfile.cs index bff3742988..a4592e654a 100644 --- a/MediaBrowser.Controller/Dlna/CodecProfile.cs +++ b/MediaBrowser.Controller/Dlna/CodecProfile.cs @@ -32,6 +32,12 @@ namespace MediaBrowser.Controller.Dlna public ProfileConditionType Condition { get; set; } public ProfileConditionValue Property { get; set; } public string Value { get; set; } + public bool IsRequired { get; set; } + + public ProfileCondition() + { + IsRequired = true; + } } public enum ProfileConditionType @@ -46,11 +52,14 @@ namespace MediaBrowser.Controller.Dlna { AudioChannels, AudioBitrate, + AudioProfile, Filesize, Width, Height, + Has64BitOffsets, VideoBitrate, VideoFramerate, - VideoLevel + VideoLevel, + VideoProfile } } diff --git a/MediaBrowser.Controller/Dlna/DeviceProfile.cs b/MediaBrowser.Controller/Dlna/DeviceProfile.cs index 91be73bba8..49568e7d43 100644 --- a/MediaBrowser.Controller/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Controller/Dlna/DeviceProfile.cs @@ -60,6 +60,9 @@ namespace MediaBrowser.Controller.Dlna public int TimelineOffsetSeconds { get; set; } + public bool RequiresPlainVideoItems { get; set; } + public bool RequiresPlainFolders { get; set; } + public DeviceProfile() { DirectPlayProfiles = new DirectPlayProfile[] { }; diff --git a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs index 530a44b8ca..1073f74aaf 100644 --- a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs @@ -11,6 +11,10 @@ namespace MediaBrowser.Controller.Dlna public string VideoCodec { get; set; } public string AudioCodec { get; set; } + public bool EstimateContentLength { get; set; } + + public TranscodeSeekInfo TranscodeSeekInfo { get; set; } + public List Settings { get; set; } public TranscodingProfile() @@ -27,6 +31,13 @@ namespace MediaBrowser.Controller.Dlna public enum TranscodingSettingType { - Profile + Profile = 0, + MaxAudioChannels = 1 + } + + public enum TranscodeSeekInfo + { + Auto = 0, + Bytes = 1 } } diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index be7295e12f..24e9d83a03 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -233,9 +233,26 @@ namespace MediaBrowser.Dlna 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" + 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[] @@ -243,12 +260,31 @@ namespace MediaBrowser.Dlna new TranscodingProfile { Container = "mp3", + AudioCodec = "mp3", Type = DlnaProfileType.Audio }, new TranscodingProfile { - Container = "ts", - Type = DlnaProfileType.Video + 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 TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo } }, @@ -256,18 +292,59 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3"}, - Type = DlnaProfileType.Audio + Containers = new[]{"avi"}, + VideoCodec = "mpeg4", + AudioCodec = "ac3,mp3", + Type = DlnaProfileType.Video }, new DirectPlayProfile { Containers = new[]{"avi"}, + VideoCodec = "h264", + AudioCodec = "aac", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"mp4"}, + Containers = new[]{"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 + { + Containers = new[]{"asf"}, + VideoCodec = "wmv2,wmv3,vc1", + AudioCodec = "wmav2,wmapro", Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Containers = new[]{"asf"}, + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Containers = new[]{"mp3"}, + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Containers = new[]{"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"} + } } }, @@ -279,6 +356,69 @@ namespace MediaBrowser.Dlna 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} + } + } } }); diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs index 6817c4eaa0..5da845d068 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs @@ -36,15 +36,19 @@ namespace MediaBrowser.Dlna.PlayTo var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); - var directPlay = profile.DirectPlayProfiles - .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsSupported(i, item, audioStream)); - - if (directPlay != null) + if (profile.CodecProfiles.Where(i => i.Type == CodecType.AudioCodec) + .All(i => IsCodecProfileSupported(i, item.Path, null, audioStream))) { - playlistItem.Transcode = false; - playlistItem.Container = Path.GetExtension(item.Path); + var directPlay = profile.DirectPlayProfiles + .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsSupported(i, item, audioStream)); - return playlistItem; + if (directPlay != null) + { + playlistItem.Transcode = false; + playlistItem.Container = Path.GetExtension(item.Path); + + return playlistItem; + } } var transcodingProfile = profile.TranscodingProfiles @@ -113,15 +117,19 @@ namespace MediaBrowser.Dlna.PlayTo var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); - var directPlay = profile.DirectPlayProfiles - .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsSupported(i, item, videoStream, audioStream)); - - if (directPlay != null) + if (profile.CodecProfiles.Where(i => i.Type == CodecType.VideoCodec || i.Type == CodecType.VideoAudioCodec) + .All(i => IsCodecProfileSupported(i, item.Path, videoStream, audioStream))) { - playlistItem.Transcode = false; - playlistItem.Container = Path.GetExtension(item.Path); + var directPlay = profile.DirectPlayProfiles + .FirstOrDefault(i => i.Type == playlistItem.MediaType && IsSupported(i, item, videoStream, audioStream)); - return playlistItem; + if (directPlay != null) + { + playlistItem.Transcode = false; + playlistItem.Container = Path.GetExtension(item.Path); + + return playlistItem; + } } var transcodingProfile = profile.TranscodingProfiles @@ -281,6 +289,24 @@ namespace MediaBrowser.Dlna.PlayTo return true; } + private bool IsCodecProfileSupported(CodecProfile profile, 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; + } + /// /// Determines whether [is condition satisfied] [the specified condition]. /// @@ -292,30 +318,70 @@ namespace MediaBrowser.Dlna.PlayTo /// Unexpected ProfileConditionType private bool IsConditionSatisfied(ProfileCondition condition, string mediaPath, MediaStream videoStream, MediaStream audioStream) { - var actualValue = GetConditionValue(condition, mediaPath, videoStream, audioStream); + if (condition.Property == ProfileConditionValue.VideoProfile) + { + var profile = videoStream == null ? null : videoStream.Profile; - if (actualValue.HasValue) + if (!string.IsNullOrWhiteSpace(profile)) + { + switch (condition.Condition) + { + case ProfileConditionType.Equals: + return string.Equals(profile, condition.Value, StringComparison.OrdinalIgnoreCase); + case ProfileConditionType.NotEquals: + return !string.Equals(profile, condition.Value, StringComparison.OrdinalIgnoreCase); + default: + throw new InvalidOperationException("Unexpected ProfileConditionType"); + } + } + } + + else if (condition.Property == ProfileConditionValue.AudioProfile) { - long expected; - if (long.TryParse(condition.Value, NumberStyles.Any, _usCulture, out expected)) + var profile = audioStream == null ? null : audioStream.Profile; + + if (!string.IsNullOrWhiteSpace(profile)) { switch (condition.Condition) { case ProfileConditionType.Equals: - return actualValue.Value == expected; - case ProfileConditionType.GreaterThanEqual: - return actualValue.Value >= expected; - case ProfileConditionType.LessThanEqual: - return actualValue.Value <= expected; + return string.Equals(profile, condition.Value, StringComparison.OrdinalIgnoreCase); case ProfileConditionType.NotEquals: - return actualValue.Value != expected; + return !string.Equals(profile, condition.Value, StringComparison.OrdinalIgnoreCase); default: throw new InvalidOperationException("Unexpected ProfileConditionType"); } } } - return false; + else + { + var actualValue = GetConditionValue(condition, mediaPath, videoStream, audioStream); + + if (actualValue.HasValue) + { + long expected; + if (long.TryParse(condition.Value, NumberStyles.Any, _usCulture, out expected)) + { + switch (condition.Condition) + { + case ProfileConditionType.Equals: + return actualValue.Value == expected; + case ProfileConditionType.GreaterThanEqual: + return actualValue.Value >= expected; + case ProfileConditionType.LessThanEqual: + return actualValue.Value <= expected; + case ProfileConditionType.NotEquals: + return actualValue.Value != expected; + default: + throw new InvalidOperationException("Unexpected ProfileConditionType"); + } + } + } + } + + // Value doesn't exist in metadata. Fail it if required. + return !condition.IsRequired; } /// From f3e992b82be4b23e33e6130d1495f2b5203d0576 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 01:10:33 -0400 Subject: [PATCH 02/12] support more profile features --- MediaBrowser.Api/Movies/MoviesService.cs | 5 +- .../Playback/BaseStreamingService.cs | 40 ++-- MediaBrowser.Api/Playback/StreamRequest.cs | 5 +- MediaBrowser.Api/Playback/StreamState.cs | 10 - .../Dlna/TranscodingProfile.cs | 5 +- MediaBrowser.Dlna/DlnaManager.cs | 26 ++- MediaBrowser.Dlna/PlayTo/DlnaController.cs | 97 +++++++-- MediaBrowser.Dlna/PlayTo/PlaylistItem.cs | 20 +- .../PlayTo/PlaylistItemFactory.cs | 64 +----- MediaBrowser.Dlna/PlayTo/StreamHelper.cs | 188 +++--------------- 10 files changed, 188 insertions(+), 272 deletions(-) diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index f9b7608696..204a7aab45 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -117,10 +117,9 @@ namespace MediaBrowser.Api.Movies public object Get(GetMovieRecommendations request) { - var user = request.UserId.HasValue ? _userManager.GetUserById(request.UserId.Value) : null; + var user = _userManager.GetUserById(request.UserId.Value); - var folder = user.RootFolder; - var movies = folder.RecursiveChildren.OfType().ToList(); + var movies = user.RootFolder.GetRecursiveChildren(user).OfType().ToList(); var result = GetRecommendationCategories(user, movies, request.CategoryLimit, request.ItemLimit, request.GetItemFields().ToList()); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 1001980ec1..9ec28700dc 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -745,6 +745,16 @@ namespace MediaBrowser.Api.Playback } } + if (request.MaxAudioChannels.HasValue) + { + if (audioStream != null && audioStream.Channels.HasValue) + { + return Math.Min(request.MaxAudioChannels.Value, audioStream.Channels.Value); + } + + return request.MaxAudioChannels.Value; + } + return request.AudioChannels; } @@ -1205,73 +1215,73 @@ namespace MediaBrowser.Api.Playback } else if (i == 1) { - request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); + request.MediaSourceId = val; } else if (i == 2) + { + request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); + } + else if (i == 3) { if (videoRequest != null) { videoRequest.VideoCodec = (VideoCodecs)Enum.Parse(typeof(VideoCodecs), val, true); } } - else if (i == 3) + else if (i == 4) { request.AudioCodec = (AudioCodecs)Enum.Parse(typeof(AudioCodecs), val, true); } - else if (i == 4) + else if (i == 5) { if (videoRequest != null) { videoRequest.AudioStreamIndex = int.Parse(val, UsCulture); } } - else if (i == 5) + else if (i == 6) { if (videoRequest != null) { videoRequest.SubtitleStreamIndex = int.Parse(val, UsCulture); } } - else if (i == 6) + else if (i == 7) { if (videoRequest != null) { videoRequest.VideoBitRate = int.Parse(val, UsCulture); } } - else if (i == 7) + else if (i == 8) { request.AudioBitRate = int.Parse(val, UsCulture); } - else if (i == 8) + else if (i == 9) { - request.AudioChannels = int.Parse(val, UsCulture); + request.MaxAudioChannels = int.Parse(val, UsCulture); } - else if (i == 9) + else if (i == 10) { if (videoRequest != null) { request.StartTimeTicks = long.Parse(val, UsCulture); } } - else if (i == 10) + else if (i == 11) { if (videoRequest != null) { videoRequest.Profile = val; } } - else if (i == 11) + else if (i == 12) { if (videoRequest != null) { videoRequest.Level = val; } } - else if (i == 12) - { - request.ForcedMimeType = val; - } } } diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index df52e5e3ee..2251ce52d3 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -49,6 +49,9 @@ namespace MediaBrowser.Api.Playback [ApiMember(Name = "AudioChannels", Description = "Optional. Specify a specific number of audio channels to encode to, e.g. 2", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? AudioChannels { get; set; } + [ApiMember(Name = "MaxAudioChannels", Description = "Optional. Specify a maximum number of audio channels to encode to, e.g. 2", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? MaxAudioChannels { get; set; } + /// /// Gets or sets the audio sample rate. /// @@ -69,8 +72,6 @@ namespace MediaBrowser.Api.Playback public bool ThrowDebugError { get; set; } public string Params { get; set; } - - public string ForcedMimeType { get; set; } } public class VideoStreamRequest : StreamRequest diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index 88daf9f623..ecc5c93ef2 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -79,16 +79,6 @@ namespace MediaBrowser.Api.Playback public string GetMimeType(string outputPath) { - if (!string.IsNullOrWhiteSpace(Request.ForcedMimeType)) - { - if (VideoRequest == null) - { - return "audio/" + Request.ForcedMimeType; - } - - return "video/" + Request.ForcedMimeType; - } - return MimeTypes.GetMimeType(outputPath); } } 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 diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 24e9d83a03..ec2a09c52e 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -274,11 +274,9 @@ namespace MediaBrowser.Dlna Settings = new List { - new TranscodingSetting - { - Name = TranscodingSettingType.MaxAudioChannels, - Value = "6" - } + new TranscodingSetting { Name = TranscodingSettingType.MaxAudioChannels, Value = "6" }, + new TranscodingSetting{ Name = TranscodingSettingType.VideoLevel, Value = "3"}, + new TranscodingSetting{ Name = TranscodingSettingType.VideoProfile, Value = "baseline"} } }, new TranscodingProfile @@ -791,7 +789,13 @@ namespace MediaBrowser.Dlna Container = "ts", Type = DlnaProfileType.Video, VideoCodec = "h264", - AudioCodec = "aac" + AudioCodec = "aac", + + Settings = new List + { + new TranscodingSetting{ Name = TranscodingSettingType.VideoLevel, Value = "3"}, + new TranscodingSetting{ Name = TranscodingSettingType.VideoProfile, Value = "baseline"} + } }, new TranscodingProfile { @@ -1010,12 +1014,20 @@ namespace MediaBrowser.Dlna new TranscodingProfile { Container = "mp3", + AudioCodec = "mp3", Type = DlnaProfileType.Audio }, new TranscodingProfile { Container = "ts", - Type = DlnaProfileType.Video + Type = DlnaProfileType.Video, + AudioCodec = "aac", + VideoCodec = "h264", + Settings = new List + { + new TranscodingSetting{ Name = TranscodingSettingType.VideoLevel, Value = "3"}, + new TranscodingSetting{ Name = TranscodingSettingType.VideoProfile, Value = "baseline"} + } } }, diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs index e94663802f..4f9c92da52 100644 --- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs +++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs @@ -270,7 +270,7 @@ namespace MediaBrowser.Dlna.PlayTo playlistItem.StartPositionTicks = newItem.StartPositionTicks; playlistItem.StreamUrl = newItem.StreamUrl; playlistItem.Didl = newItem.Didl; - return _device.SetAvTransport(playlistItem.StreamUrl, playlistItem.DlnaHeaders, playlistItem.Didl); + return _device.SetAvTransport(playlistItem.StreamUrl, GetDlnaHeaders(playlistItem), playlistItem.Didl); } return _device.Seek(TimeSpan.FromTicks(command.SeekPositionTicks ?? 0)); @@ -391,16 +391,20 @@ namespace MediaBrowser.Dlna.PlayTo private PlaylistItem CreatePlaylistItem(BaseItem item, long startPostionTicks, string serverAddress) { - var streams = _itemRepository.GetMediaStreams(new MediaStreamQuery { ItemId = item.Id }).ToList(); + var streams = _itemRepository.GetMediaStreams(new MediaStreamQuery + { + ItemId = item.Id + + }).ToList(); var deviceInfo = _device.Properties; - var playlistItem = GetPlaylistItem(item, _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification())); + var playlistItem = GetPlaylistItem(item, streams, _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification())); playlistItem.StartPositionTicks = startPostionTicks; if (playlistItem.MediaType == DlnaProfileType.Audio) { - playlistItem.StreamUrl = StreamHelper.GetAudioUrl(playlistItem, serverAddress); + playlistItem.StreamUrl = StreamHelper.GetAudioUrl(deviceInfo, playlistItem, streams, serverAddress); } else { @@ -410,32 +414,92 @@ namespace MediaBrowser.Dlna.PlayTo var didl = DidlBuilder.Build(item, _session.UserId.ToString(), serverAddress, playlistItem.StreamUrl, streams); playlistItem.Didl = didl; - var header = StreamHelper.GetDlnaHeaders(playlistItem); - playlistItem.DlnaHeaders = header; return playlistItem; } - private PlaylistItem GetPlaylistItem(BaseItem item, DeviceProfile profile) + private string GetDlnaHeaders(PlaylistItem item) + { + var orgOp = item.Transcode ? ";DLNA.ORG_OP=00" : ";DLNA.ORG_OP=01"; + + var orgCi = item.Transcode ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; + + const string dlnaflags = ";DLNA.ORG_FLAGS=01500000000000000000000000000000"; + + string contentFeatures; + + var container = item.Container.TrimStart('.'); + + if (string.Equals(container, "mp3", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=MP3"; + } + else if (string.Equals(container, "wma", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=WMABASE"; + } + else if (string.Equals(container, "wmw", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=WMVMED_BASE"; + } + else if (string.Equals(container, "asf", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=WMVMED_BASE"; + } + else if (string.Equals(container, "avi", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=AVI"; + } + else if (string.Equals(container, "mkv", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=MATROSKA"; + } + else if (string.Equals(container, "mp4", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC"; + } + else if (string.Equals(container, "mpeg", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL"; + } + else if (string.Equals(container, "ts", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL"; + } + else if (item.MediaType == DlnaProfileType.Video) + { + // Default to AVI for video + contentFeatures = "DLNA.ORG_PN=AVI"; + } + else + { + // Default to MP3 for audio + contentFeatures = "DLNA.ORG_PN=MP3"; + } + + return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); + } + + private PlaylistItem GetPlaylistItem(BaseItem item, List mediaStreams, DeviceProfile profile) { var video = item as Video; if (video != null) { - return new PlaylistItemFactory(_itemRepository).Create(video, profile); + return new PlaylistItemFactory().Create(video, mediaStreams, profile); } var audio = item as Audio; if (audio != null) { - return new PlaylistItemFactory(_itemRepository).Create(audio, profile); + return new PlaylistItemFactory().Create(audio, mediaStreams, profile); } var photo = item as Photo; if (photo != null) { - return new PlaylistItemFactory(_itemRepository).Create(photo, profile); + return new PlaylistItemFactory().Create(photo, profile); } throw new ArgumentException("Unrecognized item type."); @@ -482,11 +546,18 @@ namespace MediaBrowser.Dlna.PlayTo await _device.SetStop(); return true; } + nextTrack.PlayState = 1; - _logger.Debug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", _device.Properties.Name, nextTrack.StreamUrl, nextTrack.DlnaHeaders); - await _device.SetAvTransport(nextTrack.StreamUrl, nextTrack.DlnaHeaders, nextTrack.Didl); + + var dlnaheaders = GetDlnaHeaders(nextTrack); + + _logger.Debug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", _device.Properties.Name, nextTrack.StreamUrl, dlnaheaders); + + await _device.SetAvTransport(nextTrack.StreamUrl, dlnaheaders, nextTrack.Didl); + if (nextTrack.StartPositionTicks > 0 && !nextTrack.Transcode) await _device.Seek(TimeSpan.FromTicks(nextTrack.StartPositionTicks)); + return true; } @@ -508,7 +579,7 @@ namespace MediaBrowser.Dlna.PlayTo return Task.FromResult(false); prevTrack.PlayState = 1; - return _device.SetAvTransport(prevTrack.StreamUrl, prevTrack.DlnaHeaders, prevTrack.Didl); + return _device.SetAvTransport(prevTrack.StreamUrl, GetDlnaHeaders(prevTrack), prevTrack.Didl); } #endregion diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs index 1304f61b11..77b9085f75 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Dlna; +using System.Collections.Generic; namespace MediaBrowser.Dlna.PlayTo { @@ -14,16 +15,27 @@ namespace MediaBrowser.Dlna.PlayTo public string Container { get; set; } - public string MimeType { get; set; } - public int PlayState { get; set; } public string StreamUrl { get; set; } - public string DlnaHeaders { get; set; } - public string Didl { get; set; } public long StartPositionTicks { get; set; } + + public string VideoCodec { get; set; } + + public string AudioCodec { get; set; } + + public List TranscodingSettings { get; set; } + + public int? AudioStreamIndex { get; set; } + + public int? SubtitleStreamIndex { get; set; } + + public PlaylistItem() + { + TranscodingSettings = new List(); + } } } \ No newline at end of file diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs index 5da845d068..8655e58da0 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs @@ -1,9 +1,9 @@ using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; @@ -12,15 +12,9 @@ namespace MediaBrowser.Dlna.PlayTo { public class PlaylistItemFactory { - private readonly IItemRepository _itemRepo; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public PlaylistItemFactory(IItemRepository itemRepo) - { - _itemRepo = itemRepo; - } - - public PlaylistItem Create(Audio item, DeviceProfile profile) + public PlaylistItem Create(Audio item, List mediaStreams, DeviceProfile profile) { var playlistItem = new PlaylistItem { @@ -28,12 +22,6 @@ namespace MediaBrowser.Dlna.PlayTo MediaType = DlnaProfileType.Audio }; - var mediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery - { - ItemId = item.Id, - Type = MediaStreamType.Audio - }); - var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); if (profile.CodecProfiles.Where(i => i.Type == CodecType.AudioCodec) @@ -57,11 +45,9 @@ namespace MediaBrowser.Dlna.PlayTo if (transcodingProfile != null) { playlistItem.Transcode = true; - + playlistItem.TranscodingSettings = transcodingProfile.Settings.ToList(); playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.'); } - - AttachMediaProfile(playlistItem, profile); return playlistItem; } @@ -91,16 +77,14 @@ namespace MediaBrowser.Dlna.PlayTo if (transcodingProfile != null) { playlistItem.Transcode = true; - + playlistItem.TranscodingSettings = transcodingProfile.Settings.ToList(); playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.'); } - - AttachMediaProfile(playlistItem, profile); return playlistItem; } - public PlaylistItem Create(Video item, DeviceProfile profile) + public PlaylistItem Create(Video item, List mediaStreams, DeviceProfile profile) { var playlistItem = new PlaylistItem { @@ -108,12 +92,6 @@ namespace MediaBrowser.Dlna.PlayTo MediaType = DlnaProfileType.Video }; - var mediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery - { - ItemId = item.Id - - }).ToList(); - var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); @@ -138,43 +116,13 @@ namespace MediaBrowser.Dlna.PlayTo if (transcodingProfile != null) { playlistItem.Transcode = true; + playlistItem.TranscodingSettings = transcodingProfile.Settings.ToList(); playlistItem.Container = "." + transcodingProfile.Container.TrimStart('.'); } - AttachMediaProfile(playlistItem, profile); - return playlistItem; } - private void AttachMediaProfile(PlaylistItem item, DeviceProfile profile) - { - var mediaProfile = GetMediaProfile(item, profile); - - if (mediaProfile != null) - { - item.MimeType = (mediaProfile.MimeType ?? string.Empty).Split('/').LastOrDefault(); - - // TODO: Org_pn? - } - } - - private MediaProfile GetMediaProfile(PlaylistItem item, DeviceProfile profile) - { - return profile.MediaProfiles.FirstOrDefault(i => - { - if (i.Type == item.MediaType) - { - if (string.Equals(item.Container.TrimStart('.'), i.Container.TrimStart('.'), StringComparison.OrdinalIgnoreCase)) - { - // TODO: Enforce codecs - return true; - } - } - - return false; - }); - } - private bool IsSupported(DirectPlayProfile profile, Photo item) { var mediaPath = item.Path; diff --git a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs index cb2b72a038..2a8e2d6170 100644 --- a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs +++ b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs @@ -1,6 +1,5 @@ -using MediaBrowser.Model.Dto; +using MediaBrowser.Controller.Dlna; using MediaBrowser.Model.Entities; -using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -9,91 +8,21 @@ namespace MediaBrowser.Dlna.PlayTo { class StreamHelper { - /// - /// Gets the dlna headers. - /// - /// The item. - /// - internal static string GetDlnaHeaders(PlaylistItem item) - { - var orgOp = item.Transcode ? ";DLNA.ORG_OP=00" : ";DLNA.ORG_OP=01"; - - var orgCi = item.Transcode ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; - - const string dlnaflags = ";DLNA.ORG_FLAGS=01500000000000000000000000000000"; - - var contentFeatures = string.Empty; - - if (string.Equals(item.Container, "mp3", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=MP3"; - } - else if (string.Equals(item.Container, "wma", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=WMABASE"; - } - else if (string.Equals(item.Container, "wmw", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=WMVMED_BASE"; - } - else if (string.Equals(item.Container, "asf", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=WMVMED_BASE"; - } - else if (string.Equals(item.Container, "avi", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=AVI"; - } - else if (string.Equals(item.Container, "mkv", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=MATROSKA"; - } - else if (string.Equals(item.Container, "mp4", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC"; - } - else if (string.Equals(item.Container, "mpeg", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL"; - } - else if (string.Equals(item.Container, "ts", StringComparison.OrdinalIgnoreCase)) - { - contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL"; - } - else if (item.MediaType == Controller.Dlna.DlnaProfileType.Video) - { - //Default to AVI for video - contentFeatures = "DLNA.ORG_PN=AVI"; - } - else - { - //Default to MP3 for audio - contentFeatures = "DLNA.ORG_PN=MP3"; - } - - return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); - } - - #region Audio - /// /// Gets the audio URL. /// + /// The device properties. /// The item. + /// The streams. /// The server address. /// System.String. - internal static string GetAudioUrl(PlaylistItem item, string serverAddress) + internal static string GetAudioUrl(DeviceInfo deviceProperties, PlaylistItem item, List streams, string serverAddress) { - if (!item.Transcode) - return string.Format("{0}/audio/{1}/stream{2}?Static=True", serverAddress, item.ItemId, item.Container); + var dlnaCommand = BuildDlnaUrl(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.mp3?AudioCodec=Mp3", serverAddress, item.ItemId); + return string.Format("{0}/audio/{1}/stream{2}?{3}", serverAddress, item.ItemId, "." + item.Container.TrimStart('.'), dlnaCommand); } - #endregion - - #region Video - /// /// Gets the video URL. /// @@ -104,97 +33,40 @@ namespace MediaBrowser.Dlna.PlayTo /// The url to send to the device internal static string GetVideoUrl(DeviceInfo deviceProperties, PlaylistItem item, List streams, string serverAddress) { - string dlnaCommand = string.Empty; - if (!item.Transcode) - { - dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, !item.Transcode, null, null, null, null, null, null, null, null, null, null, item.MimeType); - return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.Container, dlnaCommand); - } - var videostream = streams.Where(m => m.Type == MediaStreamType.Video).OrderBy(m => m.IsDefault).FirstOrDefault(); - var audiostream = streams.Where(m => m.Type == MediaStreamType.Audio).OrderBy(m => m.IsDefault).FirstOrDefault(); - - var videoCodec = GetVideoCodec(videostream); - var audioCodec = GetAudioCodec(audiostream); - int? videoBitrate = null; - int? audioBitrate = null; - int? audioChannels = null; - - if (videoCodec != VideoCodecs.Copy) - videoBitrate = 2000000; + var dlnaCommand = BuildDlnaUrl(item.MediaSourceId, deviceProperties.UUID, !item.Transcode, item.VideoCodec, item.AudioCodec, item.AudioStreamIndex, item.SubtitleStreamIndex, 1500000, 128000, item.StartPositionTicks, item.TranscodingSettings); - if (audioCodec != AudioCodecs.Copy) - { - audioBitrate = 128000; - audioChannels = 2; - } - - dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, !item.Transcode, videoCodec, audioCodec, null, null, videoBitrate, audioChannels, audioBitrate, item.StartPositionTicks, "baseline", "3", item.MimeType); return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.Container, dlnaCommand); } - /// - /// Gets the video codec. - /// - /// The video stream. - /// - private static VideoCodecs GetVideoCodec(MediaStream videoStream) - { - switch (videoStream.Codec.ToLower()) - { - case "h264": - case "mpeg4": - return VideoCodecs.Copy; - - } - return VideoCodecs.H264; - } - - /// - /// Gets the audio codec. - /// - /// The audio stream. - /// - private static AudioCodecs GetAudioCodec(MediaStream audioStream) - { - if (audioStream != null) - { - switch (audioStream.Codec.ToLower()) - { - case "aac": - case "mp3": - case "wma": - return AudioCodecs.Copy; - - } - } - return AudioCodecs.Aac; - } - /// /// Builds the dlna URL. /// - private static string BuildDlnaUrl(string deviceID, bool isStatic, VideoCodecs? videoCodec, AudioCodecs? audioCodec, int? subtitleIndex, int? audiostreamIndex, int? videoBitrate, int? audiochannels, int? audioBitrate, long? startPositionTicks, string profile, string videoLevel, string mimeType) + 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) { - var usCulture = new CultureInfo("en-US"); + 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 dlnaparam = string.Format("Params={0};", deviceID); - dlnaparam += isStatic ? "true;" : "false;"; - dlnaparam += videoCodec.HasValue ? videoCodec.Value + ";" : ";"; - dlnaparam += audioCodec.HasValue ? audioCodec.Value + ";" : ";"; - dlnaparam += audiostreamIndex.HasValue ? audiostreamIndex.Value.ToString(usCulture) + ";" : ";"; - dlnaparam += subtitleIndex.HasValue ? subtitleIndex.Value.ToString(usCulture) + ";" : ";"; - dlnaparam += videoBitrate.HasValue ? videoBitrate.Value.ToString(usCulture) + ";" : ";"; - dlnaparam += audioBitrate.HasValue ? audioBitrate.Value.ToString(usCulture) + ";" : ";"; - dlnaparam += audiochannels.HasValue ? audiochannels.Value.ToString(usCulture) + ";" : ";"; - dlnaparam += startPositionTicks.HasValue ? startPositionTicks.Value.ToString(usCulture) + ";" : ";"; - dlnaparam += profile + ";"; - dlnaparam += videoLevel + ";"; - dlnaparam += mimeType + ";"; + var usCulture = new CultureInfo("en-US"); - return dlnaparam; + var list = new List + { + 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, + profile ?? string.Empty, + videoLevel ?? string.Empty + }; + + return string.Format("Params={0}", string.Join(";", list.ToArray())); } - - #endregion - } } \ No newline at end of file From e0c60dc29ade31bb29501562126d3cc55c8eb881 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 02:07:43 -0400 Subject: [PATCH 03/12] update panasonic profile --- MediaBrowser.Controller/Dlna/CodecProfile.cs | 1 + .../Dlna/DirectPlayProfile.cs | 7 +- MediaBrowser.Dlna/DlnaManager.cs | 226 +++++++++++------- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 10 +- .../PlayTo/PlaylistItemFactory.cs | 12 +- 5 files changed, 149 insertions(+), 107 deletions(-) diff --git a/MediaBrowser.Controller/Dlna/CodecProfile.cs b/MediaBrowser.Controller/Dlna/CodecProfile.cs index a4592e654a..0d66d90ae8 100644 --- a/MediaBrowser.Controller/Dlna/CodecProfile.cs +++ b/MediaBrowser.Controller/Dlna/CodecProfile.cs @@ -57,6 +57,7 @@ namespace MediaBrowser.Controller.Dlna Width, Height, Has64BitOffsets, + VideoBitDepth, VideoBitrate, VideoFramerate, VideoLevel, diff --git a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs index 53d32a2f8d..56dd15ca32 100644 --- a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs +++ b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs @@ -5,7 +5,7 @@ namespace MediaBrowser.Controller.Dlna { public class DirectPlayProfile { - public string[] Containers { get; set; } + public string Container { get; set; } public string AudioCodec { get; set; } public string VideoCodec { get; set; } @@ -16,8 +16,11 @@ namespace MediaBrowser.Controller.Dlna public DirectPlayProfile() { Conditions = new List(); + } - Containers = new string[] { }; + public List GetContainers() + { + return (Container ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); } public List GetAudioCodecs() diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index ec2a09c52e..7c3123b781 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -56,22 +56,22 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "mp3", Type = DlnaProfileType.Audio, }, new DirectPlayProfile { - Containers = new[]{"mkv"}, + Container = "mkv", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"mp4"}, + Container = "mp4", Type = DlnaProfileType.Video } }, @@ -123,22 +123,22 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "mp3", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"mkv"}, + Container = "mkv", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"mp4"}, + Container = "mp4", Type = DlnaProfileType.Video } }, @@ -190,22 +190,22 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "mp3", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"mkv"}, + Container = "mkv", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"mp4"}, + Container = "mp4", Type = DlnaProfileType.Video } }, @@ -290,21 +290,21 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", VideoCodec = "mpeg4", AudioCodec = "ac3,mp3", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", VideoCodec = "h264", AudioCodec = "aac", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"mp4", "mov"}, + Container = "mp4,mov", VideoCodec = "h264,mpeg4", AudioCodec = "aac,ac3", Type = DlnaProfileType.Video, @@ -316,26 +316,26 @@ namespace MediaBrowser.Dlna }, new DirectPlayProfile { - Containers = new[]{"asf"}, + Container = "asf", VideoCodec = "wmv2,wmv3,vc1", AudioCodec = "wmav2,wmapro", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"asf"}, + Container = "asf", AudioCodec = "wmav2,wmapro,wmavoice", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "mp3", AudioCodec = "mp3", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"jpeg"}, + Container = "jpeg", Type = DlnaProfileType.Photo, Conditions = new List @@ -449,12 +449,12 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "mp3", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", Type = DlnaProfileType.Video } }, @@ -498,17 +498,17 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "mp3", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"asf"}, + Container = "asf", Type = DlnaProfileType.Audio } }, @@ -559,22 +559,22 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "mp3", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"wma"}, + Container = "wma", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"mp4"}, + Container = "mp4", Type = DlnaProfileType.Video } }, @@ -613,27 +613,41 @@ namespace MediaBrowser.Dlna list.Add(new DeviceProfile { - //Panasonic Viera (2011|2012) Without AVI Support - Name = "Panasonic Viera E/S/ST/VT (2011)", + Name = "Panasonic Viera", ClientType = "DLNA", Identification = new DeviceIdentification { - FriendlyName = @"(VIERA (E|S)T?(3|5)0?.*)|(VIERA VT30.*)", - Manufacturer = "Panasonic" + 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 } }, @@ -641,69 +655,97 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3"}, - Type = DlnaProfileType.Audio + Container = "mpeg", + VideoCodec = "mpeg2video,mpeg4", + AudioCodec = "ac3,mp3", + Type = DlnaProfileType.Video }, + new DirectPlayProfile { - Containers = new[]{"mkv"}, + Container = "mkv", + VideoCodec = "h264", + AudioCodec = "aac,ac3,mp3,pcm", Type = DlnaProfileType.Video - } - } - }); + }, - list.Add(new DeviceProfile - { - //Panasonic Viera (2011|2012) With AVI Support - Name = "Panasonic Viera G/GT/DT/UT/VT (2011/2012)", - ClientType = "DLNA", + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "aac,mp3", + Type = DlnaProfileType.Video + }, - Identification = new DeviceIdentification - { - FriendlyName = @"(VIERA (G|D|U)T?(3|5)0?.*)|(VIERA VT50.*)", - Manufacturer = "Panasonic" - }, + new DirectPlayProfile + { + Container = "mp4", + VideoCodec = "h264", + AudioCodec = "aac,ac3,mp3,pcm", + Type = DlnaProfileType.Video + }, - TranscodingProfiles = new[] - { - new TranscodingProfile + new DirectPlayProfile { - Container = "mp3", - Type = DlnaProfileType.Audio + Container = "mov", + VideoCodec = "h264", + AudioCodec = "aac,pcm", + Type = DlnaProfileType.Video }, - new TranscodingProfile + + new DirectPlayProfile { - Container = "ts", - Type = DlnaProfileType.Video - } - }, + Container = "avi", + VideoCodec = "mpeg4", + AudioCodec = "pcm", + Type = DlnaProfileType.Video + }, - DirectPlayProfiles = new[] - { new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "flv", + VideoCodec = "h264", + AudioCodec = "aac", + Type = DlnaProfileType.Video + }, + + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", Type = DlnaProfileType.Audio }, + new DirectPlayProfile { - Containers = new[]{"mkv"}, - Type = DlnaProfileType.Video + Container = "mp4", + AudioCodec = "aac", + Type = DlnaProfileType.Audio }, - new DirectPlayProfile + + new DirectPlayProfile { - Containers = new[]{"avi"}, - Type = DlnaProfileType.Video + 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[] + CodecProfiles = new [] { - new MediaProfile + new CodecProfile { - Container ="avi", - MimeType = "video/divx", - Type = DlnaProfileType.Video + 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} + } } } }); @@ -723,19 +765,19 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3", "wma"}, + Container = "mp3,wma", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", Type = DlnaProfileType.Video }, new DirectPlayProfile { - Containers = new[]{"mkv"}, + Container = "mkv", Type = DlnaProfileType.Video } }, @@ -808,7 +850,7 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"avi"}, + Container = "avi", Type = DlnaProfileType.Video, VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1", AudioCodec = "ac3,dca,mp2,mp3,pcm" @@ -816,7 +858,7 @@ namespace MediaBrowser.Dlna new DirectPlayProfile { - Containers = new[]{"mpeg"}, + Container = "mpeg", Type = DlnaProfileType.Video, VideoCodec = "mpeg1video,mpeg2video", AudioCodec = "ac3,dca,mp2,mp3,pcm" @@ -824,7 +866,7 @@ namespace MediaBrowser.Dlna new DirectPlayProfile { - Containers = new[]{"mkv"}, + Container = "mkv", Type = DlnaProfileType.Video, VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1", AudioCodec = "ac3,dca,aac,mp2,mp3,pcm" @@ -832,7 +874,7 @@ namespace MediaBrowser.Dlna new DirectPlayProfile { - Containers = new[]{"ts"}, + Container = "ts", Type = DlnaProfileType.Video, VideoCodec = "mpeg1video,mpeg2video,h264,vc1", AudioCodec = "ac3,dca,mp2,mp3" @@ -840,7 +882,7 @@ namespace MediaBrowser.Dlna new DirectPlayProfile { - Containers = new[]{"mp4", "mov"}, + Container = "mp4,mov", Type = DlnaProfileType.Video, VideoCodec = "h264,mpeg4", AudioCodec = "ac3,aac,mp2,mp3" @@ -848,7 +890,7 @@ namespace MediaBrowser.Dlna new DirectPlayProfile { - Containers = new[]{"asf"}, + Container = "asf", Type = DlnaProfileType.Video, VideoCodec = "vc1", AudioCodec = "wmav2,wmapro" @@ -856,7 +898,7 @@ namespace MediaBrowser.Dlna new DirectPlayProfile { - Containers = new[]{"asf"}, + Container = "asf", Type = DlnaProfileType.Video, VideoCodec = "mpeg2video", AudioCodec = "mp2,ac3" @@ -864,35 +906,35 @@ namespace MediaBrowser.Dlna new DirectPlayProfile { - Containers = new[]{"mp3"}, + Container = "mp3", AudioCodec = "mp2,mp3", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"mp4"}, + Container = "mp4", AudioCodec = "mp4", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"flac"}, + Container = "flac", AudioCodec = "flac", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"asf"}, + Container = "asf", AudioCodec = "wmav2,wmapro,wmavoice", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"ogg"}, + Container = "ogg", AudioCodec = "vorbis", Type = DlnaProfileType.Audio }, @@ -901,7 +943,7 @@ namespace MediaBrowser.Dlna { Type = DlnaProfileType.Photo, - Containers = new[]{"jpeg", "png", "gif", "bmp", "tiff"}, + Container = "jpeg,png,gif,bmp,tiff", Conditions = new List { @@ -964,13 +1006,13 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3", "flac", "m4a", "wma"}, + Container = "mp3,flac,m4a,wma", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"avi", "mp4", "mkv", "ts"}, + Container = "avi,mp4,mkv,ts", Type = DlnaProfileType.Video } } @@ -991,7 +1033,7 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3", "flac", "m4a", "wma"}, + Container = "mp3,flac,m4a,wma", Type = DlnaProfileType.Audio }, } @@ -1035,13 +1077,13 @@ namespace MediaBrowser.Dlna { new DirectPlayProfile { - Containers = new[]{"mp3", "wma"}, + Container = "mp3,wma", Type = DlnaProfileType.Audio }, new DirectPlayProfile { - Containers = new[]{"avi", "mp4"}, + Container = "avi,mp4", Type = DlnaProfileType.Video } } diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index d02da303b6..6279fb1cb6 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -7,6 +7,7 @@ using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Session; using System; using System.Collections.Concurrent; using System.Linq; @@ -16,7 +17,6 @@ using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Session; namespace MediaBrowser.Dlna.PlayTo { @@ -54,10 +54,8 @@ namespace MediaBrowser.Dlna.PlayTo _config = config; } - public async void Start() + public void Start() { - _logger.Log(LogSeverity.Info, "PlayTo-Manager starting"); - _locations = new ConcurrentDictionary(); foreach (var network in NetworkInterface.GetAllNetworkInterfaces()) @@ -73,7 +71,7 @@ namespace MediaBrowser.Dlna.PlayTo IPAddress localIp = null; - foreach (UnicastIPAddressInformation ipInfo in network.GetIPProperties().UnicastAddresses) + foreach (var ipInfo in network.GetIPProperties().UnicastAddresses) { if (ipInfo.Address.AddressFamily == AddressFamily.InterNetwork) { @@ -95,8 +93,6 @@ namespace MediaBrowser.Dlna.PlayTo { _logger.ErrorException("Failed to Initilize Socket", e); } - - await Task.Delay(100).ConfigureAwait(false); } } diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs index 8655e58da0..a9a33ee3dc 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs @@ -127,11 +127,11 @@ namespace MediaBrowser.Dlna.PlayTo { var mediaPath = item.Path; - if (profile.Containers.Length > 0) + if (profile.Container.Length > 0) { // Check container type var mediaContainer = Path.GetExtension(mediaPath); - if (!profile.Containers.Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase))) + if (!profile.GetContainers().Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase))) { return false; } @@ -150,11 +150,11 @@ namespace MediaBrowser.Dlna.PlayTo { var mediaPath = item.Path; - if (profile.Containers.Length > 0) + if (profile.Container.Length > 0) { // Check container type var mediaContainer = Path.GetExtension(mediaPath); - if (!profile.Containers.Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase))) + if (!profile.GetContainers().Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase))) { return false; } @@ -178,11 +178,11 @@ namespace MediaBrowser.Dlna.PlayTo var mediaPath = item.Path; - if (profile.Containers.Length > 0) + if (profile.Container.Length > 0) { // Check container type var mediaContainer = Path.GetExtension(mediaPath); - if (!profile.Containers.Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase))) + if (!profile.GetContainers().Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase))) { return false; } From 85aa11e926ae9cba2ad58bf1087ad6efaff925a3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 12:42:02 -0400 Subject: [PATCH 04/12] separate profiles --- MediaBrowser.Controller/Dlna/CodecProfile.cs | 4 +- .../Dlna/ContainerProfile.cs | 22 + .../Dlna/DeviceIdentification.cs | 10 +- MediaBrowser.Controller/Dlna/DeviceProfile.cs | 9 +- .../Dlna/DirectPlayProfile.cs | 7 - .../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 + .../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 + .../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 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); From ca37afb3a55b670ca4d5d24355f34e61f997e5a0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 13:18:24 -0400 Subject: [PATCH 05/12] rework samsung profile --- .../Playback/BaseStreamingService.cs | 28 +- MediaBrowser.Controller/Dlna/DeviceProfile.cs | 1 + MediaBrowser.Dlna/DlnaManager.cs | 283 +--------------- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 2 + MediaBrowser.Dlna/Profiles/DefaultProfile.cs | 10 + MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs | 1 - .../Profiles/LinksysDMA2100Profile.cs | 33 ++ .../Profiles/PanasonicVieraProfile.cs | 1 - .../Profiles/SamsungSmartTvProfile.cs | 315 ++++++++++++++++++ .../Profiles/SonyBravia2010Profile.cs | 1 - .../Profiles/SonyBravia2011Profile.cs | 1 - .../Profiles/SonyBravia2012Profile.cs | 1 - .../Profiles/SonyBravia2013Profile.cs | 1 - MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs | 1 - MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 2 - MediaBrowser.Dlna/Profiles/XboxOneProfile.cs | 6 - 16 files changed, 381 insertions(+), 306 deletions(-) create mode 100644 MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs create mode 100644 MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 9ec28700dc..e27fe1dda6 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1211,71 +1211,75 @@ namespace MediaBrowser.Api.Playback if (i == 0) { - request.DeviceId = val; + // Device profile name } else if (i == 1) { - request.MediaSourceId = val; + request.DeviceId = val; } else if (i == 2) { - request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); + request.MediaSourceId = val; } else if (i == 3) + { + request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); + } + else if (i == 4) { if (videoRequest != null) { videoRequest.VideoCodec = (VideoCodecs)Enum.Parse(typeof(VideoCodecs), val, true); } } - else if (i == 4) + else if (i == 5) { request.AudioCodec = (AudioCodecs)Enum.Parse(typeof(AudioCodecs), val, true); } - else if (i == 5) + else if (i == 6) { if (videoRequest != null) { videoRequest.AudioStreamIndex = int.Parse(val, UsCulture); } } - else if (i == 6) + else if (i == 7) { if (videoRequest != null) { videoRequest.SubtitleStreamIndex = int.Parse(val, UsCulture); } } - else if (i == 7) + else if (i == 8) { if (videoRequest != null) { videoRequest.VideoBitRate = int.Parse(val, UsCulture); } } - else if (i == 8) + else if (i == 9) { request.AudioBitRate = int.Parse(val, UsCulture); } - else if (i == 9) + else if (i == 10) { request.MaxAudioChannels = int.Parse(val, UsCulture); } - else if (i == 10) + else if (i == 11) { if (videoRequest != null) { request.StartTimeTicks = long.Parse(val, UsCulture); } } - else if (i == 11) + else if (i == 12) { if (videoRequest != null) { videoRequest.Profile = val; } } - else if (i == 12) + else if (i == 13) { if (videoRequest != null) { diff --git a/MediaBrowser.Controller/Dlna/DeviceProfile.cs b/MediaBrowser.Controller/Dlna/DeviceProfile.cs index 83500e407b..f3de1bc34a 100644 --- a/MediaBrowser.Controller/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Controller/Dlna/DeviceProfile.cs @@ -43,6 +43,7 @@ namespace MediaBrowser.Controller.Dlna public string ModelNumber { get; set; } public string ModelUrl { get; set; } public bool IgnoreTranscodeByteRangeRequests { get; set; } + public bool SupportsAlbumArtInDidl { get; set; } /// /// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace. diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 9588eb7b6f..d4fdf92d8d 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -29,208 +29,8 @@ namespace MediaBrowser.Dlna { 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 SamsungSmartTvProfile()); + list.Add(new Xbox360Profile()); list.Add(new XboxOneProfile()); @@ -245,87 +45,12 @@ namespace MediaBrowser.Dlna 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()); + list.Add(new LinksysDMA2100Profile()); + foreach (var item in list) { //_xmlSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".xml"); diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 590d6378f6..c370882463 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -83,7 +83,9 @@ + + diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs index 2580e8f8cf..a1c6612753 100644 --- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs @@ -6,6 +6,16 @@ namespace MediaBrowser.Dlna.Profiles { public DefaultProfile() { + ProtocolInfo = "DLNA"; + + ClientType = "DLNA"; + Manufacturer = "Media Browser"; + ModelDescription = "Media Browser"; + ModelName = "Media Browser"; + ModelNumber = "Media Browser"; + ModelUrl = "http://mediabrowser3.com/"; + ManufacturerUrl = "http://mediabrowser3.com/"; + TranscodingProfiles = new[] { new TranscodingProfile diff --git a/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs b/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs index 8029912d01..cca6ab6bb7 100644 --- a/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public DenonAvrProfile() { Name = "Denon AVR"; - ClientType = "DLNA"; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs b/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs new file mode 100644 index 0000000000..e7086c2052 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs @@ -0,0 +1,33 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class LinksysDMA2100Profile : DefaultProfile + { + public LinksysDMA2100Profile() + { + // Linksys DMA2100us does not need any transcoding of the formats we support statically + Name = "Linksys DMA2100"; + + 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 + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs index ced648e5cc..6755c06809 100644 --- a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs +++ b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public PanasonicVieraProfile() { Name = "Panasonic Viera"; - ClientType = "DLNA"; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs new file mode 100644 index 0000000000..fa6b1201ab --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs @@ -0,0 +1,315 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class SamsungSmartTvProfile : DefaultProfile + { + public SamsungSmartTvProfile() + { + Name = "Samsung Smart TV"; + + SupportsAlbumArtInDidl = true; + + Identification = new DeviceIdentification + { + ModelUrl = "samsung.com" + }; + + 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 = "asf", + VideoCodec = "h264,mpeg4,mjpeg", + AudioCodec = "mp3,ac3,wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "avi", + VideoCodec = "h264,mpeg4,mjpeg", + AudioCodec = "mp3,ac3,dca", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mkv", + VideoCodec = "h264,mpeg4,mjpeg4", + AudioCodec = "mp3,ac3,dca,aac", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp4", + VideoCodec = "h264,mpeg4", + AudioCodec = "mp3,aac", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "3gpp", + VideoCodec = "h264,mpeg4", + AudioCodec = "aac,he-aac", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mpg,mpeg", + VideoCodec = "mpeg1video,mpeg2video,h264", + AudioCodec = "ac3,mp2,mp3,aac", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "vro,vob", + VideoCodec = "mpeg1video,mpeg2video", + AudioCodec = "ac3,mp2,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "mpeg2video,h264,vc1", + AudioCodec = "ac3,aac,mp3,eac3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "asf", + VideoCodec = "wmv2,wmv3", + AudioCodec = "wmav2,wmavoice", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + 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, + Codec = "mpeg2video", + + 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" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "30720000" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoCodec, + Codec = "mpeg4", + + 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" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "8192000" + } + } + }, + + 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.VideoFramerate, + Value = "30" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "37500000" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "41" + } + } + }, + + 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" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "25600000" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3,wmav2,dca,aac,mp3", + + Conditions = new[] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6" + } + } + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "mkv", + MimeType = "video/x-mkv", + Type = DlnaProfileType.Video + } + }; + + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs index 32eab4ae46..010a18c8d1 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public SonyBravia2010Profile() { Name = "Sony Bravia (2010)"; - ClientType = "DLNA"; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs index c679dec21f..50fd6e2567 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public SonyBravia2011Profile() { Name = "Sony Bravia (2011)"; - ClientType = "DLNA"; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs index 488b7f7406..b476d9c3f6 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public SonyBravia2012Profile() { Name = "Sony Bravia (2012)"; - ClientType = "DLNA"; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs index 21a6ad40ac..ccb655adda 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public SonyBravia2013Profile() { Name = "Sony Bravia (2013)"; - ClientType = "DLNA"; Identification = new DeviceIdentification { diff --git a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs index 3487044a97..52d4a5f291 100644 --- a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs +++ b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public WdtvLiveProfile() { Name = "WDTV Live"; - ClientType = "DLNA"; TimelineOffsetSeconds = 5; IgnoreTranscodeByteRangeRequests = true; diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index 82b70fe012..7216457a3f 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Dlna; -using System.Collections.Generic; namespace MediaBrowser.Dlna.Profiles { @@ -8,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public Xbox360Profile() { Name = "Xbox 360"; - ClientType = "DLNA"; ModelName = "Windows Media Player Sharing"; ModelNumber = "12.0"; diff --git a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs index 0a5203a9c8..db45029a47 100644 --- a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs +++ b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Dlna.Profiles public XboxOneProfile() { Name = "Xbox One"; - ClientType = "DLNA"; Identification = new DeviceIdentification { @@ -38,11 +37,6 @@ namespace MediaBrowser.Dlna.Profiles { Container = "mp3", Type = DlnaProfileType.Audio - }, - new DirectPlayProfile - { - Container = "avi", - Type = DlnaProfileType.Video } }; From 87aee1625da956669bce724177821378f4f3158c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 15:36:25 -0400 Subject: [PATCH 06/12] add new device profiles --- MediaBrowser.Api/SearchService.cs | 9 +- MediaBrowser.Api/SessionsService.cs | 27 +- MediaBrowser.Api/SystemService.cs | 11 +- MediaBrowser.Api/TvShowsService.cs | 17 +- MediaBrowser.Api/UserService.cs | 27 +- MediaBrowser.Controller/Dlna/CodecProfile.cs | 4 +- MediaBrowser.Controller/Dlna/MediaProfile.cs | 7 + MediaBrowser.Dlna/DlnaManager.cs | 5 + MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 3 + .../PlayTo/PlaylistItemFactory.cs | 11 + .../Profiles/SonyBlurayPlayer2013Profile.cs | 180 ++++++++++++ .../Profiles/SonyBlurayPlayerProfile.cs | 261 ++++++++++++++++++ .../Profiles/SonyBravia2010Profile.cs | 57 +++- .../Profiles/SonyBravia2011Profile.cs | 79 ++++-- .../Profiles/SonyBravia2012Profile.cs | 55 +++- .../Profiles/SonyBravia2013Profile.cs | 50 +++- MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs | 233 ++++++++++++++++ MediaBrowser.Dlna/Profiles/XboxOneProfile.cs | 2 +- 18 files changed, 940 insertions(+), 98 deletions(-) create mode 100644 MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs create mode 100644 MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs create mode 100644 MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index f46c6b8e30..662c728e46 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -1,5 +1,4 @@ -using System; -using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -8,6 +7,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Search; using ServiceStack; +using System; using System.Linq; using System.Threading.Tasks; @@ -16,8 +16,7 @@ namespace MediaBrowser.Api /// /// Class GetSearchHints /// - [Route("/Search/Hints", "GET")] - [Api(Description = "Gets search hints based on a search term")] + [Route("/Search/Hints", "GET", Summary = "Gets search hints based on a search term")] public class GetSearchHints : IReturn { /// @@ -66,7 +65,7 @@ namespace MediaBrowser.Api [ApiMember(Name = "IncludeItemTypes", Description = "Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string IncludeItemTypes { get; set; } - + public GetSearchHints() { IncludeArtists = true; diff --git a/MediaBrowser.Api/SessionsService.cs b/MediaBrowser.Api/SessionsService.cs index e73e3490ec..070fe9e598 100644 --- a/MediaBrowser.Api/SessionsService.cs +++ b/MediaBrowser.Api/SessionsService.cs @@ -14,8 +14,7 @@ namespace MediaBrowser.Api /// /// Class GetSessions /// - [Route("/Sessions", "GET")] - [Api(("Gets a list of sessions"))] + [Route("/Sessions", "GET", Summary = "Gets a list of sessions")] public class GetSessions : IReturn> { /// @@ -35,8 +34,7 @@ namespace MediaBrowser.Api /// /// Class BrowseTo /// - [Route("/Sessions/{Id}/Viewing", "POST")] - [Api(("Instructs a session to browse to an item or view"))] + [Route("/Sessions/{Id}/Viewing", "POST", Summary = "Instructs a session to browse to an item or view")] public class BrowseTo : IReturnVoid { /// @@ -77,8 +75,7 @@ namespace MediaBrowser.Api public string Context { get; set; } } - [Route("/Sessions/{Id}/Playing", "POST")] - [Api(("Instructs a session to play an item"))] + [Route("/Sessions/{Id}/Playing", "POST", Summary = "Instructs a session to play an item")] public class Play : IReturnVoid { /// @@ -110,8 +107,7 @@ namespace MediaBrowser.Api public PlayCommand PlayCommand { get; set; } } - [Route("/Sessions/{Id}/Playing/{Command}", "POST")] - [Api(("Issues a playstate command to a client"))] + [Route("/Sessions/{Id}/Playing/{Command}", "POST", Summary = "Issues a playstate command to a client")] public class SendPlaystateCommand : IReturnVoid { /// @@ -135,8 +131,7 @@ namespace MediaBrowser.Api public PlaystateCommand Command { get; set; } } - [Route("/Sessions/{Id}/System/{Command}", "POST")] - [Api(("Issues a system command to a client"))] + [Route("/Sessions/{Id}/System/{Command}", "POST", Summary = "Issues a system command to a client")] public class SendSystemCommand : IReturnVoid { /// @@ -154,8 +149,7 @@ namespace MediaBrowser.Api public SystemCommand Command { get; set; } } - [Route("/Sessions/{Id}/Message", "POST")] - [Api(("Issues a command to a client to display a message to the user"))] + [Route("/Sessions/{Id}/Message", "POST", Summary = "Issues a command to a client to display a message to the user")] public class SendMessageCommand : IReturnVoid { /// @@ -175,8 +169,7 @@ namespace MediaBrowser.Api public long? TimeoutMs { get; set; } } - [Route("/Sessions/{Id}/Users/{UserId}", "POST")] - [Api(("Adds an additional user to a session"))] + [Route("/Sessions/{Id}/Users/{UserId}", "POST", Summary = "Adds an additional user to a session")] public class AddUserToSession : IReturnVoid { [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] @@ -186,8 +179,7 @@ namespace MediaBrowser.Api public Guid UserId { get; set; } } - [Route("/Sessions/{Id}/Users/{UserId}", "DELETE")] - [Api(("Removes an additional user from a session"))] + [Route("/Sessions/{Id}/Users/{UserId}", "DELETE", Summary = "Removes an additional user from a session")] public class RemoveUserFromSession : IReturnVoid { [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] @@ -197,8 +189,7 @@ namespace MediaBrowser.Api public Guid UserId { get; set; } } - [Route("/Sessions/{Id}/Capabilities", "POST")] - [Api(("Updates capabilities for a device"))] + [Route("/Sessions/{Id}/Capabilities", "POST", Summary = "Updates capabilities for a device")] public class PostCapabilities : IReturnVoid { /// diff --git a/MediaBrowser.Api/SystemService.cs b/MediaBrowser.Api/SystemService.cs index 9f5f3716ec..2f0741434a 100644 --- a/MediaBrowser.Api/SystemService.cs +++ b/MediaBrowser.Api/SystemService.cs @@ -8,8 +8,7 @@ namespace MediaBrowser.Api /// /// Class GetSystemInfo /// - [Route("/System/Info", "GET")] - [Api(Description = "Gets information about the server")] + [Route("/System/Info", "GET", Summary = "Gets information about the server")] public class GetSystemInfo : IReturn { @@ -18,18 +17,16 @@ namespace MediaBrowser.Api /// /// Class RestartApplication /// - [Route("/System/Restart", "POST")] - [Api(("Restarts the application, if needed"))] + [Route("/System/Restart", "POST", Summary = "Restarts the application, if needed")] public class RestartApplication { } - [Route("/System/Shutdown", "POST")] - [Api(("Shuts down the application"))] + [Route("/System/Shutdown", "POST", Summary = "Shuts down the application")] public class ShutdownApplication { } - + /// /// Class SystemInfoService /// diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index a805b7b551..7fa586a7d7 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -17,8 +17,7 @@ namespace MediaBrowser.Api /// /// Class GetNextUpEpisodes /// - [Route("/Shows/NextUp", "GET")] - [Api(("Gets a list of next up episodes"))] + [Route("/Shows/NextUp", "GET", Summary = "Gets a list of next up episodes")] public class GetNextUpEpisodes : IReturn, IHasItemFields { /// @@ -53,8 +52,7 @@ namespace MediaBrowser.Api public string SeriesId { get; set; } } - [Route("/Shows/Upcoming", "GET")] - [Api(("Gets a list of upcoming episodes"))] + [Route("/Shows/Upcoming", "GET", Summary = "Gets a list of upcoming episodes")] public class GetUpcomingEpisodes : IReturn, IHasItemFields { /// @@ -86,14 +84,12 @@ namespace MediaBrowser.Api public string Fields { get; set; } } - [Route("/Shows/{Id}/Similar", "GET")] - [Api(Description = "Finds tv shows similar to a given one.")] + [Route("/Shows/{Id}/Similar", "GET", Summary = "Finds tv shows similar to a given one.")] public class GetSimilarShows : BaseGetSimilarItemsFromItem { } - [Route("/Shows/{Id}/Episodes", "GET")] - [Api(Description = "Gets episodes for a tv season")] + [Route("/Shows/{Id}/Episodes", "GET", Summary = "Gets episodes for a tv season")] public class GetEpisodes : IReturn, IHasItemFields { /// @@ -129,8 +125,7 @@ namespace MediaBrowser.Api public string AdjacentTo { get; set; } } - [Route("/Shows/{Id}/Seasons", "GET")] - [Api(Description = "Gets seasons for a tv series")] + [Route("/Shows/{Id}/Seasons", "GET", Summary = "Gets seasons for a tv series")] public class GetSeasons : IReturn, IHasItemFields { /// @@ -320,7 +315,7 @@ namespace MediaBrowser.Api return 0; }) - .ThenByDescending(i =>i.Item2) + .ThenByDescending(i => i.Item2) .ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue) .Select(i => i.Item1); } diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 18c3bd0962..2f1b161078 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -17,8 +17,7 @@ namespace MediaBrowser.Api /// /// Class GetUsers /// - [Route("/Users", "GET")] - [Api(Description = "Gets a list of users")] + [Route("/Users", "GET", Summary = "Gets a list of users")] public class GetUsers : IReturn> { [ApiMember(Name = "IsHidden", Description = "Optional filter by IsHidden=true or false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] @@ -28,8 +27,7 @@ namespace MediaBrowser.Api public bool? IsDisabled { get; set; } } - [Route("/Users/Public", "GET")] - [Api(Description = "Gets a list of publicly visible users for display on a login screen.")] + [Route("/Users/Public", "GET", Summary = "Gets a list of publicly visible users for display on a login screen.")] public class GetPublicUsers : IReturn> { } @@ -37,8 +35,7 @@ namespace MediaBrowser.Api /// /// Class GetUser /// - [Route("/Users/{Id}", "GET")] - [Api(Description = "Gets a user by Id")] + [Route("/Users/{Id}", "GET", Summary = "Gets a user by Id")] public class GetUser : IReturn { /// @@ -52,8 +49,7 @@ namespace MediaBrowser.Api /// /// Class DeleteUser /// - [Route("/Users/{Id}", "DELETE")] - [Api(Description = "Deletes a user")] + [Route("/Users/{Id}", "DELETE", Summary = "Deletes a user")] public class DeleteUser : IReturnVoid { /// @@ -67,8 +63,7 @@ namespace MediaBrowser.Api /// /// Class AuthenticateUser /// - [Route("/Users/{Id}/Authenticate", "POST")] - [Api(Description = "Authenticates a user")] + [Route("/Users/{Id}/Authenticate", "POST", Summary = "Authenticates a user")] public class AuthenticateUser : IReturn { /// @@ -89,8 +84,7 @@ namespace MediaBrowser.Api /// /// Class AuthenticateUser /// - [Route("/Users/AuthenticateByName", "POST")] - [Api(Description = "Authenticates a user")] + [Route("/Users/AuthenticateByName", "POST", Summary = "Authenticates a user")] public class AuthenticateUserByName : IReturn { /// @@ -111,8 +105,7 @@ namespace MediaBrowser.Api /// /// Class UpdateUserPassword /// - [Route("/Users/{Id}/Password", "POST")] - [Api(Description = "Updates a user's password")] + [Route("/Users/{Id}/Password", "POST", Summary = "Updates a user's password")] public class UpdateUserPassword : IReturnVoid { /// @@ -143,8 +136,7 @@ namespace MediaBrowser.Api /// /// Class UpdateUser /// - [Route("/Users/{Id}", "POST")] - [Api(Description = "Updates a user")] + [Route("/Users/{Id}", "POST", Summary = "Updates a user")] public class UpdateUser : UserDto, IReturnVoid { } @@ -152,8 +144,7 @@ namespace MediaBrowser.Api /// /// Class CreateUser /// - [Route("/Users", "POST")] - [Api(Description = "Creates a user")] + [Route("/Users", "POST", Summary = "Creates a user")] public class CreateUser : UserDto, IReturn { } diff --git a/MediaBrowser.Controller/Dlna/CodecProfile.cs b/MediaBrowser.Controller/Dlna/CodecProfile.cs index 1dc7f21396..5621c7ef23 100644 --- a/MediaBrowser.Controller/Dlna/CodecProfile.cs +++ b/MediaBrowser.Controller/Dlna/CodecProfile.cs @@ -61,6 +61,8 @@ namespace MediaBrowser.Controller.Dlna VideoBitrate, VideoFramerate, VideoLevel, - VideoProfile + VideoPacketLength, + VideoProfile, + VideoTimestamp } } diff --git a/MediaBrowser.Controller/Dlna/MediaProfile.cs b/MediaBrowser.Controller/Dlna/MediaProfile.cs index 5fa41b18aa..1d2613face 100644 --- a/MediaBrowser.Controller/Dlna/MediaProfile.cs +++ b/MediaBrowser.Controller/Dlna/MediaProfile.cs @@ -13,6 +13,13 @@ namespace MediaBrowser.Controller.Dlna public string OrgPn { get; set; } public string MimeType { get; set; } + public ProfileCondition[] Conditions { get; set; } + + public MediaProfile() + { + Conditions = new ProfileCondition[] {}; + } + public List GetAudioCodecs() { return (AudioCodec ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index d4fdf92d8d..25a82f5290 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -34,6 +34,8 @@ namespace MediaBrowser.Dlna list.Add(new Xbox360Profile()); list.Add(new XboxOneProfile()); + + list.Add(new SonyPs3Profile()); list.Add(new SonyBravia2010Profile()); @@ -43,6 +45,9 @@ namespace MediaBrowser.Dlna list.Add(new SonyBravia2013Profile()); + list.Add(new SonyBlurayPlayer2013Profile()); + list.Add(new SonyBlurayPlayerProfile()); + list.Add(new PanasonicVieraProfile()); list.Add(new WdtvLiveProfile()); diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index c370882463..31eed483fe 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -86,10 +86,13 @@ + + + diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs index 31f15b1c31..e4c49a224c 100644 --- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs +++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs @@ -251,6 +251,11 @@ namespace MediaBrowser.Dlna.PlayTo /// Unexpected ProfileConditionType private bool IsConditionSatisfied(ProfileCondition condition, string mediaPath, MediaStream videoStream, MediaStream audioStream) { + if (condition.Property == ProfileConditionValue.Has64BitOffsets) + { + // TODO: Determine how to evaluate this + } + if (condition.Property == ProfileConditionValue.VideoProfile) { var profile = videoStream == null ? null : videoStream.Profile; @@ -346,6 +351,12 @@ namespace MediaBrowser.Dlna.PlayTo return videoStream == null ? null : videoStream.Width; case ProfileConditionValue.VideoLevel: return videoStream == null ? null : ConvertToLong(videoStream.Level); + case ProfileConditionValue.VideoPacketLength: + // TODO: Determine how to get this + return null; + case ProfileConditionValue.VideoTimestamp: + // TODO: Determine how to get this + return null; default: throw new InvalidOperationException("Unexpected Property"); } diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs new file mode 100644 index 0000000000..49aa47027a --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs @@ -0,0 +1,180 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class SonyBlurayPlayer2013Profile : DefaultProfile + { + public SonyBlurayPlayer2013Profile() + { + Identification = new DeviceIdentification + { + FriendlyName = @"Blu-ray Disc Player", + Manufacturer = "Sony", + ModelNumber = "BDP-2013" + }; + + ModelName = "Windows Media Player Sharing"; + ModelNumber = "3.0"; + Manufacturer = "Microsoft Corporation"; + + ProtocolInfo = "http-get:*:video/divx:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMABASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAFULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO_320;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS_320;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/flac:DLNA.ORG_PN=FLAC;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/ogg:DLNA.ORG_PN=OGG;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:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/png:DLNA.ORG_PN=PNG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/png:DLNA.ORG_PN=PNG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/gif:DLNA.ORG_PN=GIF_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_JP_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-flv:DLNA.ORG_PN=FLV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-dvr:DLNA.ORG_PN=DVR_MS;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/wtv:DLNA.ORG_PN=WTV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/ogg:DLNA.ORG_PN=OGV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.rn-realvideo:DLNA.ORG_PN=REAL_VIDEO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AMR;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_H263_3GPP_P0_L10_AMR;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_H263_MP4_P0_L10_AAC;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", + Type = DlnaProfileType.Video + }, + + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "mpeg1video,mpeg2video,h264", + AudioCodec = "ac3,aac,mp3,pcm", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mpeg", + VideoCodec = "mpeg1video,mpeg2video", + AudioCodec = "ac3,mp3,mp2,pcm", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp4", + VideoCodec = "mpeg4,h264", + AudioCodec = "ac3,aac,pcm,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "avi", + VideoCodec = "mpeg4,h264", + AudioCodec = "ac3,aac,mp3,pcm", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mkv", + VideoCodec = "mpeg4,h264", + AudioCodec = "ac3,dca,aac,mp3,pcm", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "mp4", + AudioCodec = "aac", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "asf", + AudioCodec = "wmav2,wmapro,wmavoice", + Type = DlnaProfileType.Audio + }, + new DirectPlayProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + 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.VideoFramerate, + Value = "30", + IsRequired = false + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3", + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6", + IsRequired = false + } + } + } + }; + + 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" + } + } + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs new file mode 100644 index 0000000000..5121726706 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs @@ -0,0 +1,261 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class SonyBlurayPlayerProfile : DefaultProfile + { + public SonyBlurayPlayerProfile() + { + Identification = new DeviceIdentification + { + FriendlyName = @"Blu-ray Disc Player", + Manufacturer = "Sony", + + Headers = new[] + { + new HttpHeaderInfo + { + Name = "X-AV-Client-Info", + Value = @"(Blu-ray Disc Player|Home Theater System|Home Theatre System|Media Player)", + Match = HeaderMatchType.Regex + }, + + new HttpHeaderInfo + { + Name = "X-AV-Physical-Unit-Info", + Value = @"(Blu-ray Disc Player|Home Theater System|Home Theatre System|Media Player)", + Match = HeaderMatchType.Regex + } + } + }; + + ModelName = "Windows Media Player Sharing"; + ModelNumber = "3.0"; + Manufacturer = "Microsoft Corporation"; + + ProtocolInfo = "http-get:*:video/divx:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMABASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAFULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO_320;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS_320;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/flac:DLNA.ORG_PN=FLAC;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/ogg:DLNA.ORG_PN=OGG;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:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/png:DLNA.ORG_PN=PNG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/png:DLNA.ORG_PN=PNG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/gif:DLNA.ORG_PN=GIF_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_JP_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-flv:DLNA.ORG_PN=FLV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-dvr:DLNA.ORG_PN=DVR_MS;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/wtv:DLNA.ORG_PN=WTV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/ogg:DLNA.ORG_PN=OGV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.rn-realvideo:DLNA.ORG_PN=REAL_VIDEO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AMR;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_H263_3GPP_P0_L10_AMR;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_H263_MP4_P0_L10_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000"; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + + new TranscodingProfile + { + Container = "ts", + VideoCodec = "mpeg2video", + AudioCodec = "ac3", + Type = DlnaProfileType.Video + }, + + new TranscodingProfile + { + Container = "jpeg", + Type = DlnaProfileType.Photo + } + }; + + DirectPlayProfiles = new[] + { + new DirectPlayProfile + { + Container = "ts", + VideoCodec = "mpeg1video,mpeg2video,h264", + AudioCodec = "ac3,aac,mp3,pcm", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mpeg", + VideoCodec = "mpeg1video,mpeg2video", + AudioCodec = "ac3,mp3,pcm", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "avi,mp4", + VideoCodec = "mpeg4,h264", + AudioCodec = "ac3,aac,mp3,pcm", + 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 + } + }; + + 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.VideoFramerate, + Value = "30", + IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "41", + IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "15360000", + IsRequired = false + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3", + 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 = "2", + IsRequired = false + } + } + } + }; + + 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 = "ts", + VideoCodec = "h264,mpeg4,vc1", + AudioCodec = "ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "avi", + MimeType = "video/mpeg", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "mkv", + MimeType = "video/vnd.dlna.mpeg-tts", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "ts", + MimeType = "video/vnd.dlna.mpeg-tts", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "mp4", + MimeType = "video/mpeg", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "mpeg", + MimeType = "video/mpeg", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "mp3", + MimeType = "audio/mpeg", + Type = DlnaProfileType.Audio + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs index 010a18c8d1..042cc0a965 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Dlna.Profiles FriendlyName = @"KDL-\d{2}[EHLNPB]X\d[01]\d.*", Manufacturer = "Sony", - Headers = new [] + Headers = new[] { new HttpHeaderInfo { @@ -91,16 +91,61 @@ namespace MediaBrowser.Dlna.Profiles { new MediaProfile { - Container = "avi", - MimeType = "video/avi", + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T", + Type = DlnaProfileType.Video, + + Conditions = new [] + { + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"}, + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"} + } + }, + + new MediaProfile + { + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/mpeg", + OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO", + Type = DlnaProfileType.Video, + + Conditions = new [] + { + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"} + } + }, + + new MediaProfile + { + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="AVC_TS_HD_24_AC3,AVC_TS_HD_50_AC3,AVC_TS_HD_60_AC3,AVC_TS_HD_EU", Type = DlnaProfileType.Video }, new MediaProfile { - Container = "asf", - MimeType = "video/x-ms-wmv", - Type = DlnaProfileType.Audio + Container = "ts", + VideoCodec="mpeg2video", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "mpeg", + VideoCodec="mpeg1video,mpeg2video", + MimeType = "video/mpeg", + OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL", + Type = DlnaProfileType.Video } }; diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs index 50fd6e2567..401c40c362 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs @@ -105,23 +105,6 @@ namespace MediaBrowser.Dlna.Profiles } }; - 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 @@ -146,6 +129,68 @@ namespace MediaBrowser.Dlna.Profiles } }; + MediaProfiles = new[] + { + new MediaProfile + { + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T", + Type = DlnaProfileType.Video, + + Conditions = new [] + { + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"}, + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"} + } + }, + + new MediaProfile + { + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/mpeg", + OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO", + Type = DlnaProfileType.Video, + + Conditions = new [] + { + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"} + } + }, + + new MediaProfile + { + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="AVC_TS_HD_24_AC3,AVC_TS_HD_50_AC3,AVC_TS_HD_60_AC3,AVC_TS_HD_EU", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "ts", + VideoCodec="mpeg2video", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "mpeg", + VideoCodec="mpeg1video,mpeg2video", + MimeType = "video/mpeg", + OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL", + Type = DlnaProfileType.Video + } + }; + CodecProfiles = new[] { new CodecProfile diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs index b476d9c3f6..2d24c406e3 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs @@ -121,16 +121,61 @@ namespace MediaBrowser.Dlna.Profiles { new MediaProfile { - Container = "avi", - MimeType = "video/avi", + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T", + Type = DlnaProfileType.Video, + + Conditions = new [] + { + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"}, + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"} + } + }, + + new MediaProfile + { + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/mpeg", + OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO", + Type = DlnaProfileType.Video, + + Conditions = new [] + { + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"} + } + }, + + new MediaProfile + { + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="AVC_TS_HD_24_AC3,AVC_TS_HD_50_AC3,AVC_TS_HD_60_AC3,AVC_TS_HD_EU", Type = DlnaProfileType.Video }, new MediaProfile { - Container = "asf", - MimeType = "video/x-ms-wmv", - Type = DlnaProfileType.Audio + Container = "ts", + VideoCodec="mpeg2video", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "mpeg", + VideoCodec="mpeg1video,mpeg2video", + MimeType = "video/mpeg", + OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL", + Type = DlnaProfileType.Video } }; diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs index ccb655adda..10f7129581 100644 --- a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs +++ b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs @@ -177,33 +177,65 @@ namespace MediaBrowser.Dlna.Profiles { new MediaProfile { - Container = "avi", - MimeType = "video/avi", - Type = DlnaProfileType.Video + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T", + Type = DlnaProfileType.Video, + + Conditions = new [] + { + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"}, + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"} + } }, new MediaProfile { - Container = "mp4", - MimeType = "video/mp4", + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/mpeg", + OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO", + Type = DlnaProfileType.Video, + + Conditions = new [] + { + new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"} + } + }, + + new MediaProfile + { + Container = "ts", + VideoCodec="h264", + AudioCodec="ac3,aac,mp3", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="AVC_TS_HD_24_AC3,AVC_TS_HD_50_AC3,AVC_TS_HD_60_AC3,AVC_TS_HD_EU", Type = DlnaProfileType.Video }, new MediaProfile { Container = "ts", - MimeType = "video/mpeg", + VideoCodec="mpeg2video", + MimeType = "video/vnd.dlna.mpeg-tts", + OrgPn="MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO", Type = DlnaProfileType.Video }, new MediaProfile { - Container = "wma", - MimeType = "video/x-ms-wma", - Type = DlnaProfileType.Audio + Container = "mpeg", + VideoCodec="mpeg1video,mpeg2video", + MimeType = "video/mpeg", + OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL", + Type = DlnaProfileType.Video } }; + CodecProfiles = new[] { new CodecProfile diff --git a/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs b/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs new file mode 100644 index 0000000000..e5fc1ed073 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs @@ -0,0 +1,233 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class SonyPs3Profile : DefaultProfile + { + public SonyPs3Profile() + { + Name = "Sony Bravia (2010)"; + + Identification = new DeviceIdentification + { + Headers = new[] + { + new HttpHeaderInfo + { + Name = "User-Agent", + Value = @"PLAYSTATION 3", + Match = HeaderMatchType.Substring + }, + + new HttpHeaderInfo + { + Name = "X-AV-Client-Info", + Value = @"PLAYSTATION 3", + Match = HeaderMatchType.Substring + } + } + }; + + SonyAggregationFlags = "10"; + XDlnaDoc = "DMS-1.50"; + + TranscodingProfiles = new[] + { + new TranscodingProfile + { + Container = "mp3", + AudioCodec = "mp3", + Type = DlnaProfileType.Audio + }, + new TranscodingProfile + { + Container = "ts", + VideoCodec = "h264", + AudioCodec = "mp3", + Type = DlnaProfileType.Video + }, + new TranscodingProfile + { + 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, + 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.VideoFramerate, + Value = "30", + IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoBitrate, + Value = "15360000", + IsRequired = false + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "41", + IsRequired = false + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6", + IsRequired = false + }, + + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioBitrate, + Value = "640000", + IsRequired = false + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "wmapro", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "2" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "aac", + + Conditions = new [] + { + new ProfileCondition + { + Condition = ProfileConditionType.NotEquals, + Property = ProfileConditionValue.AudioProfile, + Value = "he-aac", + IsRequired = false + } + } + }, + + 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" + } + } + } + }; + + MediaProfiles = new[] + { + new MediaProfile + { + Container = "mp4,mov", + AudioCodec="aac", + MimeType = "video/mp4", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "avi", + MimeType = "video/divx", + OrgPn="AVI", + Type = DlnaProfileType.Video + }, + + new MediaProfile + { + Container = "wav", + MimeType = "audio/wav", + Type = DlnaProfileType.Audio + } + }; + } + } +} diff --git a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs index db45029a47..0daa5d7a2a 100644 --- a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs +++ b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs @@ -35,7 +35,7 @@ namespace MediaBrowser.Dlna.Profiles { new DirectPlayProfile { - Container = "mp3", + Container = "mp3,wma", Type = DlnaProfileType.Audio } }; From 7438aa6dfa5569e639d769c03ccd522d66b5bdeb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 16:07:02 -0400 Subject: [PATCH 07/12] removed codec enums --- MediaBrowser.Api/LocalizationService.cs | 9 +-- MediaBrowser.Api/NewsService.cs | 9 ++- MediaBrowser.Api/NotificationsService.cs | 19 ++--- MediaBrowser.Api/PackageReviewService.cs | 22 +++--- MediaBrowser.Api/PackageService.cs | 15 ++-- .../Playback/BaseStreamingService.cs | 72 +++++++++---------- .../Playback/Hls/BaseHlsService.cs | 4 +- .../Playback/Hls/DynamicHlsService.cs | 4 +- .../BaseProgressiveStreamingService.cs | 50 +++++++------ MediaBrowser.Api/Playback/StreamRequest.cs | 4 +- MediaBrowser.Api/PluginService.cs | 21 ++---- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 6 +- MediaBrowser.Model/Dto/StreamOptions.cs | 68 +----------------- .../EntryPoints/ExternalPortForwarding.cs | 2 +- .../ApplicationHost.cs | 2 +- MediaBrowser.WebDashboard/ApiClient.js | 6 +- MediaBrowser.WebDashboard/packages.config | 2 +- 17 files changed, 117 insertions(+), 198 deletions(-) diff --git a/MediaBrowser.Api/LocalizationService.cs b/MediaBrowser.Api/LocalizationService.cs index b3f6cbd976..60270a3895 100644 --- a/MediaBrowser.Api/LocalizationService.cs +++ b/MediaBrowser.Api/LocalizationService.cs @@ -10,8 +10,7 @@ namespace MediaBrowser.Api /// /// Class GetCultures /// - [Route("/Localization/Cultures", "GET")] - [Api(Description = "Gets known cultures")] + [Route("/Localization/Cultures", "GET", Summary = "Gets known cultures")] public class GetCultures : IReturn> { } @@ -19,8 +18,7 @@ namespace MediaBrowser.Api /// /// Class GetCountries /// - [Route("/Localization/Countries", "GET")] - [Api(Description = "Gets known countries")] + [Route("/Localization/Countries", "GET", Summary = "Gets known countries")] public class GetCountries : IReturn> { } @@ -28,8 +26,7 @@ namespace MediaBrowser.Api /// /// Class ParentalRatings /// - [Route("/Localization/ParentalRatings", "GET")] - [Api(Description = "Gets known parental ratings")] + [Route("/Localization/ParentalRatings", "GET", Summary = "Gets known parental ratings")] public class GetParentalRatings : IReturn> { } diff --git a/MediaBrowser.Api/NewsService.cs b/MediaBrowser.Api/NewsService.cs index 99a4d4fa7e..6243bf25f4 100644 --- a/MediaBrowser.Api/NewsService.cs +++ b/MediaBrowser.Api/NewsService.cs @@ -5,8 +5,7 @@ using ServiceStack; namespace MediaBrowser.Api { - [Route("/News/Product", "GET")] - [Api(Description = "Gets the latest product news.")] + [Route("/News/Product", "GET", Summary = "Gets the latest product news.")] public class GetProductNews : IReturn> { /// @@ -23,7 +22,7 @@ namespace MediaBrowser.Api [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? Limit { get; set; } } - + public class NewsService : BaseApiService { private readonly INewsService _newsService; @@ -37,8 +36,8 @@ namespace MediaBrowser.Api { var result = _newsService.GetProductNews(new NewsQuery { - StartIndex = request.StartIndex, - Limit = request.Limit + StartIndex = request.StartIndex, + Limit = request.Limit }); diff --git a/MediaBrowser.Api/NotificationsService.cs b/MediaBrowser.Api/NotificationsService.cs index 45a16347bc..a71a85395a 100644 --- a/MediaBrowser.Api/NotificationsService.cs +++ b/MediaBrowser.Api/NotificationsService.cs @@ -1,15 +1,14 @@ using MediaBrowser.Controller.Notifications; using MediaBrowser.Model.Notifications; +using ServiceStack; using System; using System.Linq; using System.Threading; using System.Threading.Tasks; -using ServiceStack; namespace MediaBrowser.Api { - [Route("/Notifications/{UserId}", "GET")] - [Api(Description = "Gets notifications")] + [Route("/Notifications/{UserId}", "GET", Summary = "Gets notifications")] public class GetNotifications : IReturn { [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] @@ -25,16 +24,14 @@ namespace MediaBrowser.Api public int? Limit { get; set; } } - [Route("/Notifications/{UserId}/Summary", "GET")] - [Api(Description = "Gets a notification summary for a user")] + [Route("/Notifications/{UserId}/Summary", "GET", Summary = "Gets a notification summary for a user")] public class GetNotificationsSummary : IReturn { [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public Guid UserId { get; set; } } - [Route("/Notifications/{UserId}", "POST")] - [Api(Description = "Adds a notifications")] + [Route("/Notifications/{UserId}", "POST", Summary = "Adds a notifications")] public class AddUserNotification : IReturn { [ApiMember(Name = "Id", Description = "The Id of the new notification. If unspecified one will be provided.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] @@ -61,9 +58,8 @@ namespace MediaBrowser.Api [ApiMember(Name = "Level", Description = "The notification level", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] public NotificationLevel Level { get; set; } } - - [Route("/Notifications/{UserId}/Read", "POST")] - [Api(Description = "Marks notifications as read")] + + [Route("/Notifications/{UserId}/Read", "POST", Summary = "Marks notifications as read")] public class MarkRead : IReturnVoid { [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] @@ -73,8 +69,7 @@ namespace MediaBrowser.Api public string Ids { get; set; } } - [Route("/Notifications/{UserId}/Unread", "POST")] - [Api(Description = "Marks notifications as unread")] + [Route("/Notifications/{UserId}/Unread", "POST", Summary = "Marks notifications as unread")] public class MarkUnread : IReturnVoid { [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] diff --git a/MediaBrowser.Api/PackageReviewService.cs b/MediaBrowser.Api/PackageReviewService.cs index b2de908d9f..94ff1b62e2 100644 --- a/MediaBrowser.Api/PackageReviewService.cs +++ b/MediaBrowser.Api/PackageReviewService.cs @@ -1,21 +1,20 @@ -using System.Collections.Generic; -using System.Globalization; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Constants; +using MediaBrowser.Common.Constants; using MediaBrowser.Common.Net; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Serialization; using ServiceStack; +using System.Collections.Generic; +using System.Globalization; +using System.Net; +using System.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Api { /// /// Class InstallPackage /// - [Route("/PackageReviews/{Id}", "POST")] - [Api(("Creates or updates a package review"))] + [Route("/Packages/Reviews/{Id}", "POST", Summary = "Creates or updates a package review")] public class CreateReviewRequest : IReturnVoid { /// @@ -57,8 +56,7 @@ namespace MediaBrowser.Api /// /// Class InstallPackage /// - [Route("/PackageReviews/{Id}", "GET")] - [Api(("Retrieve reviews for a package"))] + [Route("/Packages/{Id}/Reviews", "GET", Summary = "Gets reviews for a package")] public class ReviewRequest : IReturn> { /// @@ -114,7 +112,7 @@ namespace MediaBrowser.Api public object Get(ReviewRequest request) { var parms = "?id=" + request.Id; - + if (request.MaxRating > 0) { parms += "&max=" + request.MaxRating; @@ -132,7 +130,7 @@ namespace MediaBrowser.Api parms += "&title=true"; } - var result = _httpClient.Get(Constants.MbAdminUrl + "/service/packageReview/retrieve"+parms, CancellationToken.None).Result; + var result = _httpClient.Get(Constants.MbAdminUrl + "/service/packageReview/retrieve" + parms, CancellationToken.None).Result; var reviews = _serializer.DeserializeFromStream>(result); diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index 793b666ea0..948a67f16f 100644 --- a/MediaBrowser.Api/PackageService.cs +++ b/MediaBrowser.Api/PackageService.cs @@ -14,8 +14,7 @@ namespace MediaBrowser.Api /// /// Class GetPackage /// - [Route("/Packages/{Name}", "GET")] - [Api(("Gets a package, by name or assembly guid"))] + [Route("/Packages/{Name}", "GET", Summary = "Gets a package, by name or assembly guid")] public class GetPackage : IReturn { /// @@ -36,8 +35,7 @@ namespace MediaBrowser.Api /// /// Class GetPackages /// - [Route("/Packages", "GET")] - [Api(("Gets available packages"))] + [Route("/Packages", "GET", Summary = "Gets available packages")] public class GetPackages : IReturn> { /// @@ -57,8 +55,7 @@ namespace MediaBrowser.Api /// /// Class GetPackageVersionUpdates /// - [Route("/Packages/Updates", "GET")] - [Api(("Gets available package updates for currently installed packages"))] + [Route("/Packages/Updates", "GET", Summary = "Gets available package updates for currently installed packages")] public class GetPackageVersionUpdates : IReturn> { /// @@ -72,8 +69,7 @@ namespace MediaBrowser.Api /// /// Class InstallPackage /// - [Route("/Packages/Installed/{Name}", "POST")] - [Api(("Installs a package"))] + [Route("/Packages/Installed/{Name}", "POST", Summary = "Installs a package")] public class InstallPackage : IReturnVoid { /// @@ -108,8 +104,7 @@ namespace MediaBrowser.Api /// /// Class CancelPackageInstallation /// - [Route("/Packages/Installing/{Id}", "DELETE")] - [Api(("Cancels a package installation"))] + [Route("/Packages/Installing/{Id}", "DELETE", Summary = "Cancels a package installation")] public class CancelPackageInstallation : IReturnVoid { /// diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index e27fe1dda6..a6b3b72942 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -9,7 +9,6 @@ using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Drawing; -using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Library; @@ -735,13 +734,10 @@ namespace MediaBrowser.Api.Playback { if (audioStream != null) { - if (audioStream.Channels > 2 && request.AudioCodec.HasValue) + if (audioStream.Channels > 2 && string.Equals(request.AudioCodec, "wma", StringComparison.OrdinalIgnoreCase)) { - if (request.AudioCodec.Value == AudioCodecs.Wma) - { - // wmav2 currently only supports two channel output - return 2; - } + // wmav2 currently only supports two channel output + return 2; } } @@ -778,26 +774,26 @@ namespace MediaBrowser.Api.Playback { var codec = request.AudioCodec; - if (codec.HasValue) + if (!string.IsNullOrEmpty(codec)) { - if (codec == AudioCodecs.Aac) + if (string.Equals(codec, "aac", StringComparison.OrdinalIgnoreCase)) { return "aac -strict experimental"; } - if (codec == AudioCodecs.Mp3) + if (string.Equals(codec, "mp3", StringComparison.OrdinalIgnoreCase)) { return "libmp3lame"; } - if (codec == AudioCodecs.Vorbis) + if (string.Equals(codec, "vorbis", StringComparison.OrdinalIgnoreCase)) { return "libvorbis"; } - if (codec == AudioCodecs.Wma) + if (string.Equals(codec, "wma", StringComparison.OrdinalIgnoreCase)) { return "wmav2"; } - return codec.ToString().ToLower(); + return codec.ToLower(); } return "copy"; @@ -812,26 +808,26 @@ namespace MediaBrowser.Api.Playback { var codec = request.VideoCodec; - if (codec.HasValue) + if (!string.IsNullOrEmpty(codec)) { - if (codec == VideoCodecs.H264) + if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase)) { return "libx264"; } - if (codec == VideoCodecs.Vpx) + if (string.Equals(codec, "vpx", StringComparison.OrdinalIgnoreCase)) { return "libvpx"; } - if (codec == VideoCodecs.Wmv) + if (string.Equals(codec, "wmv", StringComparison.OrdinalIgnoreCase)) { return "msmpeg4"; } - if (codec == VideoCodecs.Theora) + if (string.Equals(codec, "theora", StringComparison.OrdinalIgnoreCase)) { return "libtheora"; } - return codec.ToString().ToLower(); + return codec.ToLower(); } return "copy"; @@ -1229,12 +1225,12 @@ namespace MediaBrowser.Api.Playback { if (videoRequest != null) { - videoRequest.VideoCodec = (VideoCodecs)Enum.Parse(typeof(VideoCodecs), val, true); + videoRequest.VideoCodec = val; } } else if (i == 5) { - request.AudioCodec = (AudioCodecs)Enum.Parse(typeof(AudioCodecs), val, true); + request.AudioCodec = val; } else if (i == 6) { @@ -1311,7 +1307,7 @@ namespace MediaBrowser.Api.Playback var url = Request.PathInfo; - if (!request.AudioCodec.HasValue) + if (string.IsNullOrEmpty(request.AudioCodec)) { request.AudioCodec = InferAudioCodec(url); } @@ -1439,7 +1435,7 @@ namespace MediaBrowser.Api.Playback if (videoRequest != null) { - if (!videoRequest.VideoCodec.HasValue) + if (string.IsNullOrEmpty(videoRequest.VideoCodec)) { videoRequest.VideoCodec = InferVideoCodec(url); } @@ -1546,41 +1542,41 @@ namespace MediaBrowser.Api.Playback /// /// The URL. /// System.Nullable{AudioCodecs}. - private AudioCodecs? InferAudioCodec(string url) + private string InferAudioCodec(string url) { var ext = Path.GetExtension(url); if (string.Equals(ext, ".mp3", StringComparison.OrdinalIgnoreCase)) { - return AudioCodecs.Mp3; + return "mp3"; } if (string.Equals(ext, ".aac", StringComparison.OrdinalIgnoreCase)) { - return AudioCodecs.Aac; + return "aac"; } if (string.Equals(ext, ".wma", StringComparison.OrdinalIgnoreCase)) { - return AudioCodecs.Wma; + return "wma"; } if (string.Equals(ext, ".ogg", StringComparison.OrdinalIgnoreCase)) { - return AudioCodecs.Vorbis; + return "vorbis"; } if (string.Equals(ext, ".oga", StringComparison.OrdinalIgnoreCase)) { - return AudioCodecs.Vorbis; + return "vorbis"; } if (string.Equals(ext, ".ogv", StringComparison.OrdinalIgnoreCase)) { - return AudioCodecs.Vorbis; + return "vorbis"; } if (string.Equals(ext, ".webm", StringComparison.OrdinalIgnoreCase)) { - return AudioCodecs.Vorbis; + return "vorbis"; } if (string.Equals(ext, ".webma", StringComparison.OrdinalIgnoreCase)) { - return AudioCodecs.Vorbis; + return "vorbis"; } return null; @@ -1591,28 +1587,28 @@ namespace MediaBrowser.Api.Playback /// /// The URL. /// System.Nullable{VideoCodecs}. - private VideoCodecs? InferVideoCodec(string url) + private string InferVideoCodec(string url) { var ext = Path.GetExtension(url); if (string.Equals(ext, ".asf", StringComparison.OrdinalIgnoreCase)) { - return VideoCodecs.Wmv; + return "wmv"; } if (string.Equals(ext, ".webm", StringComparison.OrdinalIgnoreCase)) { - return VideoCodecs.Vpx; + return "vpx"; } if (string.Equals(ext, ".ogg", StringComparison.OrdinalIgnoreCase) || string.Equals(ext, ".ogv", StringComparison.OrdinalIgnoreCase)) { - return VideoCodecs.Theora; + return "theora"; } if (string.Equals(ext, ".m3u8", StringComparison.OrdinalIgnoreCase) || string.Equals(ext, ".ts", StringComparison.OrdinalIgnoreCase)) { - return VideoCodecs.H264; + return "h264"; } - return VideoCodecs.Copy; + return "copy"; } } } diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index aec271ff20..eb8f415e0d 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -91,11 +91,11 @@ namespace MediaBrowser.Api.Playback.Hls { var state = GetState(request, CancellationToken.None).Result; - if (!state.VideoRequest.VideoBitRate.HasValue && (!state.VideoRequest.VideoCodec.HasValue || state.VideoRequest.VideoCodec.Value != VideoCodecs.Copy)) + if (!state.VideoRequest.VideoBitRate.HasValue && (string.IsNullOrEmpty(state.VideoRequest.VideoCodec) || !string.Equals(state.VideoRequest.VideoCodec, "copy", StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException("A video bitrate is required"); } - if (!state.Request.AudioBitRate.HasValue && (!state.Request.AudioCodec.HasValue || state.Request.AudioCodec.Value != AudioCodecs.Copy)) + if (!state.Request.AudioBitRate.HasValue && (string.IsNullOrEmpty(state.Request.AudioCodec) || !string.Equals(state.Request.AudioCodec, "copy", StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException("An audio bitrate is required"); } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 121957ecc9..66e8b0d149 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -136,11 +136,11 @@ namespace MediaBrowser.Api.Playback.Hls { var state = await GetState(request, CancellationToken.None).ConfigureAwait(false); - if (!state.VideoRequest.VideoBitRate.HasValue && (!state.VideoRequest.VideoCodec.HasValue || state.VideoRequest.VideoCodec.Value != VideoCodecs.Copy)) + if (!state.VideoRequest.VideoBitRate.HasValue && (string.IsNullOrEmpty(state.VideoRequest.VideoCodec) || !string.Equals(state.VideoRequest.VideoCodec, "copy", StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException("A video bitrate is required"); } - if (!state.Request.AudioBitRate.HasValue && (!state.Request.AudioCodec.HasValue || state.Request.AudioCodec.Value != AudioCodecs.Copy)) + if (!state.Request.AudioBitRate.HasValue && (string.IsNullOrEmpty(state.Request.AudioCodec) || !string.Equals(state.Request.AudioCodec, "copy", StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException("An audio bitrate is required"); } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 8ae61b5219..9cb989fc21 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -50,39 +50,49 @@ namespace MediaBrowser.Api.Playback.Progressive var videoRequest = state.Request as VideoStreamRequest; // Try to infer based on the desired video codec - if (videoRequest != null && videoRequest.VideoCodec.HasValue) + if (videoRequest != null && !string.IsNullOrEmpty(videoRequest.VideoCodec)) { if (state.IsInputVideo) { - switch (videoRequest.VideoCodec.Value) + if (string.Equals(videoRequest.VideoCodec, "h264", StringComparison.OrdinalIgnoreCase)) { - case VideoCodecs.H264: - return ".ts"; - case VideoCodecs.Theora: - return ".ogv"; - case VideoCodecs.Vpx: - return ".webm"; - case VideoCodecs.Wmv: - return ".asf"; + return ".ts"; + } + if (string.Equals(videoRequest.VideoCodec, "theora", StringComparison.OrdinalIgnoreCase)) + { + return ".ogv"; + } + if (string.Equals(videoRequest.VideoCodec, "vpx", StringComparison.OrdinalIgnoreCase)) + { + return ".webm"; + } + if (string.Equals(videoRequest.VideoCodec, "wmv", StringComparison.OrdinalIgnoreCase)) + { + return ".asf"; } } } // Try to infer based on the desired audio codec - if (state.Request.AudioCodec.HasValue) + if (!string.IsNullOrEmpty(state.Request.AudioCodec)) { if (!state.IsInputVideo) { - switch (state.Request.AudioCodec.Value) + if (string.Equals("aac", state.Request.AudioCodec, StringComparison.OrdinalIgnoreCase)) + { + return ".aac"; + } + if (string.Equals("mp3", state.Request.AudioCodec, StringComparison.OrdinalIgnoreCase)) + { + return ".mp3"; + } + if (string.Equals("vorbis", state.Request.AudioCodec, StringComparison.OrdinalIgnoreCase)) + { + return ".ogg"; + } + if (string.Equals("wma", state.Request.AudioCodec, StringComparison.OrdinalIgnoreCase)) { - case AudioCodecs.Aac: - return ".aac"; - case AudioCodecs.Mp3: - return ".mp3"; - case AudioCodecs.Vorbis: - return ".ogg"; - case AudioCodecs.Wma: - return ".wma"; + return ".wma"; } } } diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index 2251ce52d3..67948e19ab 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -26,7 +26,7 @@ namespace MediaBrowser.Api.Playback /// /// The audio codec. [ApiMember(Name = "AudioCodec", Description = "Optional. Specify a audio codec to encode to, e.g. mp3. If omitted the server will auto-select using the url's extension. Options: aac, mp3, vorbis, wma.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] - public AudioCodecs? AudioCodec { get; set; } + public string AudioCodec { get; set; } /// /// Gets or sets the start time ticks. @@ -81,7 +81,7 @@ namespace MediaBrowser.Api.Playback /// /// The video codec. [ApiMember(Name = "VideoCodec", Description = "Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will auto-select using the url's extension. Options: h264, mpeg4, theora, vpx, wmv.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] - public VideoCodecs? VideoCodec { get; set; } + public string VideoCodec { get; set; } /// /// Gets or sets the video bit rate. diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index e66f432df8..31463dc3f4 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -18,8 +18,7 @@ namespace MediaBrowser.Api /// /// Class Plugins /// - [Route("/Plugins", "GET")] - [Api(("Gets a list of currently installed plugins"))] + [Route("/Plugins", "GET", Summary = "Gets a list of currently installed plugins")] public class GetPlugins : IReturn> { } @@ -27,8 +26,7 @@ namespace MediaBrowser.Api /// /// Class UninstallPlugin /// - [Route("/Plugins/{Id}", "DELETE")] - [Api(("Uninstalls a plugin"))] + [Route("/Plugins/{Id}", "DELETE", Summary = "Uninstalls a plugin")] public class UninstallPlugin : IReturnVoid { /// @@ -42,8 +40,7 @@ namespace MediaBrowser.Api /// /// Class GetPluginConfiguration /// - [Route("/Plugins/{Id}/Configuration", "GET")] - [Api(("Gets a plugin's configuration"))] + [Route("/Plugins/{Id}/Configuration", "GET", Summary = "Gets a plugin's configuration")] public class GetPluginConfiguration { /// @@ -57,8 +54,7 @@ namespace MediaBrowser.Api /// /// Class UpdatePluginConfiguration /// - [Route("/Plugins/{Id}/Configuration", "POST")] - [Api(("Updates a plugin's configuration"))] + [Route("/Plugins/{Id}/Configuration", "POST", Summary = "Updates a plugin's configuration")] public class UpdatePluginConfiguration : IRequiresRequestStream, IReturnVoid { /// @@ -78,8 +74,7 @@ namespace MediaBrowser.Api /// /// Class GetPluginSecurityInfo /// - [Route("/Plugins/SecurityInfo", "GET")] - [Api(("Gets plugin registration information"))] + [Route("/Plugins/SecurityInfo", "GET", Summary = "Gets plugin registration information")] public class GetPluginSecurityInfo : IReturn { } @@ -87,14 +82,12 @@ namespace MediaBrowser.Api /// /// Class UpdatePluginSecurityInfo /// - [Route("/Plugins/SecurityInfo", "POST")] - [Api("Updates plugin registration information")] + [Route("/Plugins/SecurityInfo", "POST", Summary = "Updates plugin registration information")] public class UpdatePluginSecurityInfo : PluginSecurityInfo, IReturnVoid { } - [Route("/Plugins/RegistrationRecords/{Name}", "GET")] - [Api("Gets registration status for a feature")] + [Route("/Plugins/RegistrationRecords/{Name}", "GET", Summary = "Gets registration status for a feature")] public class GetRegistrationStatus { [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index 6279fb1cb6..d7460c352e 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -135,7 +135,7 @@ namespace MediaBrowser.Dlna.PlayTo _logger.Info("SSDP listener - Task completed"); } - catch (OperationCanceledException c) + catch (OperationCanceledException) { } catch (Exception e) @@ -154,7 +154,7 @@ namespace MediaBrowser.Dlna.PlayTo { await CreateController(uri).ConfigureAwait(false); } - catch (OperationCanceledException c) + catch (OperationCanceledException) { } catch (Exception ex) @@ -179,7 +179,7 @@ namespace MediaBrowser.Dlna.PlayTo await Task.Delay(10000).ConfigureAwait(false); } } - catch (OperationCanceledException c) + catch (OperationCanceledException) { } catch (Exception ex) diff --git a/MediaBrowser.Model/Dto/StreamOptions.cs b/MediaBrowser.Model/Dto/StreamOptions.cs index 17fd06cb6a..c38707e536 100644 --- a/MediaBrowser.Model/Dto/StreamOptions.cs +++ b/MediaBrowser.Model/Dto/StreamOptions.cs @@ -10,7 +10,7 @@ /// Omit to copy /// /// The video codec. - public VideoCodecs? VideoCodec { get; set; } + public string VideoCodec { get; set; } /// /// Gets or sets the video bit rate. @@ -113,7 +113,7 @@ /// Omit to copy the original stream /// /// The audio encoding format. - public AudioCodecs? AudioCodec { get; set; } + public string AudioCodec { get; set; } /// /// Gets or sets the item id. @@ -158,68 +158,4 @@ /// The device id. public string DeviceId { get; set; } } - - /// - /// These are the codecs the api is capable of encoding to - /// - public enum AudioCodecs - { - /// - /// The aac - /// - Aac, - /// - /// The MP3 - /// - Mp3, - /// - /// The vorbis - /// - Vorbis, - /// - /// The wma - /// - Wma, - /// - /// The copy - /// - Copy - } - - /// - /// Enum VideoCodecs - /// - public enum VideoCodecs - { - H263, - - /// - /// The H264 - /// - H264, - - /// - /// The mpeg4 - /// - Mpeg4, - - /// - /// The theora - /// - Theora, - - /// - /// The VPX - /// - Vpx, - - /// - /// The WMV - /// - Wmv, - /// - /// The copy - /// - Copy - } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index ad2852a914..098d1295f1 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -88,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints CreateRules(device); } - catch (Exception ex) + catch (Exception) { //_logger.ErrorException("Error creating port forwarding rules", ex); } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index dec1a10310..e49244edf0 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -266,7 +266,7 @@ namespace MediaBrowser.ServerApplication { MigrateUserFolders(); } - catch (IOException ex) + catch (IOException) { } diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 765cae6128..ea1905bad5 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -3809,7 +3809,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi var deferred = $.Deferred(); var msg = [itemId, canSeek, queueableMediaTypes]; - + if (mediaSourceId) { msg.push(mediaSourceId); } @@ -4029,7 +4029,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi self.createPackageReview = function (review) { - var url = self.getUrl("PackageReviews/" + review.id, review); + var url = self.getUrl("Packages/Reviews/" + review.id, review); return self.ajax({ type: "POST", @@ -4058,7 +4058,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi options.ForceTitle = true; } - var url = self.getUrl("PackageReviews/" + packageId, options); + var url = self.getUrl("Packages/" + packageId + "Reviews", options); return self.ajax({ type: "GET", diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 7396527bb3..a5074d3c88 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file From f226d94012cbe0ce0855efadc561ec4fb215fc94 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 16:49:05 -0400 Subject: [PATCH 08/12] add more dlna options --- MediaBrowser.Api/Playback/StreamRequest.cs | 3 +-- MediaBrowser.Api/SessionsService.cs | 2 +- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 4 +++- MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs | 6 +++--- MediaBrowser.Model/Configuration/DlnaOptions.cs | 4 +++- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index 67948e19ab..3439621e95 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Model.Dto; -using ServiceStack; +using ServiceStack; namespace MediaBrowser.Api.Playback { diff --git a/MediaBrowser.Api/SessionsService.cs b/MediaBrowser.Api/SessionsService.cs index 070fe9e598..a509c876ce 100644 --- a/MediaBrowser.Api/SessionsService.cs +++ b/MediaBrowser.Api/SessionsService.cs @@ -27,7 +27,7 @@ namespace MediaBrowser.Api [ApiMember(Name = "ControllableByUserId", Description = "Optional. Filter by sessions that a given user is allowed to remote control.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public Guid? ControllableByUserId { get; set; } - [ApiMember(Name = "DeviceId", Description = "Optional. Filter by device id.", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + [ApiMember(Name = "DeviceId", Description = "Optional. Filter by device id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string DeviceId { get; set; } } diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index d7460c352e..f3901e0b40 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -176,7 +176,9 @@ namespace MediaBrowser.Dlna.PlayTo { socket.SendTo(request, new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900)); - await Task.Delay(10000).ConfigureAwait(false); + var delay = _config.Configuration.DlnaOptions.ClientDiscoveryIntervalSeconds*1000; + + await Task.Delay(delay).ConfigureAwait(false); } } catch (OperationCanceledException) diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs index 7a4928e5ca..f540a80041 100644 --- a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs +++ b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs @@ -49,7 +49,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url.ToString(), UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnablePlayToDebugLogging + LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging }; options.RequestHeaders["HOST"] = ip + ":" + port; @@ -88,7 +88,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url.ToString(), UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnablePlayToDebugLogging + LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging }; options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName; @@ -112,7 +112,7 @@ namespace MediaBrowser.Dlna.PlayTo { Url = url.ToString(), UserAgent = USERAGENT, - LogRequest = _config.Configuration.DlnaOptions.EnablePlayToDebugLogging + LogRequest = _config.Configuration.DlnaOptions.EnableDebugLogging }; options.RequestHeaders["SOAPAction"] = soapAction; diff --git a/MediaBrowser.Model/Configuration/DlnaOptions.cs b/MediaBrowser.Model/Configuration/DlnaOptions.cs index b2503ebc7e..893e377faf 100644 --- a/MediaBrowser.Model/Configuration/DlnaOptions.cs +++ b/MediaBrowser.Model/Configuration/DlnaOptions.cs @@ -4,11 +4,13 @@ namespace MediaBrowser.Model.Configuration public class DlnaOptions { public bool EnablePlayTo { get; set; } - public bool EnablePlayToDebugLogging { get; set; } + public bool EnableDebugLogging { get; set; } + public int ClientDiscoveryIntervalSeconds { get; set; } public DlnaOptions() { EnablePlayTo = true; + ClientDiscoveryIntervalSeconds = 30; } } } From c9ca62329e0e2d28dfc28f568b09a202f5b6e0ff Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 17:46:13 -0400 Subject: [PATCH 09/12] added an lg profile --- MediaBrowser.Dlna/DlnaManager.cs | 46 ++--- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 1 + MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 2 +- MediaBrowser.Dlna/Profiles/LgTvProfile.cs | 192 +++++++++++++++++++++ 4 files changed, 212 insertions(+), 29 deletions(-) create mode 100644 MediaBrowser.Dlna/Profiles/LgTvProfile.cs diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 25a82f5290..8b8644bee0 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -27,35 +27,25 @@ namespace MediaBrowser.Dlna public IEnumerable GetProfiles() { - var list = new List(); - - list.Add(new SamsungSmartTvProfile()); - - list.Add(new Xbox360Profile()); - - list.Add(new XboxOneProfile()); - - list.Add(new SonyPs3Profile()); - - list.Add(new SonyBravia2010Profile()); - - list.Add(new SonyBravia2011Profile()); - - list.Add(new SonyBravia2012Profile()); - - list.Add(new SonyBravia2013Profile()); - - list.Add(new SonyBlurayPlayer2013Profile()); - list.Add(new SonyBlurayPlayerProfile()); - - list.Add(new PanasonicVieraProfile()); - - list.Add(new WdtvLiveProfile()); - - list.Add(new DenonAvrProfile()); + var list = new List + { + new SamsungSmartTvProfile(), + new Xbox360Profile(), + new XboxOneProfile(), + new SonyPs3Profile(), + new SonyBravia2010Profile(), + new SonyBravia2011Profile(), + new SonyBravia2012Profile(), + new SonyBravia2013Profile(), + new SonyBlurayPlayer2013Profile(), + new SonyBlurayPlayerProfile(), + new PanasonicVieraProfile(), + new WdtvLiveProfile(), + new DenonAvrProfile(), + new LinksysDMA2100Profile(), + new LgTvProfile() + }; - list.Add(new LinksysDMA2100Profile()); - foreach (var item in list) { //_xmlSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".xml"); diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 31eed483fe..4eb305e0f9 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -83,6 +83,7 @@ + diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index f3901e0b40..ca76116feb 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -176,7 +176,7 @@ namespace MediaBrowser.Dlna.PlayTo { socket.SendTo(request, new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900)); - var delay = _config.Configuration.DlnaOptions.ClientDiscoveryIntervalSeconds*1000; + var delay = _config.Configuration.DlnaOptions.ClientDiscoveryIntervalSeconds * 1000; await Task.Delay(delay).ConfigureAwait(false); } diff --git a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs new file mode 100644 index 0000000000..ec20c9df84 --- /dev/null +++ b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs @@ -0,0 +1,192 @@ +using MediaBrowser.Controller.Dlna; + +namespace MediaBrowser.Dlna.Profiles +{ + public class LgTvProfile : DefaultProfile + { + public LgTvProfile() + { + Name = "LG Smart TV"; + + TimelineOffsetSeconds = 10; + + Identification = new DeviceIdentification + { + FriendlyName = @"LG.*", + + Headers = new[] + { + new HttpHeaderInfo + { + Name = "User-Agent", + Value = "LG", + Match = HeaderMatchType.Substring + } + } + }; + + 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 = "ts", + VideoCodec = "h264", + AudioCodec = "aac,ac3,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mkv", + VideoCodec = "h264", + AudioCodec = "aac,ac3,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp4", + VideoCodec = "h264,mpeg4", + AudioCodec = "aac,ac3,mp3", + Type = DlnaProfileType.Video + }, + new DirectPlayProfile + { + Container = "mp3", + AudioCodec = "mp3", + 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, + Codec = "mpeg4", + + 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" + } + } + }, + + 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.VideoFramerate, + Value = "30" + }, + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.VideoLevel, + Value = "41" + } + } + }, + + new CodecProfile + { + Type = CodecType.VideoAudioCodec, + Codec = "ac3,aac,mp3", + + Conditions = new[] + { + new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + Property = ProfileConditionValue.AudioChannels, + Value = "6" + } + } + } + }; + } + } +} From 787f5e8382af65279dfc05e0b23ac9ec874c80ad Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 23 Mar 2014 18:21:49 -0400 Subject: [PATCH 10/12] updated nuget --- MediaBrowser.Model/ApiClient/IApiClient.cs | 2 +- .../Configuration/DlnaOptions.cs | 2 +- .../LiveTv/SeriesTimerInfoDto.cs | 104 +----------------- MediaBrowser.Model/LiveTv/TimerInfoDto.cs | 92 ++++++++-------- Nuget/MediaBrowser.Common.Internal.nuspec | 4 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- 7 files changed, 58 insertions(+), 152 deletions(-) diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 91ac67a1f7..8de54f34a9 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -1030,7 +1030,7 @@ namespace MediaBrowser.Model.ApiClient /// The timer. /// The cancellation token. /// Task. - Task CreateLiveTvTimerAsync(TimerInfoDto timer, CancellationToken cancellationToken); + Task CreateLiveTvTimerAsync(BaseTimerInfoDto timer, CancellationToken cancellationToken); /// /// Updates the live tv timer asynchronous. diff --git a/MediaBrowser.Model/Configuration/DlnaOptions.cs b/MediaBrowser.Model/Configuration/DlnaOptions.cs index 893e377faf..b6398239fa 100644 --- a/MediaBrowser.Model/Configuration/DlnaOptions.cs +++ b/MediaBrowser.Model/Configuration/DlnaOptions.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Model.Configuration public DlnaOptions() { EnablePlayTo = true; - ClientDiscoveryIntervalSeconds = 30; + ClientDiscoveryIntervalSeconds = 60; } } } diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs index 0198cc3995..393233c1bf 100644 --- a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs @@ -1,80 +1,14 @@ -using System; +using MediaBrowser.Model.Entities; +using System; using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; using System.Runtime.Serialization; -using MediaBrowser.Model.Entities; namespace MediaBrowser.Model.LiveTv { [DebuggerDisplay("Name = {Name}")] - public class SeriesTimerInfoDto : INotifyPropertyChanged + public class SeriesTimerInfoDto : BaseTimerInfoDto { - /// - /// Id of the recording. - /// - public string Id { get; set; } - - /// - /// Gets or sets the external identifier. - /// - /// The external identifier. - public string ExternalId { get; set; } - - /// - /// ChannelId of the recording. - /// - public string ChannelId { get; set; } - - /// - /// Gets or sets the name of the service. - /// - /// The name of the service. - public string ServiceName { get; set; } - - /// - /// Gets or sets the external channel identifier. - /// - /// The external channel identifier. - public string ExternalChannelId { get; set; } - - /// - /// ChannelName of the recording. - /// - public string ChannelName { get; set; } - - /// - /// Gets or sets the program identifier. - /// - /// The program identifier. - public string ProgramId { get; set; } - - /// - /// Gets or sets the external program identifier. - /// - /// The external program identifier. - public string ExternalProgramId { get; set; } - - /// - /// Name of the recording. - /// - public string Name { get; set; } - - /// - /// Description of the recording. - /// - public string Overview { get; set; } - - /// - /// The start date of the recording, in UTC. - /// - public DateTime StartDate { get; set; } - - /// - /// The end date of the recording, in UTC. - /// - public DateTime EndDate { get; set; } - /// /// Gets or sets a value indicating whether [record any time]. /// @@ -105,36 +39,6 @@ namespace MediaBrowser.Model.LiveTv /// The day pattern. public DayPattern? DayPattern { get; set; } - /// - /// Gets or sets the priority. - /// - /// The priority. - public int Priority { get; set; } - - /// - /// Gets or sets the pre padding seconds. - /// - /// The pre padding seconds. - public int PrePaddingSeconds { get; set; } - - /// - /// Gets or sets the post padding seconds. - /// - /// The post padding seconds. - public int PostPaddingSeconds { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is pre padding required. - /// - /// true if this instance is pre padding required; otherwise, false. - public bool IsPrePaddingRequired { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is post padding required. - /// - /// true if this instance is post padding required; otherwise, false. - public bool IsPostPaddingRequired { get; set; } - /// /// Gets or sets the image tags. /// @@ -156,7 +60,5 @@ namespace MediaBrowser.Model.LiveTv ImageTags = new Dictionary(); Days = new List(); } - - public event PropertyChangedEventHandler PropertyChanged; } } diff --git a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs index a330f44d8e..137c957192 100644 --- a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs @@ -3,8 +3,47 @@ using System.ComponentModel; namespace MediaBrowser.Model.LiveTv { - public class TimerInfoDto : INotifyPropertyChanged + public class TimerInfoDto : BaseTimerInfoDto { + /// + /// Gets or sets the status. + /// + /// The status. + public RecordingStatus Status { get; set; } + + /// + /// Gets or sets the series timer identifier. + /// + /// The series timer identifier. + public string SeriesTimerId { get; set; } + + /// + /// Gets or sets the external series timer identifier. + /// + /// The external series timer identifier. + public string ExternalSeriesTimerId { get; set; } + + /// + /// Gets or sets the run time ticks. + /// + /// The run time ticks. + public long? RunTimeTicks { get; set; } + + /// + /// Gets or sets the program information. + /// + /// The program information. + public ProgramInfoDto ProgramInfo { get; set; } + + } + + public class BaseTimerInfoDto : INotifyPropertyChanged + { + /// + /// Occurs when a property value changes. + /// + public event PropertyChangedEventHandler PropertyChanged; + /// /// Id of the recording. /// @@ -26,18 +65,12 @@ namespace MediaBrowser.Model.LiveTv /// /// The external channel identifier. public string ExternalChannelId { get; set; } - + /// /// ChannelName of the recording. /// public string ChannelName { get; set; } - /// - /// Gets or sets the name of the service. - /// - /// The name of the service. - public string ServiceName { get; set; } - /// /// Gets or sets the program identifier. /// @@ -49,7 +82,7 @@ namespace MediaBrowser.Model.LiveTv /// /// The external program identifier. public string ExternalProgramId { get; set; } - + /// /// Name of the recording. /// @@ -71,22 +104,16 @@ namespace MediaBrowser.Model.LiveTv public DateTime EndDate { get; set; } /// - /// Gets or sets the status. - /// - /// The status. - public RecordingStatus Status { get; set; } - - /// - /// Gets or sets the series timer identifier. + /// Gets or sets the name of the service. /// - /// The series timer identifier. - public string SeriesTimerId { get; set; } + /// The name of the service. + public string ServiceName { get; set; } /// - /// Gets or sets the external series timer identifier. + /// Gets or sets the priority. /// - /// The external series timer identifier. - public string ExternalSeriesTimerId { get; set; } + /// The priority. + public int Priority { get; set; } /// /// Gets or sets the pre padding seconds. @@ -111,28 +138,5 @@ namespace MediaBrowser.Model.LiveTv /// /// true if this instance is post padding required; otherwise, false. public bool IsPostPaddingRequired { get; set; } - - /// - /// Gets or sets the run time ticks. - /// - /// The run time ticks. - public long? RunTimeTicks { get; set; } - - /// - /// Gets or sets the priority. - /// - /// The priority. - public int Priority { get; set; } - - /// - /// Gets or sets the program information. - /// - /// The program information. - public ProgramInfoDto ProgramInfo { get; set; } - - /// - /// Occurs when a property value changes. - /// - public event PropertyChangedEventHandler PropertyChanged; } } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 12219e81dc..c550b350c6 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.343 + 3.0.345 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 495dc3f2b8..a6fa5c152c 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.343 + 3.0.345 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 398adc2079..cc87b00300 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.343 + 3.0.345 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + From 765b777853421893404cafe75690b04ac2e162c0 Mon Sep 17 00:00:00 2001 From: 7illusions Date: Mon, 24 Mar 2014 08:47:23 +0100 Subject: [PATCH 11/12] DLNA profile fixes --- MediaBrowser.Dlna/DlnaManager.cs | 18 +++++++++--------- MediaBrowser.Dlna/PlayTo/Device.cs | 5 ++++- MediaBrowser.Dlna/PlayTo/DeviceInfo.cs | 5 ++++- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 8b8644bee0..c6da865cd7 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -70,55 +70,55 @@ namespace MediaBrowser.Dlna { if (!string.IsNullOrWhiteSpace(profileInfo.DeviceDescription)) { - if (!Regex.IsMatch(deviceInfo.DeviceDescription, profileInfo.DeviceDescription)) + if (deviceInfo.DeviceDescription == null || !Regex.IsMatch(deviceInfo.DeviceDescription, profileInfo.DeviceDescription)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.FriendlyName)) { - if (!Regex.IsMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) + if (deviceInfo.FriendlyName == null || !Regex.IsMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.Manufacturer)) { - if (!Regex.IsMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) + if (deviceInfo.Manufacturer == null || !Regex.IsMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ManufacturerUrl)) { - if (!Regex.IsMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) + if (deviceInfo.ManufacturerUrl == null || !Regex.IsMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ModelDescription)) { - if (!Regex.IsMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) + if (deviceInfo.ModelDescription == null || !Regex.IsMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ModelName)) { - if (!Regex.IsMatch(deviceInfo.ModelName, profileInfo.ModelName)) + if (deviceInfo.ModelName == null || !Regex.IsMatch(deviceInfo.ModelName, profileInfo.ModelName)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ModelNumber)) { - if (!Regex.IsMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) + if (deviceInfo.ModelNumber == null || !Regex.IsMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.ModelUrl)) { - if (!Regex.IsMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) + if (deviceInfo.ModelUrl == null || !Regex.IsMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) return false; } if (!string.IsNullOrWhiteSpace(profileInfo.SerialNumber)) { - if (!Regex.IsMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) + if (deviceInfo.SerialNumber == null || !Regex.IsMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) return false; } diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs index 5952a213ae..2b43c019c0 100644 --- a/MediaBrowser.Dlna/PlayTo/Device.cs +++ b/MediaBrowser.Dlna/PlayTo/Device.cs @@ -681,7 +681,10 @@ namespace MediaBrowser.Dlna.PlayTo var presentationUrl = document.Descendants(uPnpNamespaces.ud.GetName("presentationURL")).FirstOrDefault(); if (presentationUrl != null) deviceProperties.PresentationUrl = presentationUrl.Value; - + var modelUrl = document.Descendants(uPnpNamespaces.ud.GetName("modelURL")).FirstOrDefault(); + if (modelUrl != null) + deviceProperties.ModelUrl = modelUrl.Value; + deviceProperties.BaseUrl = String.Format("http://{0}:{1}", url.Host, url.Port); diff --git a/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs b/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs index 4b40daf704..c57e95c194 100644 --- a/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs +++ b/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs @@ -34,6 +34,8 @@ namespace MediaBrowser.Dlna.PlayTo public string ModelNumber { get; set; } + public string ModelUrl { get; set; } + public string Manufacturer { get; set; } public string ManufacturerUrl { get; set; } @@ -72,7 +74,8 @@ namespace MediaBrowser.Dlna.PlayTo ModelName = ModelName, ModelNumber = ModelNumber, FriendlyName = Name, - ManufacturerUrl = ManufacturerUrl + ManufacturerUrl = ManufacturerUrl, + ModelUrl = ModelUrl }; } } From 501dedb13cd59dc2683ac4192cd11289bd304cfb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 24 Mar 2014 08:47:39 -0400 Subject: [PATCH 12/12] stub out dlna server --- .../ScheduledTasksWebSocketListener.cs | 22 +- .../Net/BasePeriodicWebSocketListener.cs | 18 +- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 9 +- .../Server/DlnaServerEntryPoint.cs | 115 ++++++++ MediaBrowser.Dlna/Server/Headers.cs | 164 +++++++++++ MediaBrowser.Dlna/Server/RawHeaders.cs | 16 ++ MediaBrowser.Dlna/Server/SsdpHandler.cs | 260 ++++++++++++++++++ MediaBrowser.Dlna/Server/UpnpDevice.cs | 28 ++ .../Configuration/DlnaOptions.cs | 2 + 9 files changed, 623 insertions(+), 11 deletions(-) create mode 100644 MediaBrowser.Dlna/Server/DlnaServerEntryPoint.cs create mode 100644 MediaBrowser.Dlna/Server/Headers.cs create mode 100644 MediaBrowser.Dlna/Server/RawHeaders.cs create mode 100644 MediaBrowser.Dlna/Server/SsdpHandler.cs create mode 100644 MediaBrowser.Dlna/Server/UpnpDevice.cs diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index c143635bfa..0d3f5dfcdf 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -39,6 +39,8 @@ namespace MediaBrowser.Api.ScheduledTasks TaskManager = taskManager; } + private bool _lastResponseHadTasksRunning = true; + /// /// Gets the data to send. /// @@ -46,7 +48,25 @@ namespace MediaBrowser.Api.ScheduledTasks /// Task{IEnumerable{TaskInfo}}. protected override Task> GetDataToSend(object state) { - return Task.FromResult(TaskManager.ScheduledTasks + var tasks = TaskManager.ScheduledTasks.ToList(); + + var anyRunning = tasks.Any(i => i.State != TaskState.Idle); + + if (anyRunning) + { + _lastResponseHadTasksRunning = true; + } + else + { + if (!_lastResponseHadTasksRunning) + { + return Task.FromResult>(null); + } + + _lastResponseHadTasksRunning = false; + } + + return Task.FromResult(tasks .OrderBy(i => i.Name) .Select(ScheduledTaskHelpers.GetTaskInfo) .Where(i => !i.IsHidden)); diff --git a/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs index 4ff34cfa12..33d3f368b6 100644 --- a/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs @@ -1,11 +1,11 @@ -using System.Globalization; -using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Net; namespace MediaBrowser.Common.Net { @@ -16,6 +16,7 @@ namespace MediaBrowser.Common.Net /// The type of the T state type. public abstract class BasePeriodicWebSocketListener : IWebSocketListener, IDisposable where TStateType : class, new() + where TReturnDataType : class { /// /// The _active connections @@ -144,12 +145,15 @@ namespace MediaBrowser.Common.Net var data = await GetDataToSend(tuple.Item4).ConfigureAwait(false); - await connection.SendAsync(new WebSocketMessage + if (data != null) { - MessageType = Name, - Data = data + await connection.SendAsync(new WebSocketMessage + { + MessageType = Name, + Data = data - }, tuple.Item2.Token).ConfigureAwait(false); + }, tuple.Item2.Token).ConfigureAwait(false); + } tuple.Item5.Release(); } diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 4eb305e0f9..bea281b614 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -98,6 +98,11 @@ + + + + + @@ -113,9 +118,7 @@ MediaBrowser.Model - - - +