Browse Source

add dish hopper profile

Luke Pulverenti 10 years ago
parent
commit
995353e216

+ 1 - 1
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -1638,7 +1638,7 @@ namespace MediaBrowser.Api.Playback
 
             AttachMediaStreamInfo(state, mediaStreams, videoRequest, url);
 
-            state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 7;
+            state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 6;
             state.HlsListSize = state.ReadInputAtNativeFramerate ? 100 : 1440;
 
             var container = Path.GetExtension(state.RequestedUrl);

+ 27 - 40
MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs

@@ -24,32 +24,32 @@ namespace MediaBrowser.Common.Implementations.Networking
         /// <returns>IPAddress.</returns>
         public IEnumerable<string> GetLocalIpAddresses()
         {
-            var list = GetIPsDefault()
-                .Where(i => !IPAddress.IsLoopback(i))
-                .Select(i => i.ToString())
-                .ToList();
+            var list = GetIPsDefault().Where(i => !IPAddress.IsLoopback(i)).Select(i => i.ToString()).ToList();
 
-            try
+            if (list.Count > 0)
             {
-                var listFromDns = Dns.GetHostAddresses(Dns.GetHostName())
-                    .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
-                    .Where(i => !IPAddress.IsLoopback(i))
-                    .Select(i => i.ToString())
-                    .ToList();
-
-                if (listFromDns.Count > 0)
-                {
-                    return listFromDns
-                        .OrderBy(i => (list.Contains(i, StringComparer.OrdinalIgnoreCase) ? 0 : 1))
-                        .ToList();
-                }
+                return list;
             }
-            catch
-            {
 
-            }
-            
-            return list;
+            return GetLocalIpAddressesFallback();
+        }
+
+        private bool IsInPrivateAddressSpace(string endpoint)
+        {
+            // Private address space:
+            // http://en.wikipedia.org/wiki/Private_network
+
+            return
+
+                // If url was requested with computer name, we may see this
+                endpoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 ||
+
+                endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) ||
+                endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) ||
+                endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) ||
+                endpoint.StartsWith("192.", StringComparison.OrdinalIgnoreCase) ||
+                endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase) ||
+                endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase);
         }
 
         public bool IsInLocalNetwork(string endpoint)
@@ -64,6 +64,11 @@ namespace MediaBrowser.Common.Implementations.Networking
                 throw new ArgumentNullException("endpoint");
             }
 
+            if (IsInPrivateAddressSpace(endpoint))
+            {
+                return true;
+            }
+
             const int lengthMatch = 4;
 
             if (endpoint.Length >= lengthMatch)
@@ -77,24 +82,6 @@ namespace MediaBrowser.Common.Implementations.Networking
                 }
             }
 
-            // Private address space:
-            // http://en.wikipedia.org/wiki/Private_network
-
-            var isPrivate =
-
-                // If url was requested with computer name, we may see this
-                endpoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 ||
-
-                endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) ||
-                endpoint.StartsWith("192.", StringComparison.OrdinalIgnoreCase) ||
-                endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase) ||
-                endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase);
-
-            if (isPrivate)
-            {
-                return true;
-            }
-
             IPAddress address;
             if (resolveHost && !IPAddress.TryParse(endpoint, out address))
             {

+ 6 - 2
MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
 using MediaBrowser.Dlna.Service;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Logging;
@@ -21,6 +22,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
         private readonly IDlnaManager _dlna;
         private readonly IServerConfigurationManager _config;
         private readonly IUserManager _userManager;
+        private readonly ILocalizationManager _localization;
 
         public ContentDirectory(IDlnaManager dlna,
             IUserDataManager userDataManager,
@@ -29,7 +31,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
             IServerConfigurationManager config,
             IUserManager userManager,
             ILogger logger,
-            IHttpClient httpClient)
+            IHttpClient httpClient, ILocalizationManager localization)
             : base(logger, httpClient)
         {
             _dlna = dlna;
@@ -38,6 +40,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
             _libraryManager = libraryManager;
             _config = config;
             _userManager = userManager;
+            _localization = localization;
         }
 
         private int SystemUpdateId
@@ -73,7 +76,8 @@ namespace MediaBrowser.Dlna.ContentDirectory
                 _userDataManager,
                 user,
                 SystemUpdateId,
-                _config)
+                _config,
+                _localization)
                 .ProcessControlRequest(request);
         }
 

