From 83c1503333fae11af63199ae6daba95d62673ee2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 15 May 2017 15:45:39 -0400 Subject: update recorder --- .../LiveTv/EmbyTV/DirectRecorder.cs | 31 +++++++++++++++++++++- .../LiveTv/EmbyTV/EncodedRecorder.cs | 13 ++++++++- .../LiveTv/EmbyTV/IRecorder.cs | 9 ++----- 3 files changed, 44 insertions(+), 9 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs index ef440899cb..e43e058398 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs @@ -6,6 +6,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.IO; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Logging; @@ -29,7 +30,35 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return targetFile; } - public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) + public Task Record(IDirectStreamProvider directStreamProvider, MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) + { + if (directStreamProvider != null) + { + return RecordFromDirectStreamProvider(directStreamProvider, targetFile, duration, onStarted, cancellationToken); + } + + return RecordFromMediaSource(mediaSource, targetFile, duration, onStarted, cancellationToken); + } + + private async Task RecordFromDirectStreamProvider(IDirectStreamProvider directStreamProvider, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) + { + using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read)) + { + onStarted(); + + _logger.Info("Copying recording stream to file {0}", targetFile); + + // The media source if infinite so we need to handle stopping ourselves + var durationToken = new CancellationTokenSource(duration); + cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; + + await directStreamProvider.CopyToAsync(output, cancellationToken).ConfigureAwait(false); + } + + _logger.Info("Recording completed to file {0}", targetFile); + } + + private async Task RecordFromMediaSource(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) { var httpRequestOptions = new HttpRequestOptions { diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 790e6c27d1..2f449bee2b 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -21,6 +21,7 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Library; namespace Emby.Server.Implementations.LiveTv.EmbyTV { @@ -64,6 +65,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { return "mkv"; } + if (string.Equals(format, "ts", StringComparison.OrdinalIgnoreCase)) + { + return "ts"; + } return "mp4"; } @@ -90,7 +95,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV return Path.ChangeExtension(targetFile, "." + extension); } - public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) + public async Task Record(IDirectStreamProvider directStreamProvider, MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) { //var durationToken = new CancellationTokenSource(duration); //cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; @@ -177,6 +182,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV videoArgs = "-codec:v:0 copy"; } + videoArgs += " -fflags +genpts"; + var durationParam = " -t " + _mediaEncoder.GetTimeParameter(duration.Ticks); var flags = new List(); @@ -188,6 +195,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { flags.Add("+ignidx"); } + if (mediaSource.GenPtsInput) + { + flags.Add("+genpts"); + } var inputModifiers = "-async 1 -vsync -1"; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs index 3b5e60c4a7..e639a312c0 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs @@ -1,6 +1,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; namespace Emby.Server.Implementations.LiveTv.EmbyTV @@ -10,13 +11,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV /// /// Records the specified media source. /// - /// The media source. - /// The target file. - /// The duration. - /// The on started. - /// The cancellation token. - /// Task. - Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken); + Task Record(IDirectStreamProvider directStreamProvider, MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken); string GetOutputPath(MediaSourceInfo mediaSource, string targetFile); } -- cgit v1.2.3 From 7446d2803d26fa4cb4ef86f1b3014c837f08f66d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 15 May 2017 15:47:16 -0400 Subject: update recording --- .../LiveTv/EmbyTV/EmbyTV.cs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index f1b3f41b42..7f1a9ba6d1 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1517,7 +1517,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV EnforceKeepUpTo(timer, seriesPath); }; - await recorder.Record(mediaStreamInfo, recordPath, duration, onStarted, cancellationToken).ConfigureAwait(false); + await recorder.Record(liveStreamInfo.Item1 as IDirectStreamProvider, mediaStreamInfo, recordPath, duration, onStarted, cancellationToken).ConfigureAwait(false); recordingStatus = RecordingStatus.Completed; _logger.Info("Recording completed: {0}", recordPath); @@ -1759,17 +1759,27 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { var config = GetConfiguration(); - if (config.EnableRecordingEncoding) - { - var regInfo = await _liveTvManager.GetRegistrationInfo("embytvrecordingconversion").ConfigureAwait(false); + var regInfo = await _liveTvManager.GetRegistrationInfo("embytvrecordingconversion").ConfigureAwait(false); - if (regInfo.IsValid) + if (regInfo.IsValid) + { + if (config.EnableRecordingEncoding) { return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, config, _httpClient, _processFactory, _config); } + + return new DirectRecorder(_logger, _httpClient, _fileSystem); + + //var options = new LiveTvOptions + //{ + // EnableOriginalAudioWithEncodedRecordings = true, + // RecordedVideoCodec = "copy", + // RecordingEncodingFormat = "ts" + //}; + //return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, options, _httpClient, _processFactory, _config); } - return new DirectRecorder(_logger, _httpClient, _fileSystem); + throw new InvalidOperationException("Emby DVR Requires an active Emby Premiere subscription."); } private async void OnSuccessfulRecording(TimerInfo timer, string path) -- cgit v1.2.3 From 077a2dc12dba122f56c3c9cc5015dfb63a2fb800 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 15 May 2017 17:14:51 -0400 Subject: update a/r calculation --- Emby.Server.Implementations/Dto/DtoService.cs | 28 ++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index d784bcb09b..0b66a8e1f0 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -1582,24 +1582,30 @@ namespace Emby.Server.Implementations.Dto ImageSize size; - if (supportedEnhancers.Count == 0) - { - var defaultAspectRatio = item.GetDefaultPrimaryImageAspectRatio(); + var defaultAspectRatio = item.GetDefaultPrimaryImageAspectRatio(); - if (defaultAspectRatio.HasValue) + if (defaultAspectRatio.HasValue) + { + if (supportedEnhancers.Count == 0) { return defaultAspectRatio.Value; } - } - try - { - size = _imageProcessor.GetImageSize(imageInfo); + double dummyWidth = 200; + double dummyHeight = dummyWidth / defaultAspectRatio.Value; + size = new ImageSize(dummyWidth, dummyHeight); } - catch + else { - //_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); - return null; + try + { + size = _imageProcessor.GetImageSize(imageInfo); + } + catch + { + //_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); + return null; + } } foreach (var enhancer in supportedEnhancers) -- cgit v1.2.3 From 6d50748b97584ec110fba99443b14bd691fced55 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 16 May 2017 02:42:33 -0400 Subject: update recordings --- .../TunerHosts/HdHomerun/HdHomerunHttpStream.cs | 2 +- .../TunerHosts/HdHomerun/HdHomerunUdpStream.cs | 2 +- .../LiveTv/TunerHosts/MulticastStream.cs | 59 +--------------- MediaBrowser.Mono.sln | 78 ++++++++++++---------- 4 files changed, 48 insertions(+), 93 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs index 2798805fa0..739146c664 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs @@ -137,7 +137,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun public Task CopyToAsync(Stream stream, CancellationToken cancellationToken) { - return _multicastStream.CopyToAsync(stream); + return _multicastStream.CopyToAsync(stream , cancellationToken); } } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index e1572ea3ff..1732b0d219 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -164,7 +164,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun public Task CopyToAsync(Stream stream, CancellationToken cancellationToken) { - return _multicastStream.CopyToAsync(stream); + return _multicastStream.CopyToAsync(stream, cancellationToken); } } diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs index 02ebbcf16d..e650086d34 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs @@ -15,7 +15,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts { private readonly ConcurrentDictionary _outputStreams = new ConcurrentDictionary(); private const int BufferSize = 81920; - private CancellationToken _cancellationToken; private readonly ILogger _logger; public MulticastStream(ILogger logger) @@ -25,8 +24,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public async Task CopyUntilCancelled(Stream source, Action onStarted, CancellationToken cancellationToken) { - _cancellationToken = cancellationToken; - byte[] buffer = new byte[BufferSize]; if (source == null) @@ -72,59 +69,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts } } - private static int RtpHeaderBytes = 12; - public async Task CopyUntilCancelled(ISocket udpClient, Action onStarted, CancellationToken cancellationToken) - { - _cancellationToken = cancellationToken; - - while (!cancellationToken.IsCancellationRequested) - { - var receiveToken = cancellationToken; - - // On the first connection attempt, put a timeout to avoid being stuck indefinitely in the event of failure - if (onStarted != null) - { - receiveToken = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(5000).Token, cancellationToken).Token; - } - - var data = await udpClient.ReceiveAsync(receiveToken).ConfigureAwait(false); - var bytesRead = data.ReceivedBytes - RtpHeaderBytes; - - if (bytesRead > 0) - { - var allStreams = _outputStreams.ToList(); - - if (allStreams.Count == 1) - { - await allStreams[0].Value.WriteAsync(data.Buffer, 0, bytesRead).ConfigureAwait(false); - } - else - { - byte[] copy = new byte[bytesRead]; - Buffer.BlockCopy(data.Buffer, RtpHeaderBytes, copy, 0, bytesRead); - - foreach (var stream in allStreams) - { - stream.Value.Queue(copy, 0, copy.Length); - } - } - - if (onStarted != null) - { - var onStartedCopy = onStarted; - onStarted = null; - Task.Run(onStartedCopy); - } - } - - else - { - await Task.Delay(100).ConfigureAwait(false); - } - } - } - - public Task CopyToAsync(Stream stream) + public Task CopyToAsync(Stream stream, CancellationToken cancellationToken) { var result = new QueueStream(stream, _logger) { @@ -133,7 +78,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts _outputStreams.TryAdd(result.Id, result); - result.Start(_cancellationToken); + result.Start(cancellationToken); return result.TaskCompletion.Task; } diff --git a/MediaBrowser.Mono.sln b/MediaBrowser.Mono.sln index 2bae1ab00f..1b303a3315 100644 --- a/MediaBrowser.Mono.sln +++ b/MediaBrowser.Mono.sln @@ -77,9 +77,10 @@ Global {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.ActiveCfg = Debug|Any CPU {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.Build.0 = Debug|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|x86.ActiveCfg = Release|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|x86.Build.0 = Release|Any CPU {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.ActiveCfg = Release|Any CPU {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.Build.0 = Release|Any CPU {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.ActiveCfg = Release|Any CPU @@ -91,9 +92,10 @@ Global {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.ActiveCfg = Debug|Any CPU {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.Build.0 = Debug|Any CPU - {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|x86.ActiveCfg = Release|Any CPU + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|x86.Build.0 = Release|Any CPU {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.Build.0 = Release|Any CPU {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.ActiveCfg = Release|Any CPU @@ -105,9 +107,10 @@ Global {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|x86.ActiveCfg = Debug|Any CPU {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|x86.Build.0 = Debug|Any CPU - {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|x86.ActiveCfg = Release|Any CPU + {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|x86.Build.0 = Release|Any CPU {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.Build.0 = Release|Any CPU {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.ActiveCfg = Release|Any CPU @@ -119,9 +122,10 @@ Global {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.ActiveCfg = Debug|Any CPU {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.Build.0 = Debug|Any CPU - {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|x86.ActiveCfg = Release|Any CPU + {2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|x86.Build.0 = Release|Any CPU {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.Build.0 = Release|Any CPU {2E781478-814D-4A48-9D80-BFF206441A65}.Release|x86.ActiveCfg = Release|Any CPU @@ -133,9 +137,10 @@ Global {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|x86.ActiveCfg = Debug|Any CPU {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|x86.Build.0 = Debug|Any CPU - {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|x86.ActiveCfg = Release|Any CPU + {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|x86.Build.0 = Release|Any CPU {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.ActiveCfg = Release|Any CPU {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.Build.0 = Release|Any CPU {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.ActiveCfg = Release|Any CPU @@ -147,9 +152,10 @@ Global {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|x86.ActiveCfg = Debug|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|x86.Build.0 = Debug|Any CPU - {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|x86.ActiveCfg = Release|Any CPU + {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|x86.Build.0 = Release|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.ActiveCfg = Release|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.Build.0 = Release|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.ActiveCfg = Release|Any CPU @@ -158,26 +164,29 @@ Global {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|Any CPU.Build.0 = Release|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|x86.ActiveCfg = Release|Any CPU {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Signed|x86.Build.0 = Release|Any CPU - {175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.ActiveCfg = Debug|x86 - {175A9388-F352-4586-A6B4-070DED62B644}.Debug|x86.ActiveCfg = Debug|x86 - {175A9388-F352-4586-A6B4-070DED62B644}.Debug|x86.Build.0 = Debug|x86 - {175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.Build.0 = Debug|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Debug|x86.ActiveCfg = Debug|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Debug|x86.Build.0 = Debug|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|x86.ActiveCfg = Release|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|x86.Build.0 = Release|Any CPU {175A9388-F352-4586-A6B4-070DED62B644}.Release|Any CPU.ActiveCfg = Release|Any CPU {175A9388-F352-4586-A6B4-070DED62B644}.Release|Any CPU.Build.0 = Release|Any CPU - {175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.ActiveCfg = Release|x86 - {175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.Build.0 = Release|x86 + {175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.ActiveCfg = Release|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.Build.0 = Release|Any CPU {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Any CPU.ActiveCfg = Debug|Any CPU {175A9388-F352-4586-A6B4-070DED62B644}.Signed|Any CPU.Build.0 = Debug|Any CPU - {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x86.ActiveCfg = Release Mono|x86 - {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x86.Build.0 = Release Mono|x86 + {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x86.ActiveCfg = Debug|Any CPU + {175A9388-F352-4586-A6B4-070DED62B644}.Signed|x86.Build.0 = Debug|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x86.ActiveCfg = Debug|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x86.Build.0 = Debug|Any CPU - {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|x86.ActiveCfg = Release|Any CPU + {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|x86.Build.0 = Release|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.ActiveCfg = Release|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.Build.0 = Release|Any CPU {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x86.ActiveCfg = Release|Any CPU @@ -189,9 +198,10 @@ Global {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|x86.ActiveCfg = Debug|Any CPU {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|x86.Build.0 = Debug|Any CPU - {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Any CPU.ActiveCfg = Release Mono|Any CPU - {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Any CPU.Build.0 = Release Mono|Any CPU - {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Any CPU.Build.0 = Release|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|x86.ActiveCfg = Release|Any CPU + {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|x86.Build.0 = Release|Any CPU {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.Build.0 = Release|Any CPU {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x86.ActiveCfg = Release|Any CPU -- cgit v1.2.3 From 9cd2d793be694d680aceae3e045b9cda9af89e69 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 May 2017 14:18:18 -0400 Subject: update image encoding --- Emby.Drawing.ImageMagick/ImageMagickEncoder.cs | 18 +++-- Emby.Drawing.Skia/SkiaEncoder.cs | 39 +++++++--- Emby.Drawing/ImageProcessor.cs | 84 +++++++++++++++++----- Emby.Drawing/NullImageEncoder.cs | 2 +- .../LiveTv/Listings/SchedulesDirect.cs | 8 ++- MediaBrowser.Controller/Drawing/IImageEncoder.cs | 2 +- MediaBrowser.Controller/Drawing/IImageProcessor.cs | 2 + MediaBrowser.Controller/Drawing/ImageHelper.cs | 10 ++- .../MediaEncoding/EncodingHelper.cs | 16 ++++- 9 files changed, 139 insertions(+), 42 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs index 13bde3ca5d..4c911cc7a3 100644 --- a/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs @@ -130,7 +130,7 @@ namespace Emby.Drawing.ImageMagick string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase); } - public void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { // Even if the caller specified 100, don't use it because it takes forever quality = Math.Min(quality, 99); @@ -144,9 +144,13 @@ namespace Emby.Drawing.ImageMagick originalImage.CurrentImage.TrimImage(10); } - if (options.CropWhiteSpace || !originalImageSize.HasValue) + var originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height); + ImageHelper.SaveImageSize(inputPath, dateModified, originalImageSize); + + if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize)) { - originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height); + // Just spit out the original file if all the options are default + return inputPath; } var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize); @@ -174,10 +178,8 @@ namespace Emby.Drawing.ImageMagick { using (var originalImage = new MagickWand(inputPath)) { - if (options.CropWhiteSpace || !originalImageSize.HasValue) - { - originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height); - } + var originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height); + ImageHelper.SaveImageSize(inputPath, dateModified, originalImageSize); var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize); @@ -205,6 +207,8 @@ namespace Emby.Drawing.ImageMagick } } } + + return outputPath; } private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options) diff --git a/Emby.Drawing.Skia/SkiaEncoder.cs b/Emby.Drawing.Skia/SkiaEncoder.cs index 018de5bc96..d742799524 100644 --- a/Emby.Drawing.Skia/SkiaEncoder.cs +++ b/Emby.Drawing.Skia/SkiaEncoder.cs @@ -191,18 +191,18 @@ namespace Emby.Drawing.Skia } private string[] TransparentImageTypes = new string[] { ".png", ".gif", ".webp" }; - private SKBitmap Decode(string path) + private SKBitmap Decode(string path, bool forceCleanBitmap = false) { var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); - if (requiresTransparencyHack) + if (requiresTransparencyHack || forceCleanBitmap) { using (var stream = new SKFileStream(path)) { var codec = SKCodec.Create(stream); // create the bitmap - var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height); + var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack); // decode codec.GetPixels(bitmap.Info, bitmap.GetPixels()); @@ -210,7 +210,18 @@ namespace Emby.Drawing.Skia } } - return SKBitmap.Decode(path); + var resultBitmap = SKBitmap.Decode(path); + + // If we have to resize these they often end up distorted + if (resultBitmap.ColorType == SKColorType.Gray8) + { + using (resultBitmap) + { + return Decode(path, true); + } + } + + return resultBitmap; } private SKBitmap GetBitmap(string path, bool cropWhitespace) @@ -226,7 +237,7 @@ namespace Emby.Drawing.Skia return Decode(path); } - public void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { if (string.IsNullOrWhiteSpace(inputPath)) { @@ -246,9 +257,20 @@ namespace Emby.Drawing.Skia using (var bitmap = GetBitmap(inputPath, options.CropWhiteSpace)) { - if (options.CropWhiteSpace || !originalImageSize.HasValue) + if (bitmap == null) + { + throw new Exception(string.Format("Skia unable to read image {0}", inputPath)); + } + + //_logger.Info("Color type {0}", bitmap.Info.ColorType); + + var originalImageSize = new ImageSize(bitmap.Width, bitmap.Height); + ImageHelper.SaveImageSize(inputPath, dateModified, originalImageSize); + + if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize)) { - originalImageSize = new ImageSize(bitmap.Width, bitmap.Height); + // Just spit out the original file if all the options are default + return inputPath; } var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize); @@ -269,7 +291,7 @@ namespace Emby.Drawing.Skia using (var outputStream = new SKFileWStream(outputPath)) { resizedBitmap.Encode(outputStream, skiaOutputFormat, quality); - return; + return outputPath; } } @@ -326,6 +348,7 @@ namespace Emby.Drawing.Skia } } } + return outputPath; } public void CreateImageCollage(ImageCollageOptions options) diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 3fa6f64503..89bc96be5f 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -75,6 +75,7 @@ namespace Emby.Drawing ImageEnhancers = new List(); _saveImageSizeTimer = timerFactory.Create(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite); + ImageHelper.ImageProcessor = this; Dictionary sizeDictionary; @@ -212,19 +213,12 @@ namespace Emby.Drawing return new Tuple(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); } - ImageSize? originalImageSize = null; - try - { - originalImageSize = GetImageSize(originalImagePath, dateModified, true); - if (options.HasDefaultOptions(originalImagePath, originalImageSize.Value)) - { - // Just spit out the original file if all the options are default - return new Tuple(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); - } - } - catch + ImageSize? originalImageSize = GetSavedImageSize(originalImagePath, dateModified); + if (originalImageSize.HasValue && options.HasDefaultOptions(originalImagePath, originalImageSize.Value)) { - originalImageSize = null; + // Just spit out the original file if all the options are default + _logger.Info("Returning original image {0}", originalImagePath); + return new Tuple(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); } var newSize = ImageHelper.GetNewImageSize(options, originalImageSize); @@ -243,7 +237,13 @@ namespace Emby.Drawing var tmpPath = Path.ChangeExtension(Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N")), Path.GetExtension(cacheFilePath)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(tmpPath)); - _imageEncoder.EncodeImage(originalImagePath, originalImageSize, tmpPath, AutoOrient(options.Item), quality, options, outputFormat); + var resultPath =_imageEncoder.EncodeImage(originalImagePath, dateModified, tmpPath, AutoOrient(options.Item), quality, options, outputFormat); + + if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase)) + { + return new Tuple(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); + } + CopyFile(tmpPath, cacheFilePath); return new Tuple(tmpPath, GetMimeType(outputFormat, cacheFilePath), _fileSystem.GetLastWriteTimeUtc(tmpPath)); @@ -422,24 +422,70 @@ namespace Emby.Drawing throw new ArgumentNullException("path"); } - var name = path + "datemodified=" + imageDateModified.Ticks; - ImageSize size; - var cacheHash = name.GetMD5(); + var cacheHash = GetImageSizeKey(path, imageDateModified); if (!_cachedImagedSizes.TryGetValue(cacheHash, out size)) { size = GetImageSizeInternal(path, allowSlowMethod); - if (size.Width > 0 && size.Height > 0) + SaveImageSize(size, cacheHash, false); + } + + return size; + } + + public void SaveImageSize(string path, DateTime imageDateModified, ImageSize size) + { + var cacheHash = GetImageSizeKey(path, imageDateModified); + SaveImageSize(size, cacheHash, true); + } + + private void SaveImageSize(ImageSize size, Guid cacheHash, bool checkExists) + { + if (size.Width <= 0 || size.Height <= 0) + { + return; + } + + if (checkExists && _cachedImagedSizes.ContainsKey(cacheHash)) + { + return; + } + + if (checkExists) + { + if (_cachedImagedSizes.TryAdd(cacheHash, size)) { StartSaveImageSizeTimer(); - _cachedImagedSizes.AddOrUpdate(cacheHash, size, (keyName, oldValue) => size); } } + else + { + StartSaveImageSizeTimer(); + _cachedImagedSizes.AddOrUpdate(cacheHash, size, (keyName, oldValue) => size); + } + } - return size; + private Guid GetImageSizeKey(string path, DateTime imageDateModified) + { + var name = path + "datemodified=" + imageDateModified.Ticks; + return name.GetMD5(); + } + + public ImageSize? GetSavedImageSize(string path, DateTime imageDateModified) + { + ImageSize size; + + var cacheHash = GetImageSizeKey(path, imageDateModified); + + if (_cachedImagedSizes.TryGetValue(cacheHash, out size)) + { + return size; + } + + return null; } /// diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs index 1723e0637b..2241c5a868 100644 --- a/Emby.Drawing/NullImageEncoder.cs +++ b/Emby.Drawing/NullImageEncoder.cs @@ -32,7 +32,7 @@ namespace Emby.Drawing throw new NotImplementedException(); } - public void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) + public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { throw new NotImplementedException(); } diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index a36cb124db..da6759b34d 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -167,10 +167,12 @@ namespace Emby.Server.Implementations.LiveTv.Listings { var programEntry = programDict[schedule.programID]; - var data = images[imageIndex].data ?? new List(); - data = data.OrderByDescending(GetSizeOrder).ToList(); + var allImages = (images[imageIndex].data ?? new List()).OrderByDescending(GetSizeOrder).ToList(); + var imagesWithText = allImages.Where(i => string.Equals(i.text, "yes", StringComparison.OrdinalIgnoreCase)).ToList(); + + programEntry.primaryImage = GetProgramImage(ApiUrl, imagesWithText, "Logo", true, 600) ?? + GetProgramImage(ApiUrl, allImages, "Logo", true, 600); - programEntry.primaryImage = GetProgramImage(ApiUrl, data, "Logo", true, 600); //programEntry.thumbImage = GetProgramImage(ApiUrl, data, "Iconic", false); //programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ?? // GetProgramImage(ApiUrl, data, "Banner-L1", false) ?? diff --git a/MediaBrowser.Controller/Drawing/IImageEncoder.cs b/MediaBrowser.Controller/Drawing/IImageEncoder.cs index 64d997dba0..9b895587f3 100644 --- a/MediaBrowser.Controller/Drawing/IImageEncoder.cs +++ b/MediaBrowser.Controller/Drawing/IImageEncoder.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Controller.Drawing /// /// Encodes the image. /// - void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat outputFormat); + string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat outputFormat); /// /// Creates the image collage. diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index a107c12328..7d84719ab8 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -114,5 +114,7 @@ namespace MediaBrowser.Controller.Drawing bool SupportsImageCollageCreation { get; } IImageEncoder ImageEncoder { get; set; } + + void SaveImageSize(string path, DateTime imageDateModified, ImageSize size); } } diff --git a/MediaBrowser.Controller/Drawing/ImageHelper.cs b/MediaBrowser.Controller/Drawing/ImageHelper.cs index 30c4e90fb0..54f2ff987a 100644 --- a/MediaBrowser.Controller/Drawing/ImageHelper.cs +++ b/MediaBrowser.Controller/Drawing/ImageHelper.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Entities; +using System; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; @@ -18,6 +19,13 @@ namespace MediaBrowser.Controller.Drawing return GetSizeEstimate(options); } + public static IImageProcessor ImageProcessor { get; set; } + + public static void SaveImageSize(string path, DateTime dateModified, ImageSize size) + { + ImageProcessor.SaveImageSize(path, dateModified, size); + } + private static ImageSize GetSizeEstimate(ImageProcessingOptions options) { if (options.Width.HasValue && options.Height.HasValue) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 29d37f99b8..67ba633b7d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -968,7 +968,7 @@ namespace MediaBrowser.Controller.MediaEncoding { if (bitrate.HasValue && videoStream.BitRate.HasValue) { - bitrate = Math.Min(bitrate.Value, videoStream.BitRate.Value); + bitrate = GetMinBitrate(bitrate.Value, videoStream.BitRate.Value); } } } @@ -981,13 +981,25 @@ namespace MediaBrowser.Controller.MediaEncoding // If a max bitrate was requested, don't let the scaled bitrate exceed it if (request.VideoBitRate.HasValue) { - bitrate = Math.Min(bitrate.Value, request.VideoBitRate.Value); + bitrate = GetMinBitrate(bitrate.Value, request.VideoBitRate.Value); } } return bitrate; } + private int GetMinBitrate(int sourceBitrate, int requestedBitrate) + { + if (sourceBitrate <= 2000000) + { + sourceBitrate *= 2; + } + + var bitrate = Math.Min(sourceBitrate, requestedBitrate); + + return bitrate; + } + public int? GetAudioBitrateParam(BaseEncodingJobOptions request, MediaStream audioStream) { if (request.AudioBitRate.HasValue) -- cgit v1.2.3 From 47fc7c6aeeb6d4304a03d1ec83489f9702feea51 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 May 2017 17:05:47 -0400 Subject: add GenreItems property --- Emby.Drawing.Skia/SkiaEncoder.cs | 5 ++ .../Data/SqliteItemRepository.cs | 7 +- Emby.Server.Implementations/Dto/DtoService.cs | 67 ++++++++--------- .../Library/LibraryManager.cs | 33 ++++++++- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 85 ++++++++++------------ MediaBrowser.Api/Playback/UniversalAudioService.cs | 62 ++++++++++++++-- MediaBrowser.Controller/Library/ILibraryManager.cs | 8 ++ MediaBrowser.Model/Dto/BaseItemDto.cs | 4 +- MediaBrowser.Model/Dto/StudioDto.cs | 22 +----- MediaBrowser.Model/Querying/ItemFields.cs | 2 + 10 files changed, 176 insertions(+), 119 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Drawing.Skia/SkiaEncoder.cs b/Emby.Drawing.Skia/SkiaEncoder.cs index d742799524..222ecf733d 100644 --- a/Emby.Drawing.Skia/SkiaEncoder.cs +++ b/Emby.Drawing.Skia/SkiaEncoder.cs @@ -212,6 +212,11 @@ namespace Emby.Drawing.Skia var resultBitmap = SKBitmap.Decode(path); + if (resultBitmap == null) + { + return Decode(path, true); + } + // If we have to resize these they often end up distorted if (resultBitmap.ColorType == SKColorType.Gray8) { diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index e07425c865..51aee444e4 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -241,7 +241,6 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "InheritedTags", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "CleanName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "PresentationUniqueKey", "Text", existingColumnNames); - AddColumn(db, "TypedBaseItems", "SlugName", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "OriginalTitle", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "PrimaryVersionId", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateLastMediaAdded", "DATETIME", existingColumnNames); @@ -573,7 +572,6 @@ namespace Emby.Server.Implementations.Data "InheritedTags", "CleanName", "PresentationUniqueKey", - "SlugName", "OriginalTitle", "PrimaryVersionId", "DateLastMediaAdded", @@ -950,7 +948,6 @@ namespace Emby.Server.Implementations.Data } saveItemStatement.TryBind("@PresentationUniqueKey", item.PresentationUniqueKey); - saveItemStatement.TryBind("@SlugName", item.SlugName); saveItemStatement.TryBind("@OriginalTitle", item.OriginalTitle); var video = item as Video; @@ -3665,10 +3662,10 @@ namespace Emby.Server.Implementations.Data if (!string.IsNullOrWhiteSpace(query.SlugName)) { - whereClauses.Add("SlugName=@SlugName"); + whereClauses.Add("CleanName=@SlugName"); if (statement != null) { - statement.TryBind("@SlugName", query.SlugName); + statement.TryBind("@SlugName", GetCleanValue(query.SlugName)); } } diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 0b66a8e1f0..fe5642f1d3 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -751,45 +751,41 @@ namespace Emby.Server.Implementations.Dto /// Task. private void AttachStudios(BaseItemDto dto, BaseItem item) { - var studios = item.Studios.ToList(); - - dto.Studios = new StudioDto[studios.Count]; - - var dictionary = studios.Distinct(StringComparer.OrdinalIgnoreCase).Select(name => - { - try + dto.Studios = item.Studios + .Where(i => !string.IsNullOrWhiteSpace(i)) + .Select(i => new NameIdPair { - return _libraryManager.GetStudio(name); - } - catch (IOException ex) - { - _logger.ErrorException("Error getting studio {0}", ex, name); - return null; - } - }) - .Where(i => i != null) - .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) - .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase); - - for (var i = 0; i < studios.Count; i++) - { - var studio = studios[i]; + Name = i, + Id = _libraryManager.GetStudioId(i).ToString("N") + }) + .ToArray(); + } - var studioDto = new StudioDto + private void AttachGenreItems(BaseItemDto dto, BaseItem item) + { + dto.GenreItems = item.Genres + .Where(i => !string.IsNullOrWhiteSpace(i)) + .Select(i => new NameIdPair { - Name = studio - }; - - Studio entity; + Name = i, + Id = GetStudioId(i, item) + }) + .ToArray(); + } - if (dictionary.TryGetValue(studio, out entity)) - { - studioDto.Id = entity.Id.ToString("N"); - studioDto.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary); - } + private string GetStudioId(string name, BaseItem owner) + { + if (owner is IHasMusicGenres) + { + return _libraryManager.GetGameGenreId(name).ToString("N"); + } - dto.Studios[i] = studioDto; + if (owner is Game || owner is GameSystem) + { + return _libraryManager.GetGameGenreId(name).ToString("N"); } + + return _libraryManager.GetGenreId(name).ToString("N"); } /// @@ -903,6 +899,11 @@ namespace Emby.Server.Implementations.Dto dto.Genres = item.Genres; } + if (fields.Contains(ItemFields.GenreItems)) + { + AttachGenreItems(dto, item); + } + if (options.EnableImages) { dto.ImageTags = new Dictionary(); diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 3c94f97842..c8151ec864 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -895,6 +895,26 @@ namespace Emby.Server.Implementations.Library return CreateItemByName(Studio.GetPath, name); } + public Guid GetStudioId(string name) + { + return GetItemByNameId(Studio.GetPath, name); + } + + public Guid GetGenreId(string name) + { + return GetItemByNameId(Genre.GetPath, name); + } + + public Guid GetMusicGenreId(string name) + { + return GetItemByNameId(MusicGenre.GetPath, name); + } + + public Guid GetGameGenreId(string name) + { + return GetItemByNameId(GameGenre.GetPath, name); + } + /// /// Gets a Genre /// @@ -974,14 +994,13 @@ namespace Emby.Server.Implementations.Library } } - var path = getPathFn(name); - var forceCaseInsensitiveId = ConfigurationManager.Configuration.EnableNormalizedItemByNameIds; - var id = GetNewItemIdInternal(path, typeof(T), forceCaseInsensitiveId); + var id = GetItemByNameId(getPathFn, name); var item = GetItemById(id) as T; if (item == null) { + var path = getPathFn(name); item = new T { Name = name, @@ -998,6 +1017,14 @@ namespace Emby.Server.Implementations.Library return item; } + private Guid GetItemByNameId(Func getPathFn, string name) + where T : BaseItem, new() + { + var path = getPathFn(name); + var forceCaseInsensitiveId = ConfigurationManager.Configuration.EnableNormalizedItemByNameIds; + return GetNewItemIdInternal(path, typeof(T), forceCaseInsensitiveId); + } + public IEnumerable GetAlbumArtists(IEnumerable items) { var names = items diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index d64c009a07..4003fb4634 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -542,6 +542,12 @@ namespace MediaBrowser.Api.Playback.Hls var queryStringIndex = Request.RawUrl.IndexOf('?'); var queryString = queryStringIndex == -1 ? string.Empty : Request.RawUrl.Substring(queryStringIndex); + // from universal audio service + if (queryString.IndexOf("SegmentContainer", StringComparison.OrdinalIgnoreCase) == -1 && !string.IsNullOrWhiteSpace(state.Request.SegmentContainer)) + { + queryString += "&SegmentContainer=" + state.Request.SegmentContainer; + } + // Main stream var playlistUrl = isLiveStream ? "live.m3u8" : "main.m3u8"; @@ -918,60 +924,43 @@ namespace MediaBrowser.Api.Playback.Hls var startNumberParam = isEncoding ? startNumber.ToString(UsCulture) : "0"; var mapArgs = state.IsOutputVideo ? EncodingHelper.GetMapArgs(state) : string.Empty; - var useGenericSegmenter = true; - if (useGenericSegmenter) + var outputTsArg = Path.Combine(FileSystem.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request); + + var timeDeltaParam = String.Empty; + + if (isEncoding && startNumber > 0) { - var outputTsArg = Path.Combine(FileSystem.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state.Request); + var startTime = state.SegmentLength * startNumber; + timeDeltaParam = string.Format("-segment_time_delta -{0}", startTime); + } - var timeDeltaParam = String.Empty; + var segmentFormat = GetSegmentFileExtension(state.Request).TrimStart('.'); + if (string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase)) + { + segmentFormat = "mpegts"; + } - if (isEncoding && startNumber > 0) - { - var startTime = state.SegmentLength * startNumber; - timeDeltaParam = string.Format("-segment_time_delta -{0}", startTime); - } + var videoCodec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions()); + var breakOnNonKeyFrames = state.EnableBreakOnNonKeyFrames(videoCodec); - var segmentFormat = GetSegmentFileExtension(state.Request).TrimStart('.'); - if (string.Equals(segmentFormat, "ts", StringComparison.OrdinalIgnoreCase)) - { - segmentFormat = "mpegts"; - } + var breakOnNonKeyFramesArg = breakOnNonKeyFrames ? " -break_non_keyframes 1" : ""; - var videoCodec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions()); - var breakOnNonKeyFrames = state.EnableBreakOnNonKeyFrames(videoCodec); - - var breakOnNonKeyFramesArg = breakOnNonKeyFrames ? " -break_non_keyframes 1" : ""; - - return string.Format("{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} {10} -individual_header_trailer 0{12} -segment_format {11} -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"", - inputModifier, - EncodingHelper.GetInputArgument(state, encodingOptions), - threads, - mapArgs, - GetVideoArguments(state), - GetAudioArguments(state), - state.SegmentLength.ToString(UsCulture), - startNumberParam, - outputPath, - outputTsArg, - timeDeltaParam, - segmentFormat, - breakOnNonKeyFramesArg - ).Trim(); - } - - return string.Format("{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {6} -individual_header_trailer 0 -start_number {7} -hls_list_size {8} -y \"{9}\"", - inputModifier, - EncodingHelper.GetInputArgument(state, encodingOptions), - threads, - mapArgs, - GetVideoArguments(state), - GetAudioArguments(state), - state.SegmentLength.ToString(UsCulture), - startNumberParam, - state.HlsListSize.ToString(UsCulture), - outputPath - ).Trim(); + return string.Format("{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} {10} -individual_header_trailer 0{12} -segment_format {11} -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"", + inputModifier, + EncodingHelper.GetInputArgument(state, encodingOptions), + threads, + mapArgs, + GetVideoArguments(state), + GetAudioArguments(state), + state.SegmentLength.ToString(UsCulture), + startNumberParam, + outputPath, + outputTsArg, + timeDeltaParam, + segmentFormat, + breakOnNonKeyFramesArg + ).Trim(); } } } \ No newline at end of file diff --git a/MediaBrowser.Api/Playback/UniversalAudioService.cs b/MediaBrowser.Api/Playback/UniversalAudioService.cs index e50d0f2c54..ae64623df9 100644 --- a/MediaBrowser.Api/Playback/UniversalAudioService.cs +++ b/MediaBrowser.Api/Playback/UniversalAudioService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Threading.Tasks; using MediaBrowser.Api.Playback.Hls; @@ -35,8 +36,6 @@ namespace MediaBrowser.Api.Playback [ApiMember(Name = "DeviceId", Description = "The device id of the client requesting. Used to stop encoding processes when needed.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string DeviceId { get; set; } - public string Token { get; set; } - public string UserId { get; set; } public string AudioCodec { get; set; } public string Container { get; set; } @@ -47,6 +46,10 @@ namespace MediaBrowser.Api.Playback [ApiMember(Name = "StartTimeTicks", Description = "Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public long? StartTimeTicks { get; set; } + + public string TranscodingContainer { get; set; } + public string TranscodingProtocol { get; set; } + public int? MaxAudioSampleRate { get; set; } } [Route("/Audio/{Id}/universal.{Container}", "GET", Summary = "Gets an audio stream")] @@ -125,12 +128,52 @@ namespace MediaBrowser.Api.Playback { Type = DlnaProfileType.Audio, Context = EncodingContext.Streaming, - Container = "ts", - AudioCodec = "aac", - Protocol = "hls" + Container = request.TranscodingContainer, + AudioCodec = request.AudioCodec, + Protocol = request.TranscodingProtocol } }; + var codecProfiles = new List(); + var conditions = new List(); + + if (request.MaxAudioSampleRate.HasValue) + { + // codec profile + conditions.Add(new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + IsRequired = false, + Property = ProfileConditionValue.AudioSampleRate, + Value = request.MaxAudioSampleRate.Value.ToString(CultureInfo.InvariantCulture) + }); + } + + if (request.MaxAudioChannels.HasValue) + { + // codec profile + conditions.Add(new ProfileCondition + { + Condition = ProfileConditionType.LessThanEqual, + IsRequired = false, + Property = ProfileConditionValue.AudioChannels, + Value = request.MaxAudioChannels.Value.ToString(CultureInfo.InvariantCulture) + }); + } + + if (conditions.Count > 0) + { + // codec profile + codecProfiles.Add(new CodecProfile + { + Type = CodecType.Audio, + Container = request.Container, + Conditions = conditions.ToArray() + }); + } + + deviceProfile.CodecProfiles = codecProfiles.ToArray(); + return deviceProfile; } @@ -194,7 +237,9 @@ namespace MediaBrowser.Api.Playback MediaSourceId = mediaSource.Id, PlaySessionId = playbackInfoResult.PlaySessionId, StartTimeTicks = request.StartTimeTicks, - Static = isStatic + Static = isStatic, + SegmentContainer = request.TranscodingContainer, + AudioSampleRate = request.MaxAudioSampleRate }; if (isHeadRequest) @@ -226,7 +271,7 @@ namespace MediaBrowser.Api.Playback var newRequest = new GetAudioStream { AudioBitRate = isStatic ? (int?)null : Convert.ToInt32(Math.Min(request.MaxStreamingBitrate ?? 192000, int.MaxValue)), - //AudioCodec = request.AudioCodec, + AudioCodec = request.AudioCodec, Container = isStatic ? null : ("." + mediaSource.TranscodingContainer), DeviceId = request.DeviceId, Id = request.Id, @@ -234,7 +279,8 @@ namespace MediaBrowser.Api.Playback MediaSourceId = mediaSource.Id, PlaySessionId = playbackInfoResult.PlaySessionId, StartTimeTicks = request.StartTimeTicks, - Static = isStatic + Static = isStatic, + AudioSampleRate = request.MaxAudioSampleRate }; if (isHeadRequest) diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index dd23799407..70a635872a 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -557,6 +557,14 @@ namespace MediaBrowser.Controller.Library /// true if XXXX, false otherwise. bool IgnoreFile(FileSystemMetadata file, BaseItem parent); + Guid GetStudioId(string name); + + Guid GetGenreId(string name); + + Guid GetMusicGenreId(string name); + + Guid GetGameGenreId(string name); + void AddVirtualFolder(string name, string collectionType, LibraryOptions options, bool refreshLibrary); void RemoveVirtualFolder(string name, bool refreshLibrary); void AddMediaPath(string virtualFolderName, MediaPathInfo path); diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 9384446eb2..d446597056 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -346,7 +346,9 @@ namespace MediaBrowser.Model.Dto /// Gets or sets the studios. /// /// The studios. - public StudioDto[] Studios { get; set; } + public NameIdPair[] Studios { get; set; } + + public NameIdPair[] GenreItems { get; set; } /// /// If the item does not have a logo, this will hold the Id of the Parent that has one. diff --git a/MediaBrowser.Model/Dto/StudioDto.cs b/MediaBrowser.Model/Dto/StudioDto.cs index 13623fb1a9..10dc606997 100644 --- a/MediaBrowser.Model/Dto/StudioDto.cs +++ b/MediaBrowser.Model/Dto/StudioDto.cs @@ -1,6 +1,4 @@ -using System.ComponentModel; -using System.Diagnostics; -using MediaBrowser.Model.Serialization; +using System.Diagnostics; namespace MediaBrowser.Model.Dto { @@ -27,23 +25,5 @@ namespace MediaBrowser.Model.Dto /// /// The primary image tag. public string PrimaryImageTag { get; set; } - - /// - /// Gets a value indicating whether this instance has primary image. - /// - /// true if this instance has primary image; otherwise, false. - [IgnoreDataMember] - public bool HasPrimaryImage - { - get - { - return PrimaryImageTag != null; - } - } - - /// - /// Occurs when [property changed]. - /// - public event PropertyChangedEventHandler PropertyChanged; } } \ No newline at end of file diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index ab560875ec..1f2b68b459 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -82,6 +82,8 @@ /// Genres, + GenreItems, + /// /// The home page URL /// -- cgit v1.2.3 From 9459bf7ffc5a7bda7160bf25108b554117cc40c0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 May 2017 17:16:46 -0400 Subject: 3.2.17.6 --- Emby.Server.Implementations/Dto/DtoService.cs | 4 ---- MediaBrowser.Model/Querying/ItemFields.cs | 2 -- SharedVersion.cs | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index fe5642f1d3..ec4f552a60 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -897,10 +897,6 @@ namespace Emby.Server.Implementations.Dto if (fields.Contains(ItemFields.Genres)) { dto.Genres = item.Genres; - } - - if (fields.Contains(ItemFields.GenreItems)) - { AttachGenreItems(dto, item); } diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 1f2b68b459..ab560875ec 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -82,8 +82,6 @@ /// Genres, - GenreItems, - /// /// The home page URL /// diff --git a/SharedVersion.cs b/SharedVersion.cs index 89c95c4239..2d9c474098 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.17.5")] +[assembly: AssemblyVersion("3.2.17.6")] -- cgit v1.2.3 From 8109b83972e354dbc145edf848a4e3c6f8334ac2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 May 2017 12:39:40 -0400 Subject: update hdhr stream --- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 4 +++- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs | 6 +++--- .../LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index d724a9fbc4..5d489985f2 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -421,7 +421,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun SupportsDirectStream = true, SupportsTranscoding = true, IsInfiniteStream = true, - IgnoreDts = true + IgnoreDts = true, + IgnoreIndex = true, + GenPtsInput = true }; mediaSource.InferTotalBitrate(); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs index 739146c664..dd63bbb726 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs @@ -57,9 +57,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; OpenedMediaSource.Protocol = MediaProtocol.Http; - OpenedMediaSource.SupportsDirectPlay = false; - OpenedMediaSource.SupportsDirectStream = true; - OpenedMediaSource.SupportsTranscoding = true; + //OpenedMediaSource.SupportsDirectPlay = false; + //OpenedMediaSource.SupportsDirectStream = true; + //OpenedMediaSource.SupportsTranscoding = true; await taskCompletionSource.Task.ConfigureAwait(false); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index 1732b0d219..c84aebce76 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -70,9 +70,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; OpenedMediaSource.Protocol = MediaProtocol.Http; - OpenedMediaSource.SupportsDirectPlay = false; - OpenedMediaSource.SupportsDirectStream = true; - OpenedMediaSource.SupportsTranscoding = true; + //OpenedMediaSource.SupportsDirectPlay = false; + //OpenedMediaSource.SupportsDirectStream = true; + //OpenedMediaSource.SupportsTranscoding = true; await taskCompletionSource.Task.ConfigureAwait(false); -- cgit v1.2.3 From 799494af0b4c5ff380eeb873ff727ee179c97193 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 May 2017 13:09:37 -0400 Subject: update image methods --- Emby.Drawing/ImageProcessor.cs | 4 ++-- .../Collections/CollectionImageProvider.cs | 2 +- .../Images/BaseDynamicImageProvider.cs | 26 +++++++++++----------- .../Photos/PhotoAlbumImageProvider.cs | 2 +- .../UserViews/CollectionFolderImageProvider.cs | 12 +++++----- .../UserViews/DynamicImageProvider.cs | 4 ++-- MediaBrowser.Controller/Drawing/IImageProcessor.cs | 2 +- 7 files changed, 26 insertions(+), 26 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 89bc96be5f..92382aa47a 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -670,7 +670,7 @@ namespace Emby.Drawing var ehnancedImagePath = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid).ConfigureAwait(false); // If the path changed update dateModified - if (!ehnancedImagePath.Equals(originalImagePath, StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(ehnancedImagePath, originalImagePath, StringComparison.OrdinalIgnoreCase)) { return GetResult(ehnancedImagePath); } @@ -829,7 +829,7 @@ namespace Emby.Drawing return Path.Combine(path, filename); } - public async Task CreateImageCollage(ImageCollageOptions options) + public void CreateImageCollage(ImageCollageOptions options) { _logger.Info("Creating image collage and saving to {0}", options.OutputPath); diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs index b82d4e44e0..aafb13329d 100644 --- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs +++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs @@ -76,7 +76,7 @@ namespace Emby.Server.Implementations.Collections return Task.FromResult(GetFinalItems(items, 2)); } - protected override Task CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected string CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); } diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index b2ec84a82a..19681a8326 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -140,7 +140,7 @@ namespace Emby.Server.Implementations.Images { var outputPathWithoutExtension = Path.Combine(ApplicationPaths.TempDirectory, Guid.NewGuid().ToString("N")); FileSystem.CreateDirectory(FileSystem.GetDirectoryName(outputPathWithoutExtension)); - string outputPath = await CreateImage(item, itemsWithImages, outputPathWithoutExtension, imageType, 0).ConfigureAwait(false); + string outputPath = CreateImage(item, itemsWithImages, outputPathWithoutExtension, imageType, 0); if (string.IsNullOrWhiteSpace(outputPath)) { @@ -161,7 +161,7 @@ namespace Emby.Server.Implementations.Images protected abstract Task> GetItemsWithImages(IHasImages item); - protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath) + protected string CreateThumbCollage(IHasImages primaryItem, List items, string outputPath) { return CreateCollage(primaryItem, items, outputPath, 640, 360); } @@ -188,22 +188,22 @@ namespace Emby.Server.Implementations.Images .Where(i => !string.IsNullOrWhiteSpace(i)); } - protected Task CreatePosterCollage(IHasImages primaryItem, List items, string outputPath) + protected string CreatePosterCollage(IHasImages primaryItem, List items, string outputPath) { return CreateCollage(primaryItem, items, outputPath, 400, 600); } - protected Task CreateSquareCollage(IHasImages primaryItem, List items, string outputPath) + protected string CreateSquareCollage(IHasImages primaryItem, List items, string outputPath) { return CreateCollage(primaryItem, items, outputPath, 600, 600); } - protected Task CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, int width, int height) + protected string CreateThumbCollage(IHasImages primaryItem, List items, string outputPath, int width, int height) { return CreateCollage(primaryItem, items, outputPath, width, height); } - private async Task CreateCollage(IHasImages primaryItem, List items, string outputPath, int width, int height) + private string CreateCollage(IHasImages primaryItem, List items, string outputPath, int width, int height) { FileSystem.CreateDirectory(FileSystem.GetDirectoryName(outputPath)); @@ -225,7 +225,7 @@ namespace Emby.Server.Implementations.Images return null; } - await ImageProcessor.CreateImageCollage(options).ConfigureAwait(false); + ImageProcessor.CreateImageCollage(options); return outputPath; } @@ -234,7 +234,7 @@ namespace Emby.Server.Implementations.Images get { return "Dynamic Image Provider"; } } - protected virtual async Task CreateImage(IHasImages item, + protected virtual string CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, @@ -249,20 +249,20 @@ namespace Emby.Server.Implementations.Images if (imageType == ImageType.Thumb) { - return await CreateThumbCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); + return CreateThumbCollage(item, itemsWithImages, outputPath); } if (imageType == ImageType.Primary) { if (item is UserView) { - return await CreateSquareCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); + return CreateSquareCollage(item, itemsWithImages, outputPath); } if (item is Playlist || item is MusicGenre || item is Genre || item is GameGenre || item is PhotoAlbum) { - return await CreateSquareCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); + return CreateSquareCollage(item, itemsWithImages, outputPath); } - return await CreatePosterCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); + return CreatePosterCollage(item, itemsWithImages, outputPath); } throw new ArgumentException("Unexpected image type"); @@ -346,7 +346,7 @@ namespace Emby.Server.Implementations.Images } } - protected async Task CreateSingleImage(List itemsWithImages, string outputPathWithoutExtension, ImageType imageType) + protected string CreateSingleImage(List itemsWithImages, string outputPathWithoutExtension, ImageType imageType) { var image = itemsWithImages .Where(i => i.HasImage(imageType) && i.GetImageInfo(imageType, 0).IsLocalFile && Path.HasExtension(i.GetImagePath(imageType))) diff --git a/Emby.Server.Implementations/Photos/PhotoAlbumImageProvider.cs b/Emby.Server.Implementations/Photos/PhotoAlbumImageProvider.cs index cc1756f960..c425a761ab 100644 --- a/Emby.Server.Implementations/Photos/PhotoAlbumImageProvider.cs +++ b/Emby.Server.Implementations/Photos/PhotoAlbumImageProvider.cs @@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.Photos return Task.FromResult(items); } - protected override Task CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected string CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); } diff --git a/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs index ab63072386..7d3a118c0e 100644 --- a/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs +++ b/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs @@ -98,7 +98,7 @@ namespace Emby.Server.Implementations.UserViews return item is CollectionFolder; } - protected override async Task CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected override string CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); @@ -109,10 +109,10 @@ namespace Emby.Server.Implementations.UserViews return null; } - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); + return CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540); } - return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); + return base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex); } } @@ -155,7 +155,7 @@ namespace Emby.Server.Implementations.UserViews return item is ManualCollectionsFolder; } - protected override async Task CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected override string CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); @@ -166,10 +166,10 @@ namespace Emby.Server.Implementations.UserViews return null; } - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); + return CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540); } - return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); + return base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex); } } diff --git a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs index b8d03db3d3..b0fb954e26 100644 --- a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -159,7 +159,7 @@ namespace Emby.Server.Implementations.UserViews return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty); } - protected override async Task CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + protected override string CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { if (itemsWithImages.Count == 0) { @@ -168,7 +168,7 @@ namespace Emby.Server.Implementations.UserViews var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); + return CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540); } } } diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index 7d84719ab8..d98638d556 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -105,7 +105,7 @@ namespace MediaBrowser.Controller.Drawing /// Creates the image collage. /// /// The options. - Task CreateImageCollage(ImageCollageOptions options); + void CreateImageCollage(ImageCollageOptions options); /// /// Gets a value indicating whether [supports image collage creation]. -- cgit v1.2.3 From 5137e3abf6f1500e33fc3d9aad3ade2dcb2bc89c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 20 May 2017 12:42:47 -0400 Subject: update live streams --- Emby.Server.Implementations/LiveTv/LiveTvManager.cs | 3 ++- MediaBrowser.Api/Playback/MediaInfoService.cs | 2 +- MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs | 8 +++++++- MediaBrowser.Providers/Manager/ImageSaver.cs | 5 ----- 4 files changed, 10 insertions(+), 8 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index fa86ac36d0..5ba96283bb 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -477,7 +477,8 @@ namespace Emby.Server.Implementations.LiveTv if (!(service is EmbyTV.EmbyTV)) { - // We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says + // We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says + mediaSource.SupportsDirectPlay = false; mediaSource.SupportsDirectStream = false; mediaSource.SupportsTranscoding = true; foreach (var stream in mediaSource.MediaStreams) diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index fcd18bfe47..55fe738e89 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -127,7 +127,7 @@ namespace MediaBrowser.Api.Playback SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate, request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex, - request.SubtitleStreamIndex, request.MaxAudioChannels, request.PlaySessionId, request.UserId, true, true, true, true, true, true); + request.SubtitleStreamIndex, request.MaxAudioChannels, request.PlaySessionId, request.UserId, request.EnableDirectPlay, request.ForceDirectPlayRemoteMediaSource, request.EnableDirectStream, true, true, true); } else { diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs index 913967352f..025f1bc7a6 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -15,9 +15,15 @@ namespace MediaBrowser.Model.MediaInfo public string ItemId { get; set; } public DeviceProfile DeviceProfile { get; set; } + public bool EnableDirectPlay { get; set; } + public bool EnableDirectStream { get; set; } + public bool ForceDirectPlayRemoteMediaSource { get; set; } + public LiveStreamRequest() { - + ForceDirectPlayRemoteMediaSource = true; + EnableDirectPlay = true; + EnableDirectStream = true; } public LiveStreamRequest(AudioOptions options) diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs index 4bd5044094..91c366df5b 100644 --- a/MediaBrowser.Providers/Manager/ImageSaver.cs +++ b/MediaBrowser.Providers/Manager/ImageSaver.cs @@ -226,7 +226,6 @@ namespace MediaBrowser.Providers.Manager return retryPath; } - private SemaphoreSlim _imageSaveSemaphore = new SemaphoreSlim(1, 1); /// /// Saves the image to location. /// @@ -240,8 +239,6 @@ namespace MediaBrowser.Providers.Manager var parentFolder = _fileSystem.GetDirectoryName(path); - await _imageSaveSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - try { _libraryMonitor.ReportFileSystemChangeBeginning(path); @@ -263,8 +260,6 @@ namespace MediaBrowser.Providers.Manager } finally { - _imageSaveSemaphore.Release(); - _libraryMonitor.ReportFileSystemChangeComplete(path, false); _libraryMonitor.ReportFileSystemChangeComplete(parentFolder, false); } -- cgit v1.2.3 From da77b058172e1c7cdeb6dadd6106ea3fdd739544 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 May 2017 03:25:49 -0400 Subject: update data queries --- Emby.Dlna/ContentDirectory/ControlHandler.cs | 22 ++++-- Emby.Drawing/ImageProcessor.cs | 21 +++++- .../Channels/ChannelManager.cs | 4 +- .../Data/SqliteItemRepository.cs | 73 +++++++++++--------- Emby.Server.Implementations/Dto/DtoService.cs | 28 +++++--- .../FileOrganization/EpisodeFileOrganizer.cs | 7 +- .../Library/LibraryManager.cs | 12 ++-- .../Library/LocalTrailerPostScanTask.cs | 7 +- .../Library/MusicManager.cs | 48 +++++++------ .../Library/SearchEngine.cs | 13 +++- .../Library/UserViewManager.cs | 10 +-- .../LiveTv/EmbyTV/EmbyTV.cs | 18 +++-- .../LiveTv/EmbyTV/EncodedRecorder.cs | 17 +++-- .../LiveTv/LiveTvDtoService.cs | 30 ++++++-- .../LiveTv/LiveTvManager.cs | 61 +++++++---------- .../Playlists/PlaylistImageProvider.cs | 7 +- .../Playlists/PlaylistManager.cs | 19 ++++-- .../ScheduledTasks/ChapterImagesTask.cs | 5 +- .../Session/SessionManager.cs | 19 ++++-- .../TV/SeriesPostScanTask.cs | 7 +- Emby.Server.Implementations/TV/TVSeriesManager.cs | 18 ++--- .../UserViews/CollectionFolderImageProvider.cs | 7 +- .../UserViews/DynamicImageProvider.cs | 9 ++- MediaBrowser.Api/BaseApiService.cs | 10 --- MediaBrowser.Api/GamesService.cs | 18 ++++- MediaBrowser.Api/Images/ImageService.cs | 2 + MediaBrowser.Api/Library/LibraryService.cs | 24 +++++-- MediaBrowser.Api/LiveTv/LiveTvService.cs | 5 +- MediaBrowser.Api/Movies/MoviesService.cs | 18 +++-- MediaBrowser.Api/Music/InstantMixService.cs | 52 ++++++++------ MediaBrowser.Api/TvShowsService.cs | 18 ++--- .../UserLibrary/BaseItemsByNameService.cs | 3 +- MediaBrowser.Api/UserLibrary/ItemsService.cs | 8 +-- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 10 +-- .../Drawing/ImageProcessingOptions.cs | 2 + MediaBrowser.Controller/Dto/DtoOptions.cs | 21 ++++-- .../Entities/Audio/MusicArtist.cs | 14 ---- .../Entities/Audio/MusicGenre.cs | 10 --- MediaBrowser.Controller/Entities/BaseItem.cs | 79 +++++++++++++++++----- MediaBrowser.Controller/Entities/Folder.cs | 26 +++++-- MediaBrowser.Controller/Entities/GameGenre.cs | 10 --- MediaBrowser.Controller/Entities/Genre.cs | 10 --- MediaBrowser.Controller/Entities/IItemByName.cs | 7 -- .../Entities/InternalItemsQuery.cs | 33 +++++---- MediaBrowser.Controller/Entities/Person.cs | 16 ----- MediaBrowser.Controller/Entities/Studio.cs | 10 --- MediaBrowser.Controller/Entities/TV/Season.cs | 19 +++--- MediaBrowser.Controller/Entities/TV/Series.cs | 28 +++++--- MediaBrowser.Controller/Entities/UserView.cs | 8 ++- .../Entities/UserViewBuilder.cs | 11 +-- MediaBrowser.Controller/Entities/Year.cs | 20 ------ MediaBrowser.Controller/Library/IMusicManager.cs | 18 ++--- .../Library/IUserViewManager.cs | 3 +- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 11 +-- MediaBrowser.Controller/Playlists/Playlist.cs | 24 ++++--- MediaBrowser.Controller/TV/ITVSeriesManager.cs | 10 +-- MediaBrowser.Model/Querying/ItemFields.cs | 11 ++- MediaBrowser.Providers/Manager/ProviderManager.cs | 7 +- .../MediaInfo/SubtitleScheduledTask.cs | 4 +- .../People/TvdbPersonImageProvider.cs | 7 +- .../TV/TheTVDB/TvdbPrescanTask.cs | 13 +++- MediaBrowser.XbmcMetadata/EntryPoint.cs | 4 +- 62 files changed, 620 insertions(+), 446 deletions(-) (limited to 'Emby.Server.Implementations') diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 2251a8f58c..a5229c4faa 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -23,6 +23,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Globalization; @@ -459,10 +460,16 @@ namespace Emby.Dlna.ContentDirectory IsMissing = false, ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name }, IsFolder = isFolder, - MediaTypes = mediaTypes.ToArray() + MediaTypes = mediaTypes.ToArray(), + DtoOptions = GetDtoOptions() }); } + private DtoOptions GetDtoOptions() + { + return new DtoOptions(true); + } + private async Task> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit) { if (item is MusicGenre) @@ -513,7 +520,8 @@ namespace Emby.Dlna.ContentDirectory IsMissing = false, PresetViews = new[] {CollectionType.Movies, CollectionType.TvShows, CollectionType.Music}, ExcludeItemTypes = new[] {typeof (Game).Name, typeof (Book).Name}, - IsPlaceHolder = false + IsPlaceHolder = false, + DtoOptions = GetDtoOptions() }; SetSorting(query, sort, folder.IsPreSorted); @@ -532,7 +540,8 @@ namespace Emby.Dlna.ContentDirectory ArtistIds = new[] { item.Id.ToString("N") }, IncludeItemTypes = new[] { typeof(MusicAlbum).Name }, Limit = limit, - StartIndex = startIndex + StartIndex = startIndex, + DtoOptions = GetDtoOptions() }; SetSorting(query, sort, false); @@ -551,7 +560,8 @@ namespace Emby.Dlna.ContentDirectory GenreIds = new[] {item.Id.ToString("N")}, IncludeItemTypes = new[] {typeof (MusicAlbum).Name}, Limit = limit, - StartIndex = startIndex + StartIndex = startIndex, + DtoOptions = GetDtoOptions() }; SetSorting(query, sort, false); @@ -595,8 +605,8 @@ namespace Emby.Dlna.ContentDirectory IncludeItemTypes = new[] { typeof(Movie).Name, typeof(Series).Name, typeof(Trailer).Name }, SortBy = new[] { ItemSortBy.SortName }, Limit = limit, - StartIndex = startIndex - + StartIndex = startIndex, + DtoOptions = GetDtoOptions() }); var serverItems = itemsResult.Items.Select(i => new ServerItem(i)) diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 92382aa47a..d5a3b73c27 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -179,10 +179,15 @@ namespace Emby.Drawing } var originalImage = options.Image; + IHasImages item = options.Item; if (!originalImage.IsLocalFile) { - originalImage = await _libraryManager().ConvertImageToLocal(options.Item, originalImage, options.ImageIndex).ConfigureAwait(false); + if (item == null) + { + item = _libraryManager().GetItemById(options.ItemId); + } + originalImage = await _libraryManager().ConvertImageToLocal(item, originalImage, options.ImageIndex).ConfigureAwait(false); } var originalImagePath = originalImage.Path; @@ -195,13 +200,18 @@ namespace Emby.Drawing if (options.Enhancers.Count > 0) { + if (item == null) + { + item = _libraryManager().GetItemById(options.ItemId); + } + var tuple = await GetEnhancedImage(new ItemImageInfo { DateModified = dateModified, Type = originalImage.Type, Path = originalImagePath - }, options.Item, options.ImageIndex, options.Enhancers).ConfigureAwait(false); + }, item, options.ImageIndex, options.Enhancers).ConfigureAwait(false); originalImagePath = tuple.Item1; dateModified = tuple.Item2; @@ -237,7 +247,12 @@ namespace Emby.Drawing var tmpPath = Path.ChangeExtension(Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N")), Path.GetExtension(cacheFilePath)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(tmpPath)); - var resultPath =_imageEncoder.EncodeImage(originalImagePath, dateModified, tmpPath, AutoOrient(options.Item), quality, options, outputFormat); + if (item == null && string.Equals(options.ItemType, typeof(Photo).Name, StringComparison.OrdinalIgnoreCase)) + { + item = _libraryManager().GetItemById(options.ItemId); + } + + var resultPath =_imageEncoder.EncodeImage(originalImagePath, dateModified, tmpPath, AutoOrient(item), quality, options, outputFormat); if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase)) { diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 0cdd934b7a..067260dfd9 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -460,12 +460,12 @@ namespace Emby.Server.Implementations.Channels public IEnumerable GetAllChannelFeatures() { - return _libraryManager.GetItemList(new InternalItemsQuery + return _libraryManager.GetItemIds(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Channel).Name }, SortBy = new[] { ItemSortBy.SortName } - }).Select(i => GetChannelFeatures(i.Id.ToString("N"))); + }).Select(i => GetChannelFeatures(i.ToString("N"))); } public ChannelFeatures GetChannelFeatures(string id) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 51aee444e4..49bf9e39c5 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -207,8 +207,6 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "TypedBaseItems", "DateCreated", "DATETIME", existingColumnNames); AddColumn(db, "TypedBaseItems", "DateModified", "DATETIME", existingColumnNames); - AddColumn(db, "TypedBaseItems", "ForcedSortName", "Text", existingColumnNames); - AddColumn(db, "TypedBaseItems", "IsSeries", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsLive", "BIT", existingColumnNames); AddColumn(db, "TypedBaseItems", "IsNews", "BIT", existingColumnNames); @@ -426,7 +424,7 @@ namespace Emby.Server.Implementations.Data "OfficialRating", "HomePageUrl", "DisplayMediaType", - "ForcedSortName", + "SortName", "RunTimeTicks", "VoteCount", "DateCreated", @@ -549,7 +547,6 @@ namespace Emby.Server.Implementations.Data "DisplayMediaType", "DateCreated", "DateModified", - "ForcedSortName", "PreferredMetadataLanguage", "PreferredMetadataCountryCode", "IsHD", @@ -826,8 +823,6 @@ namespace Emby.Server.Implementations.Data saveItemStatement.TryBind("@DateCreated", item.DateCreated); saveItemStatement.TryBind("@DateModified", item.DateModified); - saveItemStatement.TryBind("@ForcedSortName", item.ForcedSortName); - saveItemStatement.TryBind("@PreferredMetadataLanguage", item.PreferredMetadataLanguage); saveItemStatement.TryBind("@PreferredMetadataCountryCode", item.PreferredMetadataCountryCode); saveItemStatement.TryBind("@IsHD", item.IsHD); @@ -1237,7 +1232,7 @@ namespace Emby.Server.Implementations.Data foreach (var row in statement.ExecuteQuery()) { - return GetItem(row); + return GetItem(row, new InternalItemsQuery()); } } @@ -1246,11 +1241,6 @@ namespace Emby.Server.Implementations.Data } } - private BaseItem GetItem(IReadOnlyList reader) - { - return GetItem(reader, new InternalItemsQuery()); - } - private bool TypeRequiresDeserialization(Type type) { if (_config.Configuration.SkipDeserializationForBasicTypes) @@ -1535,11 +1525,14 @@ namespace Emby.Server.Implementations.Data } index++; - if (!reader.IsDBNull(index)) + if (query.HasField(ItemFields.ExternalEtag)) { - item.ExternalEtag = reader.GetString(index); + if (!reader.IsDBNull(index)) + { + item.ExternalEtag = reader.GetString(index); + } + index++; } - index++; if (!reader.IsDBNull(index)) { @@ -1614,7 +1607,7 @@ namespace Emby.Server.Implementations.Data { if (!reader.IsDBNull(index)) { - item.ForcedSortName = reader.GetString(index); + item.SortName = reader.GetString(index); } index++; } @@ -1821,29 +1814,41 @@ namespace Emby.Server.Implementations.Data } index++; - if (!reader.IsDBNull(index)) + if (query.HasField(ItemFields.PresentationUniqueKey)) { - item.PresentationUniqueKey = reader.GetString(index); + if (!reader.IsDBNull(index)) + { + item.PresentationUniqueKey = reader.GetString(index); + } + index++; } - index++; - if (!reader.IsDBNull(index)) + if (query.HasField(ItemFields.InheritedParentalRatingValue)) { - item.InheritedParentalRatingValue = reader.GetInt32(index); + if (!reader.IsDBNull(index)) + { + item.InheritedParentalRatingValue = reader.GetInt32(index); + } + index++; } - index++; - if (!reader.IsDBNull(index)) + if (query.HasField(ItemFields.Tags)) { - item.InheritedTags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + if (!reader.IsDBNull(index)) + { + item.InheritedTags = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + } + index++; } - index++; - if (!reader.IsDBNull(index)) + if (query.HasField(ItemFields.ExternalSeriesId)) { - item.ExternalSeriesId = reader.GetString(index); + if (!reader.IsDBNull(index)) + { + item.ExternalSeriesId = reader.GetString(index); + } + index++; } - index++; if (query.HasField(ItemFields.Taglines)) { @@ -2240,12 +2245,16 @@ namespace Emby.Server.Implementations.Data } if (field == ItemFields.SortName) { - return new[] { "ForcedSortName" }; + return new[] { "SortName" }; } if (field == ItemFields.Taglines) { return new[] { "Tagline" }; } + if (field == ItemFields.Tags) + { + return new[] { "Tags", "InheritedTags" }; + } return new[] { field.ToString() }; } @@ -4916,7 +4925,9 @@ namespace Emby.Server.Implementations.Data var columns = _retriveItemColumns.ToList(); columns.AddRange(itemCountColumns.Select(i => i.Item2).ToArray()); - var commandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, columns.ToArray())) + GetFromText(); + columns = GetFinalColumnsToSelect(query, columns.ToArray()).ToList(); + + var commandText = "select " + string.Join(",", columns.ToArray()) + GetFromText(); commandText += GetJoinUserDataText(query); var innerQuery = new InternalItemsQuery(query.User) @@ -5042,7 +5053,7 @@ namespace Emby.Server.Implementations.Data foreach (var row in statement.ExecuteQuery()) { - var item = GetItem(row); + var item = GetItem(row, query); if (item != null) { var countStartColumn = columns.Count - 1; diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index ec4f552a60..bb46e60063 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -127,7 +127,11 @@ namespace Emby.Server.Implementations.Dto { var libraryItems = byName.GetTaggedItems(new InternalItemsQuery(user) { - Recursive = true + Recursive = true, + DtoOptions = new DtoOptions(false) + { + EnableImages = false + } }); SetItemByNameInfo(item, dto, libraryItems.ToList(), user); @@ -177,7 +181,11 @@ namespace Emby.Server.Implementations.Dto { if (options.Fields.Contains(ItemFields.ItemCounts)) { - SetItemByNameInfo(item, dto, GetTaggedItems(byName, user), user); + SetItemByNameInfo(item, dto, GetTaggedItems(byName, user, new DtoOptions(false) + { + EnableImages = false + + }), user); } FillSyncInfo(dto, item, options, user, syncDictionary); @@ -189,11 +197,12 @@ namespace Emby.Server.Implementations.Dto return dto; } - private List GetTaggedItems(IItemByName byName, User user) + private List GetTaggedItems(IItemByName byName, User user, DtoOptions options) { var items = byName.GetTaggedItems(new InternalItemsQuery(user) { - Recursive = true + Recursive = true, + DtoOptions = options }).ToList(); @@ -595,16 +604,17 @@ namespace Emby.Server.Implementations.Dto { if (!string.IsNullOrEmpty(item.Album)) { - var parentAlbum = _libraryManager.GetItemList(new InternalItemsQuery + var parentAlbumIds = _libraryManager.GetItemIds(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(MusicAlbum).Name }, - Name = item.Album + Name = item.Album, + Limit = 1 - }).FirstOrDefault(); + }); - if (parentAlbum != null) + if (parentAlbumIds.Count > 0) { - dto.AlbumId = GetDtoId(parentAlbum); + dto.AlbumId = parentAlbumIds[0].ToString("N"); } } diff --git a/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 86c8c5f68e..7371b4fdbc 100644 --- a/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -16,6 +16,7 @@ using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Library; using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; @@ -588,7 +589,8 @@ namespace Emby.Server.Implementations.FileOrganization var series = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Series).Name }, - Recursive = true + Recursive = true, + DtoOptions = new DtoOptions(true) }) .Cast() .Select(i => NameUtils.GetMatchScore(nameWithoutYear, yearInName, i)) @@ -607,7 +609,8 @@ namespace Emby.Server.Implementations.FileOrganization { IncludeItemTypes = new[] { typeof(Series).Name }, Recursive = true, - Name = info.ItemName + Name = info.ItemName, + DtoOptions = new DtoOptions(true) }).Cast().FirstOrDefault(); } diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index c8151ec864..a423db9d6f 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -41,6 +41,7 @@ using SortOrder = MediaBrowser.Model.Entities.SortOrder; using VideoResolver = MediaBrowser.Naming.Video.VideoResolver; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Tasks; @@ -313,7 +314,8 @@ namespace Emby.Server.Implementations.Library { IncludeItemTypes = new[] { typeof(Season).Name }, Recursive = true, - IndexNumber = 0 + IndexNumber = 0, + DtoOptions = new DtoOptions(true) }).Cast() .Where(i => !string.Equals(i.Name, newName, StringComparison.Ordinal)) @@ -342,7 +344,7 @@ namespace Emby.Server.Implementations.Library } if (item is IItemByName) { - if (!(item is MusicArtist) && !(item is Studio)) + if (!(item is MusicArtist)) { return; } @@ -868,7 +870,8 @@ namespace Emby.Server.Implementations.Library IsFolder = isFolder, SortBy = new[] { ItemSortBy.DateCreated }, SortOrder = SortOrder.Descending, - Limit = 1 + Limit = 1, + DtoOptions = new DtoOptions(true) }; return GetItemList(query) @@ -981,7 +984,8 @@ namespace Emby.Server.Implementations.Library var existing = GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(T).Name }, - Name = name + Name = name, + DtoOptions = new DtoOptions(true) }).Cast() .OrderBy(i => i.IsAccessedByName ? 1 : 0) diff --git a/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs b/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs index 7424ed5e5e..e64980dff8 100644 --- a/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs +++ b/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs @@ -6,6 +6,7 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -27,7 +28,8 @@ namespace Emby.Server.Implementations.Library var items = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(BoxSet).Name, typeof(Game).Name, typeof(Movie).Name, typeof(Series).Name }, - Recursive = true + Recursive = true, + DtoOptions = new DtoOptions(true) }).OfType().ToList(); @@ -40,7 +42,8 @@ namespace Emby.Server.Implementations.Library { IncludeItemTypes = new[] { typeof(Trailer).Name }, TrailerTypes = trailerTypes, - Recursive = true + Recursive = true, + DtoOptions = new DtoOptions(false) }).ToArray(); diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs index b15c011254..f0d07cc3c4 100644 --- a/Emby.Server.Implementations/Library/MusicManager.cs +++ b/Emby.Server.Implementations/Library/MusicManager.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Playlists; using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Controller.Dto; using MediaBrowser.Model.Querying; namespace Emby.Server.Implementations.Library @@ -18,47 +19,48 @@ namespace Emby.Server.Implementations.Library _libraryManager = libraryManager; } - public IEnumerable /// Task{Episode}. - private Tuple> GetNextUp(string seriesKey, User user) + private Tuple> GetNextUp(string seriesKey, User user, DtoOptions dtoOptions) { var enableSeriesPresentationKey = _config.Configuration.EnableSeriesPresentationUniqueKey; @@ -213,7 +214,8 @@ namespace Emby.Server.Implementations.TV IsPlayed = false, IsVirtualItem = false, ParentIndexNumberNotEquals = 0, - MinSortName = lastWatchedEpisode == null ? null : lastWatchedEpisode.SortName + MinSortName = lastWatchedEpisode == null ? null : lastWatchedEpisode.SortName, + DtoOptions = dtoOptions }).Cast().FirstOrDefault(); }; diff --git a/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs index 7d3a118c0e..3766965365 100644 --- a/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs +++ b/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs @@ -14,6 +14,7 @@ using Emby.Server.Implementations.Images; using MediaBrowser.Common.IO; using MediaBrowser.Model.IO; using MediaBrowser.Controller.Collections; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; @@ -46,7 +47,8 @@ namespace Emby.Server.Implementations.UserViews { CollapseBoxSetItems = false, Recursive = recursive, - ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Playlist" } + ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Playlist" }, + DtoOptions = new DtoOptions(false) }).ConfigureAwait(false); @@ -144,7 +146,8 @@ namespace Emby.Server.Implementations.UserViews Recursive = recursive, IncludeItemTypes = new[] { typeof(BoxSet).Name }, Limit = 20, - SortBy = new[] { ItemSortBy.Random } + SortBy = new[] { ItemSortBy.Random }, + DtoOptions = new DtoOptions(false) }); return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8); diff --git a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs index b0fb954e26..06f7d73e57 100644 --- a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -12,6 +12,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using Emby.Server.Implementations.Images; +using MediaBrowser.Controller.Dto; using MediaBrowser.Model.IO; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Extensions; @@ -58,7 +59,9 @@ namespace Emby.Server.Implementations.UserViews IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, ImageTypes = new[] { ImageType.Primary }, Limit = 30, - IsMovie = true + IsMovie = true, + DtoOptions = new DtoOptions(false) + }).ToList(); return GetFinalItems(programs).ToList(); @@ -69,7 +72,8 @@ namespace Emby.Server.Implementations.UserViews { var userItemsResult = await view.GetItems(new InternalItemsQuery { - CollapseBoxSetItems = false + CollapseBoxSetItems = false, + DtoOptions = new DtoOptions(false) }); return userItemsResult.Items.ToList(); @@ -84,6 +88,7 @@ namespace Emby.Server.Implementations.UserViews CollapseBoxSetItems = false, Recursive = recursive, ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Person" }, + DtoOptions = new DtoOptions(false) }).ConfigureAwait(false); diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index a802e56af0..1a57ff62dd 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -151,16 +151,6 @@ namespace MediaBrowser.Api options.Fields.Add(Model.Querying.ItemFields.ChildCount); } - if (client.IndexOf("web", StringComparison.OrdinalIgnoreCase) == -1 && - - // covers both emby mobile and emby for android mobile - client.IndexOf("mobile", StringComparison.OrdinalIgnoreCase) == -1 && - client.IndexOf("ios", StringComparison.OrdinalIgnoreCase) == -1 && - client.IndexOf("theater", StringComparison.OrdinalIgnoreCase) == -1) - { - options.Fields.Add(Model.Querying.ItemFields.ChildCount); - } - var hasDtoOptions = request as IHasDtoOptions; if (hasDtoOptions != null) { diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index a9394b52e4..2d161ccfd5 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -110,7 +110,11 @@ namespace MediaBrowser.Api var user = request.UserId == null ? null : _userManager.GetUserById(request.UserId); var query = new InternalItemsQuery(user) { - IncludeItemTypes = new[] { typeof(GameSystem).Name } + IncludeItemTypes = new[] { typeof(GameSystem).Name }, + DtoOptions = new DtoOptions(false) + { + EnableImages = false + } }; var gameSystems = _libraryManager.GetItemList(query) .Cast() @@ -130,7 +134,11 @@ namespace MediaBrowser.Api var user = request.UserId == null ? null : _userManager.GetUserById(request.UserId); var query = new InternalItemsQuery(user) { - IncludeItemTypes = new[] { typeof(Game).Name } + IncludeItemTypes = new[] { typeof(Game).Name }, + DtoOptions = new DtoOptions(false) + { + EnableImages = false + } }; var games = _libraryManager.GetItemList(query) .Cast() @@ -167,7 +175,11 @@ namespace MediaBrowser.Api system.GetRecursiveChildren(i => i is Game) : system.GetRecursiveChildren(user, new InternalItemsQuery(user) { - IncludeItemTypes = new[] { typeof(Game).Name } + IncludeItemTypes = new[] { typeof(Game).Name }, + DtoOptions = new DtoOptions(false) + { + EnableImages = false + } }); var games = items.Cast().ToList(); diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 9f144c8e45..cbbaa82b80 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -617,6 +617,8 @@ namespace MediaBrowser.Api.Images ImageIndex = request.Index ?? 0, Image = image, Item = item, + ItemId = item.Id.ToString("N"), + ItemType = item.GetType().Name, MaxHeight = request.MaxHeight, MaxWidth = request.MaxWidth, Quality = request.Quality ?? 100, diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index e654cc8f6a..31292618d0 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -427,7 +427,11 @@ namespace MediaBrowser.Api.Library { var series = _libraryManager.GetItemList(new InternalItemsQuery { - IncludeItemTypes = new[] { typeof(Series).Name } + IncludeItemTypes = new[] { typeof(Series).Name }, + DtoOptions = new DtoOptions(false) + { + EnableImages = false + } }).Where(i => string.Equals(request.TvdbId, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase)).ToArray(); @@ -448,7 +452,11 @@ namespace MediaBrowser.Api.Library { var movies = _libraryManager.GetItemList(new InternalItemsQuery { - IncludeItemTypes = new[] { typeof(Movie).Name } + IncludeItemTypes = new[] { typeof(Movie).Name }, + DtoOptions = new DtoOptions(false) + { + EnableImages = false + } }).ToArray(); @@ -668,7 +676,11 @@ namespace MediaBrowser.Api.Library Recursive = true, IsVirtualItem = false, SourceTypes = new[] { SourceType.Library }, - IsFavorite = request.IsFavorite + IsFavorite = request.IsFavorite, + DtoOptions = new DtoOptions(false) + { + EnableImages = false + } }; return _libraryManager.GetItemsResult(query).TotalRecordCount; @@ -898,7 +910,11 @@ namespace MediaBrowser.Api.Library var query = new InternalItemsQuery(user) { IncludeItemTypes = includeTypes, - Recursive = true + Recursive = true, + DtoOptions = new DtoOptions(false) + { + EnableImages = false + } }; var items = _libraryManager.GetItemList(query); diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 9fcdb4be56..3494754d0a 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -889,6 +889,8 @@ namespace MediaBrowser.Api.LiveTv public async Task Get(GetChannels request) { + var options = GetDtoOptions(_authContext, request); + var channelResult = await _liveTvManager.GetInternalChannels(new LiveTvChannelQuery { ChannelType = request.Type, @@ -908,11 +910,10 @@ namespace MediaBrowser.Api.LiveTv SortOrder = request.SortOrder ?? SortOrder.Ascending, AddCurrentProgram = request.AddCurrentProgram - }, CancellationToken.None).ConfigureAwait(false); + }, options, CancellationToken.None).ConfigureAwait(false); var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId); - var options = GetDtoOptions(_authContext, request); RemoveFields(options); options.AddCurrentProgram = request.AddCurrentProgram; diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index b5c6f52fc0..e20fa2cca1 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Api.Movies } [Route("/Movies/Recommendations", "GET", Summary = "Gets movie recommendations")] - public class GetMovieRecommendations : IReturn, IHasItemFields + public class GetMovieRecommendations : IReturn, IHasDtoOptions { [ApiMember(Name = "CategoryLimit", Description = "The max number of categories to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int CategoryLimit { get; set; } @@ -58,6 +58,18 @@ namespace MediaBrowser.Api.Movies [ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string ParentId { get; set; } + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableUserData { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } + public GetMovieRecommendations() { CategoryLimit = 5; @@ -115,14 +127,12 @@ namespace MediaBrowser.Api.Movies return ToOptimizedSerializedResultUsingCache(result); } - public async Task Get(GetMovieRecommendations request) + public object Get(GetMovieRecommendations request) { var user = _userManager.GetUserById(request.UserId); var dtoOptions = GetDtoOptions(_authContext, request); - dtoOptions.Fields = request.GetItemFields().ToList(); - var result = GetRecommendationCategories(user, request.ParentId, request.CategoryLimit, request.ItemLimit, dtoOptions); return ToOptimizedResult(result); diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs index d735dd7cd0..797edd9402 100644 --- a/MediaBrowser.Api/Music/InstantMixService.cs +++ b/MediaBrowser.Api/Music/InstantMixService.cs @@ -85,9 +85,11 @@ namespace MediaBrowser.Api.Music var user = _userManager.GetUserById(request.UserId); - var items = _musicManager.GetInstantMixFromItem(item, user); + var dtoOptions = GetDtoOptions(_authContext, request); + + var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions); - return GetResult(items, user, request); + return GetResult(items, user, request, dtoOptions); } public Task Get(GetInstantMixFromArtistId request) @@ -96,9 +98,11 @@ namespace MediaBrowser.Api.Music var user = _userManager.GetUserById(request.UserId); - var items = _musicManager.GetInstantMixFromItem(item, user); + var dtoOptions = GetDtoOptions(_authContext, request); - return GetResult(items, user, request); + var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions); + + return GetResult(items, user, request, dtoOptions); } public Task Get(GetInstantMixFromMusicGenreId request) @@ -107,9 +111,11 @@ namespace MediaBrowser.Api.Music var user = _userManager.GetUserById(request.UserId); - var items = _musicManager.GetInstantMixFromItem(item, user); + var dtoOptions = GetDtoOptions(_authContext, request); - return GetResult(items, user, request); + var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions); + + return GetResult(items, user, request, dtoOptions); } public Task Get(GetInstantMixFromSong request) @@ -118,9 +124,11 @@ namespace MediaBrowser.Api.Music var user = _userManager.GetUserById(request.UserId); - var items = _musicManager.GetInstantMixFromItem(item, user); + var dtoOptions = GetDtoOptions(_authContext, request); + + var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions); - return GetResult(items, user, request); + return GetResult(items, user, request, dtoOptions); } public Task Get(GetInstantMixFromAlbum request) @@ -129,9 +137,11 @@ namespace MediaBrowser.Api.Music var user = _userManager.GetUserById(request.UserId); - var items = _musicManager.GetInstantMixFromItem(album, user); + var dtoOptions = GetDtoOptions(_authContext, request); + + var items = _musicManager.GetInstantMixFromItem(album, user, dtoOptions); - return GetResult(items, user, request); + return GetResult(items, user, request, dtoOptions); } public Task Get(GetInstantMixFromPlaylist request) @@ -140,18 +150,22 @@ namespace MediaBrowser.Api.Music var user = _userManager.GetUserById(request.UserId); - var items = _musicManager.GetInstantMixFromItem(playlist, user); + var dtoOptions = GetDtoOptions(_authContext, request); + + var items = _musicManager.GetInstantMixFromItem(playlist, user, dtoOptions); - return GetResult(items, user, request); + return GetResult(items, user, request, dtoOptions); } public Task Get(GetInstantMixFromMusicGenre request) { var user = _userManager.GetUserById(request.UserId); - var items = _musicManager.GetInstantMixFromGenres(new[] { request.Name }, user); + var dtoOptions = GetDtoOptions(_authContext, request); + + var items = _musicManager.GetInstantMixFromGenres(new[] { request.Name }, user, dtoOptions); - return GetResult(items, user, request); + return GetResult(items, user, request, dtoOptions); } public Task Get(GetInstantMixFromArtist request) @@ -159,12 +173,14 @@ namespace MediaBrowser.Api.Music var user = _userManager.GetUserById(request.UserId); var artist = _libraryManager.GetArtist(request.Name); - var items = _musicManager.GetInstantMixFromArtist(artist, user); + var dtoOptions = GetDtoOptions(_authContext, request); + + var items = _musicManager.GetInstantMixFromArtist(artist, user, dtoOptions); - return GetResult(items, user, request); + return GetResult(items, user, request, dtoOptions); } - private async Task GetResult(IEnumerable