aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2015-04-05 11:01:57 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2015-04-05 11:01:57 -0400
commit30104bd8de62715d127823e69dc0de9e65d99840 (patch)
tree224778b0ee698cc387e1e28058b5398f99a0da23 /MediaBrowser.Server.Implementations
parent2b7a80cfb5b9212260734c095a5b3439af7d64e2 (diff)
probe live streams after opening
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs4
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/ThrottledStream.cs393
-rw-r--r--MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs27
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs2
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs10
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/server.json8
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj1
-rw-r--r--MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sync/MediaSync.cs27
-rw-r--r--MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncManager.cs56
13 files changed, 108 insertions, 442 deletions
diff --git a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs
index bbe37cb50..8f5d8fe9b 100644
--- a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs
+++ b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs
@@ -14,9 +14,7 @@ namespace MediaBrowser.Server.Implementations.Collections
public override bool IsVisible(User user)
{
- return base.IsVisible(user) && GetChildren(user, false)
- .OfType<BoxSet>()
- .Any(i => i.IsVisible(user));
+ return base.IsVisible(user) && GetChildren(user, false).Any();
}
public override bool IsHidden
diff --git a/MediaBrowser.Server.Implementations/HttpServer/ThrottledStream.cs b/MediaBrowser.Server.Implementations/HttpServer/ThrottledStream.cs
deleted file mode 100644
index 1c01fa9e0..000000000
--- a/MediaBrowser.Server.Implementations/HttpServer/ThrottledStream.cs
+++ /dev/null
@@ -1,393 +0,0 @@
-using System;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Server.Implementations.HttpServer
-{
- /// <summary>
- /// Class for streaming data with throttling support.
- /// </summary>
- public class ThrottledStream : Stream
- {
- /// <summary>
- /// A constant used to specify an infinite number of bytes that can be transferred per second.
- /// </summary>
- public const long Infinite = 0;
-
- #region Private members
- /// <summary>
- /// The base stream.
- /// </summary>
- private readonly Stream _baseStream;
-
- /// <summary>
- /// The maximum bytes per second that can be transferred through the base stream.
- /// </summary>
- private long _maximumBytesPerSecond;
-
- /// <summary>
- /// The number of bytes that has been transferred since the last throttle.
- /// </summary>
- private long _byteCount;
-
- /// <summary>
- /// The start time in milliseconds of the last throttle.
- /// </summary>
- private long _start;
- #endregion
-
- #region Properties
- /// <summary>
- /// Gets the current milliseconds.
- /// </summary>
- /// <value>The current milliseconds.</value>
- protected long CurrentMilliseconds
- {
- get
- {
- return Environment.TickCount;
- }
- }
-
- /// <summary>
- /// Gets or sets the maximum bytes per second that can be transferred through the base stream.
- /// </summary>
- /// <value>The maximum bytes per second.</value>
- public long MaximumBytesPerSecond
- {
- get
- {
- return _maximumBytesPerSecond;
- }
- set
- {
- if (MaximumBytesPerSecond != value)
- {
- _maximumBytesPerSecond = value;
- Reset();
- }
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether the current stream supports reading.
- /// </summary>
- /// <returns>true if the stream supports reading; otherwise, false.</returns>
- public override bool CanRead
- {
- get
- {
- return _baseStream.CanRead;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether the current stream supports seeking.
- /// </summary>
- /// <value></value>
- /// <returns>true if the stream supports seeking; otherwise, false.</returns>
- public override bool CanSeek
- {
- get
- {
- return _baseStream.CanSeek;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether the current stream supports writing.
- /// </summary>
- /// <value></value>
- /// <returns>true if the stream supports writing; otherwise, false.</returns>
- public override bool CanWrite
- {
- get
- {
- return _baseStream.CanWrite;
- }
- }
-
- /// <summary>
- /// Gets the length in bytes of the stream.
- /// </summary>
- /// <value></value>
- /// <returns>A long value representing the length of the stream in bytes.</returns>
- /// <exception cref="T:System.NotSupportedException">The base stream does not support seeking. </exception>
- /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
- public override long Length
- {
- get
- {
- return _baseStream.Length;
- }
- }
-
- /// <summary>
- /// Gets or sets the position within the current stream.
- /// </summary>
- /// <value></value>
- /// <returns>The current position within the stream.</returns>
- /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
- /// <exception cref="T:System.NotSupportedException">The base stream does not support seeking. </exception>
- /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
- public override long Position
- {
- get
- {
- return _baseStream.Position;
- }
- set
- {
- _baseStream.Position = value;
- }
- }
- #endregion
-
- public long MinThrottlePosition;
-
- #region Ctor
- /// <summary>
- /// Initializes a new instance of the <see cref="T:ThrottledStream"/> class.
- /// </summary>
- /// <param name="baseStream">The base stream.</param>
- /// <param name="maximumBytesPerSecond">The maximum bytes per second that can be transferred through the base stream.</param>
- /// <exception cref="ArgumentNullException">Thrown when <see cref="baseStream"/> is a null reference.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown when <see cref="maximumBytesPerSecond"/> is a negative value.</exception>
- public ThrottledStream(Stream baseStream, long maximumBytesPerSecond)
- {
- if (baseStream == null)
- {
- throw new ArgumentNullException("baseStream");
- }
-
- if (maximumBytesPerSecond < 0)
- {
- throw new ArgumentOutOfRangeException("maximumBytesPerSecond",
- maximumBytesPerSecond, "The maximum number of bytes per second can't be negative.");
- }
-
- _baseStream = baseStream;
- _maximumBytesPerSecond = maximumBytesPerSecond;
- _start = CurrentMilliseconds;
- _byteCount = 0;
- }
- #endregion
-
- #region Public methods
- /// <summary>
- /// Clears all buffers for this stream and causes any buffered data to be written to the underlying device.
- /// </summary>
- /// <exception cref="T:System.IO.IOException">An I/O error occurs.</exception>
- public override void Flush()
- {
- _baseStream.Flush();
- }
-
- /// <summary>
- /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
- /// </summary>
- /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source.</param>
- /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
- /// <param name="count">The maximum number of bytes to be read from the current stream.</param>
- /// <returns>
- /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
- /// </returns>
- /// <exception cref="T:System.ArgumentException">The sum of offset and count is larger than the buffer length. </exception>
- /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
- /// <exception cref="T:System.NotSupportedException">The base stream does not support reading. </exception>
- /// <exception cref="T:System.ArgumentNullException">buffer is null. </exception>
- /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
- /// <exception cref="T:System.ArgumentOutOfRangeException">offset or count is negative. </exception>
- public override int Read(byte[] buffer, int offset, int count)
- {
- Throttle(count);
-
- return _baseStream.Read(buffer, offset, count);
- }
-
- /// <summary>
- /// Sets the position within the current stream.
- /// </summary>
- /// <param name="offset">A byte offset relative to the origin parameter.</param>
- /// <param name="origin">A value of type <see cref="T:System.IO.SeekOrigin"></see> indicating the reference point used to obtain the new position.</param>
- /// <returns>
- /// The new position within the current stream.
- /// </returns>
- /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
- /// <exception cref="T:System.NotSupportedException">The base stream does not support seeking, such as if the stream is constructed from a pipe or console output. </exception>
- /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
- public override long Seek(long offset, SeekOrigin origin)
- {
- return _baseStream.Seek(offset, origin);
- }
-
- /// <summary>
- /// Sets the length of the current stream.
- /// </summary>
- /// <param name="value">The desired length of the current stream in bytes.</param>
- /// <exception cref="T:System.NotSupportedException">The base stream does not support both writing and seeking, such as if the stream is constructed from a pipe or console output. </exception>
- /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
- /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
- public override void SetLength(long value)
- {
- _baseStream.SetLength(value);
- }
-
- private long _bytesWritten;
-
- /// <summary>
- /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
- /// </summary>
- /// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
- /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
- /// <param name="count">The number of bytes to be written to the current stream.</param>
- /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
- /// <exception cref="T:System.NotSupportedException">The base stream does not support writing. </exception>
- /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
- /// <exception cref="T:System.ArgumentNullException">buffer is null. </exception>
- /// <exception cref="T:System.ArgumentException">The sum of offset and count is greater than the buffer length. </exception>
- /// <exception cref="T:System.ArgumentOutOfRangeException">offset or count is negative. </exception>
- public override void Write(byte[] buffer, int offset, int count)
- {
- Throttle(count);
-
- _baseStream.Write(buffer, offset, count);
-
- _bytesWritten += count;
- }
-
- public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- await ThrottleAsync(count, cancellationToken).ConfigureAwait(false);
-
- await _baseStream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
-
- _bytesWritten += count;
- }
-
- /// <summary>
- /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
- /// </returns>
- public override string ToString()
- {
- return _baseStream.ToString();
- }
- #endregion
-
- private bool ThrottleCheck(int bufferSizeInBytes)
- {
- if (_bytesWritten < MinThrottlePosition)
- {
- return false;
- }
-
- // Make sure the buffer isn't empty.
- if (_maximumBytesPerSecond <= 0 || bufferSizeInBytes <= 0)
- {
- return false;
- }
-
- return true;
- }
-
- #region Protected methods
- /// <summary>
- /// Throttles for the specified buffer size in bytes.
- /// </summary>
- /// <param name="bufferSizeInBytes">The buffer size in bytes.</param>
- protected void Throttle(int bufferSizeInBytes)
- {
- if (!ThrottleCheck(bufferSizeInBytes))
- {
- return ;
- }
-
- _byteCount += bufferSizeInBytes;
- long elapsedMilliseconds = CurrentMilliseconds - _start;
-
- if (elapsedMilliseconds > 0)
- {
- // Calculate the current bps.
- long bps = _byteCount * 1000L / elapsedMilliseconds;
-
- // If the bps are more then the maximum bps, try to throttle.
- if (bps > _maximumBytesPerSecond)
- {
- // Calculate the time to sleep.
- long wakeElapsed = _byteCount * 1000L / _maximumBytesPerSecond;
- int toSleep = (int)(wakeElapsed - elapsedMilliseconds);
-
- if (toSleep > 1)
- {
- try
- {
- // The time to sleep is more then a millisecond, so sleep.
- Thread.Sleep(toSleep);
- }
- catch (ThreadAbortException)
- {
- // Eatup ThreadAbortException.
- }
-
- // A sleep has been done, reset.
- Reset();
- }
- }
- }
- }
-
- protected async Task ThrottleAsync(int bufferSizeInBytes, CancellationToken cancellationToken)
- {
- if (!ThrottleCheck(bufferSizeInBytes))
- {
- return;
- }
-
- _byteCount += bufferSizeInBytes;
- long elapsedMilliseconds = CurrentMilliseconds - _start;
-
- if (elapsedMilliseconds > 0)
- {
- // Calculate the current bps.
- long bps = _byteCount * 1000L / elapsedMilliseconds;
-
- // If the bps are more then the maximum bps, try to throttle.
- if (bps > _maximumBytesPerSecond)
- {
- // Calculate the time to sleep.
- long wakeElapsed = _byteCount * 1000L / _maximumBytesPerSecond;
- int toSleep = (int)(wakeElapsed - elapsedMilliseconds);
-
- if (toSleep > 1)
- {
- // The time to sleep is more then a millisecond, so sleep.
- await Task.Delay(toSleep, cancellationToken).ConfigureAwait(false);
-
- // A sleep has been done, reset.
- Reset();
- }
- }
- }
- }
-
- /// <summary>
- /// Will reset the bytecount to 0 and reset the start time to the current time.
- /// </summary>
- protected void Reset()
- {
- long difference = CurrentMilliseconds - _start;
-
- // Only reset counters when a known history is available of more then 1 second.
- if (difference > 1000)
- {
- _byteCount = 0;
- _start = CurrentMilliseconds;
- }
- }
- #endregion
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
index 27a7d4ea9..01efe0ab1 100644
--- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
@@ -137,21 +137,16 @@ namespace MediaBrowser.Server.Implementations.Library
public async Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, CancellationToken cancellationToken)
{
var item = _libraryManager.GetItemById(id);
- IEnumerable<MediaSourceInfo> mediaSources;
var hasMediaSources = (IHasMediaSources)item;
User user = null;
- if (string.IsNullOrWhiteSpace(userId))
- {
- mediaSources = hasMediaSources.GetMediaSources(enablePathSubstitution);
- }
- else
+ if (!string.IsNullOrWhiteSpace(userId))
{
user = _userManager.GetUserById(userId);
- mediaSources = GetStaticMediaSources(hasMediaSources, enablePathSubstitution, user);
}
+ var mediaSources = GetStaticMediaSources(hasMediaSources, enablePathSubstitution, user);
var dynamicMediaSources = await GetDynamicMediaSources(hasMediaSources, cancellationToken).ConfigureAwait(false);
var list = new List<MediaSourceInfo>();
@@ -166,9 +161,11 @@ namespace MediaBrowser.Server.Implementations.Library
}
if (source.Protocol == MediaProtocol.File)
{
- source.SupportsDirectStream = File.Exists(source.Path);
-
// TODO: Path substitution
+ if (!File.Exists(source.Path))
+ {
+ source.SupportsDirectStream = false;
+ }
}
else if (source.Protocol == MediaProtocol.Http)
{
@@ -183,6 +180,17 @@ namespace MediaBrowser.Server.Implementations.Library
list.Add(source);
}
+ foreach (var source in list)
+ {
+ if (user != null)
+ {
+ if (!user.Policy.EnableMediaPlaybackTranscoding)
+ {
+ source.SupportsTranscoding = false;
+ }
+ }
+ }
+
return SortMediaSources(list).Where(i => i.Type != MediaSourceType.Placeholder);
}
@@ -343,6 +351,7 @@ namespace MediaBrowser.Server.Implementations.Library
}
var json = _jsonSerializer.SerializeToString(mediaSource);
+ _logger.Debug("Live stream opened: " + json);
var clone = _jsonSerializer.DeserializeFromString<MediaSourceInfo>(json);
if (!string.IsNullOrWhiteSpace(request.UserId))
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 71daf2b0c..f88293b2a 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -64,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
if (string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
{
- return ResolveVideos<Video>(parent, files, directoryService, collectionType, false);
+ //return ResolveVideos<Video>(parent, files, directoryService, collectionType, false);
}
if (string.IsNullOrEmpty(collectionType))
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index 18cc172cc..84b4053a1 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
@@ -123,7 +124,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
var inputPaths = new[] { mediaSource.Path };
- var info = await _mediaEncoder.GetMediaInfo(inputPaths, mediaSource.Path, mediaSource.Protocol, isAudio, false, cancellationToken)
+ var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
+ {
+ InputPath = mediaSource.Path,
+ Protocol = mediaSource.Protocol,
+ MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
+ ExtractChapters = false
+
+ }, cancellationToken)
.ConfigureAwait(false);
mediaSource.Bitrate = info.Bitrate;
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index 835e9b3be..bf03498db 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -53,6 +53,7 @@
"LabelAddConnectSupporterHelp": "To add a user who isn't listed, you'll need to first link their account to Emby Connect from their user profile page.",
"LabelPinCode": "Pin code:",
"OptionHideWatchedContentFromLatestMedia": "Hide watched content from latest media",
+ "HeaderSync": "Sync",
"ButtonOk": "Ok",
"ButtonCancel": "Cancel",
"ButtonExit": "Exit",
@@ -1405,5 +1406,10 @@
"LabelShowLibraryTileNames": "Show library tile names",
"LabelShowLibraryTileNamesHelp": "Determines if labels will be displayed underneath library tiles on the home page",
"OptionEnableTranscodingThrottle": "Enable throttling",
- "OptionEnableTranscodingThrottleHelp": "Throttling will automatically adjust transcoding speed in order to minimize server cpu utilization during playback."
+ "OptionEnableTranscodingThrottleHelp": "Throttling will automatically adjust transcoding speed in order to minimize server cpu utilization during playback.",
+ "LabelUploadSpeedLimit": "Upload speed limit (mbps):",
+ "OptionAllowSyncTranscoding": "Allow syncing that requires transcoding",
+ "HeaderPlayback": "Media Playback",
+ "OptionAllowMediaPlaybackTranscoding": "Allow media playback that requires transcoding",
+ "OptionAllowMediaPlaybackTranscodingHelp": "Users will receive friendly messages when content is unplayable based on policy."
}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index dd770b0c8..8e026ea1d 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -180,7 +180,6 @@
<Compile Include="HttpServer\SocketSharp\WebSocketSharpListener.cs" />
<Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
<Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" />
- <Compile Include="HttpServer\ThrottledStream.cs" />
<Compile Include="Intros\DefaultIntroProvider.cs" />
<Compile Include="IO\LibraryMonitor.cs" />
<Compile Include="Library\CoreResolutionIgnoreRule.cs" />
diff --git a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs
index 73d9183a5..ea0a93a55 100644
--- a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs
@@ -17,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.Photos
protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item)
{
var photoAlbum = (PhotoAlbum)item;
- var items = GetFinalItems(photoAlbum.GetRecursiveChildren(i => i is Photo).ToList());
+ var items = GetFinalItems(photoAlbum.GetRecursiveChildren().ToList());
return Task.FromResult(items);
}
diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
index 99d758233..7b1fa4dec 100644
--- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
+++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
@@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public string Name
{
- get { return "App Sync"; }
+ get { return "Mobile Sync"; }
}
public IEnumerable<SyncTarget> GetAllSyncTargets()
diff --git a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
index 26413c033..ad313670a 100644
--- a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
+++ b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
@@ -1,7 +1,9 @@
using System.Globalization;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Progress;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Sync;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -25,13 +27,15 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly IServerApplicationHost _appHost;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
+ private readonly IConfigurationManager _config;
- public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost, IFileSystem fileSystem)
+ public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost, IFileSystem fileSystem, IConfigurationManager config)
{
_logger = logger;
_syncManager = syncManager;
_appHost = appHost;
_fileSystem = fileSystem;
+ _config = config;
}
public async Task Sync(IServerSyncProvider provider,
@@ -152,12 +156,14 @@ namespace MediaBrowser.Server.Implementations.Sync
var transferSuccess = false;
Exception transferException = null;
+ var options = _config.GetSyncOptions();
+
try
{
var fileTransferProgress = new ActionableProgress<double>();
fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));
- var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem.LocalPath, target, fileTransferProgress, cancellationToken).ConfigureAwait(false);
+ var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem.LocalPath, target, options, fileTransferProgress, cancellationToken).ConfigureAwait(false);
if (localItem.Item.MediaSources != null)
{
@@ -179,7 +185,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var mediaSource = localItem.Item.MediaSources.FirstOrDefault();
if (mediaSource != null)
{
- await SendSubtitles(localItem, mediaSource, provider, dataProvider, target, cancellationToken).ConfigureAwait(false);
+ await SendSubtitles(localItem, mediaSource, provider, dataProvider, target, options, cancellationToken).ConfigureAwait(false);
}
}
@@ -207,7 +213,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- private async Task SendSubtitles(LocalItem localItem, MediaSourceInfo mediaSource, IServerSyncProvider provider, ISyncDataProvider dataProvider, SyncTarget target, CancellationToken cancellationToken)
+ private async Task SendSubtitles(LocalItem localItem, MediaSourceInfo mediaSource, IServerSyncProvider provider, ISyncDataProvider dataProvider, SyncTarget target, SyncOptions options, CancellationToken cancellationToken)
{
var failedSubtitles = new List<MediaStream>();
var requiresSave = false;
@@ -219,7 +225,7 @@ namespace MediaBrowser.Server.Implementations.Sync
try
{
var remotePath = GetRemoteSubtitlePath(localItem, mediaStream, provider, target);
- var sendFileResult = await SendFile(provider, mediaStream.Path, remotePath, target, new Progress<double>(), cancellationToken).ConfigureAwait(false);
+ var sendFileResult = await SendFile(provider, mediaStream.Path, remotePath, target, options, new Progress<double>(), cancellationToken).ConfigureAwait(false);
// This is the path that will be used when talking to the provider
mediaStream.ExternalId = remotePath;
@@ -307,11 +313,18 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- private async Task<SyncedFileInfo> SendFile(IServerSyncProvider provider, string inputPath, string remotePath, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken)
+ private async Task<SyncedFileInfo> SendFile(IServerSyncProvider provider, string inputPath, string remotePath, SyncTarget target, SyncOptions options, IProgress<double> progress, CancellationToken cancellationToken)
{
_logger.Debug("Sending {0} to {1}. Remote path: {2}", inputPath, provider.Name, remotePath);
- using (var stream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
+ using (var fileStream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
{
+ Stream stream = fileStream;
+
+ if (options.UploadSpeedLimitBytes > 0 && provider is IRemoteSyncProvider)
+ {
+ stream = new ThrottledStream(stream, options.UploadSpeedLimitBytes);
+ }
+
return await provider.SendFile(stream, remotePath, target, progress, cancellationToken).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs b/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
index a8bc24c2a..6f09e96f0 100644
--- a/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
+++ b/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.IO;
using MediaBrowser.Common.Progress;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Sync;
@@ -18,13 +19,15 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly IServerApplicationHost _appHost;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
+ private readonly IConfigurationManager _config;
- public MultiProviderSync(SyncManager syncManager, IServerApplicationHost appHost, ILogger logger, IFileSystem fileSystem)
+ public MultiProviderSync(SyncManager syncManager, IServerApplicationHost appHost, ILogger logger, IFileSystem fileSystem, IConfigurationManager config)
{
_syncManager = syncManager;
_appHost = appHost;
_logger = logger;
_fileSystem = fileSystem;
+ _config = config;
}
public async Task Sync(IEnumerable<IServerSyncProvider> providers, IProgress<double> progress, CancellationToken cancellationToken)
@@ -56,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.Sync
var dataProvider = _syncManager.GetDataProvider(target.Item1, target.Item2);
- await new MediaSync(_logger, _syncManager, _appHost, _fileSystem)
+ await new MediaSync(_logger, _syncManager, _appHost, _fileSystem, _config)
.Sync(target.Item1, dataProvider, target.Item2, innerProgress, cancellationToken)
.ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
index 148602bd4..9477a23f1 100644
--- a/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.IO;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Sync;
@@ -17,13 +18,15 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly IServerApplicationHost _appHost;
+ private readonly IConfigurationManager _config;
- public ServerSyncScheduledTask(ISyncManager syncManager, ILogger logger, IFileSystem fileSystem, IServerApplicationHost appHost)
+ public ServerSyncScheduledTask(ISyncManager syncManager, ILogger logger, IFileSystem fileSystem, IServerApplicationHost appHost, IConfigurationManager config)
{
_syncManager = syncManager;
_logger = logger;
_fileSystem = fileSystem;
_appHost = appHost;
+ _config = config;
}
public string Name
@@ -46,7 +49,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
- return new MultiProviderSync((SyncManager)_syncManager, _appHost, _logger, _fileSystem)
+ return new MultiProviderSync((SyncManager)_syncManager, _appHost, _logger, _fileSystem, _config)
.Sync(ServerSyncProviders, progress, cancellationToken);
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index a39a2b1cd..f3662086b 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -1168,13 +1168,18 @@ namespace MediaBrowser.Server.Implementations.Sync
public IEnumerable<SyncQualityOption> GetQualityOptions(string targetId)
{
+ return GetQualityOptions(targetId, null);
+ }
+
+ public IEnumerable<SyncQualityOption> GetQualityOptions(string targetId, User user)
+ {
foreach (var provider in _providers)
{
foreach (var target in GetSyncTargets(provider))
{
if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase))
{
- return GetQualityOptions(provider, target);
+ return GetQualityOptions(provider, target, user);
}
}
}
@@ -1182,12 +1187,19 @@ namespace MediaBrowser.Server.Implementations.Sync
return new List<SyncQualityOption>();
}
- private IEnumerable<SyncQualityOption> GetQualityOptions(ISyncProvider provider, SyncTarget target)
+ private IEnumerable<SyncQualityOption> GetQualityOptions(ISyncProvider provider, SyncTarget target, User user)
{
var hasQuality = provider as IHasSyncQuality;
if (hasQuality != null)
{
- return hasQuality.GetQualityOptions(target);
+ var options = hasQuality.GetQualityOptions(target);
+
+ if (user != null && !user.Policy.EnableSyncTranscoding)
+ {
+ options = options.Where(i => i.IsOriginalQuality);
+ }
+
+ return options;
}
// Default options for providers that don't override
@@ -1217,7 +1229,7 @@ namespace MediaBrowser.Server.Implementations.Sync
};
}
- public IEnumerable<SyncProfileOption> GetProfileOptions(string targetId)
+ public IEnumerable<SyncProfileOption> GetProfileOptions(string targetId, User user)
{
foreach (var provider in _providers)
{
@@ -1225,7 +1237,7 @@ namespace MediaBrowser.Server.Implementations.Sync
{
if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase))
{
- return GetProfileOptions(provider, target);
+ return GetProfileOptions(provider, target, user);
}
}
}
@@ -1233,7 +1245,12 @@ namespace MediaBrowser.Server.Implementations.Sync
return new List<SyncProfileOption>();
}
- private IEnumerable<SyncProfileOption> GetProfileOptions(ISyncProvider provider, SyncTarget target)
+ public IEnumerable<SyncProfileOption> GetProfileOptions(string targetId)
+ {
+ return GetProfileOptions(targetId, null);
+ }
+
+ private IEnumerable<SyncProfileOption> GetProfileOptions(ISyncProvider provider, SyncTarget target, User user)
{
var hasQuality = provider as IHasSyncQuality;
if (hasQuality != null)
@@ -1251,20 +1268,23 @@ namespace MediaBrowser.Server.Implementations.Sync
EnableQualityOptions = false
});
- list.Add(new SyncProfileOption
+ if (user == null || user.Policy.EnableSyncTranscoding)
{
- 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 = "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",
- Id = "general",
- Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices. Targets H264/AAC/AC3 video and MP3 audio.",
- IsDefault = true
- });
+ list.Add(new SyncProfileOption
+ {
+ Name = "General",
+ Id = "general",
+ Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices. Targets H264/AAC/AC3 video and MP3 audio.",
+ IsDefault = true
+ });
+ }
return list;
}