+ 6 - 5
MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
 using MediaBrowser.Dlna.Didl;
 using MediaBrowser.Dlna.Server;
 using MediaBrowser.Dlna.Service;
@@ -38,7 +39,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
 
         private readonly DeviceProfile _profile;
 
-        public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config)
+        public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization)
             : base(config, logger)
         {
             _libraryManager = libraryManager;
@@ -47,7 +48,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
             _systemUpdateId = systemUpdateId;
             _profile = profile;
 
-            _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, userDataManager);
+            _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, userDataManager, localization);
         }
 
         protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, Headers methodParams)
@@ -182,7 +183,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
 
                 if (folder == null)
                 {
-                    result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, item, deviceId, filter));
+                    result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, item, null, deviceId, filter));
                 }
                 else
                 {
@@ -214,7 +215,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
                     }
                     else
                     {
-                        result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, deviceId, filter));
+                        result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, folder, deviceId, filter));
                     }
                 }
             }
@@ -288,7 +289,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
                 }
                 else
                 {
-                    result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, deviceId, filter));
+                    result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, folder, deviceId, filter));
                 }
             }
 

+ 46 - 10
MediaBrowser.Dlna/Didl/DidlBuilder.cs

@@ -7,6 +7,7 @@ using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Playlists;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Drawing;
@@ -33,17 +34,19 @@ namespace MediaBrowser.Dlna.Didl
         private readonly string _serverAddress;
         private readonly User _user;
         private readonly IUserDataManager _userDataManager;
+        private readonly ILocalizationManager _localization;
 
-        public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, IUserDataManager userDataManager)
+        public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, IUserDataManager userDataManager, ILocalizationManager localization)
         {
             _profile = profile;
             _imageProcessor = imageProcessor;
             _serverAddress = serverAddress;
             _userDataManager = userDataManager;
+            _localization = localization;
             _user = user;
         }
 
-        public string GetItemDidl(BaseItem item, string deviceId, Filter filter, StreamInfo streamInfo)
+        public string GetItemDidl(BaseItem item, BaseItem context, string deviceId, Filter filter, StreamInfo streamInfo)
         {
             var result = new XmlDocument();
 
@@ -60,12 +63,12 @@ namespace MediaBrowser.Dlna.Didl
 
             result.AppendChild(didl);
 
-            result.DocumentElement.AppendChild(GetItemElement(result, item, deviceId, filter, streamInfo));
+            result.DocumentElement.AppendChild(GetItemElement(result, item, context, deviceId, filter, streamInfo));
 
             return result.DocumentElement.OuterXml;
         }
 
-        public XmlElement GetItemElement(XmlDocument doc, BaseItem item, string deviceId, Filter filter, StreamInfo streamInfo = null)
+        public XmlElement GetItemElement(XmlDocument doc, BaseItem item, BaseItem context, string deviceId, Filter filter, StreamInfo streamInfo = null)
         {
             var element = doc.CreateElement(string.Empty, "item", NS_DIDL);
             element.SetAttribute("restricted", "1");
@@ -78,7 +81,7 @@ namespace MediaBrowser.Dlna.Didl
 
             //AddBookmarkInfo(item, user, element);
 
-            AddGeneralProperties(item, element, filter);
+            AddGeneralProperties(item, context, element, filter);
 
             // refID?
             // storeAttribute(itemNode, object, ClassProperties.REF_ID, false);
@@ -276,6 +279,38 @@ namespace MediaBrowser.Dlna.Didl
 
             container.AppendChild(res);
         }
+
+        private string GetDisplayName(BaseItem item, BaseItem context)
+        {
+            var episode = item as Episode;
+
+            if (episode != null)
+            {
+                // This is a special embedded within a season
+                if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0)
+                {
+                    var season = context as Season;
+                    if (season != null && season.IndexNumber.HasValue && season.IndexNumber.Value != 0)
+                    {
+                        return string.Format(_localization.GetLocalizedString("ValueSpecialEpisodeName"), item.Name);
+                    }
+                }
+
+                if (item.IndexNumber.HasValue)
+                {
+                    var number = item.IndexNumber.Value.ToString("00").ToString(CultureInfo.InvariantCulture);
+
+                    if (episode.IndexNumberEnd.HasValue)
+                    {
+                        number += "-" + episode.IndexNumberEnd.Value.ToString("00").ToString(CultureInfo.InvariantCulture);
+                    }
+
+                    return number + " - " + item.Name;
+                }
+            }
+
+            return item.Name;
+        }
         
         private void AddAudioResource(XmlElement container, IHasMediaSources audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
         {
@@ -408,7 +443,7 @@ namespace MediaBrowser.Dlna.Didl
                 }
             }
 
