diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index dedde2d9e1..e0ea6eb9a2 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Events; using MediaBrowser.Model.Querying; @@ -149,5 +150,20 @@ namespace MediaBrowser.Controller.Sync /// The query. /// 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); } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 116eda66ad..e3db46427a 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -421,7 +421,7 @@ namespace MediaBrowser.Server.Implementations.Sync var video = item as Video; if (video != null) { - await Sync(jobItem, video, user, deviceProfile, enableConversion, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, job, video, user, deviceProfile, enableConversion, progress, cancellationToken).ConfigureAwait(false); } else if (item is Audio) @@ -436,24 +436,27 @@ namespace MediaBrowser.Server.Implementations.Sync else { - await SyncGeneric(jobItem, item, deviceProfile, cancellationToken).ConfigureAwait(false); + await SyncGeneric(jobItem, item, cancellationToken).ConfigureAwait(false); } } - private async Task Sync(SyncJobItem jobItem, Video item, User user, DeviceProfile profile, bool enableConversion, IProgress progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, DeviceProfile profile, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { - var options = new VideoOptions - { - Context = EncodingContext.Static, - ItemId = item.Id.ToString("N"), - DeviceId = jobItem.TargetId, - Profile = profile, - MediaSources = item.GetMediaSources(false, user).ToList() - }; + 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 = item.GetMediaSources(false, user).ToList(); var streamInfo = new StreamBuilder().BuildVideoItem(options); var mediaSource = streamInfo.MediaSource; - var externalSubs = streamInfo.GetExternalSubtitles("dummy", false); + + // No sense creating external subs if we're already burning one into the video + var externalSubs = streamInfo.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode ? + new List() : + streamInfo.GetExternalSubtitles("dummy", false); // Mark as requiring conversion if transcoding the video, or if any subtitles need to be extracted var requiresConversion = streamInfo.PlayMethod == PlayMethod.Transcode || externalSubs.Any(i => RequiresExtraction(i, mediaSource)); @@ -610,14 +613,13 @@ namespace MediaBrowser.Server.Implementations.Sync private async Task Sync(SyncJobItem jobItem, Audio item, User user, DeviceProfile profile, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { - var options = new AudioOptions - { - Context = EncodingContext.Static, - ItemId = item.Id.ToString("N"), - DeviceId = jobItem.TargetId, - Profile = profile, - MediaSources = item.GetMediaSources(false, user).ToList() - }; + var options = _syncManager.GetAudioOptions(jobItem); + + options.DeviceId = jobItem.TargetId; + options.Context = EncodingContext.Static; + options.Profile = profile; + options.ItemId = item.Id.ToString("N"); + options.MediaSources = item.GetMediaSources(false, user).ToList(); var streamInfo = new StreamBuilder().BuildAudioItem(options); var mediaSource = streamInfo.MediaSource; @@ -693,7 +695,7 @@ namespace MediaBrowser.Server.Implementations.Sync await _syncRepo.Update(jobItem).ConfigureAwait(false); } - private async Task SyncGeneric(SyncJobItem jobItem, BaseItem item, DeviceProfile profile, CancellationToken cancellationToken) + private async Task SyncGeneric(SyncJobItem jobItem, BaseItem item, CancellationToken cancellationToken) { jobItem.OutputPath = item.Path; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index e468a5d73b..3c5b27d63c 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -103,14 +103,14 @@ namespace MediaBrowser.Server.Implementations.Sync var target = GetSyncTargets(request.UserId) .FirstOrDefault(i => string.Equals(request.TargetId, i.Id)); - + if (target == null) { throw new ArgumentException("Sync target not found."); } var jobId = Guid.NewGuid().ToString("N"); - + var job = new SyncJob { Id = jobId, @@ -748,5 +748,39 @@ namespace MediaBrowser.Server.Implementations.Sync { return _repo.GetLibraryItemIds(query); } + + public AudioOptions GetAudioOptions(SyncJobItem jobItem) + { + var profile = GetDeviceProfile(jobItem.TargetId); + + return new AudioOptions + { + Profile = profile + }; + } + + public VideoOptions GetVideoOptions(SyncJobItem jobItem, SyncJob job) + { + var profile = GetDeviceProfile(jobItem.TargetId); + var maxBitrate = profile.MaxStaticBitrate; + + if (maxBitrate.HasValue) + { + if (job.Quality == SyncQuality.Medium) + { + maxBitrate = Convert.ToInt32(maxBitrate.Value * .75); + } + else if (job.Quality == SyncQuality.Low) + { + maxBitrate = Convert.ToInt32(maxBitrate.Value * .5); + } + } + + return new VideoOptions + { + Profile = profile, + MaxBitrate = maxBitrate + }; + } } }