diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index fc48e9a3a..503f9927c 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -135,6 +135,7 @@
+
diff --git a/MediaBrowser.Model/Sync/SyncHelper.cs b/MediaBrowser.Api/Sync/SyncHelper.cs
similarity index 97%
rename from MediaBrowser.Model/Sync/SyncHelper.cs
rename to MediaBrowser.Api/Sync/SyncHelper.cs
index 34a5ba995..d0a866c02 100644
--- a/MediaBrowser.Model/Sync/SyncHelper.cs
+++ b/MediaBrowser.Api/Sync/SyncHelper.cs
@@ -1,7 +1,8 @@
using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Sync;
using System.Collections.Generic;
-namespace MediaBrowser.Model.Sync
+namespace MediaBrowser.Api.Sync
{
public static class SyncHelper
{
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 06f18729b..beb64b373 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -397,6 +397,7 @@
+
diff --git a/MediaBrowser.Controller/Sync/SyncJobOptions.cs b/MediaBrowser.Controller/Sync/SyncJobOptions.cs
new file mode 100644
index 000000000..abd6d2553
--- /dev/null
+++ b/MediaBrowser.Controller/Sync/SyncJobOptions.cs
@@ -0,0 +1,19 @@
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Controller.Sync
+{
+ public class SyncJobOptions
+ where T : AudioOptions, new ()
+ {
+ ///
+ /// Gets or sets the conversion options.
+ ///
+ /// The conversion options.
+ public T ConversionOptions { get; set; }
+ ///
+ /// Gets or sets a value indicating whether this instance is converting.
+ ///
+ /// true if this instance is converting; otherwise, false.
+ public bool IsConverting { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index f60f227d7..c2d46b9b3 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -1100,9 +1100,6 @@
Sync\SyncedItem.cs
-
- Sync\SyncHelper.cs
-
Sync\SyncJob.cs
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index 1685d5f7b..129c667a0 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -1059,9 +1059,6 @@
Sync\SyncedItem.cs
-
- Sync\SyncHelper.cs
-
Sync\SyncJob.cs
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index c546958aa..3a6eda620 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -387,7 +387,6 @@
-
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index c4ef3e9de..1915814e1 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -231,6 +231,7 @@
+
diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
index ff43816b0..016ad19eb 100644
--- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
+++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
@@ -3,7 +3,6 @@ using MediaBrowser.Controller.Sync;
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Sync;
-using System;
using System.Collections.Generic;
using System.Linq;
@@ -37,21 +36,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var caps = _deviceManager.GetCapabilities(target.Id);
var deviceProfile = caps == null || caps.DeviceProfile == null ? new DeviceProfile() : caps.DeviceProfile;
- var maxBitrate = deviceProfile.MaxStaticBitrate;
-
- if (maxBitrate.HasValue)
- {
- if (string.Equals(quality, "medium", StringComparison.OrdinalIgnoreCase))
- {
- maxBitrate = Convert.ToInt32(maxBitrate.Value * .75);
- }
- else if (string.Equals(quality, "low", StringComparison.OrdinalIgnoreCase))
- {
- maxBitrate = Convert.ToInt32(maxBitrate.Value * .5);
- }
-
- deviceProfile.MaxStaticBitrate = maxBitrate;
- }
+ deviceProfile.MaxStaticBitrate = SyncHelper.AdjustBitrate(deviceProfile.MaxStaticBitrate, quality);
return deviceProfile;
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs
new file mode 100644
index 000000000..6bcb27328
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Globalization;
+
+namespace MediaBrowser.Server.Implementations.Sync
+{
+ public class SyncHelper
+ {
+ public static int? AdjustBitrate(int? profileBitrate, string quality)
+ {
+ if (profileBitrate.HasValue)
+ {
+ if (string.Equals(quality, "medium", StringComparison.OrdinalIgnoreCase))
+ {
+ profileBitrate = Convert.ToInt32(profileBitrate.Value * .75);
+ }
+ else if (string.Equals(quality, "low", StringComparison.OrdinalIgnoreCase))
+ {
+ profileBitrate = Convert.ToInt32(profileBitrate.Value*.5);
+ }
+ else
+ {
+ int value;
+ if (int.TryParse(quality, NumberStyles.Any, CultureInfo.InvariantCulture, out value))
+ {
+ profileBitrate = value;
+ }
+ }
+ }
+
+ return profileBitrate;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
index 8fb4b5a3a..aecd9280d 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
@@ -476,22 +476,17 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- private bool IsOriginalQuality(SyncJob job)
- {
- return string.IsNullOrWhiteSpace(job.Quality) ||
- string.Equals(job.Quality, "original", StringComparison.OrdinalIgnoreCase);
- }
-
private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, IProgress progress, CancellationToken cancellationToken)
{
- var options = _syncManager.GetVideoOptions(jobItem, job);
+ var jobOptions = _syncManager.GetVideoOptions(jobItem, job);
+ var conversionOptions = jobOptions.ConversionOptions;
- options.DeviceId = jobItem.TargetId;
- options.Context = EncodingContext.Static;
- options.ItemId = item.Id.ToString("N");
- options.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList();
+ conversionOptions.DeviceId = jobItem.TargetId;
+ conversionOptions.Context = EncodingContext.Static;
+ conversionOptions.ItemId = item.Id.ToString("N");
+ conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList();
- var streamInfo = new StreamBuilder().BuildVideoItem(options);
+ var streamInfo = new StreamBuilder().BuildVideoItem(conversionOptions);
var mediaSource = streamInfo.MediaSource;
// No sense creating external subs if we're already burning one into the video
@@ -500,7 +495,7 @@ namespace MediaBrowser.Server.Implementations.Sync
streamInfo.GetExternalSubtitles(false);
// Mark as requiring conversion if transcoding the video, or if any subtitles need to be extracted
- var requiresVideoTranscoding = streamInfo.PlayMethod == PlayMethod.Transcode && IsOriginalQuality(job);
+ var requiresVideoTranscoding = streamInfo.PlayMethod == PlayMethod.Transcode && jobOptions.IsConverting;
var requiresConversion = requiresVideoTranscoding || externalSubs.Any(i => RequiresExtraction(i, mediaSource));
if (requiresConversion && !enableConversion)
@@ -538,7 +533,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
});
- jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, options.Profile)
+ jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, conversionOptions.Profile)
{
OutputDirectory = jobItem.TemporaryPath
@@ -676,20 +671,21 @@ namespace MediaBrowser.Server.Implementations.Sync
private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, bool enableConversion, IProgress progress, CancellationToken cancellationToken)
{
- var options = _syncManager.GetAudioOptions(jobItem, job);
+ var jobOptions = _syncManager.GetAudioOptions(jobItem, job);
+ var conversionOptions = jobOptions.ConversionOptions;
- options.DeviceId = jobItem.TargetId;
- options.Context = EncodingContext.Static;
- options.ItemId = item.Id.ToString("N");
- options.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList();
+ conversionOptions.DeviceId = jobItem.TargetId;
+ conversionOptions.Context = EncodingContext.Static;
+ conversionOptions.ItemId = item.Id.ToString("N");
+ conversionOptions.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, false, user).ToList();
- var streamInfo = new StreamBuilder().BuildAudioItem(options);
+ var streamInfo = new StreamBuilder().BuildAudioItem(conversionOptions);
var mediaSource = streamInfo.MediaSource;
jobItem.MediaSourceId = streamInfo.MediaSourceId;
jobItem.TemporaryPath = GetTemporaryPath(jobItem);
- if (streamInfo.PlayMethod == PlayMethod.Transcode && !IsOriginalQuality(job))
+ if (streamInfo.PlayMethod == PlayMethod.Transcode && jobOptions.IsConverting)
{
if (!enableConversion)
{
@@ -716,7 +712,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
});
- jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, options.Profile)
+ jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, conversionOptions.Profile)
{
OutputDirectory = jobItem.TemporaryPath
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index 19e3841d1..0ec05a0aa 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -982,23 +982,34 @@ namespace MediaBrowser.Server.Implementations.Sync
return _repo.GetLibraryItemIds(query);
}
- public AudioOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job)
+ private bool IsOriginalQuality(SyncJob job)
{
- var profile = GetDeviceProfile(jobItem.TargetId, null, null);
-
- return new AudioOptions
+ return string.IsNullOrWhiteSpace(job.Quality) ||
+ string.Equals(job.Quality, "original", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(job.Profile, "original", StringComparison.OrdinalIgnoreCase);
+ }
+
+ public SyncJobOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job)
+ {
+ return new SyncJobOptions
{
- Profile = profile
+ ConversionOptions = new AudioOptions
+ {
+ Profile = GetDeviceProfile(jobItem.TargetId, null, null)
+ },
+ IsConverting = !IsOriginalQuality(job)
};
}
- public VideoOptions GetVideoOptions(SyncJobItem jobItem, SyncJob job)
+ public SyncJobOptions GetVideoOptions(SyncJobItem jobItem, SyncJob job)
{
- var profile = GetDeviceProfile(jobItem.TargetId, job.Profile, job.Quality);
-
- return new VideoOptions
+ return new SyncJobOptions
{
- Profile = profile
+ ConversionOptions = new VideoOptions
+ {
+ Profile = GetDeviceProfile(jobItem.TargetId, job.Profile, job.Quality)
+ },
+ IsConverting = !IsOriginalQuality(job)
};
}
@@ -1033,21 +1044,7 @@ namespace MediaBrowser.Server.Implementations.Sync
private DeviceProfile GetDeviceProfile(string profile, string quality)
{
var deviceProfile = new CloudSyncProfile(true, false);
- var maxBitrate = deviceProfile.MaxStaticBitrate;
-
- if (maxBitrate.HasValue)
- {
- if (string.Equals(quality, "medium", StringComparison.OrdinalIgnoreCase))
- {
- maxBitrate = Convert.ToInt32(maxBitrate.Value * .75);
- }
- else if (string.Equals(quality, "low", StringComparison.OrdinalIgnoreCase))
- {
- maxBitrate = Convert.ToInt32(maxBitrate.Value * .5);
- }
-
- deviceProfile.MaxStaticBitrate = maxBitrate;
- }
+ deviceProfile.MaxStaticBitrate = SyncHelper.AdjustBitrate(deviceProfile.MaxStaticBitrate, quality);
return deviceProfile;
}
@@ -1139,16 +1136,16 @@ namespace MediaBrowser.Server.Implementations.Sync
list.Add(new SyncProfileOption
{
- Name = "Web - H264/AAC, MP3",
- Id = "mobile",
- Description = "Designed for compatibility with all devices, including web browsers."
+ Name = "Baseline",
+ Id = "baseline",
+ Description = "Designed for compatibility with all devices, including web browsers. Targets H264/AAC video and MP3 audio."
});
list.Add(new SyncProfileOption
{
- Name = "General - H264/AAC/AC3, MP3",
+ Name = "General",
Id = "general",
- Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices.",
+ Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices. Targets H264/AAC/AC3 video and MP3 audio.",
IsDefault = true
});