From bfc8facc60f919f8455d4c6c7f48a4eca17f2812 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 16 Apr 2016 01:05:34 -0400 Subject: fixes #1261 - Sync quality cannot be changed --- .../Sync/SyncJobProcessor.cs | 45 +++++++++------------- 1 file changed, 18 insertions(+), 27 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 01334c121..33874b4d4 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -149,16 +149,6 @@ namespace MediaBrowser.Server.Implementations.Sync { var job = _syncRepo.GetJob(id); - return UpdateJobStatus(job); - } - - private Task UpdateJobStatus(SyncJob job) - { - if (job == null) - { - throw new ArgumentNullException("job"); - } - var result = _syncManager.GetJobItems(new SyncJobItemQuery { JobId = job.Id, @@ -476,14 +466,12 @@ namespace MediaBrowser.Server.Implementations.Sync if (jobItem != null) { - var job = _syncRepo.GetJob(jobItem.JobId); if (jobItem.Status != SyncJobItemStatus.Cancelled) { - await ProcessJobItem(job, jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); + await ProcessJobItem(jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); } - job = _syncRepo.GetJob(jobItem.JobId); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } numComplete++; @@ -493,7 +481,7 @@ namespace MediaBrowser.Server.Implementations.Sync } } - private async Task ProcessJobItem(SyncJob job, SyncJobItem jobItem, bool enableConversion, IProgress progress, CancellationToken cancellationToken) + private async Task ProcessJobItem(SyncJobItem jobItem, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { var item = _libraryManager.GetItemById(jobItem.ItemId); if (item == null) @@ -507,6 +495,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 0; var syncOptions = _config.GetSyncOptions(); + var job = _syncManager.GetJob(jobItem.JobId); var user = _userManager.GetUserById(job.UserId); if (user == null) { @@ -521,7 +510,7 @@ namespace MediaBrowser.Server.Implementations.Sync { AddMetadata = false, ItemId = jobItem.ItemId, - TargetId = job.TargetId, + TargetId = jobItem.TargetId, Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring } }); @@ -531,7 +520,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (duplicateJobItems.Count > 0) { - var syncProvider = _syncManager.GetSyncProvider(jobItem, job) as IHasDuplicateCheck; + var syncProvider = _syncManager.GetSyncProvider(jobItem) as IHasDuplicateCheck; if (!duplicateJobItems.Any(i => AllowDuplicateJobItem(syncProvider, i, jobItem))) { @@ -545,12 +534,12 @@ namespace MediaBrowser.Server.Implementations.Sync var video = item as Video; if (video != null) { - await Sync(jobItem, job, video, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, video, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); } else if (item is Audio) { - await Sync(jobItem, job, (Audio)item, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, (Audio)item, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); } else if (item is Photo) @@ -574,8 +563,9 @@ namespace MediaBrowser.Server.Implementations.Sync return true; } - private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) { + var job = _syncManager.GetJob(jobItem.JobId); var jobOptions = _syncManager.GetVideoOptions(jobItem, job); var conversionOptions = new VideoOptions { @@ -616,7 +606,7 @@ namespace MediaBrowser.Server.Implementations.Sync { // Save the job item now since conversion could take a while await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); try { @@ -630,7 +620,7 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Progress = pct / 2; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } }); @@ -642,7 +632,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); - _syncManager.OnConversionComplete(jobItem, job); + _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) { @@ -775,8 +765,9 @@ namespace MediaBrowser.Server.Implementations.Sync private const int DatabaseProgressUpdateIntervalSeconds = 2; - private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Audio item, User user, bool enableConversion, SyncOptions syncOptions, IProgress progress, CancellationToken cancellationToken) { + var job = _syncManager.GetJob(jobItem.JobId); var jobOptions = _syncManager.GetAudioOptions(jobItem, job); var conversionOptions = new AudioOptions { @@ -803,7 +794,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Status = SyncJobItemStatus.Converting; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); try { @@ -817,7 +808,7 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Progress = pct / 2; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } }); @@ -828,7 +819,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); - _syncManager.OnConversionComplete(jobItem, job); + _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) { -- cgit v1.2.3 From f7128c7f8f04a39272ec10c699f3a05dac1a8e67 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Apr 2016 16:24:53 -0400 Subject: resync media after changes --- MediaBrowser.Model/Sync/SyncJobItem.cs | 2 ++ .../Sync/SyncJobProcessor.cs | 6 ++++++ MediaBrowser.Server.Implementations/Sync/SyncManager.cs | 16 +++++++++++++++- .../Sync/SyncRepository.cs | 9 ++++++++- 4 files changed, 31 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs') diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs index 77464be58..1c72ccd52 100644 --- a/MediaBrowser.Model/Sync/SyncJobItem.cs +++ b/MediaBrowser.Model/Sync/SyncJobItem.cs @@ -102,6 +102,8 @@ namespace MediaBrowser.Model.Sync /// The index of the job item. public int JobItemIndex { get; set; } + public long ItemDateModifiedTicks { get; set; } + public SyncJobItem() { AdditionalFiles = new List(); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 33874b4d4..0bec528bb 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -632,6 +632,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) @@ -668,6 +669,7 @@ namespace MediaBrowser.Server.Implementations.Sync throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol)); } + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; jobItem.MediaSource = mediaSource; } @@ -819,6 +821,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) @@ -855,6 +858,7 @@ namespace MediaBrowser.Server.Implementations.Sync throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol)); } + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; jobItem.MediaSource = mediaSource; } @@ -871,6 +875,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 50; jobItem.Status = SyncJobItemStatus.ReadyToTransfer; + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } @@ -880,6 +885,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 50; jobItem.Status = SyncJobItemStatus.ReadyToTransfer; + jobItem.ItemDateModifiedTicks = item.DateModified.Ticks; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 044c8b93a..fe1a7fb28 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -775,6 +775,13 @@ namespace MediaBrowser.Server.Implementations.Sync removeFromDevice = true; } } + else if (libraryItem != null && libraryItem.DateModified.Ticks != jobItem.ItemDateModifiedTicks && jobItem.ItemDateModifiedTicks > 0) + { + _logger.Info("Setting status to Queued for {0} because the media has been modified since the original sync.", jobItem.ItemId); + jobItem.Status = SyncJobItemStatus.Queued; + jobItem.Progress = 0; + requiresSaving = true; + } } else { @@ -881,6 +888,13 @@ namespace MediaBrowser.Server.Implementations.Sync removeFromDevice = true; } } + else if (libraryItem != null && libraryItem.DateModified.Ticks != jobItem.ItemDateModifiedTicks && jobItem.ItemDateModifiedTicks > 0) + { + _logger.Info("Setting status to Queued for {0} because the media has been modified since the original sync.", jobItem.ItemId); + jobItem.Status = SyncJobItemStatus.Queued; + jobItem.Progress = 0; + requiresSaving = true; + } } else { @@ -1117,7 +1131,7 @@ namespace MediaBrowser.Server.Implementations.Sync public SyncJobOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job) { var options = GetSyncJobOptions(jobItem.TargetId, null, null); - + if (job.Bitrate.HasValue) { options.DeviceProfile.MaxStaticBitrate = job.Bitrate.Value; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 464e8aa58..249c4212e 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -50,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Profile TEXT, Quality TEXT, Bitrate INT, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", - "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT)", + "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT, JobItemIndex INT, ItemDateModifiedTicks BIGINT)", "create index if not exists idx_SyncJobItems on SyncJobs(Id)", //pragmas @@ -63,6 +63,7 @@ namespace MediaBrowser.Server.Implementations.Sync _connection.AddColumn(Logger, "SyncJobs", "Profile", "TEXT"); _connection.AddColumn(Logger, "SyncJobs", "Bitrate", "INT"); + _connection.AddColumn(Logger, "SyncJobItems", "ItemDateModifiedTicks", "BIGINT"); PrepareStatements(); } @@ -678,6 +679,7 @@ namespace MediaBrowser.Server.Implementations.Sync cmd.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); cmd.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; cmd.GetParameter(index++).Value = jobItem.JobItemIndex; + cmd.GetParameter(index++).Value = jobItem.ItemDateModifiedTicks; cmd.Transaction = transaction; @@ -782,6 +784,11 @@ namespace MediaBrowser.Server.Implementations.Sync info.IsMarkedForRemoval = reader.GetBoolean(13); info.JobItemIndex = reader.GetInt32(14); + if (!reader.IsDBNull(15)) + { + info.ItemDateModifiedTicks = reader.GetInt64(15); + } + return info; } -- cgit v1.2.3 From d54f791159ecdf82e80c54ac663614eedf57f959 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Apr 2016 16:29:27 -0400 Subject: update resync --- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 5 +++++ MediaBrowser.Server.Implementations/Sync/SyncRepository.cs | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 0bec528bb..10b872753 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -149,6 +149,11 @@ namespace MediaBrowser.Server.Implementations.Sync { var job = _syncRepo.GetJob(id); + if (job == null) + { + return Task.FromResult(true); + } + var result = _syncManager.GetJobItems(new SyncJobItemQuery { JobId = job.Id, diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 249c4212e..965c081eb 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -128,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.Sync // _insertJobItemCommand _insertJobItemCommand = _connection.CreateCommand(); - _insertJobItemCommand.CommandText = "insert into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex)"; + _insertJobItemCommand.CommandText = "insert into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex, ItemDateModifiedTicks) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval, @JobItemIndex, @ItemDateModifiedTicks)"; _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@Id"); _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemId"); @@ -145,10 +145,11 @@ namespace MediaBrowser.Server.Implementations.Sync _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@MediaSource"); _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@IsMarkedForRemoval"); _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@JobItemIndex"); + _insertJobItemCommand.Parameters.Add(_insertJobItemCommand, "@ItemDateModifiedTicks"); // _updateJobItemCommand _updateJobItemCommand = _connection.CreateCommand(); - _updateJobItemCommand.CommandText = "update SyncJobItems set ItemId=@ItemId,ItemName=@ItemName,MediaSourceId=@MediaSourceId,JobId=@JobId,TemporaryPath=@TemporaryPath,OutputPath=@OutputPath,Status=@Status,TargetId=@TargetId,DateCreated=@DateCreated,Progress=@Progress,AdditionalFiles=@AdditionalFiles,MediaSource=@MediaSource,IsMarkedForRemoval=@IsMarkedForRemoval,JobItemIndex=@JobItemIndex where Id=@Id"; + _updateJobItemCommand.CommandText = "update SyncJobItems set ItemId=@ItemId,ItemName=@ItemName,MediaSourceId=@MediaSourceId,JobId=@JobId,TemporaryPath=@TemporaryPath,OutputPath=@OutputPath,Status=@Status,TargetId=@TargetId,DateCreated=@DateCreated,Progress=@Progress,AdditionalFiles=@AdditionalFiles,MediaSource=@MediaSource,IsMarkedForRemoval=@IsMarkedForRemoval,JobItemIndex=@JobItemIndex,ItemDateModifiedTicks=@ItemDateModifiedTicks where Id=@Id"; _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@Id"); _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemId"); @@ -165,10 +166,11 @@ namespace MediaBrowser.Server.Implementations.Sync _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@MediaSource"); _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@IsMarkedForRemoval"); _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@JobItemIndex"); + _updateJobItemCommand.Parameters.Add(_updateJobItemCommand, "@ItemDateModifiedTicks"); } private const string BaseJobSelectText = "select Id, TargetId, Name, Profile, Quality, Bitrate, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; - private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex from SyncJobItems"; + private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval, JobItemIndex, ItemDateModifiedTicks from SyncJobItems"; public SyncJob GetJob(string id) { -- cgit v1.2.3 From a15a762ba114683ffcc4c6aab5974d24f8f32c02 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 30 Apr 2016 15:16:43 -0400 Subject: fixes #1484 - (Feature request) Make emby choose output stream based on ffmpeg config --- MediaBrowser.Api/Playback/MediaInfoService.cs | 7 ++++-- .../MediaEncoding/IMediaEncoder.cs | 3 ++- .../ContentDirectory/ContentDirectory.cs | 8 +++++-- .../ContentDirectory/ControlHandler.cs | 7 ++++-- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 9 +++++--- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 8 +++++-- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 11 +++++---- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 8 +++++-- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 26 ++++++++++++++++++++-- MediaBrowser.Model/Dlna/ILocalPlayer.cs | 13 +++++++++++ MediaBrowser.Model/Dlna/StreamBuilder.cs | 23 +++++++++++++++---- .../Sync/SyncJobProcessor.cs | 4 ++-- .../ApplicationHost.cs | 2 +- .../FFMpeg/FFmpegValidator.cs | 4 +++- 14 files changed, 105 insertions(+), 28 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs') diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index ffe7c50c8..2d9cc40c0 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -15,6 +15,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Api.Playback { @@ -66,14 +67,16 @@ namespace MediaBrowser.Api.Playback private readonly ILibraryManager _libraryManager; private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; + private readonly IMediaEncoder _mediaEncoder; - public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager) + public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager, IMediaEncoder mediaEncoder) { _mediaSourceManager = mediaSourceManager; _deviceManager = deviceManager; _libraryManager = libraryManager; _config = config; _networkManager = networkManager; + _mediaEncoder = mediaEncoder; } public object Get(GetBitrateTestBytes request) @@ -241,7 +244,7 @@ namespace MediaBrowser.Api.Playback int? subtitleStreamIndex, string playSessionId) { - var streamBuilder = new StreamBuilder(Logger); + var streamBuilder = new StreamBuilder(_mediaEncoder, Logger); var options = new VideoOptions { diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index d2feb4116..7c3959f6e 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -4,13 +4,14 @@ using System; using System.IO; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Dlna; namespace MediaBrowser.Controller.MediaEncoding { /// /// Interface IMediaEncoder /// - public interface IMediaEncoder + public interface IMediaEncoder : ITranscoderSupport { /// /// Gets the encoder path. diff --git a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs index 21289970e..093b37df3 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs @@ -12,6 +12,7 @@ using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.ContentDirectory { @@ -27,6 +28,7 @@ namespace MediaBrowser.Dlna.ContentDirectory private readonly IChannelManager _channelManager; private readonly IMediaSourceManager _mediaSourceManager; private readonly IUserViewManager _userViewManager; + private readonly Func _mediaEncoder; public ContentDirectory(IDlnaManager dlna, IUserDataManager userDataManager, @@ -35,7 +37,7 @@ namespace MediaBrowser.Dlna.ContentDirectory IServerConfigurationManager config, IUserManager userManager, ILogger logger, - IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager) + IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, Func mediaEncoder) : base(logger, httpClient) { _dlna = dlna; @@ -48,6 +50,7 @@ namespace MediaBrowser.Dlna.ContentDirectory _channelManager = channelManager; _mediaSourceManager = mediaSourceManager; _userViewManager = userViewManager; + _mediaEncoder = mediaEncoder; } private int SystemUpdateId @@ -89,7 +92,8 @@ namespace MediaBrowser.Dlna.ContentDirectory _localization, _channelManager, _mediaSourceManager, - _userViewManager) + _userViewManager, + _mediaEncoder()) .ProcessControlRequest(request); } diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 01c7c33b6..34fb2a6df 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -23,6 +23,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.ContentDirectory { @@ -34,6 +35,7 @@ namespace MediaBrowser.Dlna.ContentDirectory private readonly IServerConfigurationManager _config; private readonly User _user; private readonly IUserViewManager _userViewManager; + private readonly IMediaEncoder _mediaEncoder; private const string NS_DC = "http://purl.org/dc/elements/1.1/"; private const string NS_DIDL = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"; @@ -47,7 +49,7 @@ namespace MediaBrowser.Dlna.ContentDirectory private readonly DeviceProfile _profile; - public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager) + public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, IMediaEncoder mediaEncoder) : base(config, logger) { _libraryManager = libraryManager; @@ -56,10 +58,11 @@ namespace MediaBrowser.Dlna.ContentDirectory _systemUpdateId = systemUpdateId; _channelManager = channelManager; _userViewManager = userViewManager; + _mediaEncoder = mediaEncoder; _profile = profile; _config = config; - _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, libraryManager); + _didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, Logger, libraryManager, _mediaEncoder); } protected override IEnumerable> GetResult(string methodName, Headers methodParams) diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs index 89d00eb32..af833a85c 100644 --- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs +++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs @@ -19,6 +19,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Xml; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Dlna.Didl @@ -42,8 +43,9 @@ namespace MediaBrowser.Dlna.Didl private readonly IMediaSourceManager _mediaSourceManager; private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; + private readonly IMediaEncoder _mediaEncoder; - public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, string accessToken, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, ILogger logger, ILibraryManager libraryManager) + public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, string accessToken, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, ILogger logger, ILibraryManager libraryManager, IMediaEncoder mediaEncoder) { _profile = profile; _imageProcessor = imageProcessor; @@ -53,6 +55,7 @@ namespace MediaBrowser.Dlna.Didl _mediaSourceManager = mediaSourceManager; _logger = logger; _libraryManager = libraryManager; + _mediaEncoder = mediaEncoder; _accessToken = accessToken; _user = user; } @@ -142,7 +145,7 @@ namespace MediaBrowser.Dlna.Didl { var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user).ToList(); - streamInfo = new StreamBuilder(GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions + streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions { ItemId = GetClientId(video), MediaSources = sources, @@ -385,7 +388,7 @@ namespace MediaBrowser.Dlna.Didl { var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user).ToList(); - streamInfo = new StreamBuilder(GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions + streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions { ItemId = GetClientId(audio), MediaSources = sources, diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 37584f006..733bda9ae 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -14,6 +14,7 @@ using MediaBrowser.Dlna.Ssdp; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.Main { @@ -34,6 +35,7 @@ namespace MediaBrowser.Dlna.Main private readonly IUserDataManager _userDataManager; private readonly ILocalizationManager _localization; private readonly IMediaSourceManager _mediaSourceManager; + private readonly IMediaEncoder _mediaEncoder; private readonly SsdpHandler _ssdpHandler; private readonly IDeviceDiscovery _deviceDiscovery; @@ -54,7 +56,7 @@ namespace MediaBrowser.Dlna.Main IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, - ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery) + ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery, IMediaEncoder mediaEncoder) { _config = config; _appHost = appHost; @@ -69,6 +71,7 @@ namespace MediaBrowser.Dlna.Main _localization = localization; _mediaSourceManager = mediaSourceManager; _deviceDiscovery = deviceDiscovery; + _mediaEncoder = mediaEncoder; _ssdpHandler = (SsdpHandler)ssdpHandler; _logger = logManager.GetLogger("Dlna"); } @@ -196,7 +199,8 @@ namespace MediaBrowser.Dlna.Main _config, _userDataManager, _localization, - _mediaSourceManager); + _mediaSourceManager, + _mediaEncoder); _manager.Start(); } diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs index db5e0ee29..80bb756ef 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs @@ -18,6 +18,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.PlayTo { @@ -35,6 +36,7 @@ namespace MediaBrowser.Dlna.PlayTo private readonly ILocalizationManager _localization; private readonly IMediaSourceManager _mediaSourceManager; private readonly IConfigurationManager _config; + private readonly IMediaEncoder _mediaEncoder; private readonly IDeviceDiscovery _deviceDiscovery; private readonly string _serverAddress; @@ -74,7 +76,7 @@ namespace MediaBrowser.Dlna.PlayTo get { return IsSessionActive; } } - public PlayToController(SessionInfo session, ISessionManager sessionManager, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, IDeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IConfigurationManager config) + public PlayToController(SessionInfo session, ISessionManager sessionManager, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, IDeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IConfigurationManager config, IMediaEncoder mediaEncoder) { _session = session; _sessionManager = sessionManager; @@ -88,6 +90,7 @@ namespace MediaBrowser.Dlna.PlayTo _localization = localization; _mediaSourceManager = mediaSourceManager; _config = config; + _mediaEncoder = mediaEncoder; _accessToken = accessToken; _logger = logger; _creationTime = DateTime.UtcNow; @@ -478,7 +481,7 @@ namespace MediaBrowser.Dlna.PlayTo playlistItem.StreamUrl = playlistItem.StreamInfo.ToDlnaUrl(_serverAddress, _accessToken); - var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _libraryManager) + var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _libraryManager, _mediaEncoder) .GetItemDidl(_config.GetDlnaConfiguration(), item, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo); playlistItem.Didl = itemXml; @@ -550,7 +553,7 @@ namespace MediaBrowser.Dlna.PlayTo { return new PlaylistItem { - StreamInfo = new StreamBuilder(GetStreamBuilderLogger()).BuildVideoItem(new VideoOptions + StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildVideoItem(new VideoOptions { ItemId = item.Id.ToString("N"), MediaSources = mediaSources, @@ -570,7 +573,7 @@ namespace MediaBrowser.Dlna.PlayTo { return new PlaylistItem { - StreamInfo = new StreamBuilder(GetStreamBuilderLogger()).BuildAudioItem(new AudioOptions + StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildAudioItem(new AudioOptions { ItemId = item.Id.ToString("N"), MediaSources = mediaSources, diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index 18daef331..bbb9bf6de 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Dlna.PlayTo { @@ -32,11 +33,12 @@ namespace MediaBrowser.Dlna.PlayTo private readonly IDeviceDiscovery _deviceDiscovery; private readonly IMediaSourceManager _mediaSourceManager; + private readonly IMediaEncoder _mediaEncoder; private readonly List _nonRendererUrls = new List(); private DateTime _lastRendererClear; - public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager) + public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder) { _logger = logger; _sessionManager = sessionManager; @@ -51,6 +53,7 @@ namespace MediaBrowser.Dlna.PlayTo _userDataManager = userDataManager; _localization = localization; _mediaSourceManager = mediaSourceManager; + _mediaEncoder = mediaEncoder; } public void Start() @@ -132,7 +135,8 @@ namespace MediaBrowser.Dlna.PlayTo _userDataManager, _localization, _mediaSourceManager, - _config); + _config, + _mediaEncoder); controller.Init(device); diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 01fb31d0c..399fdead9 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -96,15 +96,23 @@ namespace MediaBrowser.MediaEncoding.Encoder FFMpegPath = ffMpegPath; } + private List _encoders = new List(); public void SetAvailableEncoders(List list) { - + _encoders = list.ToList(); + //_logger.Info("Supported encoders: {0}", string.Join(",", list.ToArray())); } private List _decoders = new List(); public void SetAvailableDecoders(List list) { _decoders = list.ToList(); + //_logger.Info("Supported decoders: {0}", string.Join(",", list.ToArray())); + } + + public bool SupportsEncoder(string decoder) + { + return _encoders.Contains(decoder, StringComparer.OrdinalIgnoreCase); } public bool SupportsDecoder(string decoder) @@ -112,6 +120,20 @@ namespace MediaBrowser.MediaEncoding.Encoder return _decoders.Contains(decoder, StringComparer.OrdinalIgnoreCase); } + public bool CanEncodeToAudioCodec(string codec) + { + if (string.Equals(codec, "opus", StringComparison.OrdinalIgnoreCase)) + { + codec = "libopus"; + } + else if (string.Equals(codec, "mp3", StringComparison.OrdinalIgnoreCase)) + { + codec = "libmp3lame"; + } + + return SupportsEncoder(codec); + } + /// /// Gets the encoder path. /// @@ -296,7 +318,7 @@ namespace MediaBrowser.MediaEncoding.Encoder formats.Contains("ts", StringComparer.OrdinalIgnoreCase) || formats.Contains("mpegts", StringComparer.OrdinalIgnoreCase) || formats.Contains("wtv", StringComparer.OrdinalIgnoreCase); - + // If it's mpeg based, assume true if ((videoStream.Codec ?? string.Empty).IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) != -1) { diff --git a/MediaBrowser.Model/Dlna/ILocalPlayer.cs b/MediaBrowser.Model/Dlna/ILocalPlayer.cs index 55e11ec4b..9de360023 100644 --- a/MediaBrowser.Model/Dlna/ILocalPlayer.cs +++ b/MediaBrowser.Model/Dlna/ILocalPlayer.cs @@ -23,4 +23,17 @@ namespace MediaBrowser.Model.Dlna /// true if this instance [can access URL] the specified URL; otherwise, false. bool CanAccessUrl(string url, bool requiresCustomRequestHeaders); } + + public interface ITranscoderSupport + { + bool CanEncodeToAudioCodec(string codec); + } + + public class FullTranscoderSupport : ITranscoderSupport + { + public bool CanEncodeToAudioCodec(string codec) + { + return true; + } + } } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 98d246980..07a4b8995 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -13,15 +13,27 @@ namespace MediaBrowser.Model.Dlna { private readonly ILocalPlayer _localPlayer; private readonly ILogger _logger; + private readonly ITranscoderSupport _transcoderSupport; - public StreamBuilder(ILocalPlayer localPlayer, ILogger logger) + public StreamBuilder(ILocalPlayer localPlayer, ITranscoderSupport transcoderSupport, ILogger logger) { + _transcoderSupport = transcoderSupport; _localPlayer = localPlayer; _logger = logger; } + public StreamBuilder(ITranscoderSupport transcoderSupport, ILogger logger) + : this(new NullLocalPlayer(), transcoderSupport, logger) + { + } + + public StreamBuilder(ILocalPlayer localPlayer, ILogger logger) + : this(localPlayer, new FullTranscoderSupport(), logger) + { + } + public StreamBuilder(ILogger logger) - : this(new NullLocalPlayer(), logger) + : this(new NullLocalPlayer(), new FullTranscoderSupport(), logger) { } @@ -185,8 +197,11 @@ namespace MediaBrowser.Model.Dlna { if (i.Type == playlistItem.MediaType && i.Context == options.Context) { - transcodingProfile = i; - break; + if (_transcoderSupport.CanEncodeToAudioCodec(i.AudioCodec ?? i.Container)) + { + transcodingProfile = i; + break; + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 10b872753..d95a4fefb 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -582,7 +582,7 @@ namespace MediaBrowser.Server.Implementations.Sync conversionOptions.ItemId = item.Id.ToString("N"); conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList(); - var streamInfo = new StreamBuilder(_logger).BuildVideoItem(conversionOptions); + var streamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildVideoItem(conversionOptions); var mediaSource = streamInfo.MediaSource; // No sense creating external subs if we're already burning one into the video @@ -786,7 +786,7 @@ namespace MediaBrowser.Server.Implementations.Sync conversionOptions.ItemId = item.Id.ToString("N"); conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList(); - var streamInfo = new StreamBuilder(_logger).BuildAudioItem(conversionOptions); + var streamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildAudioItem(conversionOptions); var mediaSource = streamInfo.MediaSource; jobItem.MediaSourceId = streamInfo.MediaSourceId; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 01575e71f..fd6dee0f6 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -515,7 +515,7 @@ namespace MediaBrowser.Server.Startup.Common UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager); RegisterSingleInstance(UserViewManager); - var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager); + var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager, MediaSourceManager, UserViewManager, () => MediaEncoder); RegisterSingleInstance(contentDirectory); var mediaRegistrar = new MediaReceiverRegistrar(LogManager.GetLogger("MediaReceiverRegistrar"), HttpClient, ServerConfigurationManager); diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs index 5ba5fb44a..0ae021407 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs @@ -42,6 +42,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg catch { } + //_logger.Debug("ffmpeg decoder query result: {0}", output ?? string.Empty); var found = new List(); var required = new[] @@ -78,6 +79,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg catch { } + //_logger.Debug("ffmpeg encoder query result: {0}", output ?? string.Empty); var found = new List(); var required = new[] @@ -89,8 +91,8 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg //"libvpx", //"libvpx-vp9", "aac", - "ac3", "libmp3lame", + "libopus", //"libvorbis", "srt" }; -- cgit v1.2.3 From 6adc668bed55948b89ee6adcc379cce7253da82c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 7 May 2016 13:47:41 -0400 Subject: update icons --- .../Entities/Audio/MusicArtist.cs | 14 ++++++++++ .../Entities/Audio/MusicGenre.cs | 8 ++++++ MediaBrowser.Controller/Entities/GameGenre.cs | 8 ++++++ MediaBrowser.Controller/Entities/Genre.cs | 8 ++++++ MediaBrowser.Controller/Entities/IItemByName.cs | 2 ++ .../Entities/InternalItemsQuery.cs | 1 + MediaBrowser.Controller/Entities/Person.cs | 7 +++++ MediaBrowser.Controller/Entities/PhotoAlbum.cs | 9 ------- MediaBrowser.Controller/Entities/Studio.cs | 7 +++++ MediaBrowser.Controller/Entities/TV/Series.cs | 16 +++--------- MediaBrowser.Controller/Entities/Year.cs | 16 ++++++++++++ MediaBrowser.Controller/Playlists/Playlist.cs | 11 ++++---- .../Library/MusicManager.cs | 2 +- .../Persistence/SqliteItemRepository.cs | 6 +++++ .../Photos/BaseDynamicImageProvider.cs | 15 +++++++++++ .../Session/SessionManager.cs | 25 ++++++++++-------- .../Sync/SyncJobProcessor.cs | 30 +++++++++------------- 17 files changed, 129 insertions(+), 56 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs') diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 2cca63217..2637e729c 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -40,6 +40,20 @@ namespace MediaBrowser.Controller.Entities.Audio return !IsAccessedByName; } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + var itemByNameFilter = GetItemFilter(); + + if (query.User != null) + { + return query.User.RootFolder + .GetRecursiveChildren(query.User, i => !i.IsFolder && itemByNameFilter(i)); + } + + return LibraryManager.RootFolder + .GetRecursiveChildren(i => !i.IsFolder && itemByNameFilter(i)); + } + protected override IEnumerable ActualChildren { get diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 4d041264c..05870176e 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -79,5 +79,13 @@ namespace MediaBrowser.Controller.Entities.Audio return false; } } + + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.ExcludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name }; + + return LibraryManager.GetItemList(query); + } } } diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 71028d4cf..7c1e88cb1 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -62,6 +62,14 @@ namespace MediaBrowser.Controller.Entities return i => i is Game && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.IncludeItemTypes = new[] { typeof(Game).Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index fa890ad9e..c87d4daaf 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -66,6 +66,14 @@ namespace MediaBrowser.Controller.Entities return i => !(i is Game) && !(i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Genres = new[] { Name }; + query.ExcludeItemTypes = new[] { typeof(Game).Name, typeof(MusicVideo).Name, typeof(Audio.Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index e6667290c..7747e738c 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -20,6 +20,8 @@ namespace MediaBrowser.Controller.Entities /// /// Func<BaseItem, System.Boolean>. Func GetItemFilter(); + + IEnumerable GetTaggedItems(InternalItemsQuery query); } public interface IHasDualAccess : IItemByName diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 2615f351a..385ee81e9 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -134,6 +134,7 @@ namespace MediaBrowser.Controller.Entities public string[] AlbumNames { get; set; } public string[] ArtistNames { get; set; } + public string AncestorWithPresentationUniqueKey { get; set; } public bool GroupByPresentationUniqueKey { get; set; } diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 89581e967..2b099e3d5 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -31,6 +31,13 @@ namespace MediaBrowser.Controller.Entities return GetItemLookupInfo(); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Person = Name; + + return LibraryManager.GetItemList(query); + } + /// /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs index c8ab67a69..b0ddcfb8c 100644 --- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs +++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs @@ -7,15 +7,6 @@ namespace MediaBrowser.Controller.Entities { public class PhotoAlbum : Folder { - [IgnoreDataMember] - public override bool SupportsLocalMetadata - { - get - { - return false; - } - } - [IgnoreDataMember] public override bool AlwaysScanInternalMetadataPath { diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 7ceefbc6e..48ca7bbcc 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -65,6 +65,13 @@ namespace MediaBrowser.Controller.Entities return i => i.Studios.Contains(Name, StringComparer.OrdinalIgnoreCase); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + query.Studios = new[] { Name }; + + return LibraryManager.GetItemList(query); + } + [IgnoreDataMember] public override bool SupportsPeople { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index abca6a643..a70bac6db 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MoreLinq; namespace MediaBrowser.Controller.Entities.TV { @@ -180,7 +181,7 @@ namespace MediaBrowser.Controller.Entities.TV else { items = query.Recursive - ? GetRecursiveChildren(user, filter) + ? GetSeasons(user).Cast().Concat(GetEpisodes(user)).Where(filter) : GetSeasons(user).Where(filter); } @@ -211,7 +212,7 @@ namespace MediaBrowser.Controller.Entities.TV } else { - seasons = base.GetChildren(user, true).OfType(); + seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType(); } if (!includeMissingSeasons && !includeVirtualUnaired) @@ -250,17 +251,8 @@ namespace MediaBrowser.Controller.Entities.TV // Specials could appear twice based on above - once in season 0, once in the aired season // This depends on settings for that series // When this happens, remove the duplicate from season 0 - var returnList = new List(); - foreach (var episode in allEpisodes) - { - if (!returnList.Contains(episode)) - { - returnList.Insert(0, episode); - } - } - - return returnList; + return allEpisodes.DistinctBy(i => i.Id).Reverse(); } public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken) diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index f27ce79dd..db896f1fc 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -70,6 +70,22 @@ namespace MediaBrowser.Controller.Entities return inputItems.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year); } + public IEnumerable GetTaggedItems(InternalItemsQuery query) + { + int year; + + var usCulture = new CultureInfo("en-US"); + + if (!int.TryParse(Name, NumberStyles.Integer, usCulture, out year)) + { + return new List(); + } + + query.Years = new[] { year }; + + return LibraryManager.GetItemList(query); + } + public int? GetYearValue() { int i; diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 750dea361..cd0c5dc1c 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -99,11 +99,12 @@ namespace MediaBrowser.Controller.Playlists var musicGenre = item as MusicGenre; if (musicGenre != null) { - Func filter = i => i is Audio && i.Genres.Contains(musicGenre.Name, StringComparer.OrdinalIgnoreCase); - - var items = user == null - ? LibraryManager.RootFolder.GetRecursiveChildren(filter) - : user.RootFolder.GetRecursiveChildren(user, filter); + var items = LibraryManager.GetItemList(new InternalItemsQuery(user) + { + Recursive = true, + IncludeItemTypes = new[] { typeof(Audio).Name }, + Genres = new[] { musicGenre.Name } + }); return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending); } diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index aad7c112b..c82c4cdf7 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable public interface IHasUserData : IHasId { - /// - /// Gets the user data key. - /// - /// System.String. - string GetUserDataKey(); - List GetUserDataKeys(); /// diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs index 5e0baa1f6..1eda79f02 100644 --- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs +++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs @@ -125,11 +125,6 @@ namespace MediaBrowser.Dlna.Ssdp args.EndPoint = endPoint; args.LocalEndPoint = new IPEndPoint(localIp, 0); - if (_ssdpHandler.IgnoreMessage(args, true)) - { - return; - } - _ssdpHandler.LogMessageReceived(args, true); TryCreateDevice(args); diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs index 0fabbf54a..f637160be 100644 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -199,22 +200,22 @@ namespace MediaBrowser.Server.Implementations.Library public UserItemData GetUserData(IHasUserData user, IHasUserData item) { - return GetUserData(user.Id, item.GetUserDataKey()); + return GetUserData(user.Id, item.GetUserDataKeys().First()); } public UserItemData GetUserData(string userId, IHasUserData item) { - return GetUserData(userId, item.GetUserDataKey()); + return GetUserData(userId, item.GetUserDataKeys().First()); } public UserItemData GetUserData(Guid userId, IHasUserData item) { - return GetUserData(userId, item.GetUserDataKey()); + return GetUserData(userId, item.GetUserDataKeys().First()); } public UserItemDataDto GetUserDataDto(IHasUserData item, User user) { - var userData = GetUserData(user.Id, item.GetUserDataKey()); + var userData = GetUserData(user.Id, item.GetUserDataKeys().First()); var dto = GetUserItemDataDto(userData); item.FillUserDataDtoValues(dto, userData, user); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 379e2f056..bbba06870 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -345,7 +345,8 @@ namespace MediaBrowser.Server.Implementations.Sync if (!folder.IsPreSorted) { - items = items.OrderBy(i => i.SortName).ToArray(); + items = _libraryManager.Sort(items, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending) + .ToArray(); } return items; diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 271b02d9a..f5abcf336 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -158,7 +158,7 @@ namespace MediaBrowser.ServerApplication.Native info.FFMpegFilename = "ffmpeg.exe"; info.FFProbeFilename = "ffprobe.exe"; - info.Version = "20160508"; + info.Version = "20160410"; info.ArchiveType = "7z"; info.IsEmbedded = false; info.DownloadUrls = GetDownloadUrls(); @@ -214,14 +214,14 @@ namespace MediaBrowser.ServerApplication.Native case Architecture.X86_X64: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win64.7z", - "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160508-git-caee88d-win64-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win64.7z", + "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160409-git-0c90b2e-win64-static.7z" }; case Architecture.X86: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win32.7z", - "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160508-git-caee88d-win32-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win32.7z", + "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160409-git-0c90b2e-win32-static.7z" }; } return new string[] { }; -- cgit v1.2.3 From e5655d32f122b4840057aac30bba24d2a94c36fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 27 May 2016 13:17:57 -0400 Subject: fix timestamps in hls subtitles --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 6 +++++- MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs | 8 +------- MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs | 6 ++++-- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs') diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index c2183ad7b..1382527e2 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -98,6 +98,9 @@ namespace MediaBrowser.Api.Subtitles [ApiMember(Name = "EndPositionTicks", Description = "EndPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public long? EndPositionTicks { get; set; } + + [ApiMember(Name = "CopyTimestamps", Description = "CopyTimestamps", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool CopyTimestamps { get; set; } } [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/subtitles.m3u8", "GET", Summary = "Gets an HLS subtitle playlist.")] @@ -175,7 +178,7 @@ namespace MediaBrowser.Api.Subtitles var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks); - var url = string.Format("stream.vtt?StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}", + var url = string.Format("stream.vtt?CopyTimestamps=true,StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}", positionTicks.ToString(CultureInfo.InvariantCulture), endPositionTicks.ToString(CultureInfo.InvariantCulture), accessToken); @@ -222,6 +225,7 @@ namespace MediaBrowser.Api.Subtitles request.Format, request.StartPositionTicks, request.EndPositionTicks, + request.CopyTimestamps, CancellationToken.None).ConfigureAwait(false); } diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs index e538b84d8..44489cbf5 100644 --- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs @@ -10,13 +10,6 @@ namespace MediaBrowser.Controller.MediaEncoding /// /// Gets the subtitles. /// - /// The item identifier. - /// The media source identifier. - /// Index of the subtitle stream. - /// The output format. - /// The start time ticks. - /// The end time ticks. - /// The cancellation token. /// Task{Stream}. Task GetSubtitles(string itemId, string mediaSourceId, @@ -24,6 +17,7 @@ namespace MediaBrowser.Controller.MediaEncoding string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken); /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 8c33cc7c0..25adbcdb0 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -58,6 +58,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken) { var ms = new MemoryStream(); @@ -68,7 +69,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles var trackInfo = reader.Parse(stream, cancellationToken); - FilterEvents(trackInfo, startTimeTicks, endTimeTicks, false); + FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps); var writer = GetWriter(outputFormat); @@ -116,6 +117,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken) { var subtitle = await GetSubtitleStream(itemId, mediaSourceId, subtitleStreamIndex, cancellationToken) @@ -130,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles using (var stream = subtitle.Item1) { - return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, cancellationToken).ConfigureAwait(false); + return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, preserveOriginalTimestamps, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index bbba06870..398dcc86b 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -748,7 +748,7 @@ namespace MediaBrowser.Server.Implementations.Sync _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, cancellationToken).ConfigureAwait(false)) + using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, false, cancellationToken).ConfigureAwait(false)) { using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { -- cgit v1.2.3 From cba6c99d548ba8735de3ffdbc2f6c710a00f096b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 May 2016 14:42:18 -0400 Subject: add null check to sync process --- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 398dcc86b..886308d43 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -483,6 +483,11 @@ namespace MediaBrowser.Server.Implementations.Sync private async Task ProcessJobItem(SyncJobItem jobItem, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { + if (jobItem == null) + { + throw new ArgumentNullException("jobItem"); + } + var item = _libraryManager.GetItemById(jobItem.ItemId); if (item == null) { -- cgit v1.2.3 From 759f5a856064450acdb4c26839d6d890afb99a17 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 19 Jun 2016 02:18:29 -0400 Subject: update task results --- Emby.Drawing/ImageMagick/ImageMagickEncoder.cs | 11 --- MediaBrowser.Api/BaseApiService.cs | 2 +- MediaBrowser.Api/GamesService.cs | 9 +- MediaBrowser.Api/Images/ImageService.cs | 10 +-- MediaBrowser.Api/Images/RemoteImageService.cs | 10 +-- MediaBrowser.Api/ItemLookupService.cs | 36 ++++---- MediaBrowser.Api/Library/LibraryService.cs | 6 +- MediaBrowser.Api/LiveTv/LiveTvService.cs | 2 +- MediaBrowser.Api/Movies/MoviesService.cs | 18 ++-- MediaBrowser.Api/Music/AlbumsService.cs | 13 +-- MediaBrowser.Api/Music/InstantMixService.cs | 21 ++--- MediaBrowser.Api/PackageReviewService.cs | 12 +-- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 4 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 2 +- MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs | 9 +- .../Playback/Progressive/AudioService.cs | 5 +- .../Progressive/BaseProgressiveStreamingService.cs | 28 ++++--- .../Playback/Progressive/VideoService.cs | 5 +- MediaBrowser.Api/PlaylistService.cs | 4 +- MediaBrowser.Api/SimilarItemsHelper.cs | 12 +-- MediaBrowser.Api/Subtitles/SubtitleService.cs | 10 +-- MediaBrowser.Api/Sync/SyncService.cs | 14 ++-- MediaBrowser.Api/System/SystemService.cs | 2 +- MediaBrowser.Api/TvShowsService.cs | 25 +++--- MediaBrowser.Api/UserLibrary/ItemsService.cs | 2 +- MediaBrowser.Api/UserLibrary/PlaystateService.cs | 6 +- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 12 +-- MediaBrowser.Controller/Dto/IDtoService.cs | 3 +- MediaBrowser.Controller/Entities/BaseItem.cs | 4 +- MediaBrowser.Controller/Entities/Folder.cs | 24 ++++-- MediaBrowser.Controller/Entities/IHasUserData.cs | 3 +- MediaBrowser.Controller/IServerApplicationHost.cs | 5 +- .../Library/IUserDataManager.cs | 4 +- MediaBrowser.Controller/Net/IHttpResultFactory.cs | 8 +- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 4 +- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 13 +-- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 35 ++++---- MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs | 4 +- MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs | 7 +- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 29 +++---- MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs | 11 ++- .../Channels/ChannelManager.cs | 8 +- .../Connect/ConnectManager.cs | 14 ++-- .../Dto/DtoService.cs | 95 ++++++++++------------ .../EntryPoints/AutomaticRestartEntryPoint.cs | 28 ++++--- .../EntryPoints/UserDataChangeNotifier.cs | 2 +- .../HttpServer/HttpResultFactory.cs | 10 +-- .../HttpServer/SwaggerService.cs | 2 +- .../Library/LibraryManager.cs | 2 +- .../Library/UserDataManager.cs | 13 ++- .../Library/UserManager.cs | 2 +- .../LiveTv/LiveTvManager.cs | 6 +- .../LiveTv/LiveTvMediaSourceProvider.cs | 2 +- .../Session/SessionManager.cs | 29 ++++--- .../Sync/SyncJobProcessor.cs | 32 ++++++-- .../Udp/UdpServer.cs | 12 +-- .../ApplicationHost.cs | 49 +++++------ MediaBrowser.WebDashboard/Api/DashboardService.cs | 9 +- 58 files changed, 404 insertions(+), 355 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs') diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index 180f797e3..3dbe7239d 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -111,7 +111,6 @@ namespace Emby.Drawing.ImageMagick wand.CurrentImage.TrimImage(10); wand.SaveImage(outputPath); } - SaveDelay(); } public ImageSize GetImageSize(string path) @@ -189,7 +188,6 @@ namespace Emby.Drawing.ImageMagick } } } - SaveDelay(); } private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options) @@ -294,15 +292,6 @@ namespace Emby.Drawing.ImageMagick { new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height); } - - SaveDelay(); - } - - private void SaveDelay() - { - // For some reason the images are not always getting released right away - //var task = Task.Delay(300); - //Task.WaitAll(task); } public string Name diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 44d459a01..44a367be0 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -115,7 +115,7 @@ namespace MediaBrowser.Api /// System.Object. protected object ToStaticFileResult(string path) { - return ResultFactory.GetStaticFileResult(Request, path); + return ResultFactory.GetStaticFileResult(Request, path).Result; } protected DtoOptions GetDtoOptions(object request) diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index cb77e62ad..4758b0186 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Threading.Tasks; using MediaBrowser.Model.Querying; namespace MediaBrowser.Api @@ -186,14 +187,14 @@ namespace MediaBrowser.Api /// /// The request. /// System.Object. - public object Get(GetSimilarGames request) + public async Task Get(GetSimilarGames request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } - private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + private async Task> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; @@ -216,7 +217,7 @@ namespace MediaBrowser.Api var result = new QueryResult { - Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), + Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(), TotalRecordCount = itemsResult.Count }; diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index e5fe5bd68..a511f8c72 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -514,7 +514,7 @@ namespace MediaBrowser.Api.Images /// if set to true [is head request]. /// System.Object. /// - public object GetImage(ImageRequest request, IHasImages item, bool isHeadRequest) + public Task GetImage(ImageRequest request, IHasImages item, bool isHeadRequest) { if (request.PercentPlayed.HasValue) { @@ -594,8 +594,7 @@ namespace MediaBrowser.Api.Images supportedImageEnhancers, cacheDuration, responseHeaders, - isHeadRequest) - .Result; + isHeadRequest); } private async Task GetImageResult(IHasImages item, @@ -632,7 +631,7 @@ namespace MediaBrowser.Api.Images headers["Vary"] = "Accept"; - return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions + return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions { CacheDuration = cacheDuration, ResponseHeaders = headers, @@ -643,7 +642,8 @@ namespace MediaBrowser.Api.Images // Sometimes imagemagick keeps a hold on the file briefly even after it's done writing to it. // I'd rather do this than add a delay after saving the file FileShare = FileShare.ReadWrite - }); + + }).ConfigureAwait(false); } private List GetOutputFormats(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List enhancers) diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index 02d1cdbe2..b21e54495 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -238,9 +238,9 @@ namespace MediaBrowser.Api.Images } if (_fileSystem.FileExists(contentPath)) - { - return ToStaticFileResult(contentPath); - } + { + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); + } } catch (DirectoryNotFoundException) { @@ -259,9 +259,9 @@ namespace MediaBrowser.Api.Images contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); } - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } - + /// /// Downloads the image. /// diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index 41bfd9da2..30cde4883 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -132,58 +132,58 @@ namespace MediaBrowser.Api return ToOptimizedResult(infos); } - public object Post(GetMovieRemoteSearchResults request) + public async Task Post(GetMovieRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetSeriesRemoteSearchResults request) + public async Task Post(GetSeriesRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetGameRemoteSearchResults request) + public async Task Post(GetGameRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetBoxSetRemoteSearchResults request) + public async Task Post(GetBoxSetRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetPersonRemoteSearchResults request) + public async Task Post(GetPersonRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetMusicAlbumRemoteSearchResults request) + public async Task Post(GetMusicAlbumRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetMusicArtistRemoteSearchResults request) + public async Task Post(GetMusicArtistRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Get(GetRemoteSearchImage request) + public async Task Get(GetRemoteSearchImage request) { - var result = GetRemoteImage(request).Result; + var result = GetRemoteImage(request).ConfigureAwait(false); return result; } @@ -241,7 +241,7 @@ namespace MediaBrowser.Api if (_fileSystem.FileExists(contentPath)) { - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } } catch (DirectoryNotFoundException) @@ -261,7 +261,7 @@ namespace MediaBrowser.Api contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); } - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } /// diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index f9b3def97..4cd6a66ef 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -493,7 +493,7 @@ namespace MediaBrowser.Api.Library } } - public object Get(GetDownload request) + public Task Get(GetDownload request) { var item = _libraryManager.GetItemById(request.Id); var auth = _authContext.GetAuthorizationInfo(Request); @@ -552,7 +552,7 @@ namespace MediaBrowser.Api.Library } } - public object Get(GetFile request) + public Task Get(GetFile request) { var item = _libraryManager.GetItemById(request.Id); var locationType = item.LocationType; @@ -565,7 +565,7 @@ namespace MediaBrowser.Api.Library throw new ArgumentException("This command cannot be used for directories."); } - return ToStaticFileResult(item.Path); + return ResultFactory.GetStaticFileResult(Request, item.Path); } /// diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 41c0c39ea..48f7cd62e 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -785,7 +785,7 @@ namespace MediaBrowser.Api.LiveTv var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId); - var returnArray = _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ToArray(); + var returnArray = (await _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ConfigureAwait(false)).ToArray(); var result = new QueryResult { diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index ff18d440c..a2a935b12 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -111,16 +111,16 @@ namespace MediaBrowser.Api.Movies /// /// The request. /// System.Object. - public object Get(GetSimilarMovies request) + public async Task Get(GetSimilarMovies request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } - public object Get(GetSimilarTrailers request) + public async Task Get(GetSimilarTrailers request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -138,7 +138,7 @@ namespace MediaBrowser.Api.Movies return ToOptimizedResult(result); } - private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + private async Task> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; @@ -163,7 +163,7 @@ namespace MediaBrowser.Api.Movies var result = new QueryResult { - Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), + Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(), TotalRecordCount = itemsResult.Count }; @@ -296,7 +296,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = name, CategoryId = name.GetMD5().ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray() }; } } @@ -330,7 +330,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = name, CategoryId = name.GetMD5().ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray() }; } } @@ -361,7 +361,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = item.Name, CategoryId = item.Id.ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).Result.ToArray() }; } } diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index e774c3077..2d7e909bf 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -8,6 +8,7 @@ using ServiceStack; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Api.Music { @@ -49,18 +50,18 @@ namespace MediaBrowser.Api.Music _dtoService = dtoService; } - public object Get(GetSimilarArtists request) + public async Task Get(GetSimilarArtists request) { var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, + var result = await SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, _itemRepo, _libraryManager, _userDataRepository, _dtoService, Logger, request, new[] { typeof(MusicArtist) }, - SimilarItemsHelper.GetSimiliarityScore); + SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -70,18 +71,18 @@ namespace MediaBrowser.Api.Music /// /// The request. /// System.Object. - public object Get(GetSimilarAlbums request) + public async Task Get(GetSimilarAlbums request) { var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, + var result = await SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, _itemRepo, _libraryManager, _userDataRepository, _dtoService, Logger, request, new[] { typeof(MusicAlbum) }, - GetAlbumSimilarityScore); + GetAlbumSimilarityScore).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs index d2a4aa60c..19265408b 100644 --- a/MediaBrowser.Api/Music/InstantMixService.cs +++ b/MediaBrowser.Api/Music/InstantMixService.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying; using ServiceStack; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Api.Music { @@ -76,7 +77,7 @@ namespace MediaBrowser.Api.Music _libraryManager = libraryManager; } - public object Get(GetInstantMixFromItem request) + public Task Get(GetInstantMixFromItem request) { var item = _libraryManager.GetItemById(request.Id); @@ -87,7 +88,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromArtistId request) + public Task Get(GetInstantMixFromArtistId request) { var item = _libraryManager.GetItemById(request.Id); @@ -98,7 +99,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromMusicGenreId request) + public Task Get(GetInstantMixFromMusicGenreId request) { var item = _libraryManager.GetItemById(request.Id); @@ -109,7 +110,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromSong request) + public Task Get(GetInstantMixFromSong request) { var item = _libraryManager.GetItemById(request.Id); @@ -120,7 +121,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromAlbum request) + public Task Get(GetInstantMixFromAlbum request) { var album = _libraryManager.GetItemById(request.Id); @@ -131,7 +132,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromPlaylist request) + public Task Get(GetInstantMixFromPlaylist request) { var playlist = (Playlist)_libraryManager.GetItemById(request.Id); @@ -142,7 +143,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromMusicGenre request) + public Task Get(GetInstantMixFromMusicGenre request) { var user = _userManager.GetUserById(request.UserId); @@ -151,7 +152,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromArtist request) + public Task Get(GetInstantMixFromArtist request) { var user = _userManager.GetUserById(request.UserId); var artist = _libraryManager.GetArtist(request.Name); @@ -161,7 +162,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - private object GetResult(IEnumerable