diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index 4758b0186..0953b95e6 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -109,8 +109,7 @@ namespace MediaBrowser.Api { IncludeItemTypes = new[] { typeof(GameSystem).Name } }; - var parentIds = new string[] { } ; - var gameSystems = _libraryManager.GetItemList(query, parentIds) + var gameSystems = _libraryManager.GetItemList(query) .Cast() .ToList(); @@ -130,8 +129,7 @@ namespace MediaBrowser.Api { IncludeItemTypes = new[] { typeof(Game).Name } }; - var parentIds = new string[] { }; - var games = _libraryManager.GetItemList(query, parentIds) + var games = _libraryManager.GetItemList(query) .Cast() .ToList(); diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 784057b32..c687758b7 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -519,14 +519,6 @@ namespace MediaBrowser.Api.LiveTv public string ProviderName { get; set; } } - public class TunerChannelMapping - { - public string Name { get; set; } - public string Number { get; set; } - public string ProviderChannelNumber { get; set; } - public string ProviderChannelName { get; set; } - } - [Route("/LiveTv/Registration", "GET")] [Authenticated] public class GetLiveTvRegistrationInfo : IReturn @@ -595,36 +587,7 @@ namespace MediaBrowser.Api.LiveTv public async Task Post(SetChannelMapping request) { - var config = GetConfiguration(); - - var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(request.ProviderId, i.Id, StringComparison.OrdinalIgnoreCase)); - listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, request.TunerChannelNumber, StringComparison.OrdinalIgnoreCase)).ToArray(); - - if (!string.Equals(request.TunerChannelNumber, request.ProviderChannelNumber, StringComparison.OrdinalIgnoreCase)) - { - var list = listingsProviderInfo.ChannelMappings.ToList(); - list.Add(new NameValuePair - { - Name = request.TunerChannelNumber, - Value = request.ProviderChannelNumber - }); - listingsProviderInfo.ChannelMappings = list.ToArray(); - } - - UpdateConfiguration(config); - - var tunerChannels = await _liveTvManager.GetChannelsForListingsProvider(request.ProviderId, CancellationToken.None) - .ConfigureAwait(false); - - var providerChannels = await _liveTvManager.GetChannelsFromListingsProviderData(request.ProviderId, CancellationToken.None) - .ConfigureAwait(false); - - var mappings = listingsProviderInfo.ChannelMappings.ToList(); - - var tunerChannelMappings = - tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList(); - - return tunerChannelMappings.First(i => string.Equals(i.Number, request.TunerChannelNumber, StringComparison.OrdinalIgnoreCase)); + return await _liveTvManager.SetChannelMapping(request.ProviderId, request.TunerChannelNumber, request.ProviderChannelNumber).ConfigureAwait(false); } public async Task Get(GetChannelMappingOptions request) @@ -645,7 +608,7 @@ namespace MediaBrowser.Api.LiveTv var result = new ChannelMappingOptions { - TunerChannels = tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList(), + TunerChannels = tunerChannels.Select(i => _liveTvManager.GetTunerChannelMapping(i, mappings, providerChannels)).ToList(), ProviderChannels = providerChannels.Select(i => new NameIdPair { @@ -662,33 +625,6 @@ namespace MediaBrowser.Api.LiveTv return ToOptimizedResult(result); } - private TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List mappings, List providerChannels) - { - var result = new TunerChannelMapping - { - Name = channel.Number + " " + channel.Name, - Number = channel.Number - }; - - var mapping = mappings.FirstOrDefault(i => string.Equals(i.Name, channel.Number, StringComparison.OrdinalIgnoreCase)); - var providerChannelNumber = channel.Number; - - if (mapping != null) - { - providerChannelNumber = mapping.Value; - } - - var providerChannel = providerChannels.FirstOrDefault(i => string.Equals(i.Number, providerChannelNumber, StringComparison.OrdinalIgnoreCase)); - - if (providerChannel != null) - { - result.ProviderChannelNumber = providerChannel.Number; - result.ProviderChannelName = providerChannel.Name; - } - - return result; - } - public object Get(GetSatIniMappings request) { return ToOptimizedResult(_liveTvManager.GetSatIniMappings()); @@ -730,11 +666,7 @@ namespace MediaBrowser.Api.LiveTv public void Delete(DeleteListingProvider request) { - var config = GetConfiguration(); - - config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(request.Id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList(); - - _config.SaveConfiguration("livetv", config); + _liveTvManager.DeleteListingsProvider(request.Id); } public async Task Post(AddTunerHost request) diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 1d86cd9e7..755713c84 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -177,7 +177,8 @@ namespace MediaBrowser.Api.Movies { var categories = new List(); - var parentIds = string.IsNullOrWhiteSpace(parentId) ? new string[] { } : new[] { parentId }; + var parentIdGuid = string.IsNullOrWhiteSpace(parentId) ? (Guid?)null : new Guid(parentId); + var query = new InternalItemsQuery(user) { IncludeItemTypes = new[] @@ -189,10 +190,12 @@ namespace MediaBrowser.Api.Movies // IsMovie = true SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random }, SortOrder = SortOrder.Descending, - Limit = 7 + Limit = 7, + ParentId = parentIdGuid, + Recursive = true }; - var recentlyPlayedMovies = _libraryManager.GetItemList(query, parentIds).ToList(); + var recentlyPlayedMovies = _libraryManager.GetItemList(query).ToList(); var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user) { @@ -208,9 +211,11 @@ namespace MediaBrowser.Api.Movies Limit = 10, IsFavoriteOrLiked = true, ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray(), - EnableGroupByMetadataKey = true + EnableGroupByMetadataKey = true, + ParentId = parentIdGuid, + Recursive = true - }, parentIds).ToList(); + }).ToList(); var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList(); // Get recently played directors diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 4f1a29a4d..01d959d70 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -286,11 +286,19 @@ namespace MediaBrowser.Api.Playback protected string GetH264Encoder(StreamState state) { - if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) || + string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { - return "h264_qsv"; + } + if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "libnvenc", StringComparison.OrdinalIgnoreCase)) + { + return "libnvenc"; + } + if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase)) + { + return "h264_omx"; } return "libx264"; @@ -395,15 +403,18 @@ namespace MediaBrowser.Api.Playback if (!string.IsNullOrEmpty(state.VideoRequest.Profile)) { - param += " -profile:v " + state.VideoRequest.Profile; + if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase)) + { + // not supported by h264_omx + param += " -profile:v " + state.VideoRequest.Profile; + } } if (!string.IsNullOrEmpty(state.VideoRequest.Level)) { - var h264Encoder = GetH264Encoder(state); - // h264_qsv and libnvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format - if (String.Equals(h264Encoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) || String.Equals(h264Encoder, "libnvenc", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) || + string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase)) { switch (state.VideoRequest.Level) { @@ -438,16 +449,21 @@ namespace MediaBrowser.Api.Playback param += " -level " + state.VideoRequest.Level; break; } - - return param; } - else + else if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase)) { param += " -level " + state.VideoRequest.Level; } } - return "-pix_fmt yuv420p " + param; + if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) && + !string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) && + !string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase)) + { + param = "-pix_fmt yuv420p " + param; + } + + return param; } protected string GetAudioFilterParam(StreamState state, bool isHls) @@ -563,14 +579,6 @@ namespace MediaBrowser.Api.Playback filters.Add(string.Format("scale=trunc(oh*a/2)*2:min(ih\\,{0})", maxHeightParam)); } - if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) - { - if (filters.Count > 1) - { - //filters[filters.Count - 1] += ":flags=fast_bilinear"; - } - } - var output = string.Empty; if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.VideoRequest.SubtitleMethod == SubtitleDeliveryMethod.Encode) @@ -1650,7 +1658,7 @@ namespace MediaBrowser.Api.Playback if (!string.IsNullOrWhiteSpace(request.AudioCodec)) { state.SupportedAudioCodecs = request.AudioCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); - state.Request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(i => MediaEncoder.CanEncodeToAudioCodec(i)) + state.Request.AudioCodec = state.SupportedAudioCodecs.FirstOrDefault(i => MediaEncoder.CanEncodeToAudioCodec(i)) ?? state.SupportedAudioCodecs.FirstOrDefault(); } diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index f993bc4b1..38a7337ec 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -118,7 +118,7 @@ namespace MediaBrowser.Api config.EnableStandaloneMusicKeys = true; config.EnableCaseSensitiveItemIds = true; config.EnableFolderView = true; - config.SchemaVersion = 96; + config.SchemaVersion = 97; } public void Post(UpdateStartupConfiguration request) diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 1c301f62e..ceccbe423 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -317,7 +317,7 @@ namespace MediaBrowser.Api var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1); - var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; + var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId); var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) { @@ -326,9 +326,10 @@ namespace MediaBrowser.Api SortOrder = SortOrder.Ascending, MinPremiereDate = minPremiereDate, StartIndex = request.StartIndex, - Limit = request.Limit + Limit = request.Limit, + ParentId = parentIdGuid - }, parentIds).ToList(); + }).ToList(); var options = GetDtoOptions(request); diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index ce1e9fd7f..5c70179a8 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -128,11 +128,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager private void AddIpv4Option(HttpWebRequest request, HttpRequestOptions options) { - if (!options.PreferIpv4) - { - return; - } - request.ServicePoint.BindIPEndPointDelegate = (servicePount, remoteEndPoint, retryCount) => { if (remoteEndPoint.AddressFamily == AddressFamily.InterNetwork) @@ -150,7 +145,10 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager if (httpWebRequest != null) { - AddIpv4Option(httpWebRequest, options); + if (options.PreferIpv4) + { + AddIpv4Option(httpWebRequest, options); + } AddRequestHeaders(httpWebRequest, options); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 707ab0c24..0dd7b3c83 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -2175,7 +2175,7 @@ namespace MediaBrowser.Controller.Entities { get { - if (GetParent() is AggregateFolder || this is BasePluginFolder) + if (GetParent() is AggregateFolder || this is BasePluginFolder || this is Channel) { return true; } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 0cb806274..175a7240c 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -550,7 +550,7 @@ namespace MediaBrowser.Controller.Entities query.Limit = GetSpecialItemsLimit(); query.IncludeItemTypes = new[] { typeof(Movie).Name }; - return _libraryManager.GetItemsResult(query); + return ConvertToResult(_libraryManager.GetItemList(query)); } private QueryResult GetMovieResume(Folder parent, User user, InternalItemsQuery query) @@ -564,7 +564,17 @@ namespace MediaBrowser.Controller.Entities query.Limit = GetSpecialItemsLimit(); query.IncludeItemTypes = new[] { typeof(Movie).Name }; - return _libraryManager.GetItemsResult(query); + return ConvertToResult(_libraryManager.GetItemList(query)); + } + + private QueryResult ConvertToResult(IEnumerable items) + { + var arr = items.ToArray(); + return new QueryResult + { + Items = arr, + TotalRecordCount = arr.Length + }; } private async Task> GetMovieGenres(Folder parent, User user, InternalItemsQuery query) @@ -667,7 +677,7 @@ namespace MediaBrowser.Controller.Entities query.IncludeItemTypes = new[] { typeof(Episode).Name }; query.ExcludeLocationTypes = new[] { LocationType.Virtual }; - return _libraryManager.GetItemsResult(query); + return ConvertToResult(_libraryManager.GetItemList(query)); } private QueryResult GetTvNextUp(Folder parent, InternalItemsQuery query) @@ -696,7 +706,7 @@ namespace MediaBrowser.Controller.Entities query.Limit = GetSpecialItemsLimit(); query.IncludeItemTypes = new[] { typeof(Episode).Name }; - return _libraryManager.GetItemsResult(query); + return ConvertToResult(_libraryManager.GetItemList(query)); } private QueryResult GetTvSeries(Folder parent, User user, InternalItemsQuery query) diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index ffba3097c..fe69b38cb 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -345,6 +345,13 @@ namespace MediaBrowser.Controller.LiveTv /// if set to true [validate listings]. /// Task. Task SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings); + + void DeleteListingsProvider(string id); + + Task SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber); + + TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List mappings, List providerChannels); + /// /// Gets the lineups. /// diff --git a/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs new file mode 100644 index 000000000..da0527eea --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/TunerChannelMapping.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.LiveTv +{ + public class TunerChannelMapping + { + public string Name { get; set; } + public string Number { get; set; } + public string ProviderChannelNumber { get; set; } + public string ProviderChannelName { get; set; } + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index d1429c366..0462117cb 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -220,6 +220,7 @@ + diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 22f739801..77bd50b9b 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -377,7 +377,7 @@ namespace MediaBrowser.MediaEncoding.Encoder if (MediaEncoder.SupportsDecoder("h264_qsv")) { // Seeing stalls and failures with decoding. Not worth it compared to encoding. - //return "-c:v h264_qsv "; + return "-c:v h264_qsv "; } break; case "mpeg2video": @@ -672,17 +672,20 @@ namespace MediaBrowser.MediaEncoding.Encoder if (!string.IsNullOrEmpty(state.Options.Profile)) { - param += " -profile:v " + state.Options.Profile; + if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase)) + { + // not supported by h264_omx + param += " -profile:v " + state.Options.Profile; + } } var levelString = state.Options.Level.HasValue ? state.Options.Level.Value.ToString(CultureInfo.InvariantCulture) : null; if (!string.IsNullOrEmpty(levelString)) { - var h264Encoder = EncodingJobFactory.GetH264Encoder(state, GetEncodingOptions()); - // h264_qsv and libnvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format - if (String.Equals(h264Encoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) || String.Equals(h264Encoder, "libnvenc", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) || + string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase)) { switch (levelString) { @@ -718,13 +721,20 @@ namespace MediaBrowser.MediaEncoding.Encoder break; } } - else + else if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase)) { param += " -level " + levelString; } } - return "-pix_fmt yuv420p " + param; + if (!string.Equals(videoCodec, "h264_omx", StringComparison.OrdinalIgnoreCase) && + !string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase) && + !string.Equals(videoCodec, "libnvenc", StringComparison.OrdinalIgnoreCase)) + { + param = "-pix_fmt yuv420p " + param; + } + + return param; } protected string GetVideoBitrateParam(EncodingJob state, string videoCodec) diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 6059108c8..133cc8d70 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -27,17 +27,16 @@ namespace MediaBrowser.MediaEncoding.Encoder return new Tuple, List>(decoders, encoders); } - private List GetDecoders(string ffmpegPath) + private List GetDecoders(string encoderAppPath) { string output = string.Empty; try { - output = GetFFMpegOutput(ffmpegPath, "-decoders"); + output = GetProcessOutput(encoderAppPath, "-decoders"); } catch { } - //_logger.Debug("ffmpeg decoder query result: {0}", output ?? string.Empty); var found = new List(); var required = new[] @@ -51,12 +50,9 @@ namespace MediaBrowser.MediaEncoding.Encoder { var srch = " " + codec + " "; - if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1) - { - _logger.Warn("ffmpeg is missing decoder " + codec); - } - else + if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1) { + _logger.Info("Decoder available: " + codec); found.Add(codec); } } @@ -64,17 +60,16 @@ namespace MediaBrowser.MediaEncoding.Encoder return found; } - private List GetEncoders(string ffmpegPath) + private List GetEncoders(string encoderAppPath) { string output = null; try { - output = GetFFMpegOutput(ffmpegPath, "-encoders"); + output = GetProcessOutput(encoderAppPath, "-encoders"); } catch { } - //_logger.Debug("ffmpeg encoder query result: {0}", output ?? string.Empty); var found = new List(); var required = new[] @@ -89,19 +84,18 @@ namespace MediaBrowser.MediaEncoding.Encoder "libmp3lame", "libopus", //"libvorbis", - "srt" + "srt", + "libnvenc", + "h264_qsv" }; foreach (var codec in required) { var srch = " " + codec + " "; - if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1) - { - _logger.Warn("ffmpeg is missing encoder " + codec); - } - else + if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1) { + _logger.Info("Encoder available: " + codec); found.Add(codec); } } @@ -109,7 +103,7 @@ namespace MediaBrowser.MediaEncoding.Encoder return found; } - private string GetFFMpegOutput(string path, string arguments) + private string GetProcessOutput(string path, string arguments) { var process = new Process { @@ -147,7 +141,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } catch (Exception ex1) { - _logger.ErrorException("Error killing ffmpeg", ex1); + _logger.ErrorException("Error killing process", ex1); } throw; diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index 7fe7facdf..177009306 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -556,13 +556,19 @@ namespace MediaBrowser.MediaEncoding.Encoder internal static string GetH264Encoder(EncodingJob state, EncodingOptions options) { - if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) || + string.Equals(options.HardwareAccelerationType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { - // It's currently failing on live tv - if (state.RunTimeTicks.HasValue) - { - return "h264_qsv"; - } + return "h264_qsv"; + } + + if (string.Equals(options.HardwareAccelerationType, "libnvenc", StringComparison.OrdinalIgnoreCase)) + { + return "libnvenc"; + } + if (string.Equals(options.HardwareAccelerationType, "h264_omx", StringComparison.OrdinalIgnoreCase)) + { + return "h264_omx"; } return "libx264"; diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index e4c17ff2b..f779fcd61 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -192,6 +192,7 @@ namespace MediaBrowser.Model.Configuration public int MigrationVersion { get; set; } public int SchemaVersion { get; set; } + public int SqliteCachePages { get; set; } public bool DownloadImagesInAdvance { get; set; } @@ -211,6 +212,7 @@ namespace MediaBrowser.Model.Configuration { LocalNetworkAddresses = new string[] { }; Migrations = new string[] { }; + SqliteCachePages = 10000; EnableCustomPathSubFolders = true; EnableLocalizedGuids = true; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index ffcf9f60f..c118f9483 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1277,6 +1277,16 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable GetItemList(InternalItemsQuery query) { + if (query.Recursive && query.ParentId.HasValue) + { + var parent = GetItemById(query.ParentId.Value); + if (parent != null) + { + SetTopParentIdsOrAncestors(query, new List { parent }); + query.ParentId = null; + } + } + if (query.User != null) { AddUserToQuery(query, query.User); @@ -1285,6 +1295,23 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.GetItemList(query); } + public IEnumerable GetItemList(InternalItemsQuery query, IEnumerable parentIds) + { + var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList(); + + SetTopParentIdsOrAncestors(query, parents); + + if (query.AncestorIds.Length == 0 && query.TopParentIds.Length == 0) + { + if (query.User != null) + { + AddUserToQuery(query, query.User); + } + } + + return ItemRepository.GetItemList(query); + } + public QueryResult QueryItems(InternalItemsQuery query) { if (query.User != null) @@ -1406,15 +1433,6 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.GetAlbumArtists(query); } - public IEnumerable GetItemList(InternalItemsQuery query, IEnumerable parentIds) - { - var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList(); - - SetTopParentIdsOrAncestors(query, parents); - - return ItemRepository.GetItemList(query); - } - public QueryResult GetItemsResult(InternalItemsQuery query) { if (query.Recursive && query.ParentId.HasValue) @@ -1443,15 +1461,6 @@ namespace MediaBrowser.Server.Implementations.Library }; } - public QueryResult GetItemsResult(InternalItemsQuery query, IEnumerable parentIds) - { - var parents = parentIds.Select(i => GetItemById(new Guid(i))).Where(i => i != null).ToList(); - - SetTopParentIdsOrAncestors(query, parents); - - return GetItemsResult(query); - } - private void SetTopParentIdsOrAncestors(InternalItemsQuery query, List parents) { if (parents.All(i => diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index ef13ba996..3ff434898 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -98,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.Library Genres = genreList.ToArray() - }, new string[] { }); + }); var genresDictionary = genreList.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 262178790..cf6f070d0 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -168,7 +168,7 @@ namespace MediaBrowser.Server.Implementations.Library Limit = query.Limit, IncludeItemsByName = true - }, new string[] { }); + }); // Add search hints based on item name hints.AddRange(mediaItems.Where(IncludeInSearch).Select(item => diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTVRegistration.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTVRegistration.cs new file mode 100644 index 000000000..675fca325 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTVRegistration.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; +using MediaBrowser.Common.Security; + +namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV +{ + public class EmbyTVRegistration : IRequiresRegistration + { + private readonly ISecurityManager _securityManager; + + public static EmbyTVRegistration Instance; + + public EmbyTVRegistration(ISecurityManager securityManager) + { + _securityManager = securityManager; + Instance = this; + } + + private bool? _isXmlTvEnabled; + + public Task LoadRegistrationInfoAsync() + { + _isXmlTvEnabled = null; + return Task.FromResult(true); + } + + public async Task EnableXmlTv() + { + if (!_isXmlTvEnabled.HasValue) + { + var info = await _securityManager.GetRegistrationStatus("xmltv").ConfigureAwait(false); + _isXmlTvEnabled = info.IsValid; + } + return _isXmlTvEnabled.Value; + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 4d24431e6..1e82e3fce 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -103,6 +103,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings public async Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { + if (!await EmbyTV.EmbyTVRegistration.Instance.EnableXmlTv().ConfigureAwait(false)) + { + var length = endDateUtc - startDateUtc; + if (length.TotalDays > 1) + { + endDateUtc = startDateUtc.AddDays(1); + } + } + var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false); var reader = new XmlTvReader(path, GetLanguage(), null); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 8d361e6a0..f32a4b59e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1462,7 +1462,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv internalQuery.ChannelIds = new[] { query.ChannelId }; } - var queryResult = _libraryManager.GetItemList(internalQuery, new string[] { }); + var queryResult = _libraryManager.GetItemList(internalQuery); IEnumerable recordings = queryResult.Cast(); if (!string.IsNullOrWhiteSpace(query.Id)) @@ -1936,7 +1936,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv SortBy = new[] { "StartDate" }, TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Result.Id.ToString("N") } - }, new string[] { }).ToList(); + }).ToList(); foreach (var tuple in tuples) { @@ -2526,6 +2526,79 @@ namespace MediaBrowser.Server.Implementations.LiveTv return info; } + public void DeleteListingsProvider(string id) + { + var config = GetConfiguration(); + + config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList(); + + _config.SaveConfiguration("livetv", config); + _taskManager.CancelIfRunningAndQueue(); + } + + public async Task SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber) + { + var config = GetConfiguration(); + + var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(providerId, i.Id, StringComparison.OrdinalIgnoreCase)); + listingsProviderInfo.ChannelMappings = listingsProviderInfo.ChannelMappings.Where(i => !string.Equals(i.Name, tunerChannelNumber, StringComparison.OrdinalIgnoreCase)).ToArray(); + + if (!string.Equals(tunerChannelNumber, providerChannelNumber, StringComparison.OrdinalIgnoreCase)) + { + var list = listingsProviderInfo.ChannelMappings.ToList(); + list.Add(new NameValuePair + { + Name = tunerChannelNumber, + Value = providerChannelNumber + }); + listingsProviderInfo.ChannelMappings = list.ToArray(); + } + + _config.SaveConfiguration("livetv", config); + + var tunerChannels = await GetChannelsForListingsProvider(providerId, CancellationToken.None) + .ConfigureAwait(false); + + var providerChannels = await GetChannelsFromListingsProviderData(providerId, CancellationToken.None) + .ConfigureAwait(false); + + var mappings = listingsProviderInfo.ChannelMappings.ToList(); + + var tunerChannelMappings = + tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList(); + + _taskManager.CancelIfRunningAndQueue(); + + return tunerChannelMappings.First(i => string.Equals(i.Number, tunerChannelNumber, StringComparison.OrdinalIgnoreCase)); + } + + public TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List mappings, List providerChannels) + { + var result = new TunerChannelMapping + { + Name = channel.Number + " " + channel.Name, + Number = channel.Number + }; + + var mapping = mappings.FirstOrDefault(i => string.Equals(i.Name, channel.Number, StringComparison.OrdinalIgnoreCase)); + var providerChannelNumber = channel.Number; + + if (mapping != null) + { + providerChannelNumber = mapping.Value; + } + + var providerChannel = providerChannels.FirstOrDefault(i => string.Equals(i.Number, providerChannelNumber, StringComparison.OrdinalIgnoreCase)); + + if (providerChannel != null) + { + result.ProviderChannelNumber = providerChannel.Number; + result.ProviderChannelName = providerChannel.Name; + } + + return result; + } + public Task> GetLineups(string providerType, string providerId, string country, string location) { var config = GetConfiguration(); diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index bdd43c196..c78306911 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -226,6 +226,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index d0c351c5d..5d017880c 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 96; + public const int LatestSchemaVersion = 97; /// /// Initializes a new instance of the class. @@ -123,7 +123,7 @@ namespace MediaBrowser.Server.Implementations.Persistence protected override async Task CreateConnection(bool isReadOnly = false) { - var connection = await DbConnector.Connect(DbFilePath, false, false, 10000).ConfigureAwait(false); + var connection = await DbConnector.Connect(DbFilePath, false, false, _config.Configuration.SqliteCachePages).ConfigureAwait(false); connection.RunQueries(new[] { diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 08d5d73f2..1a227126e 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -524,18 +524,6 @@ namespace MediaBrowser.WebDashboard.Api await DumpFile(filename, Path.Combine(destination, filename), mode, culture, appVersion).ConfigureAwait(false); } - - var excludeFiles = new List(); - - if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) - { - excludeFiles.Add("supporterkey.html"); - } - - foreach (var file in excludeFiles) - { - _fileSystem.DeleteFile(Path.Combine(destination, file)); - } } private async Task DumpFile(string resourceVirtualPath, string destinationFilePath, string mode, string culture, string appVersion) diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 883c02914..4c353c413 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -258,7 +258,6 @@ namespace MediaBrowser.WebDashboard.Api if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { - html = ModifyForCordova(html); } else if (!string.IsNullOrWhiteSpace(path) && !string.Equals(path, "index.html", StringComparison.OrdinalIgnoreCase)) { @@ -339,41 +338,6 @@ namespace MediaBrowser.WebDashboard.Api return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); } - private string ModifyForCordova(string html) - { - // Replace CORDOVA_REPLACE_SUPPORTER_SUBMIT_START - html = ReplaceBetween(html, "", "", "${ButtonPurchase}"); - - return html; - } - - private string ReplaceBetween(string html, string startToken, string endToken, string newHtml) - { - var start = html.IndexOf(startToken, StringComparison.OrdinalIgnoreCase); - - if (start == -1) - { - return html; - } - - var end = html.IndexOf(endToken, start, StringComparison.OrdinalIgnoreCase); - - if (end == -1) - { - return html; - } - - string result = html.Substring(start, end - start); - html = html.Replace(result, newHtml); - - return ReplaceBetween(html, startToken, endToken, newHtml); - } - - private string GetLocalizationToken(string phrase) - { - return "${" + phrase + "}"; - } - /// /// Gets the meta tags. /// diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 2c42c1814..9c786dbae 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -224,9 +224,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -269,9 +266,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -482,9 +476,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -506,9 +497,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest