Ver código fonte

probe live streams after opening

Luke Pulverenti 10 anos atrás
pai
commit
30104bd8de
41 arquivos alterados com 294 adições e 132 exclusões
  1. 5 6
      MediaBrowser.Api/Sync/SyncService.cs
  2. 1 0
      MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
  3. 2 1
      MediaBrowser.Controller/Entities/Folder.cs
  4. 9 9
      MediaBrowser.Controller/Entities/Movies/BoxSet.cs
  5. 33 3
      MediaBrowser.Controller/Entities/PhotoAlbum.cs
  6. 1 1
      MediaBrowser.Controller/Entities/UserViewBuilder.cs
  7. 1 1
      MediaBrowser.Controller/IO/ThrottledStream.cs
  8. 3 0
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  9. 2 6
      MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
  10. 24 0
      MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs
  11. 10 0
      MediaBrowser.Controller/Sync/IRemoteSyncProvider.cs
  12. 14 0
      MediaBrowser.Controller/Sync/ISyncManager.cs
  13. 4 4
      MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
  14. 10 10
      MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
  15. 9 9
      MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
  16. 3 3
      MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
  17. 3 3
      MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
  18. 1 1
      MediaBrowser.Model/MediaBrowser.Model.csproj
  19. 2 1
      MediaBrowser.Model/MediaInfo/MediaInfo.cs
  20. 1 0
      MediaBrowser.Model/Sync/SyncOptions.cs
  21. 5 0
      MediaBrowser.Model/Sync/SyncQualityOption.cs
  22. 9 1
      MediaBrowser.Model/Users/UserPolicy.cs
  23. 1 5
      MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
  24. 11 6
      MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
  25. 16 7
      MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
  26. 1 3
      MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs
  27. 18 9
      MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
  28. 1 1
      MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
  29. 9 1
      MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
  30. 7 1
      MediaBrowser.Server.Implementations/Localization/Server/server.json
  31. 0 1
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  32. 1 1
      MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs
  33. 1 1
      MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs
  34. 20 7
      MediaBrowser.Server.Implementations/Sync/MediaSync.cs
  35. 6 3
      MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs
  36. 6 3
      MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs
  37. 38 18
      MediaBrowser.Server.Implementations/Sync/SyncManager.cs
  38. 2 2
      Nuget/MediaBrowser.Common.Internal.nuspec
  39. 1 1
      Nuget/MediaBrowser.Common.nuspec
  40. 1 1
      Nuget/MediaBrowser.Model.Signed.nuspec
  41. 2 2
      Nuget/MediaBrowser.Server.Core.nuspec

+ 5 - 6
MediaBrowser.Api/Sync/SyncService.cs

@@ -248,6 +248,9 @@ namespace MediaBrowser.Api.Sync
             result.Targets = _syncManager.GetSyncTargets(request.UserId)
             result.Targets = _syncManager.GetSyncTargets(request.UserId)
                 .ToList();
                 .ToList();
 
 
+            var auth = AuthorizationContext.GetAuthorizationInfo(Request);
+            var authenticatedUser = _userManager.GetUserById(auth.UserId);
+
             if (!string.IsNullOrWhiteSpace(request.TargetId))
             if (!string.IsNullOrWhiteSpace(request.TargetId))
             {
             {
                 result.Targets = result.Targets
                 result.Targets = result.Targets
@@ -255,11 +258,11 @@ namespace MediaBrowser.Api.Sync
                     .ToList();
                     .ToList();
 
 
                 result.QualityOptions = _syncManager
                 result.QualityOptions = _syncManager
-                    .GetQualityOptions(request.TargetId)
+                    .GetQualityOptions(request.TargetId, authenticatedUser)
                     .ToList();
                     .ToList();
 
 
                 result.ProfileOptions = _syncManager
                 result.ProfileOptions = _syncManager
-                    .GetProfileOptions(request.TargetId)
+                    .GetProfileOptions(request.TargetId, authenticatedUser)
                     .ToList();
                     .ToList();
             }
             }
 
 
@@ -277,10 +280,6 @@ namespace MediaBrowser.Api.Sync
                     }
                     }
                 };
                 };
 
 
-                var auth = AuthorizationContext.GetAuthorizationInfo(Request);
-
-                var authenticatedUser = _userManager.GetUserById(auth.UserId);
-
                 var items = request.ItemIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                 var items = request.ItemIds.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                     .Select(_libraryManager.GetItemById)
                     .Select(_libraryManager.GetItemById)
                     .Where(i => i != null);
                     .Where(i => i != null);

+ 1 - 0
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Users;
 using MediaBrowser.Model.Users;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;

+ 2 - 1
MediaBrowser.Controller/Entities/Folder.cs

@@ -991,8 +991,9 @@ namespace MediaBrowser.Controller.Entities
             }
             }
 
 
             var locations = user.RootFolder
             var locations = user.RootFolder
-                .GetChildren(user, true)
+                .Children
                 .OfType<CollectionFolder>()
                 .OfType<CollectionFolder>()
+                .Where(i => i.IsVisible(user))
                 .SelectMany(i => i.PhysicalLocations)
                 .SelectMany(i => i.PhysicalLocations)
                 .ToList();
                 .ToList();
 
 

+ 9 - 9
MediaBrowser.Controller/Entities/Movies/BoxSet.cs

@@ -175,19 +175,19 @@ namespace MediaBrowser.Controller.Entities.Movies
 
 
         public override bool IsVisible(User user)
         public override bool IsVisible(User user)
         {
         {
-            if (base.IsVisible(user))
-            {
-                var userId = user.Id.ToString("N");
-
-                // Need to check Count > 0 for boxsets created prior to the introduction of Shares
-                if (Shares.Count > 0 && !Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)))
-                {
-                    //return false;
-                }
+            var userId = user.Id.ToString("N");
 
 
+            // Need to check Count > 0 for boxsets created prior to the introduction of Shares
+            if (Shares.Count > 0 && Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)))
+            {
                 return true;
                 return true;
             }
             }
 
 
+            if (base.IsVisible(user))
+            {
+                return GetChildren(user, true).Any();
+            }
+
             return false;
             return false;
         }
         }
     }
     }

+ 33 - 3
MediaBrowser.Controller/Entities/PhotoAlbum.cs

@@ -1,11 +1,15 @@
-using MediaBrowser.Model.Configuration;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Users;
+using System;
 using System.Linq;
 using System.Linq;
 using System.Runtime.Serialization;
 using System.Runtime.Serialization;
-using MediaBrowser.Model.Users;
+using System.Threading;
+using System.Threading.Tasks;
 
 
 namespace MediaBrowser.Controller.Entities
 namespace MediaBrowser.Controller.Entities
 {
 {
-    public class PhotoAlbum : Folder
+    public class PhotoAlbum : Folder, IMetadataContainer
     {
     {
         public override bool SupportsLocalMetadata
         public override bool SupportsLocalMetadata
         {
         {
@@ -28,5 +32,31 @@ namespace MediaBrowser.Controller.Entities
         {
         {
             return config.BlockUnratedItems.Contains(UnratedItem.Other);
             return config.BlockUnratedItems.Contains(UnratedItem.Other);
         }
         }
+
+        public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
+        {
+            var items = GetRecursiveChildren().ToList();
+
+            var totalItems = items.Count;
+            var numComplete = 0;
+
+            // Refresh songs
+            foreach (var item in items)
+            {
+                cancellationToken.ThrowIfCancellationRequested();
+
+                await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+
+                numComplete++;
+                double percent = numComplete;
+                percent /= totalItems;
+                progress.Report(percent * 100);
+            }
+
+            // Refresh current item
+            await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+
+            progress.Report(100);
+        }
     }
     }
 }
 }

+ 1 - 1
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -259,7 +259,7 @@ namespace MediaBrowser.Controller.Entities
             list.Add(await GetUserView(SpecialFolder.MusicLatest, user, "0", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicLatest, user, "0", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicAlbums, user, "1", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicAlbums, user, "1", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, user, "2", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, user, "2", parent).ConfigureAwait(false));
-            list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "3", parent).ConfigureAwait(false));
+            //list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "3", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "4", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "4", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "5", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "5", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "6", parent).ConfigureAwait(false));
             list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "6", parent).ConfigureAwait(false));

+ 1 - 1
MediaBrowser.Server.Implementations/HttpServer/ThrottledStream.cs → MediaBrowser.Controller/IO/ThrottledStream.cs

@@ -3,7 +3,7 @@ using System.IO;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
-namespace MediaBrowser.Server.Implementations.HttpServer
+namespace MediaBrowser.Controller.IO
 {
 {
     /// <summary>
     /// <summary>
     /// Class for streaming data with throttling support.
     /// Class for streaming data with throttling support.

+ 3 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -171,6 +171,7 @@
     <Compile Include="Entities\UserView.cs" />
     <Compile Include="Entities\UserView.cs" />
     <Compile Include="Entities\UserViewBuilder.cs" />
     <Compile Include="Entities\UserViewBuilder.cs" />
     <Compile Include="FileOrganization\IFileOrganizationService.cs" />
     <Compile Include="FileOrganization\IFileOrganizationService.cs" />
+    <Compile Include="IO\ThrottledStream.cs" />
     <Compile Include="Library\DeleteOptions.cs" />
     <Compile Include="Library\DeleteOptions.cs" />
     <Compile Include="Library\ILibraryPostScanTask.cs" />
     <Compile Include="Library\ILibraryPostScanTask.cs" />
     <Compile Include="Library\IMediaSourceManager.cs" />
     <Compile Include="Library\IMediaSourceManager.cs" />
@@ -212,6 +213,7 @@
     <Compile Include="MediaEncoding\ImageEncodingOptions.cs" />
     <Compile Include="MediaEncoding\ImageEncodingOptions.cs" />
     <Compile Include="MediaEncoding\IMediaEncoder.cs" />
     <Compile Include="MediaEncoding\IMediaEncoder.cs" />
     <Compile Include="MediaEncoding\ISubtitleEncoder.cs" />
     <Compile Include="MediaEncoding\ISubtitleEncoder.cs" />
+    <Compile Include="MediaEncoding\MediaInfoRequest.cs" />
     <Compile Include="MediaEncoding\MediaStreamSelector.cs" />
     <Compile Include="MediaEncoding\MediaStreamSelector.cs" />
     <Compile Include="Net\AuthenticatedAttribute.cs" />
     <Compile Include="Net\AuthenticatedAttribute.cs" />
     <Compile Include="Net\AuthorizationInfo.cs" />
     <Compile Include="Net\AuthorizationInfo.cs" />
@@ -393,6 +395,7 @@
     <Compile Include="Subtitles\SubtitleResponse.cs" />
     <Compile Include="Subtitles\SubtitleResponse.cs" />
     <Compile Include="Subtitles\SubtitleSearchRequest.cs" />
     <Compile Include="Subtitles\SubtitleSearchRequest.cs" />
     <Compile Include="Sync\IHasDynamicAccess.cs" />
     <Compile Include="Sync\IHasDynamicAccess.cs" />
+    <Compile Include="Sync\IRemoteSyncProvider.cs" />
     <Compile Include="Sync\IServerSyncProvider.cs" />
     <Compile Include="Sync\IServerSyncProvider.cs" />
     <Compile Include="Sync\ISyncDataProvider.cs" />
     <Compile Include="Sync\ISyncDataProvider.cs" />
     <Compile Include="Sync\ISyncManager.cs" />
     <Compile Include="Sync\ISyncManager.cs" />

+ 2 - 6
MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs

@@ -67,14 +67,10 @@ namespace MediaBrowser.Controller.MediaEncoding
         /// <summary>
         /// <summary>
         /// Gets the media info.
         /// Gets the media info.
         /// </summary>
         /// </summary>
-        /// <param name="inputFiles">The input files.</param>
-        /// <param name="primaryPath">The primary path.</param>
-        /// <param name="protocol">The protocol.</param>
-        /// <param name="isAudio">if set to <c>true</c> [is audio].</param>
-        /// <param name="extractChapters">if set to <c>true</c> [extract chapters].</param>
+        /// <param name="request">The request.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        Task<MediaInfo> GetMediaInfo(string[] inputFiles, string primaryPath, MediaProtocol protocol, bool isAudio, bool extractChapters, CancellationToken cancellationToken);
+        Task<MediaInfo> GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken);
 
 
         /// <summary>
         /// <summary>
         /// Gets the probe size argument.
         /// Gets the probe size argument.

+ 24 - 0
MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs

@@ -0,0 +1,24 @@
+using MediaBrowser.Model.Dlna;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.MediaInfo;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.MediaEncoding
+{
+    public class MediaInfoRequest
+    {
+        public string InputPath { get; set; }
+        public MediaProtocol Protocol { get; set; }
+        public bool ExtractChapters { get; set; }
+        public DlnaProfileType MediaType { get; set; }
+        public IIsoMount MountedIso { get; set; }
+        public VideoType VideoType { get; set; }
+        public List<string> PlayableStreamFileNames { get; set; }
+
+        public MediaInfoRequest()
+        {
+            PlayableStreamFileNames = new List<string>();
+        }
+    }
+}

+ 10 - 0
MediaBrowser.Controller/Sync/IRemoteSyncProvider.cs

@@ -0,0 +1,10 @@
+
+namespace MediaBrowser.Controller.Sync
+{
+    /// <summary>
+    /// A marker interface
+    /// </summary>
+    public interface IRemoteSyncProvider
+    {
+    }
+}

+ 14 - 0
MediaBrowser.Controller/Sync/ISyncManager.cs

@@ -174,6 +174,13 @@ namespace MediaBrowser.Controller.Sync
         /// <param name="targetId">The target identifier.</param>
         /// <param name="targetId">The target identifier.</param>
         /// <returns>IEnumerable&lt;SyncQualityOption&gt;.</returns>
         /// <returns>IEnumerable&lt;SyncQualityOption&gt;.</returns>
         IEnumerable<SyncQualityOption> GetQualityOptions(string targetId);
         IEnumerable<SyncQualityOption> GetQualityOptions(string targetId);
+        /// <summary>
+        /// Gets the quality options.
+        /// </summary>
+        /// <param name="targetId">The target identifier.</param>
+        /// <param name="user">The user.</param>
+        /// <returns>IEnumerable&lt;SyncQualityOption&gt;.</returns>
+        IEnumerable<SyncQualityOption> GetQualityOptions(string targetId, User user);
 
 
         /// <summary>
         /// <summary>
         /// Gets the profile options.
         /// Gets the profile options.
@@ -181,5 +188,12 @@ namespace MediaBrowser.Controller.Sync
         /// <param name="targetId">The target identifier.</param>
         /// <param name="targetId">The target identifier.</param>
         /// <returns>IEnumerable&lt;SyncQualityOption&gt;.</returns>
         /// <returns>IEnumerable&lt;SyncQualityOption&gt;.</returns>
         IEnumerable<SyncProfileOption> GetProfileOptions(string targetId);
         IEnumerable<SyncProfileOption> GetProfileOptions(string targetId);
+        /// <summary>
+        /// Gets the profile options.
+        /// </summary>
+        /// <param name="targetId">The target identifier.</param>
+        /// <param name="user">The user.</param>
+        /// <returns>IEnumerable&lt;SyncProfileOption&gt;.</returns>
+        IEnumerable<SyncProfileOption> GetProfileOptions(string targetId, User user);
     }
     }
 }
 }

