diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 19740d107..74eb9c012 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/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); diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index 46f880657..2a1c5dfe6 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -24,32 +24,32 @@ namespace MediaBrowser.Common.Implementations.Networking /// IPAddress. public IEnumerable 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)) { diff --git a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs index dce93ae4e..87f705e16 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs +++ b/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); } diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 330ddba69..59b907f7d 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/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> 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)); } } diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs index 3840cbd12..fecdb2793 100644 --- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs +++ b/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 /// /// The item. + /// The context. /// The element. /// The filter. - 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; diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs index 2dd863c80..66555a90d 100644 --- a/MediaBrowser.Dlna/DlnaManager.cs +++ b/MediaBrowser.Dlna/DlnaManager.cs @@ -80,6 +80,7 @@ namespace MediaBrowser.Dlna new WindowsPhoneProfile(), new AndroidProfile(), new DirectTvProfile(), + new DishHopperJoeyProfile(), new DefaultProfile() }; diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 1d88eca03..810b1e568 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/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 _registeredServerIds = new List(); 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(); } diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 466c99009..7b09a492d 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -74,6 +74,7 @@ + @@ -192,6 +193,9 @@ + + +