diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 545ac162f..f6817e0e7 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -155,6 +155,9 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] public bool? EnableUserData { get; set; } + public bool? IsMovie { get; set; } + public bool? IsSeries { get; set; } + public GetRecordings() { EnableTotalRecordCount = true; @@ -863,7 +866,9 @@ namespace MediaBrowser.Api.LiveTv Status = request.Status, SeriesTimerId = request.SeriesTimerId, IsInProgress = request.IsInProgress, - EnableTotalRecordCount = request.EnableTotalRecordCount + EnableTotalRecordCount = request.EnableTotalRecordCount, + IsMovie = request.IsMovie, + IsSeries = request.IsSeries }, options, CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 4af564a5a..b419250f7 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -346,16 +346,32 @@ namespace MediaBrowser.Api.Playback var isVc1 = state.VideoStream != null && string.Equals(state.VideoStream.Codec, "vc1", StringComparison.OrdinalIgnoreCase); + var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions(); + if (string.Equals(videoCodec, "libx264", StringComparison.OrdinalIgnoreCase)) { - param = "-preset superfast"; + if (!string.IsNullOrWhiteSpace(encodingOptions.H264Preset)) + { + param += "-preset " + encodingOptions.H264Preset; + } + else + { + param += "-preset superfast"; + } - param += " -crf 23"; + if (encodingOptions.H264Crf >= 0 && encodingOptions.H264Crf <= 51) + { + param += " -crf " + encodingOptions.H264Crf.ToString(CultureInfo.InvariantCulture); + } + else + { + param += " -crf 23"; + } } else if (string.Equals(videoCodec, "libx265", StringComparison.OrdinalIgnoreCase)) { - param = "-preset fast"; + param += "-preset fast"; param += " -crf 28"; } @@ -363,14 +379,14 @@ namespace MediaBrowser.Api.Playback // h264 (h264_qsv) else if (string.Equals(videoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { - param = "-preset 7 -look_ahead 0"; + param += "-preset 7 -look_ahead 0"; } // h264 (h264_nvenc) else if (string.Equals(videoCodec, "h264_nvenc", StringComparison.OrdinalIgnoreCase)) { - param = "-preset default"; + param += "-preset default"; } // webm @@ -394,7 +410,7 @@ namespace MediaBrowser.Api.Playback profileScore = Math.Min(profileScore, 2); // http://www.webmproject.org/docs/encoder-parameters/ - param = string.Format("-speed 16 -quality good -profile:v {0} -slices 8 -crf {1} -qmin {2} -qmax {3}", + param += string.Format("-speed 16 -quality good -profile:v {0} -slices 8 -crf {1} -qmin {2} -qmax {3}", profileScore.ToString(UsCulture), crf, qmin, @@ -403,18 +419,18 @@ namespace MediaBrowser.Api.Playback else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase)) { - param = "-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -bf 2"; + param += "-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -bf 2"; } // asf/wmv else if (string.Equals(videoCodec, "wmv2", StringComparison.OrdinalIgnoreCase)) { - param = "-qmin 2"; + param += "-qmin 2"; } else if (string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase)) { - param = "-mbd 2"; + param += "-mbd 2"; } param += GetVideoBitrateParam(state, videoCodec); @@ -1770,6 +1786,16 @@ namespace MediaBrowser.Api.Playback // state.SegmentLength = 6; //} + if (state.VideoRequest != null) + { + if (!string.IsNullOrWhiteSpace(state.VideoRequest.VideoCodec)) + { + state.SupportedVideoCodecs = state.VideoRequest.VideoCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + state.VideoRequest.VideoCodec = state.SupportedVideoCodecs.FirstOrDefault(i => MediaEncoder.CanEncodeToAudioCodec(i)) + ?? state.SupportedVideoCodecs.FirstOrDefault(); + } + } + if (!string.IsNullOrWhiteSpace(request.AudioCodec)) { state.SupportedAudioCodecs = request.AudioCodec.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); @@ -2012,7 +2038,7 @@ namespace MediaBrowser.Api.Playback } // Source and target codecs must match - if (!string.Equals(request.VideoCodec, videoStream.Codec, StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrEmpty(videoStream.Codec) || !state.SupportedVideoCodecs.Contains(videoStream.Codec, StringComparer.OrdinalIgnoreCase)) { return false; } diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index d7d94c69b..2e92c4a49 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -112,6 +112,7 @@ namespace MediaBrowser.Api.Playback public string OutputVideoSync = "-1"; public List SupportedAudioCodecs { get; set; } + public List SupportedVideoCodecs { get; set; } public string UserAgent { get; set; } public StreamState(IMediaSourceManager mediaSourceManager, ILogger logger) @@ -119,6 +120,7 @@ namespace MediaBrowser.Api.Playback _mediaSourceManager = mediaSourceManager; _logger = logger; SupportedAudioCodecs = new List(); + SupportedVideoCodecs = new List(); PlayableStreamFileNames = new List(); RemoteHttpHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); } diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index daaa6343d..a0d69317c 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -478,7 +478,7 @@ namespace MediaBrowser.Api } else { - episodes = series.GetSeasonEpisodes(user, season); + episodes = series.GetSeasonEpisodes(season, user); } } else diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 65b7c9955..ff3e53b69 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -85,9 +85,7 @@ namespace MediaBrowser.Controller.Entities.TV public override int GetChildCount(User user) { - Logger.Debug("Season {0} getting child cound", (Path ?? Name)); var result = GetChildren(user, true).Count(); - Logger.Debug("Season {0} child cound: ", result); return result; } @@ -158,13 +156,10 @@ namespace MediaBrowser.Controller.Entities.TV var id = Guid.NewGuid().ToString("N"); - Logger.Debug("Season.GetItemsInternal entering GetEpisodes. Request id: " + id); var items = GetEpisodes(user).Where(filter); - Logger.Debug("Season.GetItemsInternal entering PostFilterAndSort. Request id: " + id); var result = PostFilterAndSort(items, query, false, false); - Logger.Debug("Season.GetItemsInternal complete. Request id: " + id); return Task.FromResult(result); } @@ -185,34 +180,12 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetEpisodes(Series series, User user, IEnumerable allSeriesEpisodes) { - return series.GetSeasonEpisodes(user, this, allSeriesEpisodes); + return series.GetSeasonEpisodes(this, user, allSeriesEpisodes); } public IEnumerable GetEpisodes() { - var episodes = GetRecursiveChildren().OfType(); - var series = Series; - - if (series != null && series.ContainsEpisodesWithoutSeasonFolders) - { - var seasonNumber = IndexNumber; - var list = episodes.ToList(); - - if (seasonNumber.HasValue) - { - list.AddRange(series.GetRecursiveChildren().OfType() - .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == seasonNumber.Value)); - } - else - { - list.AddRange(series.GetRecursiveChildren().OfType() - .Where(i => !i.ParentIndexNumber.HasValue)); - } - - episodes = list.DistinctBy(i => i.Id); - } - - return episodes; + return Series.GetSeasonEpisodes(this, null, null); } public override IEnumerable GetChildren(User user, bool includeLinkedChildren) diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 4915cfedc..7e8ba0516 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -209,7 +209,6 @@ namespace MediaBrowser.Controller.Entities.TV var seriesKey = GetUniqueSeriesKey(this); - Logger.Debug("GetSeasons SeriesKey: {0}", seriesKey); var query = new InternalItemsQuery(user) { AncestorWithPresentationUniqueKey = seriesKey, @@ -267,7 +266,6 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable GetEpisodes(User user) { var seriesKey = GetUniqueSeriesKey(this); - Logger.Debug("GetEpisodes seriesKey: {0}", seriesKey); var query = new InternalItemsQuery(user) { @@ -291,8 +289,6 @@ namespace MediaBrowser.Controller.Entities.TV var allItems = LibraryManager.GetItemList(query).ToList(); - Logger.Debug("GetEpisodes return {0} items from database", allItems.Count); - var allSeriesEpisodes = allItems.OfType().ToList(); var allEpisodes = allItems.OfType() @@ -373,27 +369,9 @@ namespace MediaBrowser.Controller.Entities.TV progress.Report(100); } - private IEnumerable GetAllEpisodes(User user) - { - Logger.Debug("Series.GetAllEpisodes entering GetItemList"); - - var result = LibraryManager.GetItemList(new InternalItemsQuery(user) - { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), - IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.SortName } - - }).Cast().ToList(); - - Logger.Debug("Series.GetAllEpisodes returning {0} episodes", result.Count); - - return result; - } - - public IEnumerable GetSeasonEpisodes(User user, Season parentSeason) + public IEnumerable GetSeasonEpisodes(Season parentSeason, User user) { var seriesKey = GetUniqueSeriesKey(this); - Logger.Debug("GetSeasonEpisodes seriesKey: {0}", seriesKey); var query = new InternalItemsQuery(user) { @@ -401,34 +379,35 @@ namespace MediaBrowser.Controller.Entities.TV IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { ItemSortBy.SortName } }; - var config = user.Configuration; - if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) + if (user != null) { - query.IsVirtualItem = false; - } - else if (!config.DisplayMissingEpisodes) - { - query.IsMissing = false; - } - else if (!config.DisplayUnairedEpisodes) - { - query.IsVirtualUnaired = false; + var config = user.Configuration; + if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) + { + query.IsVirtualItem = false; + } + else if (!config.DisplayMissingEpisodes) + { + query.IsMissing = false; + } + else if (!config.DisplayUnairedEpisodes) + { + query.IsVirtualUnaired = false; + } } var allItems = LibraryManager.GetItemList(query).OfType(); - return GetSeasonEpisodes(user, parentSeason, allItems); + return GetSeasonEpisodes(parentSeason, user, allItems); } - public IEnumerable GetSeasonEpisodes(User user, Season parentSeason, IEnumerable allSeriesEpisodes) + public IEnumerable GetSeasonEpisodes(Season parentSeason, User user, IEnumerable allSeriesEpisodes) { if (allSeriesEpisodes == null) { - Logger.Debug("GetSeasonEpisodes allSeriesEpisodes is null"); - return GetSeasonEpisodes(user, parentSeason); + return GetSeasonEpisodes(parentSeason, user); } - Logger.Debug("GetSeasonEpisodes FilterEpisodesBySeason"); var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons); var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder; diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 306ce35ec..7a987a68e 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -64,7 +64,7 @@ namespace MediaBrowser.Controller.Entities info.IsLocalTrailer = TrailerTypes.Contains(TrailerType.LocalTrailer); - if (!IsInMixedFolder) + if (!IsInMixedFolder && LocationType == LocationType.FileSystem) { info.Name = System.IO.Path.GetFileName(ContainingFolderPath); } diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 35375e7e6..194ba0ee4 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -113,7 +113,8 @@ namespace MediaBrowser.Controller.Entities { var standaloneTypes = new List { - CollectionType.Playlists + CollectionType.Playlists, + CollectionType.BoxSets }; var collectionFolder = folder as ICollectionFolder; diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index ad84ffee8..75d85cd32 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -928,7 +928,12 @@ namespace MediaBrowser.MediaEncoding.Encoder { StartProcess(processWrapper); - ranToCompletion = process.WaitForExit(10000); + var timeoutMs = ConfigurationManager.Configuration.ImageExtractionTimeoutMs; + if (timeoutMs <= 0) + { + timeoutMs = 10000; + } + ranToCompletion = process.WaitForExit(timeoutMs); if (!ranToCompletion) { diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 3c03dc12a..d49816803 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -11,6 +11,8 @@ namespace MediaBrowser.Model.Configuration public string HardwareAccelerationType { get; set; } public string EncoderAppPath { get; set; } public string VaapiDevice { get; set; } + public int H264Crf { get; set; } + public string H264Preset { get; set; } public EncodingOptions() { @@ -19,6 +21,8 @@ namespace MediaBrowser.Model.Configuration ThrottleDelaySeconds = 180; EncodingThreadCount = -1; VaapiDevice = "/dev/dri/card0"; + H264Crf = 23; + H264Preset = "superfast"; } } } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index b0595b558..44a2ae954 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -207,6 +207,7 @@ namespace MediaBrowser.Model.Configuration public bool EnableChannelView { get; set; } public bool EnableExternalContentInSuggestions { get; set; } + public int ImageExtractionTimeoutMs { get; set; } /// /// Initializes a new instance of the class. /// @@ -216,6 +217,7 @@ namespace MediaBrowser.Model.Configuration Migrations = new string[] { }; CodecsUsed = new string[] { }; SqliteCacheSize = 0; + ImageExtractionTimeoutMs = 10000; EnableLocalizedGuids = true; DisplaySpecialsWithinSeasons = true; diff --git a/MediaBrowser.Model/LiveTv/RecordingQuery.cs b/MediaBrowser.Model/LiveTv/RecordingQuery.cs index 923d303f8..cedc0b852 100644 --- a/MediaBrowser.Model/LiveTv/RecordingQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecordingQuery.cs @@ -68,6 +68,8 @@ namespace MediaBrowser.Model.LiveTv /// The fields. public ItemFields[] Fields { get; set; } public bool? EnableImages { get; set; } + public bool? IsMovie { get; set; } + public bool? IsSeries { get; set; } public int? ImageTypeLimit { get; set; } public ImageType[] EnableImageTypes { get; set; } diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index 3d1de5b37..c4d056a61 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -8,6 +8,8 @@ namespace MediaBrowser.Model.System /// public class SystemInfo : PublicSystemInfo { + public PackageVersionClass SystemUpdateLevel { get; set; } + /// /// Gets or sets the display name of the operating system. /// diff --git a/MediaBrowser.Providers/TV/DummySeasonProvider.cs b/MediaBrowser.Providers/TV/DummySeasonProvider.cs index fe0ad78be..b74eac219 100644 --- a/MediaBrowser.Providers/TV/DummySeasonProvider.cs +++ b/MediaBrowser.Providers/TV/DummySeasonProvider.cs @@ -138,8 +138,6 @@ namespace MediaBrowser.Providers.TV .Where(i => i.LocationType == LocationType.Virtual) .ToList(); - var episodes = series.GetRecursiveChildren().OfType().ToList(); - var seasonsToRemove = virtualSeasons .Where(i => { @@ -152,19 +150,15 @@ namespace MediaBrowser.Providers.TV { return true; } - - // If there are no episodes with this season number, delete it - if (episodes.All(e => !e.ParentIndexNumber.HasValue || e.ParentIndexNumber.Value != seasonNumber)) - { - return true; - } - - return false; } - // Season does not have a number - // Remove if there are no episodes directly in series without a season number - return episodes.All(s => s.ParentIndexNumber.HasValue || s.IsInSeasonFolder); + // If there are no episodes with this season number, delete it + if (!i.GetEpisodes().Any()) + { + return true; + } + + return false; }) .ToList(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 88017aa59..3d9a0f80e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -31,6 +31,8 @@ using CommonIO; using IniParser; using IniParser.Model; using MediaBrowser.Common.Events; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Events; namespace MediaBrowser.Server.Implementations.LiveTv @@ -1423,6 +1425,32 @@ namespace MediaBrowser.Server.Implementations.LiveTv return new QueryResult(); } + var includeItemTypes = new List(); + var excludeItemTypes = new List(); + + if (query.IsMovie.HasValue) + { + if (query.IsMovie.Value) + { + includeItemTypes.Add(typeof (Movie).Name); + } + else + { + excludeItemTypes.Add(typeof(Movie).Name); + } + } + if (query.IsSeries.HasValue) + { + if (query.IsSeries.Value) + { + includeItemTypes.Add(typeof(Episode).Name); + } + else + { + excludeItemTypes.Add(typeof(Episode).Name); + } + } + return _libraryManager.GetItemsResult(new InternalItemsQuery(user) { MediaTypes = new[] { MediaType.Video }, @@ -1433,7 +1461,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv Limit = Math.Min(200, query.Limit ?? int.MaxValue), SortBy = new[] { ItemSortBy.DateCreated }, SortOrder = SortOrder.Descending, - EnableTotalRecordCount = query.EnableTotalRecordCount + EnableTotalRecordCount = query.EnableTotalRecordCount, + IncludeItemTypes = includeItemTypes.ToArray(), + ExcludeItemTypes = excludeItemTypes.ToArray() }); } @@ -1492,6 +1522,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv recordings = recordings.Where(i => i.Status == val); } + if (query.IsMovie.HasValue) + { + var val = query.IsMovie.Value; + recordings = recordings.Where(i => i.IsMovie == val); + } + + if (query.IsSeries.HasValue) + { + var val = query.IsSeries.Value; + recordings = recordings.Where(i => i.IsSeries == val); + } + if (!string.IsNullOrEmpty(query.SeriesTimerId)) { var guid = new Guid(query.SeriesTimerId); @@ -1950,16 +1992,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.Number = channel.Number; dto.ChannelNumber = channel.Number; dto.ChannelType = channel.ChannelType; - dto.ServiceName = GetService(channel).Name; + dto.ServiceName = channel.ServiceName; if (options.Fields.Contains(ItemFields.MediaSources)) { dto.MediaSources = channel.GetMediaSources(true).ToList(); } - var channelIdString = channel.Id.ToString("N"); if (options.AddCurrentProgram) { + var channelIdString = channel.Id.ToString("N"); var currentProgram = programs.FirstOrDefault(i => string.Equals(i.ChannelId, channelIdString)); if (currentProgram != null) diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs index 241ceaf65..6dd5de548 100644 --- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs +++ b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs @@ -109,11 +109,6 @@ namespace MediaBrowser.Server.Implementations.Udp { var parts = messageText.Split('|'); - if (parts.Length > 1) - { - _appHost.EnableLoopback(parts[1]); - } - var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false); if (!string.IsNullOrEmpty(localUrl)) @@ -126,6 +121,11 @@ namespace MediaBrowser.Server.Implementations.Udp }; await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint).ConfigureAwait(false); + + if (parts.Length > 1) + { + _appHost.EnableLoopback(parts[1]); + } } else { diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index 3c75c8a48..f40072897 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -14,17 +14,20 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.LiveTv; namespace MediaBrowser.Server.Implementations.UserViews { public class DynamicImageProvider : BaseDynamicImageProvider { private readonly IUserManager _userManager; + private readonly ILibraryManager _libraryManager; - public DynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, IUserManager userManager) + public DynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, IUserManager userManager, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor) { _userManager = userManager; + _libraryManager = libraryManager; } public override IEnumerable GetSupportedImages(IHasImages item) @@ -50,7 +53,15 @@ namespace MediaBrowser.Server.Implementations.UserViews if (string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) { - return new List(); + var programs = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, + ImageTypes = new[] { ImageType.Primary }, + Limit = 30, + IsMovie = true + }).ToList(); + + return GetFinalItems(programs).ToList(); } if (string.Equals(view.ViewType, SpecialFolder.MovieGenre, StringComparison.OrdinalIgnoreCase) || @@ -147,6 +158,7 @@ namespace MediaBrowser.Server.Implementations.UserViews CollectionType.MusicVideos, CollectionType.HomeVideos, CollectionType.BoxSets, + CollectionType.LiveTv, CollectionType.Playlists, CollectionType.Photos, string.Empty diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index a25bd3812..86c5c06bc 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -1096,7 +1096,8 @@ namespace MediaBrowser.Server.Startup.Common LocalAddress = localAddress, SupportsLibraryMonitor = SupportsLibraryMonitor, EncoderLocationType = MediaEncoder.EncoderLocationType, - SystemArchitecture = NativeApp.Environment.SystemArchitecture + SystemArchitecture = NativeApp.Environment.SystemArchitecture, + SystemUpdateLevel = ConfigurationManager.CommonConfiguration.SystemUpdateLevel }; } diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs index 1c90a7438..de898e66c 100644 --- a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs +++ b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Implementations.Updates; @@ -55,21 +56,39 @@ namespace MediaBrowser.Server.Startup.Common.Migrations } } - private async Task CheckVersion(Version currentVersion, PackageVersionClass updateLevel, CancellationToken cancellationToken) + private async Task CheckVersion(Version currentVersion, PackageVersionClass currentUpdateLevel, CancellationToken cancellationToken) { var releases = await new GithubUpdater(_httpClient, _jsonSerializer, TimeSpan.FromMinutes(3)) .GetLatestReleases("MediaBrowser", "Emby", _releaseAssetFilename, cancellationToken).ConfigureAwait(false); - var newUpdateLevel = updateLevel; + var newUpdateLevel = GetNewUpdateLevel(currentVersion, currentUpdateLevel, releases); + + if (newUpdateLevel != currentUpdateLevel) + { + _config.Configuration.SystemUpdateLevel = newUpdateLevel; + _config.SaveConfiguration(); + } + } + + private PackageVersionClass GetNewUpdateLevel(Version currentVersion, PackageVersionClass currentUpdateLevel, List releases) + { + var newUpdateLevel = currentUpdateLevel; // If the current version is later than current stable, set the update level to beta if (releases.Count >= 1) { var release = releases[0]; var version = ParseVersion(release.tag_name); - if (version != null && currentVersion > version) + if (version != null) { - newUpdateLevel = PackageVersionClass.Beta; + if (currentVersion > version) + { + newUpdateLevel = PackageVersionClass.Beta; + } + else + { + return PackageVersionClass.Release; + } } } @@ -78,17 +97,20 @@ namespace MediaBrowser.Server.Startup.Common.Migrations { var release = releases[1]; var version = ParseVersion(release.tag_name); - if (version != null && currentVersion > version) + if (version != null) { - newUpdateLevel = PackageVersionClass.Dev; + if (currentVersion > version) + { + newUpdateLevel = PackageVersionClass.Dev; + } + else + { + return PackageVersionClass.Beta; + } } } - if (newUpdateLevel != updateLevel) - { - _config.Configuration.SystemUpdateLevel = newUpdateLevel; - _config.SaveConfiguration(); - } + return newUpdateLevel; } private Version ParseVersion(string versionString) diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 1ba456ce5..d1308a501 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -191,6 +191,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest