2
0
Эх сурвалжийг харах

support more profile features

Luke Pulverenti 11 жил өмнө
parent
commit
f3e992b82b

+ 2 - 3
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<Movie>().ToList();
+            var movies = user.RootFolder.GetRecursiveChildren(user).OfType<Movie>().ToList();
 
             var result = GetRecommendationCategories(user, movies, request.CategoryLimit, request.ItemLimit, request.GetItemFields().ToList());
 

+ 25 - 15
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;
-                }
             }
         }
 

+ 3 - 2
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; }
+        
         /// <summary>
         /// Gets or sets the audio sample rate.
         /// </summary>
@@ -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

+ 0 - 10
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);
         }
     }

+ 3 - 2
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

+ 19 - 7
MediaBrowser.Dlna/DlnaManager.cs

@@ -274,11 +274,9 @@ namespace MediaBrowser.Dlna
 
                         Settings = new List<TranscodingSetting>
                         {
-                            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<TranscodingSetting>
+                        {
+                             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<TranscodingSetting>
+                        {
+                             new TranscodingSetting{ Name = TranscodingSettingType.VideoLevel, Value = "3"},
+                             new TranscodingSetting{ Name = TranscodingSettingType.VideoProfile, Value = "baseline"}
+                        }
                     }
                 },
 

+ 84 - 13
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<MediaStream> 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

+ 16 - 4
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<TranscodingSetting> TranscodingSettings { get; set; }
+
+        public int? AudioStreamIndex { get; set; }
+
+        public int? SubtitleStreamIndex { get; set; }
+        
+        public PlaylistItem()
+        {
+            TranscodingSettings = new List<TranscodingSetting>();
+        }
     }
 }

+ 6 - 58
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<MediaStream> 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<MediaStream> 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;

+ 30 - 158
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
     {
-        /// <summary>
-        /// Gets the dlna headers.
-        /// </summary>
-        /// <param name="item">The item.</param>
-        /// <returns></returns>
-        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
-
         /// <summary>
         /// Gets the audio URL.
         /// </summary>
+        /// <param name="deviceProperties">The device properties.</param>
         /// <param name="item">The item.</param>
+        /// <param name="streams">The streams.</param>
         /// <param name="serverAddress">The server address.</param>
         /// <returns>System.String.</returns>
-        internal static string GetAudioUrl(PlaylistItem item, string serverAddress)
+        internal static string GetAudioUrl(DeviceInfo deviceProperties, PlaylistItem item, List<MediaStream> 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
-
         /// <summary>
         /// Gets the video URL.
         /// </summary>
@@ -104,97 +33,40 @@ namespace MediaBrowser.Dlna.PlayTo
         /// <returns>The url to send to the device</returns>
         internal static string GetVideoUrl(DeviceInfo deviceProperties, PlaylistItem item, List<MediaStream> 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);
         }
 
-        /// <summary>
-        /// Gets the video codec.
-        /// </summary>
-        /// <param name="videoStream">The video stream.</param>
-        /// <returns></returns>
-        private static VideoCodecs GetVideoCodec(MediaStream videoStream)
-        {
-            switch (videoStream.Codec.ToLower())
-            {
-                case "h264":
-                case "mpeg4":
-                    return VideoCodecs.Copy;
-
-            }
-            return VideoCodecs.H264;
-        }
-
-        /// <summary>
-        /// Gets the audio codec.
-        /// </summary>
-        /// <param name="audioStream">The audio stream.</param>
-        /// <returns></returns>
-        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;
-        }
-
         /// <summary>
         /// Builds the dlna URL.
         /// </summary>
-        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<TranscodingSetting> 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<string>
+            {
+                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
-
     }
 }