-            AddCommonFields(folder, container, filter);
+            AddCommonFields(folder, null, container, filter);
 
             AddCover(folder, container);
 
@@ -431,15 +466,16 @@ namespace MediaBrowser.Dlna.Didl
         /// Adds fields used by both items and folders
         /// </summary>
         /// <param name="item">The item.</param>
+        /// <param name="context">The context.</param>
         /// <param name="element">The element.</param>
         /// <param name="filter">The filter.</param>
-        private void AddCommonFields(BaseItem item, XmlElement element, Filter filter)
+        private void AddCommonFields(BaseItem item, BaseItem context, XmlElement element, Filter filter)
         {
             // Don't filter on dc:title because not all devices will include it in the filter
             // MediaMonkey for example won't display content without a title
             //if (filter.Contains("dc:title"))
             {
-                AddValue(element, "dc", "title", item.Name, NS_DC);
+                AddValue(element, "dc", "title", GetDisplayName(item, context), NS_DC);
             }
 
             element.AppendChild(CreateObjectClass(element.OwnerDocument, item));
@@ -592,9 +628,9 @@ namespace MediaBrowser.Dlna.Didl
             }
         }
 
-        private void AddGeneralProperties(BaseItem item, XmlElement element, Filter filter)
+        private void AddGeneralProperties(BaseItem item, BaseItem context, XmlElement element, Filter filter)
         {
-            AddCommonFields(item, element, filter);
+            AddCommonFields(item, context, element, filter);
 
             var audio = item as Audio;
 

+ 1 - 0
MediaBrowser.Dlna/DlnaManager.cs

@@ -80,6 +80,7 @@ namespace MediaBrowser.Dlna
                 new WindowsPhoneProfile(),
                 new AndroidProfile(),
                 new DirectTvProfile(),
+                new DishHopperJoeyProfile(),
                 new DefaultProfile()
             };
 

+ 6 - 2
MediaBrowser.Dlna/Main/DlnaEntryPoint.cs

@@ -6,6 +6,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Controller.Session;
@@ -35,6 +36,7 @@ namespace MediaBrowser.Dlna.Main
         private readonly IDlnaManager _dlnaManager;
         private readonly IImageProcessor _imageProcessor;
         private readonly IUserDataManager _userDataManager;
+        private readonly ILocalizationManager _localization;
 
         private SsdpHandler _ssdpHandler;
         private DeviceDiscovery _deviceDiscovery;
@@ -42,7 +44,7 @@ namespace MediaBrowser.Dlna.Main
         private readonly List<string> _registeredServerIds = new List<string>();
         private bool _dlnaServerStarted;
 
-        public DlnaEntryPoint(IServerConfigurationManager config, ILogManager logManager, IServerApplicationHost appHost, INetworkManager network, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IImageProcessor imageProcessor, IUserDataManager userDataManager)
+        public DlnaEntryPoint(IServerConfigurationManager config, ILogManager logManager, IServerApplicationHost appHost, INetworkManager network, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IImageProcessor imageProcessor, IUserDataManager userDataManager, ILocalizationManager localization)
         {
             _config = config;
             _appHost = appHost;
@@ -55,6 +57,7 @@ namespace MediaBrowser.Dlna.Main
             _dlnaManager = dlnaManager;
             _imageProcessor = imageProcessor;
             _userDataManager = userDataManager;
+            _localization = localization;
             _logger = logManager.GetLogger("Dlna");
         }
 
@@ -221,7 +224,8 @@ namespace MediaBrowser.Dlna.Main
                         _deviceDiscovery,
                         _httpClient,
                         _config,
-                        _userDataManager);
+                        _userDataManager,
+                        _localization);
 
                     _manager.Start();
                 }

+ 4 - 0
MediaBrowser.Dlna/MediaBrowser.Dlna.csproj

@@ -74,6 +74,7 @@
     <Compile Include="Didl\DidlBuilder.cs" />
     <Compile Include="PlayTo\PlayToController.cs" />
     <Compile Include="Profiles\DirectTvProfile.cs" />
+    <Compile Include="Profiles\DishHopperJoeyProfile.cs" />
     <Compile Include="Ssdp\DeviceDiscoveryInfo.cs" />
     <Compile Include="Ssdp\Extensions.cs" />
     <Compile Include="PlayTo\PlaybackProgressEventArgs.cs" />
@@ -192,6 +193,9 @@
   <ItemGroup>
     <EmbeddedResource Include="Profiles\Xml\DirecTV HD-DVR.xml" />
   </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Profiles\Xml\Dish Hopper-Joey.xml" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 6 - 2
MediaBrowser.Dlna/PlayTo/PlayToController.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Dlna.Didl;
@@ -33,6 +34,7 @@ namespace MediaBrowser.Dlna.PlayTo
         private readonly IUserManager _userManager;
         private readonly IImageProcessor _imageProcessor;
         private readonly IUserDataManager _userDataManager;
+        private readonly ILocalizationManager _localization;
 
         private readonly DeviceDiscovery _deviceDiscovery;
         private readonly string _serverAddress;
@@ -52,7 +54,7 @@ namespace MediaBrowser.Dlna.PlayTo
 
         private Timer _updateTimer;
 
-        public PlayToController(SessionInfo session, ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, DeviceDiscovery deviceDiscovery, IUserDataManager userDataManager)
+        public PlayToController(SessionInfo session, ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, DeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization)
         {
             _session = session;
             _itemRepository = itemRepository;
@@ -64,6 +66,7 @@ namespace MediaBrowser.Dlna.PlayTo
             _serverAddress = serverAddress;
             _deviceDiscovery = deviceDiscovery;
             _userDataManager = userDataManager;
+            _localization = localization;
             _logger = logger;
         }
 
@@ -476,7 +479,8 @@ namespace MediaBrowser.Dlna.PlayTo
 
             playlistItem.StreamUrl = playlistItem.StreamInfo.ToUrl(serverAddress);
 
-            var itemXml = new DidlBuilder(profile, user, _imageProcessor, serverAddress, _userDataManager).GetItemDidl(item, _session.DeviceId, new Filter(), playlistItem.StreamInfo);
+            var itemXml = new DidlBuilder(profile, user, _imageProcessor, serverAddress, _userDataManager, _localization)
+                .GetItemDidl(item, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo);
 
             playlistItem.Didl = itemXml;
 

+ 6 - 2
MediaBrowser.Dlna/PlayTo/PlayToManager.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Dlna.Ssdp;
@@ -30,10 +31,11 @@ namespace MediaBrowser.Dlna.PlayTo
         private readonly IHttpClient _httpClient;
         private readonly IServerConfigurationManager _config;
         private readonly IUserDataManager _userDataManager;
+        private readonly ILocalizationManager _localization;
 
         private readonly DeviceDiscovery _deviceDiscovery;
         
-        public PlayToManager(ILogger logger, ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, DeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager)
+        public PlayToManager(ILogger logger, ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, DeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization)
         {
             _logger = logger;
             _sessionManager = sessionManager;
@@ -47,6 +49,7 @@ namespace MediaBrowser.Dlna.PlayTo
             _httpClient = httpClient;
             _config = config;
             _userDataManager = userDataManager;
+            _localization = localization;
         }
 
         public void Start()
@@ -106,7 +109,8 @@ namespace MediaBrowser.Dlna.PlayTo
                             _imageProcessor,
                             serverAddress,
                             _deviceDiscovery,
-                            _userDataManager);
+                            _userDataManager,
+                            _localization);
 
                         controller.Init(device);
 

+ 6 - 0
MediaBrowser.Dlna/Profiles/DefaultProfile.cs

@@ -53,6 +53,12 @@ namespace MediaBrowser.Dlna.Profiles
                     AudioCodec = "aac",
                     VideoCodec = "h264",
                     VideoProfile= "baseline"
+                },
+
+                new TranscodingProfile
+                {
+                    Container = "jpeg",
+                    Type = DlnaProfileType.Photo
                 }
             };
 

+ 219 - 0
MediaBrowser.Dlna/Profiles/DishHopperJoeyProfile.cs

