diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations/Sync')
6 files changed, 76 insertions, 18 deletions
diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs index 7b1fa4dec..03485012f 100644 --- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs @@ -9,7 +9,7 @@ using System.Linq; namespace MediaBrowser.Server.Implementations.Sync { - public class AppSyncProvider : ISyncProvider, IHasUniqueTargetIds, IHasSyncQuality + public class AppSyncProvider : ISyncProvider, IHasUniqueTargetIds, IHasSyncQuality, IHasDuplicateCheck { private readonly IDeviceManager _deviceManager; @@ -104,5 +104,10 @@ namespace MediaBrowser.Server.Implementations.Sync IsConverting = isConverting }; } + + public bool AllowDuplicateJobItem(SyncJobItem original, SyncJobItem duplicate) + { + return false; + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs index 913d50e9d..5347e1d83 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs @@ -70,8 +70,7 @@ namespace MediaBrowser.Server.Implementations.Sync { return new ITaskTrigger[] { - new IntervalTrigger { Interval = TimeSpan.FromHours(3) }, - new StartupTrigger{ DelayMs = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalMilliseconds)} + new IntervalTrigger { Interval = TimeSpan.FromHours(3) } }; } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs index 006284ee1..b6242950f 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs @@ -10,11 +10,11 @@ namespace MediaBrowser.Server.Implementations.Sync { if (string.Equals(quality, "medium", StringComparison.OrdinalIgnoreCase)) { - profileBitrate = Convert.ToInt32(profileBitrate.Value * .75); + profileBitrate = Math.Min(Convert.ToInt32(profileBitrate.Value * .7), 4000000); } else if (string.Equals(quality, "low", StringComparison.OrdinalIgnoreCase)) { - profileBitrate = Convert.ToInt32(profileBitrate.Value*.5); + profileBitrate = Math.Min(Convert.ToInt32(profileBitrate.Value * .5), 1500000); } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 04ebcd903..1061a373e 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -466,6 +466,32 @@ namespace MediaBrowser.Server.Implementations.Sync return; } + // See if there's already another active job item for the same target + var existingJobItems = _syncManager.GetJobItems(new SyncJobItemQuery + { + AddMetadata = false, + ItemId = jobItem.ItemId, + TargetId = job.TargetId, + Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring } + }); + + var duplicateJobItems = existingJobItems.Items + .Where(i => !string.Equals(i.Id, jobItem.Id, StringComparison.OrdinalIgnoreCase)) + .ToList(); + + if (duplicateJobItems.Count > 0) + { + var syncProvider = _syncManager.GetSyncProvider(jobItem, job) as IHasDuplicateCheck; + + if (!duplicateJobItems.Any(i => AllowDuplicateJobItem(syncProvider, i, jobItem))) + { + _logger.Debug("Cancelling sync job item because there is already another active job for the same target."); + jobItem.Status = SyncJobItemStatus.Cancelled; + await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); + return; + } + } + var video = item as Video; if (video != null) { @@ -488,6 +514,16 @@ namespace MediaBrowser.Server.Implementations.Sync } } + private bool AllowDuplicateJobItem(IHasDuplicateCheck provider, SyncJobItem original, SyncJobItem duplicate) + { + if (provider != null) + { + return provider.AllowDuplicateJobItem(original, duplicate); + } + + return true; + } + private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress<double> progress, CancellationToken cancellationToken) { var jobOptions = _syncManager.GetVideoOptions(jobItem, job); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 6c71a90a0..18fcb4e79 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1,8 +1,8 @@ -using MediaBrowser.Common; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; +using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Drawing; @@ -32,7 +32,6 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common.ScheduledTasks; namespace MediaBrowser.Server.Implementations.Sync { @@ -52,8 +51,8 @@ namespace MediaBrowser.Server.Implementations.Sync private readonly IConfigurationManager _config; private readonly IUserDataManager _userDataManager; private readonly Func<IMediaSourceManager> _mediaSourceManager; - private readonly IJsonSerializer _json; - private readonly ITaskManager _taskManager; + private readonly IJsonSerializer _json; + private readonly ITaskManager _taskManager; private ISyncProvider[] _providers = { }; @@ -63,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Sync public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated; public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated; - public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json, ITaskManager taskManager) + public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json, ITaskManager taskManager) { _libraryManager = libraryManager; _repo = repo; @@ -80,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.Sync _userDataManager = userDataManager; _mediaSourceManager = mediaSourceManager; _json = json; - _taskManager = taskManager; + _taskManager = taskManager; } public void AddParts(IEnumerable<ISyncProvider> providers) @@ -126,7 +125,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (string.IsNullOrWhiteSpace(request.Name)) { - throw new ArgumentException("Please supply a name for the sync job."); + request.Name = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString(); } var target = GetSyncTargets(request.UserId) @@ -217,9 +216,10 @@ namespace MediaBrowser.Server.Implementations.Sync }, _logger); } - if (returnResult.JobItems.Any (i => i.Status == SyncJobItemStatus.Queued || i.Status == SyncJobItemStatus.Converting)) { - _taskManager.QueueScheduledTask<SyncConvertScheduledTask> (); - } + if (returnResult.JobItems.Any(i => i.Status == SyncJobItemStatus.Queued || i.Status == SyncJobItemStatus.Converting)) + { + _taskManager.QueueScheduledTask<SyncConvertScheduledTask>(); + } return returnResult; } @@ -1159,6 +1159,21 @@ namespace MediaBrowser.Server.Implementations.Sync return options; } + public ISyncProvider GetSyncProvider(SyncJobItem jobItem, SyncJob job) + { + foreach (var provider in _providers) + { + foreach (var target in GetSyncTargets(provider)) + { + if (string.Equals(target.Id, jobItem.TargetId, StringComparison.OrdinalIgnoreCase)) + { + return provider; + } + } + } + return null; + } + public SyncJobOptions GetVideoOptions(SyncJobItem jobItem, SyncJob job) { var options = GetSyncJobOptions(jobItem.TargetId, job.Profile, job.Quality); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs index f7f320741..efd37fa00 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs @@ -90,15 +90,18 @@ namespace MediaBrowser.Server.Implementations.Sync keyList.Add(provider.GetType().FullName.GetMD5().ToString("N")); keyList.Add(target.Id.GetMD5().ToString("N")); keyList.Add(item.Id); - mediaSource.OpenToken = string.Join("|", keyList.ToArray()); + mediaSource.OpenToken = string.Join(StreamIdDelimeterString, keyList.ToArray()); } list.Add(mediaSource); } + // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message. + private const string StreamIdDelimeterString = "_"; + public async Task<MediaSourceInfo> OpenMediaSource(string openToken, CancellationToken cancellationToken) { - var openKeys = openToken.Split(new[] { '|' }, 3); + var openKeys = openToken.Split(new[] { StreamIdDelimeterString[0] }, 3); var provider = _syncManager.ServerSyncProviders .FirstOrDefault(i => string.Equals(openKeys[0], i.GetType().FullName.GetMD5().ToString("N"), StringComparison.OrdinalIgnoreCase)); |
