diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index 06c2dc2df3..23590940d3 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -27,6 +27,13 @@ namespace MediaBrowser.Api.Sync public string Id { get; set; } } + [Route("/Sync/QualityOptions", "GET", Summary = "Gets quality options for a sync target.")] + public class GetQualityOptions : IReturn> + { + [ApiMember(Name = "TargetId", Description = "TargetId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string TargetId { get; set; } + } + [Route("/Sync/Jobs/{Id}", "POST", Summary = "Updates a sync job.")] public class UpdateSyncJob : SyncJob, IReturnVoid { @@ -222,6 +229,13 @@ namespace MediaBrowser.Api.Sync return ToStaticFileResult(jobItem.OutputPath); } + public object Get(GetQualityOptions request) + { + return ToOptimizedResult(_syncManager + .GetQualityOptions(request.TargetId) + .ToList()); + } + public object Get(GetSyncDialogOptions request) { var result = new SyncDialogOptions(); @@ -234,6 +248,10 @@ namespace MediaBrowser.Api.Sync result.Targets = result.Targets .Where(i => string.Equals(i.Id, request.TargetId, StringComparison.OrdinalIgnoreCase)) .ToList(); + + result.QualityOptions = _syncManager + .GetQualityOptions(request.TargetId) + .ToList(); } if (request.Category.HasValue) @@ -264,30 +282,6 @@ namespace MediaBrowser.Api.Sync result.Options = SyncHelper.GetSyncOptions(dtos); } - result.QualityOptions = new List - { - new SyncQualityOption - { - Name = SyncQuality.Original.ToString(), - Id = SyncQuality.Original.ToString() - }, - new SyncQualityOption - { - Name = SyncQuality.High.ToString(), - Id = SyncQuality.High.ToString() - }, - new SyncQualityOption - { - Name = SyncQuality.Medium.ToString(), - Id = SyncQuality.Medium.ToString() - }, - new SyncQualityOption - { - Name = SyncQuality.Low.ToString(), - Id = SyncQuality.Low.ToString() - } - }; - return ToOptimizedResult(result); } diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 4b800cac96..dea0ff9727 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -90,13 +90,6 @@ namespace MediaBrowser.Controller.Sync /// true if XXXX, false otherwise. bool SupportsSync(BaseItem item); - /// - /// Gets the device profile. - /// - /// The target identifier. - /// DeviceProfile. - DeviceProfile GetDeviceProfile(string targetId); - /// /// Reports the synchronize job item transferred. /// @@ -153,21 +146,6 @@ namespace MediaBrowser.Controller.Sync /// QueryResult<System.String>. QueryResult GetLibraryItemIds(SyncJobItemQuery query); - /// - /// Gets the audio options. - /// - /// The job item. - /// AudioOptions. - AudioOptions GetAudioOptions(SyncJobItem jobItem); - - /// - /// Gets the video options. - /// - /// The job item. - /// The job. - /// VideoOptions. - VideoOptions GetVideoOptions(SyncJobItem jobItem, SyncJob job); - /// /// Reports the synchronize job item transfer beginning. /// @@ -181,5 +159,12 @@ namespace MediaBrowser.Controller.Sync /// The identifier. /// Task. Task ReportSyncJobItemTransferFailed(string id); + + /// + /// Gets the quality options. + /// + /// The target identifier. + /// IEnumerable<SyncQualityOption>. + IEnumerable GetQualityOptions(string targetId); } } diff --git a/MediaBrowser.Model/Sync/SyncQualityOption.cs b/MediaBrowser.Model/Sync/SyncQualityOption.cs index 6dc42fa481..1945613c06 100644 --- a/MediaBrowser.Model/Sync/SyncQualityOption.cs +++ b/MediaBrowser.Model/Sync/SyncQualityOption.cs @@ -13,5 +13,10 @@ namespace MediaBrowser.Model.Sync /// /// The identifier. public string Id { get; set; } + /// + /// Gets or sets a value indicating whether this instance is default. + /// + /// true if this instance is default; otherwise, false. + public bool IsDefault { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 95443a5daa..6292defc15 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -307,7 +307,7 @@ - + diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs index 2106fc12e9..e6af28c7dd 100644 --- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs @@ -8,7 +8,7 @@ using System.Linq; namespace MediaBrowser.Server.Implementations.Sync { - public class AppSyncProvider : ISyncProvider, IHasUniqueTargetIds, IHasSyncProfile + public class AppSyncProvider : ISyncProvider, IHasUniqueTargetIds, IHasSyncQuality { private readonly IDeviceManager _deviceManager; @@ -55,5 +55,33 @@ namespace MediaBrowser.Server.Implementations.Sync Name = i.Name }); } + + public IEnumerable GetQualityOptions(SyncTarget target) + { + return new List + { + new SyncQualityOption + { + Name = SyncQuality.Original.ToString(), + Id = SyncQuality.Original.ToString() + }, + new SyncQualityOption + { + Name = SyncQuality.High.ToString(), + Id = SyncQuality.High.ToString(), + IsDefault = true + }, + new SyncQualityOption + { + Name = SyncQuality.Medium.ToString(), + Id = SyncQuality.Medium.ToString() + }, + new SyncQualityOption + { + Name = SyncQuality.Low.ToString(), + Id = SyncQuality.Low.ToString() + } + }; + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/IHasSyncProfile.cs b/MediaBrowser.Server.Implementations/Sync/IHasSyncQuality.cs similarity index 51% rename from MediaBrowser.Server.Implementations/Sync/IHasSyncProfile.cs rename to MediaBrowser.Server.Implementations/Sync/IHasSyncQuality.cs index b7e9daf496..9b45e66e12 100644 --- a/MediaBrowser.Server.Implementations/Sync/IHasSyncProfile.cs +++ b/MediaBrowser.Server.Implementations/Sync/IHasSyncQuality.cs @@ -1,9 +1,10 @@ using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Sync; +using System.Collections.Generic; namespace MediaBrowser.Server.Implementations.Sync { - public interface IHasSyncProfile + public interface IHasSyncQuality { /// /// Gets the device profile. @@ -11,5 +12,12 @@ namespace MediaBrowser.Server.Implementations.Sync /// The target. /// DeviceProfile. DeviceProfile GetDeviceProfile(SyncTarget target); + + /// + /// Gets the quality options. + /// + /// The target. + /// IEnumerable<SyncQualityOption>. + IEnumerable GetQualityOptions(SyncTarget target); } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 9be2dd5f0f..2dbf8fc1b6 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -450,15 +450,6 @@ namespace MediaBrowser.Server.Implementations.Sync return; } - var deviceProfile = _syncManager.GetDeviceProfile(jobItem.TargetId); - if (deviceProfile == null) - { - jobItem.Status = SyncJobItemStatus.Failed; - _logger.Error("Unable to locate SyncTarget for JobItem {0}, SyncTargetId {1}", jobItem.Id, jobItem.TargetId); - await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - return; - } - jobItem.Progress = 0; var user = _userManager.GetUserById(job.UserId); @@ -466,17 +457,17 @@ namespace MediaBrowser.Server.Implementations.Sync var video = item as Video; if (video != null) { - await Sync(jobItem, job, video, user, deviceProfile, enableConversion, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, job, video, user, enableConversion, progress, cancellationToken).ConfigureAwait(false); } else if (item is Audio) { - await Sync(jobItem, job, (Audio)item, user, deviceProfile, enableConversion, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, job, (Audio)item, user, enableConversion, progress, cancellationToken).ConfigureAwait(false); } else if (item is Photo) { - await Sync(jobItem, (Photo)item, deviceProfile, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, (Photo)item, cancellationToken).ConfigureAwait(false); } else @@ -491,13 +482,12 @@ namespace MediaBrowser.Server.Implementations.Sync string.Equals(job.Quality, "original", StringComparison.OrdinalIgnoreCase); } - private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, DeviceProfile profile, bool enableConversion, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { var options = _syncManager.GetVideoOptions(jobItem, job); options.DeviceId = jobItem.TargetId; options.Context = EncodingContext.Static; - options.Profile = profile; options.ItemId = item.Id.ToString("N"); options.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList(); @@ -548,7 +538,7 @@ namespace MediaBrowser.Server.Implementations.Sync } }); - jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, profile) + jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, options.Profile) { OutputDirectory = jobItem.TemporaryPath @@ -682,13 +672,12 @@ namespace MediaBrowser.Server.Implementations.Sync private const int DatabaseProgressUpdateIntervalSeconds = 2; - private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, DeviceProfile profile, bool enableConversion, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { - var options = _syncManager.GetAudioOptions(jobItem); + var options = _syncManager.GetAudioOptions(jobItem, job); options.DeviceId = jobItem.TargetId; options.Context = EncodingContext.Static; - options.Profile = profile; options.ItemId = item.Id.ToString("N"); options.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList(); @@ -725,7 +714,7 @@ namespace MediaBrowser.Server.Implementations.Sync } }); - jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile) + jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, options.Profile) { OutputDirectory = jobItem.TemporaryPath @@ -773,7 +762,7 @@ namespace MediaBrowser.Server.Implementations.Sync await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); } - private async Task Sync(SyncJobItem jobItem, Photo item, DeviceProfile profile, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Photo item, CancellationToken cancellationToken) { jobItem.OutputPath = item.Path; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 3e4d1c1a81..c02a54f901 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -92,7 +92,7 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly ConcurrentDictionary _dataProviders = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - + public ISyncDataProvider GetDataProvider(IServerSyncProvider provider, SyncTarget target) { return _dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost.SystemId, _logger, _json, _fileSystem, _config.CommonApplicationPaths)); @@ -972,9 +972,9 @@ namespace MediaBrowser.Server.Implementations.Sync return _repo.GetLibraryItemIds(query); } - public AudioOptions GetAudioOptions(SyncJobItem jobItem) + public AudioOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job) { - var profile = GetDeviceProfile(jobItem.TargetId); + var profile = GetDeviceProfile(jobItem.TargetId, job.Quality); return new AudioOptions { @@ -984,16 +984,16 @@ namespace MediaBrowser.Server.Implementations.Sync public VideoOptions GetVideoOptions(SyncJobItem jobItem, SyncJob job) { - var profile = GetDeviceProfile(jobItem.TargetId); + var profile = GetDeviceProfile(jobItem.TargetId, job.Quality); var maxBitrate = profile.MaxStaticBitrate; if (maxBitrate.HasValue) { - if (string.Equals(job.Quality, "high", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(job.Quality, "medium", StringComparison.OrdinalIgnoreCase)) { maxBitrate = Convert.ToInt32(maxBitrate.Value * .75); } - else if (string.Equals(job.Quality, "medium", StringComparison.OrdinalIgnoreCase)) + else if (string.Equals(job.Quality, "low", StringComparison.OrdinalIgnoreCase)) { maxBitrate = Convert.ToInt32(maxBitrate.Value * .5); } @@ -1006,7 +1006,7 @@ namespace MediaBrowser.Server.Implementations.Sync }; } - public DeviceProfile GetDeviceProfile(string targetId) + public DeviceProfile GetDeviceProfile(string targetId, string quality) { foreach (var provider in _providers) { @@ -1014,7 +1014,7 @@ namespace MediaBrowser.Server.Implementations.Sync { if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase)) { - return GetDeviceProfile(provider, target); + return GetDeviceProfile(provider, target, quality); } } } @@ -1022,9 +1022,9 @@ namespace MediaBrowser.Server.Implementations.Sync return null; } - public DeviceProfile GetDeviceProfile(ISyncProvider provider, SyncTarget target) + private DeviceProfile GetDeviceProfile(ISyncProvider provider, SyncTarget target, string quality) { - var hasProfile = provider as IHasSyncProfile; + var hasProfile = provider as IHasSyncQuality; if (hasProfile != null) { @@ -1033,5 +1033,56 @@ namespace MediaBrowser.Server.Implementations.Sync return new CloudSyncProfile(true, false); } + + public IEnumerable GetQualityOptions(string targetId) + { + foreach (var provider in _providers) + { + foreach (var target in GetSyncTargets(provider)) + { + if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase)) + { + return GetQualityOptions(provider, target); + } + } + } + + return new List(); + } + + private IEnumerable GetQualityOptions(ISyncProvider provider, SyncTarget target) + { + var hasQuality = provider as IHasSyncQuality; + if (hasQuality != null) + { + return hasQuality.GetQualityOptions(target); + } + + // Default options for providers that don't override + return new List + { + new SyncQualityOption + { + Name = SyncQuality.Original.ToString(), + Id = SyncQuality.Original.ToString() + }, + new SyncQualityOption + { + Name = SyncQuality.High.ToString(), + Id = SyncQuality.High.ToString(), + IsDefault = true + }, + new SyncQualityOption + { + Name = SyncQuality.Medium.ToString(), + Id = SyncQuality.Medium.ToString() + }, + new SyncQualityOption + { + Name = SyncQuality.Low.ToString(), + Id = SyncQuality.Low.ToString() + } + }; + } } }