@@ -0,0 +1,219 @@
+using MediaBrowser.Model.Dlna;
+using System.Xml.Serialization;
+
+namespace MediaBrowser.Dlna.Profiles
+{
+    [XmlRoot("Profile")]
+    public class DishHopperJoeyProfile : DefaultProfile
+    {
+        public DishHopperJoeyProfile()
+        {
+            Name = "Dish Hopper-Joey";
+
+            ProtocolInfo = "http-get:*:video/mp2t:*,http-get:*:video/MP1S:*,http-get:*:video/mpeg2:*,http-get:*:video/mp4:*,http-get:*:video/x-matroska:*,http-get:*:audio/mpeg:*,http-get:*:audio/mpeg3:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/mp4a-latm:*,http-get:*:image/jpeg:*";
+
+            Identification = new DeviceIdentification
+            {
+                Manufacturer = "Echostar Technologies LLC",
+                ManufacturerUrl = "http://www.echostar.com",
+
+                Headers = new[]
+                {
+                    new HttpHeaderInfo
+                    {
+                         Match = HeaderMatchType.Substring,
+                         Name = "User-Agent",
+                         Value ="XiP"
+                    }
+                }
+            };
+
+            TranscodingProfiles = new[]
+            {
+                new TranscodingProfile
+                {
+                    Container = "mp3",
+                    AudioCodec = "mp3",
+                    Type = DlnaProfileType.Audio
+                },
+                new TranscodingProfile
+                {
+                    Container = "mp4",
+                    Type = DlnaProfileType.Video,
+                    AudioCodec = "aac",
+                    VideoCodec = "h264"
+                },
+
+                new TranscodingProfile
+                {
+                    Container = "jpeg",
+                    Type = DlnaProfileType.Photo
+                }
+            };
+
+            DirectPlayProfiles = new[]
+            {
+                new DirectPlayProfile
+                {
+                    Container = "mp4,mkv,mpeg,ts",
+                    VideoCodec = "h264,mpeg2video",
+                    AudioCodec = "mp3,ac3,aac,he-aac,pcm",
+                    Type = DlnaProfileType.Video
+                },
+
+                new DirectPlayProfile
+                {
+                    Container = "mp3",
+                    AudioCodec = "mp3",
+                    Type = DlnaProfileType.Audio
+                },
+
+                new DirectPlayProfile
+                {
+                    Container = "alac",
+                    AudioCodec = "alac",
+                    Type = DlnaProfileType.Audio
+                },
+
+                new DirectPlayProfile
+                {
+                    Container = "flac",
+                    AudioCodec = "flac",
+                    Type = DlnaProfileType.Audio
+                },
+
+                new DirectPlayProfile
+                {
+                    Container = "jpeg",
+                    Type = DlnaProfileType.Photo
+                }
+            };
+
+            CodecProfiles = new[]
+            {
+                new CodecProfile
+                {
+                    Type = CodecType.Video,
+                    Conditions = new []
+                    {
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.Width,
+                            Value = "1920",
+                            IsRequired = true
+                        },
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.Height,
+                            Value = "1080",
+                            IsRequired = true
+                        },
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.VideoFramerate,
+                            Value = "30",
+                            IsRequired = true
+                        },
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.VideoBitrate,
+                            Value = "20000000",
+                            IsRequired = true
+                        },
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.VideoLevel,
+                            Value = "41",
+                            IsRequired = true
+                        }
+                    }
+                },
+
+                new CodecProfile
+                {
+                    Type = CodecType.Video,
+                    Codec = "mpeg2video",
+                    Conditions = new []
+                    {
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.Width,
+                            Value = "1920",
+                            IsRequired = true
+                        },
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.Height,
+                            Value = "1080",
+                            IsRequired = true
+                        },
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.VideoFramerate,
+                            Value = "30",
+                            IsRequired = true
+                        },
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.VideoBitrate,
+                            Value = "20000000",
+                            IsRequired = true
+                        }
+                    }
+                },
+
+                new CodecProfile
+                {
+                    Type = CodecType.VideoAudio,
+                    Codec = "ac3,he-aac",
+                    Conditions = new []
+                    {
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.AudioChannels,
+                            Value = "6",
+                            IsRequired = true
+                        }
+                    }
+                },
+
+                new CodecProfile
+                {
+                    Type = CodecType.VideoAudio,
+                    Codec = "aac",
+                    Conditions = new []
+                    {
+                        new ProfileCondition
+                        {
+                            Condition = ProfileConditionType.LessThanEqual,
+                            Property = ProfileConditionValue.AudioChannels,
+                            Value = "2",
+                            IsRequired = true
+                        }
+                    }
+                }
+            };
+
+            ResponseProfiles = new[]
+            {
+                new ResponseProfile
+                {
+                    Container = "mkv,ts",
+                    Type = DlnaProfileType.Video,
+                    MimeType = "video/mp4"
+                }
+            };
+
+        }
+    }
+}