+ 4 - 4
MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs

@@ -223,7 +223,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
             if (string.Equals(flag, "BrowseMetadata"))
             if (string.Equals(flag, "BrowseMetadata"))
             {
             {
                 totalCount = 1;
                 totalCount = 1;
-                
+
                 if (item.IsFolder || serverItem.StubType.HasValue)
                 if (item.IsFolder || serverItem.StubType.HasValue)
                 {
                 {
                     var childrenResult = (await GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount).ConfigureAwait(false));
                     var childrenResult = (await GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount).ConfigureAwait(false));
@@ -350,7 +350,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
             };
             };
         }
         }
 
 
-        private async Task<QueryResult<BaseItem>> GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit)
+        private Task<QueryResult<BaseItem>> GetChildrenSorted(BaseItem item, User user, SearchCriteria search, SortCriteria sort, int? startIndex, int? limit)
         {
         {
             var folder = (Folder)item;
             var folder = (Folder)item;
 
 
@@ -389,7 +389,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
                 isFolder = true;
                 isFolder = true;
             }
             }
 
 
-            return await folder.GetItems(new InternalItemsQuery
+            return folder.GetItems(new InternalItemsQuery
             {
             {
                 Limit = limit,
                 Limit = limit,
                 StartIndex = startIndex,
                 StartIndex = startIndex,
@@ -401,7 +401,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
                 IsFolder = isFolder,
                 IsFolder = isFolder,
                 MediaTypes = mediaTypes.ToArray()
                 MediaTypes = mediaTypes.ToArray()
 
 
-            }).ConfigureAwait(false);
+            });
         }
         }
 
 
         private async Task<QueryResult<ServerItem>> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit)
         private async Task<QueryResult<ServerItem>> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit)

+ 10 - 10
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -6,6 +6,7 @@ using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.MediaEncoding.Probing;
 using MediaBrowser.MediaEncoding.Probing;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
@@ -103,18 +104,17 @@ namespace MediaBrowser.MediaEncoding.Encoder
         /// <summary>
         /// <summary>
         /// Gets the media info.
         /// Gets the media info.
         /// </summary>
         /// </summary>
-        /// <param name="inputFiles">The input files.</param>
-        /// <param name="primaryPath">The primary path.</param>
-        /// <param name="protocol">The protocol.</param>
-        /// <param name="isAudio">if set to <c>true</c> [is audio].</param>
-        /// <param name="extractChapters">if set to <c>true</c> [extract chapters].</param>
+        /// <param name="request">The request.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        public Task<Model.Entities.MediaInfo> GetMediaInfo(string[] inputFiles, string primaryPath, MediaProtocol protocol, bool isAudio,
-            bool extractChapters, CancellationToken cancellationToken)
+        public Task<Model.MediaInfo.MediaInfo> GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken)
         {
         {
-            return GetMediaInfoInternal(GetInputArgument(inputFiles, protocol), primaryPath, protocol, !isAudio && extractChapters,
-                GetProbeSizeArgument(inputFiles, protocol), isAudio, cancellationToken);
+            var extractChapters = request.MediaType == DlnaProfileType.Video && request.ExtractChapters;
+
+            var inputFiles = MediaEncoderHelpers.GetInputArgument(request.InputPath, request.Protocol, request.MountedIso, request.PlayableStreamFileNames);
+
+            return GetMediaInfoInternal(GetInputArgument(inputFiles, request.Protocol), request.InputPath, request.Protocol, extractChapters,
+                GetProbeSizeArgument(inputFiles, request.Protocol), request.MediaType == DlnaProfileType.Audio, cancellationToken);
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -152,7 +152,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{MediaInfoResult}.</returns>
         /// <returns>Task{MediaInfoResult}.</returns>
         /// <exception cref="System.ApplicationException"></exception>
         /// <exception cref="System.ApplicationException"></exception>
-        private async Task<Model.Entities.MediaInfo> GetMediaInfoInternal(string inputPath, string primaryPath, MediaProtocol protocol, bool extractChapters,
+        private async Task<Model.MediaInfo.MediaInfo> GetMediaInfoInternal(string inputPath, string primaryPath, MediaProtocol protocol, bool extractChapters,
             string probeSizeArgument,
             string probeSizeArgument,
             bool isAudio,
             bool isAudio,
             CancellationToken cancellationToken)
             CancellationToken cancellationToken)

+ 9 - 9
MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs

@@ -25,9 +25,9 @@ namespace MediaBrowser.MediaEncoding.Probing
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
         }
         }
 
 
-        public Model.Entities.MediaInfo GetMediaInfo(InternalMediaInfoResult data, bool isAudio, string path, MediaProtocol protocol)
+        public Model.MediaInfo.MediaInfo GetMediaInfo(InternalMediaInfoResult data, bool isAudio, string path, MediaProtocol protocol)
         {
         {
-            var info = new Model.Entities.MediaInfo
+            var info = new Model.MediaInfo.MediaInfo
             {
             {
                 Path = path,
                 Path = path,
                 Protocol = protocol
                 Protocol = protocol
@@ -342,7 +342,7 @@ namespace MediaBrowser.MediaEncoding.Probing
             return null;
             return null;
         }
         }
 
 
-        private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.Entities.MediaInfo data)
+        private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.MediaInfo.MediaInfo data)
         {
         {
             if (result.streams != null)
             if (result.streams != null)
             {
             {
@@ -369,7 +369,7 @@ namespace MediaBrowser.MediaEncoding.Probing
             }
             }
         }
         }
 
 
-        private void SetSize(InternalMediaInfoResult data, Model.Entities.MediaInfo info)
+        private void SetSize(InternalMediaInfoResult data, Model.MediaInfo.MediaInfo info)
         {
         {
             if (data.format != null)
             if (data.format != null)
             {
             {
@@ -384,7 +384,7 @@ namespace MediaBrowser.MediaEncoding.Probing
             }
             }
         }
         }
 
 
-        private void SetAudioInfoFromTags(Model.Entities.MediaInfo audio, Dictionary<string, string> tags)
+        private void SetAudioInfoFromTags(Model.MediaInfo.MediaInfo audio, Dictionary<string, string> tags)
         {
         {
             var title = FFProbeHelpers.GetDictionaryValue(tags, "title");
             var title = FFProbeHelpers.GetDictionaryValue(tags, "title");
 
 
@@ -591,7 +591,7 @@ namespace MediaBrowser.MediaEncoding.Probing
         /// <param name="audio">The audio.</param>
         /// <param name="audio">The audio.</param>
         /// <param name="tags">The tags.</param>
         /// <param name="tags">The tags.</param>
         /// <param name="tagName">Name of the tag.</param>
         /// <param name="tagName">Name of the tag.</param>
-        private void FetchStudios(Model.Entities.MediaInfo audio, Dictionary<string, string> tags, string tagName)
+        private void FetchStudios(Model.MediaInfo.MediaInfo audio, Dictionary<string, string> tags, string tagName)
         {
         {
             var val = FFProbeHelpers.GetDictionaryValue(tags, tagName);
             var val = FFProbeHelpers.GetDictionaryValue(tags, tagName);
 
 
@@ -626,7 +626,7 @@ namespace MediaBrowser.MediaEncoding.Probing
         /// </summary>
         /// </summary>
         /// <param name="info">The information.</param>
         /// <param name="info">The information.</param>
         /// <param name="tags">The tags.</param>
         /// <param name="tags">The tags.</param>
-        private void FetchGenres(Model.Entities.MediaInfo info, Dictionary<string, string> tags)
+        private void FetchGenres(Model.MediaInfo.MediaInfo info, Dictionary<string, string> tags)
         {
         {
             var val = FFProbeHelpers.GetDictionaryValue(tags, "genre");
             var val = FFProbeHelpers.GetDictionaryValue(tags, "genre");
 
 
@@ -697,7 +697,7 @@ namespace MediaBrowser.MediaEncoding.Probing
 
 
         private const int MaxSubtitleDescriptionExtractionLength = 100; // When extracting subtitles, the maximum length to consider (to avoid invalid filenames)
         private const int MaxSubtitleDescriptionExtractionLength = 100; // When extracting subtitles, the maximum length to consider (to avoid invalid filenames)
 
 
-        private void FetchWtvInfo(Model.Entities.MediaInfo video, InternalMediaInfoResult data)
+        private void FetchWtvInfo(Model.MediaInfo.MediaInfo video, InternalMediaInfoResult data)
         {
         {
             if (data.format == null || data.format.tags == null)
             if (data.format == null || data.format.tags == null)
             {
             {
@@ -806,7 +806,7 @@ namespace MediaBrowser.MediaEncoding.Probing
             }
             }
         }
         }
 
 
-        private void ExtractTimestamp(Model.Entities.MediaInfo video)
+        private void ExtractTimestamp(Model.MediaInfo.MediaInfo video)
         {
         {
             if (video.VideoType == VideoType.VideoFile)
             if (video.VideoType == VideoType.VideoFile)
             {
             {

+ 3 - 3
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -560,9 +560,6 @@
     <Compile Include="..\MediaBrowser.Model\Entities\MBRegistrationRecord.cs">
     <Compile Include="..\MediaBrowser.Model\Entities\MBRegistrationRecord.cs">
       <Link>Entities\MBRegistrationRecord.cs</Link>
       <Link>Entities\MBRegistrationRecord.cs</Link>
     </Compile>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Entities\MediaInfo.cs">
-      <Link>Entities\MediaInfo.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Entities\MediaStream.cs">
     <Compile Include="..\MediaBrowser.Model\Entities\MediaStream.cs">
       <Link>Entities\MediaStream.cs</Link>
       <Link>Entities\MediaStream.cs</Link>
     </Compile>
     </Compile>
@@ -809,6 +806,9 @@
     <Compile Include="..\MediaBrowser.Model\MediaInfo\LiveStreamResponse.cs">
     <Compile Include="..\MediaBrowser.Model\MediaInfo\LiveStreamResponse.cs">
       <Link>MediaInfo\LiveStreamResponse.cs</Link>
       <Link>MediaInfo\LiveStreamResponse.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaInfo.cs">
+      <Link>MediaInfo\MediaInfo.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaProtocol.cs">
     <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaProtocol.cs">
       <Link>MediaInfo\MediaProtocol.cs</Link>
       <Link>MediaInfo\MediaProtocol.cs</Link>
     </Compile>
     </Compile>

+ 3 - 3
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -525,9 +525,6 @@
     <Compile Include="..\MediaBrowser.Model\Entities\MBRegistrationRecord.cs">
     <Compile Include="..\MediaBrowser.Model\Entities\MBRegistrationRecord.cs">
       <Link>Entities\MBRegistrationRecord.cs</Link>
       <Link>Entities\MBRegistrationRecord.cs</Link>
     </Compile>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Entities\MediaInfo.cs">
-      <Link>Entities\MediaInfo.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Entities\MediaStream.cs">
     <Compile Include="..\MediaBrowser.Model\Entities\MediaStream.cs">
       <Link>Entities\MediaStream.cs</Link>
       <Link>Entities\MediaStream.cs</Link>
     </Compile>
     </Compile>
@@ -765,6 +762,9 @@
     <Compile Include="..\MediaBrowser.Model\MediaInfo\LiveStreamResponse.cs">
     <Compile Include="..\MediaBrowser.Model\MediaInfo\LiveStreamResponse.cs">
       <Link>MediaInfo\LiveStreamResponse.cs</Link>
       <Link>MediaInfo\LiveStreamResponse.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaInfo.cs">
+      <Link>MediaInfo\MediaInfo.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaProtocol.cs">
     <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaProtocol.cs">
       <Link>MediaInfo\MediaProtocol.cs</Link>
       <Link>MediaInfo\MediaProtocol.cs</Link>
     </Compile>
     </Compile>

+ 1 - 1
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -226,7 +226,7 @@
     <Compile Include="Dto\RecommendationType.cs" />
     <Compile Include="Dto\RecommendationType.cs" />
     <Compile Include="Dto\SubtitleDownloadOptions.cs" />
     <Compile Include="Dto\SubtitleDownloadOptions.cs" />
     <Compile Include="Entities\IsoType.cs" />
     <Compile Include="Entities\IsoType.cs" />
-    <Compile Include="Entities\MediaInfo.cs" />
+    <Compile Include="MediaInfo\MediaInfo.cs" />
     <Compile Include="Entities\MediaStreamType.cs" />
     <Compile Include="Entities\MediaStreamType.cs" />
     <Compile Include="Entities\PackageReviewInfo.cs" />
     <Compile Include="Entities\PackageReviewInfo.cs" />
     <Compile Include="Entities\ProviderIdsExtensions.cs" />
     <Compile Include="Entities\ProviderIdsExtensions.cs" />

+ 2 - 1
MediaBrowser.Model/Entities/MediaInfo.cs → MediaBrowser.Model/MediaInfo/MediaInfo.cs

@@ -1,8 +1,9 @@
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Entities;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 
 
-namespace MediaBrowser.Model.Entities
+namespace MediaBrowser.Model.MediaInfo
 {
 {
     public class MediaInfo : MediaSourceInfo, IHasProviderIds
     public class MediaInfo : MediaSourceInfo, IHasProviderIds
     {
     {

+ 1 - 0
MediaBrowser.Model/Sync/SyncOptions.cs

@@ -4,5 +4,6 @@ namespace MediaBrowser.Model.Sync
     public class SyncOptions
     public class SyncOptions
     {
     {
         public string TemporaryPath { get; set; }
         public string TemporaryPath { get; set; }
+        public long UploadSpeedLimitBytes { get; set; }
     }
     }
 }
 }

+ 5 - 0
MediaBrowser.Model/Sync/SyncQualityOption.cs

@@ -23,5 +23,10 @@ namespace MediaBrowser.Model.Sync
         /// </summary>
         /// </summary>
         /// <value><c>true</c> if this instance is default; otherwise, <c>false</c>.</value>
         /// <value><c>true</c> if this instance is default; otherwise, <c>false</c>.</value>
         public bool IsDefault { get; set; }
         public bool IsDefault { get; set; }
+        /// <summary>
+        /// Gets or sets a value indicating whether this instance is original quality.
+        /// </summary>
+        /// <value><c>true</c> if this instance is original quality; otherwise, <c>false</c>.</value>
+        public bool IsOriginalQuality { get; set; }
     }
     }
 }
 }

+ 9 - 1
MediaBrowser.Model/Users/UserPolicy.cs

@@ -39,6 +39,8 @@ namespace MediaBrowser.Model.Users
         public bool EnableLiveTvAccess { get; set; }
         public bool EnableLiveTvAccess { get; set; }
 
 
         public bool EnableMediaPlayback { get; set; }
         public bool EnableMediaPlayback { get; set; }
+        public bool EnableMediaPlaybackTranscoding { get; set; }
+        
         public bool EnableContentDeletion { get; set; }
         public bool EnableContentDeletion { get; set; }
         public bool EnableContentDownloading { get; set; }
         public bool EnableContentDownloading { get; set; }
 
 
@@ -47,6 +49,7 @@ namespace MediaBrowser.Model.Users
         /// </summary>
         /// </summary>
         /// <value><c>true</c> if [enable synchronize]; otherwise, <c>false</c>.</value>
         /// <value><c>true</c> if [enable synchronize]; otherwise, <c>false</c>.</value>
         public bool EnableSync { get; set; }
         public bool EnableSync { get; set; }
+        public bool EnableSyncTranscoding { get; set; }
 
 
         public string[] EnabledDevices { get; set; }
         public string[] EnabledDevices { get; set; }
         public bool EnableAllDevices { get; set; }
         public bool EnableAllDevices { get; set; }
@@ -62,9 +65,14 @@ namespace MediaBrowser.Model.Users
         public UserPolicy()
         public UserPolicy()
         {
         {
             EnableSync = true;
             EnableSync = true;
-            EnableLiveTvManagement = true;
+            EnableSyncTranscoding = true;
+
             EnableMediaPlayback = true;
             EnableMediaPlayback = true;
+            EnableMediaPlaybackTranscoding = true;
+            
+            EnableLiveTvManagement = true;
             EnableLiveTvAccess = true;
             EnableLiveTvAccess = true;
+
             EnableSharedDeviceControl = true;
             EnableSharedDeviceControl = true;
 
 
             BlockedTags = new string[] { };
             BlockedTags = new string[] { };

+ 1 - 5
MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs

@@ -3,7 +3,6 @@ using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
@@ -16,11 +15,8 @@ namespace MediaBrowser.Providers.BoxSets
 {
 {
     public class BoxSetMetadataService : MetadataService<BoxSet, BoxSetInfo>
     public class BoxSetMetadataService : MetadataService<BoxSet, BoxSetInfo>
     {
     {
-        private readonly ILocalizationManager _iLocalizationManager;
-
-        public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILocalizationManager iLocalizationManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
+        public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
         {
         {
-            _iLocalizationManager = iLocalizationManager;
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 11 - 6
MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Serialization;
@@ -53,7 +54,7 @@ namespace MediaBrowser.Providers.MediaInfo
 
 
         private const string SchemaVersion = "2";
         private const string SchemaVersion = "2";
 
 
-        private async Task<Model.Entities.MediaInfo> GetMediaInfo(BaseItem item, CancellationToken cancellationToken)
+        private async Task<Model.MediaInfo.MediaInfo> GetMediaInfo(BaseItem item, CancellationToken cancellationToken)
         {
         {
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
@@ -64,7 +65,7 @@ namespace MediaBrowser.Providers.MediaInfo
 
 
             try
             try
             {
             {
-                return _json.DeserializeFromFile<Model.Entities.MediaInfo>(cachePath);
+                return _json.DeserializeFromFile<Model.MediaInfo.MediaInfo>(cachePath);
             }
             }
             catch (FileNotFoundException)
             catch (FileNotFoundException)
             {
             {
@@ -74,9 +75,13 @@ namespace MediaBrowser.Providers.MediaInfo
             {
             {
             }
             }
 
 
-            var inputPath = new[] { item.Path };
+            var result = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
+            {
+                InputPath = item.Path,
+                MediaType = DlnaProfileType.Audio,
+                Protocol = MediaProtocol.File
 
 
-            var result = await _mediaEncoder.GetMediaInfo(inputPath, item.Path, MediaProtocol.File, true, false, cancellationToken).ConfigureAwait(false);
+            }, cancellationToken).ConfigureAwait(false);
 
 
             Directory.CreateDirectory(Path.GetDirectoryName(cachePath));
             Directory.CreateDirectory(Path.GetDirectoryName(cachePath));
             _json.SerializeToFile(result, cachePath);
             _json.SerializeToFile(result, cachePath);
@@ -91,7 +96,7 @@ namespace MediaBrowser.Providers.MediaInfo
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <param name="mediaInfo">The media information.</param>
         /// <param name="mediaInfo">The media information.</param>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        protected Task Fetch(Audio audio, CancellationToken cancellationToken, Model.Entities.MediaInfo mediaInfo)
+        protected Task Fetch(Audio audio, CancellationToken cancellationToken, Model.MediaInfo.MediaInfo mediaInfo)
         {
         {
             var mediaStreams = mediaInfo.MediaStreams;
             var mediaStreams = mediaInfo.MediaStreams;
 
 
@@ -115,7 +120,7 @@ namespace MediaBrowser.Providers.MediaInfo
         /// </summary>
         /// </summary>
         /// <param name="audio">The audio.</param>
         /// <param name="audio">The audio.</param>
         /// <param name="data">The data.</param>
         /// <param name="data">The data.</param>
-        private void FetchDataFromTags(Audio audio, Model.Entities.MediaInfo data)
+        private void FetchDataFromTags(Audio audio, Model.MediaInfo.MediaInfo data)
         {
         {
             // Only set Name if title was found in the dictionary
             // Only set Name if title was found in the dictionary
             if (!string.IsNullOrEmpty(data.Title))
             if (!string.IsNullOrEmpty(data.Title))

+ 16 - 7
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs

@@ -1,5 +1,6 @@
 using DvdLib.Ifo;
 using DvdLib.Ifo;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Extensions;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Chapters;
 using MediaBrowser.Controller.Chapters;
@@ -129,9 +130,9 @@ namespace MediaBrowser.Providers.MediaInfo
             return ItemUpdateType.MetadataImport;
             return ItemUpdateType.MetadataImport;
         }
         }
 
 
-        private const string SchemaVersion = "1";
+        private const string SchemaVersion = "2";
 
 
-        private async Task<Model.Entities.MediaInfo> GetMediaInfo(Video item,
+        private async Task<Model.MediaInfo.MediaInfo> GetMediaInfo(Video item,
             IIsoMount isoMount,
             IIsoMount isoMount,
             CancellationToken cancellationToken)
             CancellationToken cancellationToken)
         {
         {
@@ -144,7 +145,7 @@ namespace MediaBrowser.Providers.MediaInfo
 
 
             try
             try
             {
             {
-                return _json.DeserializeFromFile<Model.Entities.MediaInfo>(cachePath);
+                return _json.DeserializeFromFile<Model.MediaInfo.MediaInfo>(cachePath);
             }
             }
             catch (FileNotFoundException)
             catch (FileNotFoundException)
             {
             {
@@ -158,9 +159,17 @@ namespace MediaBrowser.Providers.MediaInfo
                 ? MediaProtocol.Http
                 ? MediaProtocol.Http
                 : MediaProtocol.File;
                 : MediaProtocol.File;
 
 
-            var inputPath = MediaEncoderHelpers.GetInputArgument(item.Path, protocol, isoMount, item.PlayableStreamFileNames);
+            var result = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
+            {
+                PlayableStreamFileNames = item.PlayableStreamFileNames,
+                MountedIso = isoMount,
+                ExtractChapters = true,
+                VideoType = item.VideoType,
+                MediaType = DlnaProfileType.Video,
+                InputPath = item.Path,
+                Protocol = protocol
 
 
-            var result = await _mediaEncoder.GetMediaInfo(inputPath, item.Path, protocol, false, true, cancellationToken).ConfigureAwait(false);
+            }, cancellationToken).ConfigureAwait(false);
 
 
             Directory.CreateDirectory(Path.GetDirectoryName(cachePath));
             Directory.CreateDirectory(Path.GetDirectoryName(cachePath));
             _json.SerializeToFile(result, cachePath);
             _json.SerializeToFile(result, cachePath);
@@ -170,7 +179,7 @@ namespace MediaBrowser.Providers.MediaInfo
 
 
         protected async Task Fetch(Video video,
         protected async Task Fetch(Video video,
             CancellationToken cancellationToken,
             CancellationToken cancellationToken,
-            Model.Entities.MediaInfo mediaInfo,
+            Model.MediaInfo.MediaInfo mediaInfo,
             IIsoMount isoMount,
             IIsoMount isoMount,
             BlurayDiscInfo blurayInfo,
             BlurayDiscInfo blurayInfo,
             MetadataRefreshOptions options)
             MetadataRefreshOptions options)
@@ -348,7 +357,7 @@ namespace MediaBrowser.Providers.MediaInfo
             return _blurayExaminer.GetDiscInfo(path);
             return _blurayExaminer.GetDiscInfo(path);
         }
         }
 
 
-        private void FetchEmbeddedInfo(Video video, Model.Entities.MediaInfo data)
+        private void FetchEmbeddedInfo(Video video, Model.MediaInfo.MediaInfo data)
         {
         {
             if (!video.LockedFields.Contains(MetadataFields.OfficialRating))
             if (!video.LockedFields.Contains(MetadataFields.OfficialRating))
             {
             {

+ 1 - 3
MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs

@@ -14,9 +14,7 @@ namespace MediaBrowser.Server.Implementations.Collections
 
 
         public override bool IsVisible(User user)
         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
         public override bool IsHidden

+ 18 - 9
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)
         public async Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, CancellationToken cancellationToken)
         {
         {
             var item = _libraryManager.GetItemById(id);
             var item = _libraryManager.GetItemById(id);
-            IEnumerable<MediaSourceInfo> mediaSources;
 
 
             var hasMediaSources = (IHasMediaSources)item;
             var hasMediaSources = (IHasMediaSources)item;
             User user = null;
             User user = null;
 
 
-            if (string.IsNullOrWhiteSpace(userId))
-            {
-                mediaSources = hasMediaSources.GetMediaSources(enablePathSubstitution);
-            }
-            else
+            if (!string.IsNullOrWhiteSpace(userId))
             {
             {
                 user = _userManager.GetUserById(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 dynamicMediaSources = await GetDynamicMediaSources(hasMediaSources, cancellationToken).ConfigureAwait(false);
 
 
             var list = new List<MediaSourceInfo>();
             var list = new List<MediaSourceInfo>();
@@ -166,9 +161,11 @@ namespace MediaBrowser.Server.Implementations.Library
                 }
                 }
                 if (source.Protocol == MediaProtocol.File)
                 if (source.Protocol == MediaProtocol.File)
                 {
                 {
-                    source.SupportsDirectStream = File.Exists(source.Path);
-
                     // TODO: Path substitution
                     // TODO: Path substitution
+                    if (!File.Exists(source.Path))
+                    {
+                        source.SupportsDirectStream = false;
+                    }
                 }
                 }
                 else if (source.Protocol == MediaProtocol.Http)
                 else if (source.Protocol == MediaProtocol.Http)
                 {
                 {
@@ -183,6 +180,17 @@ namespace MediaBrowser.Server.Implementations.Library
                 list.Add(source);
                 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);
             return SortMediaSources(list).Where(i => i.Type != MediaSourceType.Placeholder);
         }
         }
 
 
@@ -343,6 +351,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 }
                 }
 
 
                 var json = _jsonSerializer.SerializeToString(mediaSource);
                 var json = _jsonSerializer.SerializeToString(mediaSource);
+                _logger.Debug("Live stream opened: " + json);
                 var clone = _jsonSerializer.DeserializeFromString<MediaSourceInfo>(json);
                 var clone = _jsonSerializer.DeserializeFromString<MediaSourceInfo>(json);
 
 
                 if (!string.IsNullOrWhiteSpace(request.UserId))
                 if (!string.IsNullOrWhiteSpace(request.UserId))

+ 1 - 1
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))
             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))
             if (string.IsNullOrEmpty(collectionType))

+ 9 - 1
MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Serialization;
@@ -123,7 +124,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
         {
         {
             var inputPaths = new[] { mediaSource.Path };
             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);
                         .ConfigureAwait(false);
 
 
             mediaSource.Bitrate = info.Bitrate;
             mediaSource.Bitrate = info.Bitrate;

+ 7 - 1
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.",
     "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:",
     "LabelPinCode": "Pin code:",
     "OptionHideWatchedContentFromLatestMedia": "Hide watched content from latest media",
     "OptionHideWatchedContentFromLatestMedia": "Hide watched content from latest media",
+    "HeaderSync": "Sync",
     "ButtonOk": "Ok",
     "ButtonOk": "Ok",
     "ButtonCancel": "Cancel",
     "ButtonCancel": "Cancel",
     "ButtonExit": "Exit",
     "ButtonExit": "Exit",
@@ -1405,5 +1406,10 @@
     "LabelShowLibraryTileNames": "Show library tile names",
     "LabelShowLibraryTileNames": "Show library tile names",
     "LabelShowLibraryTileNamesHelp": "Determines if labels will be displayed underneath library tiles on the home page",
     "LabelShowLibraryTileNamesHelp": "Determines if labels will be displayed underneath library tiles on the home page",
     "OptionEnableTranscodingThrottle": "Enable throttling",
     "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."
 }
 }

+ 0 - 1
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -180,7 +180,6 @@
     <Compile Include="HttpServer\SocketSharp\WebSocketSharpListener.cs" />
     <Compile Include="HttpServer\SocketSharp\WebSocketSharpListener.cs" />
     <Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
     <Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
     <Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" />
     <Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" />
-    <Compile Include="HttpServer\ThrottledStream.cs" />
     <Compile Include="Intros\DefaultIntroProvider.cs" />
     <Compile Include="Intros\DefaultIntroProvider.cs" />
     <Compile Include="IO\LibraryMonitor.cs" />
     <Compile Include="IO\LibraryMonitor.cs" />
     <Compile Include="Library\CoreResolutionIgnoreRule.cs" />
     <Compile Include="Library\CoreResolutionIgnoreRule.cs" />

+ 1 - 1
MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs

@@ -17,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.Photos
         protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item)
         protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item)
         {
         {
             var photoAlbum = (PhotoAlbum)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);
             return Task.FromResult(items);
         }
         }

+ 1 - 1
MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs

@@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
 
         public string Name
         public string Name
         {
         {
-            get { return "App Sync"; }
+            get { return "Mobile Sync"; }
         }
         }
 
 
         public IEnumerable<SyncTarget> GetAllSyncTargets()
         public IEnumerable<SyncTarget> GetAllSyncTargets()

+ 20 - 7
MediaBrowser.Server.Implementations/Sync/MediaSync.cs

@@ -1,7 +1,9 @@
 using System.Globalization;
 using System.Globalization;
+using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
+using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Sync;
 using MediaBrowser.Controller.Sync;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
@@ -25,13 +27,15 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly IServerApplicationHost _appHost;
         private readonly IServerApplicationHost _appHost;
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly IFileSystem _fileSystem;
         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;
             _logger = logger;
             _syncManager = syncManager;
             _syncManager = syncManager;
             _appHost = appHost;
             _appHost = appHost;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
+            _config = config;
         }
         }
 
 
         public async Task Sync(IServerSyncProvider provider,
         public async Task Sync(IServerSyncProvider provider,
@@ -152,12 +156,14 @@ namespace MediaBrowser.Server.Implementations.Sync
             var transferSuccess = false;
             var transferSuccess = false;
             Exception transferException = null;
             Exception transferException = null;
 
 
+            var options = _config.GetSyncOptions();
+
             try
             try
             {
             {
                 var fileTransferProgress = new ActionableProgress<double>();
                 var fileTransferProgress = new ActionableProgress<double>();
                 fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));
                 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)
                 if (localItem.Item.MediaSources != null)
                 {
                 {
@@ -179,7 +185,7 @@ namespace MediaBrowser.Server.Implementations.Sync
                     var mediaSource = localItem.Item.MediaSources.FirstOrDefault();
                     var mediaSource = localItem.Item.MediaSources.FirstOrDefault();
                     if (mediaSource != null)
                     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 failedSubtitles = new List<MediaStream>();
             var requiresSave = false;
             var requiresSave = false;
@@ -219,7 +225,7 @@ namespace MediaBrowser.Server.Implementations.Sync
                 try
                 try
                 {
                 {
                     var remotePath = GetRemoteSubtitlePath(localItem, mediaStream, provider, target);
                     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
                     // This is the path that will be used when talking to the provider
                     mediaStream.ExternalId = remotePath;
                     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);
             _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);
                 return await provider.SendFile(stream, remotePath, target, progress, cancellationToken).ConfigureAwait(false);
             }
             }
         }
         }

+ 6 - 3
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.Common.Progress;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Sync;
 using MediaBrowser.Controller.Sync;
@@ -18,13 +19,15 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly IServerApplicationHost _appHost;
         private readonly IServerApplicationHost _appHost;
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly IFileSystem _fileSystem;
         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;
             _syncManager = syncManager;
             _appHost = appHost;
             _appHost = appHost;
             _logger = logger;
             _logger = logger;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
+            _config = config;
         }
         }
 
 
         public async Task Sync(IEnumerable<IServerSyncProvider> providers, IProgress<double> progress, CancellationToken cancellationToken)
         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);
                 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)
                     .Sync(target.Item1, dataProvider, target.Item2, innerProgress, cancellationToken)
                     .ConfigureAwait(false);
                     .ConfigureAwait(false);
 
 

+ 6 - 3
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.Common.ScheduledTasks;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Sync;
 using MediaBrowser.Controller.Sync;
@@ -17,13 +18,15 @@ namespace MediaBrowser.Server.Implementations.Sync
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly IFileSystem _fileSystem;
         private readonly IFileSystem _fileSystem;
         private readonly IServerApplicationHost _appHost;
         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;
             _syncManager = syncManager;
             _logger = logger;
             _logger = logger;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
             _appHost = appHost;
             _appHost = appHost;
+            _config = config;
         }
         }
 
 
         public string Name
         public string Name
@@ -46,7 +49,7 @@ namespace MediaBrowser.Server.Implementations.Sync
 
 
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         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);
                 .Sync(ServerSyncProviders, progress, cancellationToken);
         }
         }
 
 

+ 38 - 18
MediaBrowser.Server.Implementations/Sync/SyncManager.cs

@@ -1167,6 +1167,11 @@ namespace MediaBrowser.Server.Implementations.Sync
         }
         }
 
 
         public IEnumerable<SyncQualityOption> GetQualityOptions(string targetId)
         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 provider in _providers)
             {
             {
@@ -1174,7 +1179,7 @@ namespace MediaBrowser.Server.Implementations.Sync
                 {
                 {
                     if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase))
                     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>();
             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;
             var hasQuality = provider as IHasSyncQuality;
             if (hasQuality != null)
             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
             // 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)
             foreach (var provider in _providers)
             {
             {
@@ -1225,7 +1237,7 @@ namespace MediaBrowser.Server.Implementations.Sync
                 {
                 {
                     if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase))
                     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>();
             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;
             var hasQuality = provider as IHasSyncQuality;
             if (hasQuality != null)
             if (hasQuality != null)
@@ -1251,20 +1268,23 @@ namespace MediaBrowser.Server.Implementations.Sync
                 EnableQualityOptions = false
                 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;
             return list;
         }
         }

+ 2 - 2
Nuget/MediaBrowser.Common.Internal.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Common.Internal</id>
         <id>MediaBrowser.Common.Internal</id>
-        <version>3.0.615</version>
+        <version>3.0.616</version>
         <title>MediaBrowser.Common.Internal</title>
         <title>MediaBrowser.Common.Internal</title>
         <authors>Luke</authors>
         <authors>Luke</authors>
         <owners>ebr,Luke,scottisafool</owners>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
         <description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
         <copyright>Copyright © Emby 2013</copyright>
         <copyright>Copyright © Emby 2013</copyright>
         <dependencies>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.615" />
+            <dependency id="MediaBrowser.Common" version="3.0.616" />
             <dependency id="NLog" version="3.2.0.0" />
             <dependency id="NLog" version="3.2.0.0" />
             <dependency id="SimpleInjector" version="2.7.0" />
             <dependency id="SimpleInjector" version="2.7.0" />
         </dependencies>
         </dependencies>

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Common</id>
         <id>MediaBrowser.Common</id>
-        <version>3.0.615</version>
+        <version>3.0.616</version>
         <title>MediaBrowser.Common</title>
         <title>MediaBrowser.Common</title>
         <authors>Emby Team</authors>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
         <owners>ebr,Luke,scottisafool</owners>

+ 1 - 1
Nuget/MediaBrowser.Model.Signed.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Model.Signed</id>
         <id>MediaBrowser.Model.Signed</id>
-        <version>3.0.615</version>
+        <version>3.0.616</version>
         <title>MediaBrowser.Model - Signed Edition</title>
         <title>MediaBrowser.Model - Signed Edition</title>
         <authors>Emby Team</authors>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
         <owners>ebr,Luke,scottisafool</owners>

+ 2 - 2
Nuget/MediaBrowser.Server.Core.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
     <metadata>
         <id>MediaBrowser.Server.Core</id>
         <id>MediaBrowser.Server.Core</id>
-        <version>3.0.615</version>
+        <version>3.0.616</version>
         <title>Media Browser.Server.Core</title>
         <title>Media Browser.Server.Core</title>
         <authors>Emby Team</authors>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains core components required to build plugins for Emby Server.</description>
         <description>Contains core components required to build plugins for Emby Server.</description>
         <copyright>Copyright © Emby 2013</copyright>
         <copyright>Copyright © Emby 2013</copyright>
         <dependencies>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.615" />
+            <dependency id="MediaBrowser.Common" version="3.0.616" />
         </dependencies>
         </dependencies>
     </metadata>
     </metadata>
     <files>
     <files>