diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index 9c8120de7d..2e5c252d63 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -79,6 +79,8 @@ namespace MediaBrowser.Api { [ApiMember(Name = "Path", Description = "Path", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Path { get; set; } + [ApiMember(Name = "PathType", Description = "PathType", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string PathType { get; set; } } public class ConfigurationService : BaseApiService @@ -110,7 +112,7 @@ namespace MediaBrowser.Api public void Post(UpdateMediaEncoderPath request) { - var task = _mediaEncoder.UpdateEncoderPath(request.Path); + var task = _mediaEncoder.UpdateEncoderPath(request.Path, request.PathType); Task.WaitAll(task); } diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index a889879d55..108eddcf9e 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -55,7 +55,7 @@ ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll - ..\packages\NLog.4.3.4\lib\net45\NLog.dll + ..\packages\NLog.4.3.5\lib\net45\NLog.dll True @@ -65,8 +65,8 @@ False ..\ThirdParty\SharpCompress\SharpCompress.dll - - ..\packages\SimpleInjector.3.1.5\lib\net45\SimpleInjector.dll + + ..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll True diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index d1ede89a11..882acc9ffd 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -2,7 +2,7 @@ - + - + \ No newline at end of file diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 43a1b9eaa1..5faf85b2a0 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -46,6 +46,7 @@ namespace MediaBrowser.Controller.Entities public string NameStartsWith { get; set; } public string NameLessThan { get; set; } public string NameContains { get; set; } + public string MinSortName { get; set; } public string PresentationUniqueKey { get; set; } public string Path { get; set; } diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 77ba1685f5..12c893b0fc 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -13,6 +13,8 @@ namespace MediaBrowser.Controller.MediaEncoding /// public interface IMediaEncoder : ITranscoderSupport { + string EncoderLocationType { get; } + /// /// Gets the encoder path. /// @@ -60,12 +62,12 @@ namespace MediaBrowser.Controller.MediaEncoding /// The maximum width. /// The cancellation token. /// Task. - Task ExtractVideoImagesOnInterval(string[] inputFiles, - MediaProtocol protocol, - Video3DFormat? threedFormat, - TimeSpan interval, - string targetDirectory, - string filenamePrefix, + Task ExtractVideoImagesOnInterval(string[] inputFiles, + MediaProtocol protocol, + Video3DFormat? threedFormat, + TimeSpan interval, + string targetDirectory, + string filenamePrefix, int? maxWidth, CancellationToken cancellationToken); @@ -131,6 +133,6 @@ namespace MediaBrowser.Controller.MediaEncoding void Init(); - Task UpdateEncoderPath(string path); + Task UpdateEncoderPath(string path, string pathType); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 11291a05a5..5b9a2a6820 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -99,6 +99,39 @@ namespace MediaBrowser.MediaEncoding.Encoder _hasExternalEncoder = hasExternalEncoder; } + public string EncoderLocationType + { + get + { + if (_hasExternalEncoder) + { + return "External"; + } + + if (string.IsNullOrWhiteSpace(FFMpegPath)) + { + return null; + } + + if (IsSystemInstalledPath(FFMpegPath)) + { + return "System"; + } + + return "Custom"; + } + } + + private bool IsSystemInstalledPath(string path) + { + if (path.IndexOf("/", StringComparison.Ordinal) == -1 && path.IndexOf("\\", StringComparison.Ordinal) == -1) + { + return true; + } + + return false; + } + public void Init() { ConfigureEncoderPaths(); @@ -115,10 +148,13 @@ namespace MediaBrowser.MediaEncoding.Encoder var valueToSave = FFMpegPath; - // if using system variable, don't save this. - if (string.Equals(valueToSave, "ffmpeg", StringComparison.OrdinalIgnoreCase)) + if (!string.IsNullOrWhiteSpace(valueToSave)) { - valueToSave = null; + // if using system variable, don't save this. + if (IsSystemInstalledPath(valueToSave)) + { + valueToSave = null; + } } if (!string.Equals(valueToSave, appPath, StringComparison.Ordinal)) @@ -128,19 +164,39 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - public async Task UpdateEncoderPath(string path) + public async Task UpdateEncoderPath(string path, string pathType) { - if (string.IsNullOrWhiteSpace(path)) + if (_hasExternalEncoder) { - throw new ArgumentNullException("path"); + return; } - if (!File.Exists(path) && !Directory.Exists(path)) + Tuple newPaths; + + if (string.Equals(pathType, "system", StringComparison.OrdinalIgnoreCase)) + { + path = "ffmpeg"; + + newPaths = TestForInstalledVersions(); + } + else if (string.Equals(pathType, "custom", StringComparison.OrdinalIgnoreCase)) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentNullException("path"); + } + + if (!File.Exists(path) && !Directory.Exists(path)) + { + throw new ResourceNotFoundException(); + } + newPaths = GetEncoderPaths(path); + } + else { - throw new ResourceNotFoundException(); + throw new ArgumentException("Unexpected pathType value"); } - var newPaths = GetEncoderPaths(path); if (string.IsNullOrWhiteSpace(newPaths.Item1)) { throw new ResourceNotFoundException("ffmpeg not found"); @@ -252,7 +308,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - private Tuple GetPathsFromDirectory(string path) + private Tuple GetPathsFromDirectory(string path) { // Since we can't predict the file extension, first try directly within the folder // If that doesn't pan out, then do a recursive search diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index 868d9dc282..3d1de5b379 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -152,7 +152,7 @@ namespace MediaBrowser.Model.System /// true if [supports automatic run at startup]; otherwise, false. public bool SupportsAutoRunAtStartup { get; set; } - public bool HasExternalEncoder { get; set; } + public string EncoderLocationType { get; set; } public Architecture SystemArchitecture { get; set; } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index cfe0564fbd..d58528b441 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -46,7 +46,7 @@ ..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll - ..\packages\Emby.XmlTv.1.0.0.53\lib\net45\Emby.XmlTv.dll + ..\packages\Emby.XmlTv.1.0.0.54\lib\net45\Emby.XmlTv.dll True @@ -69,8 +69,8 @@ ..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll - - ..\packages\SimpleInjector.3.1.5\lib\net45\SimpleInjector.dll + + ..\packages\SimpleInjector.3.2.0\lib\net45\SimpleInjector.dll True diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 096cdf880e..d0c351c5df 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -2663,6 +2663,12 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@SlugName", DbType.String).Value = query.SlugName; } + if (!string.IsNullOrWhiteSpace(query.MinSortName)) + { + whereClauses.Add("SortName>=@MinSortName"); + cmd.Parameters.Add(cmd, "@MinSortName", DbType.String).Value = query.MinSortName; + } + if (!string.IsNullOrWhiteSpace(query.Name)) { whereClauses.Add("CleanName=@Name"); @@ -3773,7 +3779,8 @@ namespace MediaBrowser.Server.Implementations.Persistence } else { - whereText += " And itemTypes not null"; + //whereText += " And itemTypes not null"; + whereText += " And CleanName In (Select CleanValue from ItemValues where Type=@ItemValueType AND ItemId in (select guid from TypedBaseItems" + innerWhereText + "))"; } var outerQuery = new InternalItemsQuery(query.User) @@ -3855,7 +3862,7 @@ namespace MediaBrowser.Server.Implementations.Persistence ? (CommandBehavior.SequentialAccess | CommandBehavior.SingleResult) : CommandBehavior.SequentialAccess; - //Logger.Debug("GetItemValues: " + cmd.CommandText); + Logger.Debug("GetItemValues: " + cmd.CommandText); using (var reader = cmd.ExecuteReader(commandBehavior)) { diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 82232ffae0..ba6534a7c3 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -107,7 +107,6 @@ namespace MediaBrowser.Server.Implementations.TV var currentUser = user; return series - .AsParallel() .Select(i => GetNextUp(i, currentUser)) // Include if an episode was found, and either the series is not unwatched or the specific series was requested .Where(i => i.Item1 != null && (!i.Item3 || !string.IsNullOrWhiteSpace(request.SeriesId))) @@ -124,67 +123,32 @@ namespace MediaBrowser.Server.Implementations.TV /// Task{Episode}. private Tuple GetNextUp(Series series, User user) { - var firstUnwatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) + var lastWatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) { AncestorWithPresentationUniqueKey = series.PresentationUniqueKey, IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { ItemSortBy.SortName }, - SortOrder = SortOrder.Ascending, + SortOrder = SortOrder.Descending, + IsPlayed = true, Limit = 1, - IsPlayed = false, IsVirtualItem = false, ParentIndexNumberNotEquals = 0 - }).Cast().FirstOrDefault(); - - // series is fully played - if (firstUnwatchedEpisode == null) - { - return new Tuple(null, DateTime.MinValue, true); - } + }).FirstOrDefault(); - var lastWatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) + var firstUnwatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) { AncestorWithPresentationUniqueKey = series.PresentationUniqueKey, IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.DatePlayed }, - SortOrder = SortOrder.Descending, + SortBy = new[] { ItemSortBy.SortName }, + SortOrder = SortOrder.Ascending, Limit = 1, + IsPlayed = false, IsVirtualItem = false, - ParentIndexNumberNotEquals = 0 + ParentIndexNumberNotEquals = 0, + MinSortName = lastWatchedEpisode == null ? null : lastWatchedEpisode.SortName - }).FirstOrDefault(); - - //// Get them in display order, then reverse - //var allEpisodes = series.GetEpisodes(user, false, false) - // .Where(i => !i.ParentIndexNumber.HasValue || i.ParentIndexNumber.Value != 0) - // .Reverse() - // .ToList(); - - //Episode lastWatched = null; - //var lastWatchedDate = DateTime.MinValue; - //Episode nextUp = null; - - //// Go back starting with the most recent episodes - //foreach (var episode in allEpisodes) - //{ - // var userData = _userDataManager.GetUserData(user, episode); - - // if (userData.Played) - // { - // if (lastWatched != null || nextUp == null) - // { - // break; - // } - - // lastWatched = episode; - // lastWatchedDate = userData.LastPlayedDate ?? DateTime.MinValue; - // } - // else - // { - // nextUp = episode; - // } - //} + }).Cast().FirstOrDefault(); if (lastWatchedEpisode != null) { diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 326721ff3b..93a7f03b9b 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,13 +1,13 @@  - + - + \ No newline at end of file diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index ec1ccbff57..1d7b65e5f1 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -658,13 +658,13 @@ namespace MediaBrowser.Server.Startup.Common encoderPath = info.EncoderPath; probePath = info.ProbePath; - _hasExternalEncoder = string.Equals(info.Version, "external", StringComparison.OrdinalIgnoreCase); + var hasExternalEncoder = string.Equals(info.Version, "external", StringComparison.OrdinalIgnoreCase); var mediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), JsonSerializer, encoderPath, probePath, - _hasExternalEncoder, + hasExternalEncoder, ServerConfigurationManager, FileSystemManager, LiveTvManager, @@ -1100,7 +1100,6 @@ namespace MediaBrowser.Server.Startup.Common } } - private bool _hasExternalEncoder; /// /// Gets the system status. /// @@ -1141,7 +1140,7 @@ namespace MediaBrowser.Server.Startup.Common ServerName = FriendlyName, LocalAddress = localAddress, SupportsLibraryMonitor = SupportsLibraryMonitor, - HasExternalEncoder = _hasExternalEncoder, + EncoderLocationType = MediaEncoder.EncoderLocationType, SystemArchitecture = NativeApp.Environment.SystemArchitecture }; } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index fd30d23d52..dc92b318e7 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -13,8 +13,8 @@ Copyright © Emby 2013 - - + +