+ 1 - 0
MediaBrowser.Dlna/Profiles/Xml/Default.xml

@@ -33,6 +33,7 @@
   <TranscodingProfiles>
     <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
     <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="baseline" context="Streaming" />
+    <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
   </TranscodingProfiles>
   <ContainerProfiles />
   <CodecProfiles />

+ 1 - 0
MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml

@@ -37,6 +37,7 @@
   <TranscodingProfiles>
     <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
     <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="baseline" context="Streaming" />
+    <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
   </TranscodingProfiles>
   <ContainerProfiles />
   <CodecProfiles />

+ 84 - 0
MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml

@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <Name>Dish Hopper-Joey</Name>
+  <Identification>
+    <Manufacturer>Echostar Technologies LLC</Manufacturer>
+    <ManufacturerUrl>http://www.echostar.com</ManufacturerUrl>
+    <Headers>
+      <HttpHeaderInfo name="User-Agent" value="XiP" match="Substring" />
+    </Headers>
+  </Identification>
+  <FriendlyName>Media Browser</FriendlyName>
+  <Manufacturer>Media Browser</Manufacturer>
+  <ManufacturerUrl>http://mediabrowser.tv/</ManufacturerUrl>
+  <ModelName>Media Browser</ModelName>
+  <ModelDescription>Media Browser</ModelDescription>
+  <ModelNumber>Media Browser</ModelNumber>
+  <ModelUrl>http://mediabrowser.tv/</ModelUrl>
+  <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+  <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+  <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+  <AlbumArtPn>JPEG_SM</AlbumArtPn>
+  <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
+  <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
+  <MaxIconWidth>48</MaxIconWidth>
+  <MaxIconHeight>48</MaxIconHeight>
+  <MaxStreamingBitrate>8000000</MaxStreamingBitrate>
+  <MaxStaticBitrate>8000000</MaxStaticBitrate>
+  <MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
+  <MusicSyncBitrate>128000</MusicSyncBitrate>
+  <XDlnaDoc>DMS-1.50</XDlnaDoc>
+  <ProtocolInfo>http-get:*:video/mp2t:*,http-get:*:video/MP1S:*,http-get:*:video/mpeg2:*,http-get:*:video/mp4:*,http-get:*:video/x-matroska:*,http-get:*:audio/mpeg:*,http-get:*:audio/mpeg3:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/mp4a-latm:*,http-get:*:image/jpeg:*</ProtocolInfo>
+  <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+  <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+  <RequiresPlainFolders>false</RequiresPlainFolders>
+  <XmlRootAttributes />
+  <DirectPlayProfiles>
+    <DirectPlayProfile container="mp4,mkv,mpeg,ts" audioCodec="mp3,ac3,aac,he-aac,pcm" videoCodec="h264,mpeg2video" type="Video" />
+    <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+    <DirectPlayProfile container="alac" audioCodec="alac" type="Audio" />
+    <DirectPlayProfile container="flac" audioCodec="flac" type="Audio" />
+    <DirectPlayProfile container="jpeg" type="Photo" />
+  </DirectPlayProfiles>
+  <TranscodingProfiles>
+    <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+    <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+    <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+  </TranscodingProfiles>
+  <ContainerProfiles />
+  <CodecProfiles>
+    <CodecProfile type="Video">
+      <Conditions>
+        <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
+        <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+        <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
+        <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="20000000" isRequired="true" />
+        <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="41" isRequired="true" />
+      </Conditions>
+    </CodecProfile>
+    <CodecProfile type="Video" codec="mpeg2video">
+      <Conditions>
+        <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
+        <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+        <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
+        <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="20000000" isRequired="true" />
+      </Conditions>
+    </CodecProfile>
+    <CodecProfile type="VideoAudio" codec="ac3,he-aac">
+      <Conditions>
+        <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
+      </Conditions>
+    </CodecProfile>
+    <CodecProfile type="VideoAudio" codec="aac">
+      <Conditions>
+        <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
+      </Conditions>
+    </CodecProfile>
+  </CodecProfiles>
+  <ResponseProfiles>
+    <ResponseProfile container="mkv,ts" type="Video" mimeType="video/mp4">
+      <Conditions />
+    </ResponseProfile>
+  </ResponseProfiles>
+  <SubtitleProfiles />
+</Profile>

+ 1 - 0
MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml

@@ -37,6 +37,7 @@
   <TranscodingProfiles>
     <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
     <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="baseline" context="Streaming" />
+    <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
   </TranscodingProfiles>
   <ContainerProfiles />
   <CodecProfiles />

+ 1 - 0
MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml

@@ -43,6 +43,7 @@
   <TranscodingProfiles>
     <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
     <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="baseline" context="Streaming" />
+    <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
   </TranscodingProfiles>
   <ContainerProfiles />
   <CodecProfiles />

+ 1 - 1
MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml

@@ -65,6 +65,6 @@
   </CodecProfiles>
   <ResponseProfiles />
   <SubtitleProfiles>
-    <SubtitleProfile format="ttml" method="External" />
+    <SubtitleProfile format="vtt" method="External" />
   </SubtitleProfiles>
 </Profile>

+ 1 - 0
MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml

@@ -43,6 +43,7 @@
   <TranscodingProfiles>
     <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
     <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" videoProfile="baseline" context="Streaming" />
+    <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
   </TranscodingProfiles>
   <ContainerProfiles />
   <CodecProfiles />

+ 11 - 0
MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -166,6 +166,17 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
         private void OnRequestReceived(string localEndPoint)
         {
+            var ignore = localEndPoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 ||
+
+                localEndPoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) ||
+                localEndPoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) ||
+                localEndPoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase);
+
+            if (ignore)
+            {
+                return;
+            }
+
             if (_localEndpointLock.TryEnterWriteLock(100))
             {
                 var list = _localEndpoints.ToList();

+ 16 - 1
MediaBrowser.Server.Implementations/Library/SearchEngine.cs

@@ -355,7 +355,22 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <returns>System.String[][].</returns>
         private List<string> GetWords(string term)
         {
-            return term.Split().Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+            var stoplist = GetStopList().ToList();
+
+            return term.Split()
+                .Where(i => !string.IsNullOrWhiteSpace(i) && !stoplist.Contains(i, StringComparer.OrdinalIgnoreCase))
+                .ToList();
+        }
+
+        private IEnumerable<string> GetStopList()
+        {
+            return new[]
+            {
+                "the",
+                "a",
+                "of",
+                "an"
+            };
         }
     }
 }

+ 8 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json

@@ -571,5 +571,12 @@
     "MediaInfoStreamTypeEmbeddedImage": "Embedded Image",
     "MediaInfoRefFrames": "Ref frames",
     "TabPlayback": "Playback",
-    "HeaderSelectCustomIntrosPath": "Select Custom Intros Path"
+    "HeaderSelectCustomIntrosPath": "Select Custom Intros Path",
+    "HeaderRateAndReview": "Rate and Review",
+    "HeaderThankYou": "Thank You",
+    "MessageThankYouForYourReview": "Thank you for your review.",
+    "LabelYourRating": "Your rating:",
+    "LabelFullReview": "Full review:",
+    "LabelShortRatingDescription": "Short rating summary:",
+    "OptionIRecommendThisItem": "I recommend this item"
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -1196,5 +1196,6 @@
     "LabelThisFeatureRequiresSupporterHelp": "This feature requires an active supporter membership.",
     "OptionTrailersFromMyMoviesHelp": "Requires setup of local trailers.",
     "LabelCustomIntrosPath": "Custom intros path:",
-    "LabelCustomIntrosPathHelp": "A folder containing video files. A video will be randomly selected and played after trailers."
+    "LabelCustomIntrosPathHelp": "A folder containing video files. A video will be randomly selected and played after trailers.",
+    "ValueSpecialEpisodeName": "Special - {0}"
 }

+ 1 - 1
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -496,7 +496,7 @@ namespace MediaBrowser.ServerApplication
             UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, FileSystemManager, UserManager, ChannelManager, LiveTvManager, ApplicationPaths, playlistManager);
             RegisterSingleInstance(UserViewManager);
 
-            var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient);
+            var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager);
             RegisterSingleInstance<IContentDirectory>(contentDirectory);
 
             NotificationManager = new NotificationManager(LogManager, UserManager, ServerConfigurationManager);