diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index f108b344fc..8f5301642f 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1748,6 +1748,11 @@ namespace MediaBrowser.Api.Playback return false; } + if (videoStream.IsAnamorphic ?? false) + { + return false; + } + // Can't stream copy if we're burning in subtitles if (request.SubtitleStreamIndex.HasValue) { diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index 9d1aef3002..302b8d834c 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Search; @@ -171,6 +172,8 @@ namespace MediaBrowser.Api ProductionYear = item.ProductionYear }; + result.ChannelId = item.ChannelId; + var primaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary); if (primaryImageTag != null) @@ -218,6 +221,12 @@ namespace MediaBrowser.Api result.Artists = song.Artists.ToArray(); } + if (!string.IsNullOrWhiteSpace(item.ChannelId)) + { + var channel = _libraryManager.GetItemById(item.ChannelId); + result.ChannelName = channel == null ? null : channel.Name; + } + return result; } diff --git a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs index 1a05f38fa9..2b53c66889 100644 --- a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs +++ b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs @@ -63,8 +63,6 @@ namespace MediaBrowser.Model.Configuration { EnableAutoUpdate = true; LogFileRetentionDays = 3; - - EnableDebugLevelLogging = true; } } } diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs index 4eced77062..d51c0325db 100644 --- a/MediaBrowser.Model/Search/SearchHint.cs +++ b/MediaBrowser.Model/Search/SearchHint.cs @@ -132,5 +132,17 @@ namespace MediaBrowser.Model.Search /// /// The episode count. public int? EpisodeCount { get; set; } + + /// + /// Gets or sets the channel identifier. + /// + /// The channel identifier. + public string ChannelId { get; set; } + + /// + /// Gets or sets the name of the channel. + /// + /// The name of the channel. + public string ChannelName { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index f12022dc71..c5565eb536 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -110,11 +110,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { var attributes = child.Attributes; - if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) - { - //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName); - continue; - } + //if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden) + //{ + // //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName); + // continue; + //} // Can't enforce this because files saved by Bitcasa are always marked System //if ((attributes & FileAttributes.System) == FileAttributes.System) diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs new file mode 100644 index 0000000000..5edebb3937 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListings.cs @@ -0,0 +1,59 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby +{ + public class EmbyGuide : IListingsProvider + { + private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _jsonSerializer; + + public EmbyGuide(IHttpClient httpClient, IJsonSerializer jsonSerializer) + { + _httpClient = httpClient; + _jsonSerializer = jsonSerializer; + } + + public string Name + { + get { return "Emby Guide"; } + } + + public string Type + { + get { return "emby"; } + } + + public Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) + { + return GetListingsProvider(info.Country).GetProgramsAsync(info, channelNumber, startDateUtc, endDateUtc, cancellationToken); + } + + public Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) + { + return GetListingsProvider(info.Country).AddMetadata(info, channels, cancellationToken); + } + + public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) + { + return GetListingsProvider(info.Country).Validate(info, validateLogin, validateListings); + } + + public Task> GetLineups(ListingsProviderInfo info, string country, string location) + { + return GetListingsProvider(country).GetLineups(info, country, location); + } + + private IEmbyListingProvider GetListingsProvider(string country) + { + return new EmbyListingsNorthAmerica(_httpClient, _jsonSerializer); + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs new file mode 100644 index 0000000000..99bd5325ee --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/EmbyListingsNorthAmerica.cs @@ -0,0 +1,144 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby +{ + public class EmbyListingsNorthAmerica : IEmbyListingProvider + { + private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _jsonSerializer; + + public EmbyListingsNorthAmerica(IHttpClient httpClient, IJsonSerializer jsonSerializer) + { + _httpClient = httpClient; + _jsonSerializer = jsonSerializer; + } + + public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) + { + return new List(); + } + + public async Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) + { + var response = await GetResponse("https://data.emby.media/service/lineups?id=" + info.ListingsId).ConfigureAwait(false); + + foreach (var channel in channels) + { + + } + } + + public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) + { + return Task.FromResult(true); + } + + public async Task> GetLineups(ListingsProviderInfo info, string country, string location) + { + var response = await GetResponse("https://data.emby.media/service/lineups?id=" + location).ConfigureAwait(false); + + return response.Select(i => new NameIdPair + { + + Name = GetName(i), + Id = i.lineupID + + }).ToList(); + } + + private string GetName(LineupInfo info) + { + var name = info.lineupName; + + if (string.Equals(info.lineupType, "cab", StringComparison.OrdinalIgnoreCase)) + { + name += " - Cable"; + } + else if (string.Equals(info.lineupType, "sat", StringComparison.OrdinalIgnoreCase)) + { + name += " - SAT"; + } + else if (string.Equals(info.lineupType, "ota", StringComparison.OrdinalIgnoreCase)) + { + name += " - OTA"; + } + + return name; + } + + private async Task GetResponse(string url) + where T : class + { + using (var stream = await _httpClient.Get(new HttpRequestOptions + { + Url = url + + }).ConfigureAwait(false)) + { + using (var reader = new StreamReader(stream)) + { + var path = await reader.ReadToEndAsync().ConfigureAwait(false); + + // location = zip code + using (var secondStream = await _httpClient.Get(new HttpRequestOptions + { + Url = "https://data.emby.media" + path + + }).ConfigureAwait(false)) + { + return _jsonSerializer.DeserializeFromStream(secondStream); + } + } + } + } + + private class LineupInfo + { + public string lineupID { get; set; } + public string lineupName { get; set; } + public string lineupType { get; set; } + public string providerID { get; set; } + public string providerName { get; set; } + public string serviceArea { get; set; } + public string country { get; set; } + } + + private class Station + { + public string number { get; set; } + public int channelNumber { get; set; } + public int subChannelNumber { get; set; } + public int stationID { get; set; } + public string name { get; set; } + public string callsign { get; set; } + public string network { get; set; } + public string stationType { get; set; } + public int NTSC_TSID { get; set; } + public int DTV_TSID { get; set; } + public string webLink { get; set; } + public string logoFilename { get; set; } + } + + private class LineupDetailResponse + { + public string lineupID { get; set; } + public string lineupName { get; set; } + public string lineupType { get; set; } + public string providerID { get; set; } + public string providerName { get; set; } + public string serviceArea { get; set; } + public string country { get; set; } + public List stations { get; set; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs new file mode 100644 index 0000000000..83477acfcf --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/Emby/IEmbyListingProvider.cs @@ -0,0 +1,18 @@ +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.LiveTv.Listings.Emby +{ + public interface IEmbyListingProvider + { + Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken); + Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken); + Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings); + Task> GetLineups(ListingsProviderInfo info, string country, string location); + } +} diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 7eddf5ed15..2571f9b2cb 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -222,6 +222,9 @@ + + + diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index b554e0d1cf..60ff36c6d3 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -529,7 +529,7 @@ namespace MediaBrowser.Server.Startup.Common var sharingRepo = new SharingRepository(LogManager, ApplicationPaths); await sharingRepo.Initialize().ConfigureAwait(false); RegisterSingleInstance(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); - + RegisterSingleInstance(new SsdpHandler(LogManager.GetLogger("SsdpHandler"), ServerConfigurationManager, this)); var activityLogRepo = await GetActivityLogRepository().ConfigureAwait(false); @@ -1088,15 +1088,24 @@ namespace MediaBrowser.Server.Startup.Common { get { - // Return the first matched address, if found, or the first known local address - var address = LocalIpAddress; + try + { + // Return the first matched address, if found, or the first known local address + var address = LocalIpAddress; - if (!string.IsNullOrWhiteSpace(address)) + if (!string.IsNullOrWhiteSpace(address)) + { + address = GetLocalApiUrl(address); + } + + return address; + } + catch (Exception ex) { - address = GetLocalApiUrl(address); + Logger.ErrorException("Error getting local Ip address information", ex); } - return address; + return null; } } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index a1e232257a..e8a2e86739 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -183,6 +183,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -213,6 +216,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest