diff options
41 files changed, 294 insertions, 132 deletions
diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index b9dbf5946..d5f88e6a4 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -248,6 +248,9 @@ namespace MediaBrowser.Api.Sync result.Targets = _syncManager.GetSyncTargets(request.UserId) .ToList(); + var auth = AuthorizationContext.GetAuthorizationInfo(Request); + var authenticatedUser = _userManager.GetUserById(auth.UserId); + if (!string.IsNullOrWhiteSpace(request.TargetId)) { result.Targets = result.Targets @@ -255,11 +258,11 @@ namespace MediaBrowser.Api.Sync .ToList(); result.QualityOptions = _syncManager - .GetQualityOptions(request.TargetId) + .GetQualityOptions(request.TargetId, authenticatedUser) .ToList(); result.ProfileOptions = _syncManager - .GetProfileOptions(request.TargetId) + .GetProfileOptions(request.TargetId, authenticatedUser) .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) .Select(_libraryManager.GetItemById) .Where(i => i != null); diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 4185590ab..e0c14821e 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Querying; using MediaBrowser.Model.Users; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 14095f7ff..61e5acdb3 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -991,8 +991,9 @@ namespace MediaBrowser.Controller.Entities } var locations = user.RootFolder - .GetChildren(user, true) + .Children .OfType<CollectionFolder>() + .Where(i => i.IsVisible(user)) .SelectMany(i => i.PhysicalLocations) .ToList(); diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 0778643da..02e9d4cf9 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -175,19 +175,19 @@ namespace MediaBrowser.Controller.Entities.Movies 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; } + if (base.IsVisible(user)) + { + return GetChildren(user, true).Any(); + } + return false; } } diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs index 24ebf8815..5b48a70e9 100644 --- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs +++ b/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.Runtime.Serialization; -using MediaBrowser.Model.Users; +using System.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Controller.Entities { - public class PhotoAlbum : Folder + public class PhotoAlbum : Folder, IMetadataContainer { public override bool SupportsLocalMetadata { @@ -28,5 +32,31 @@ namespace MediaBrowser.Controller.Entities { 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); + } } } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 0e602dabe..c01814bce 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/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.MusicAlbums, user, "1", 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.MusicGenres, user, "5", parent).ConfigureAwait(false)); list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "6", parent).ConfigureAwait(false)); diff --git a/MediaBrowser.Server.Implementations/HttpServer/ThrottledStream.cs b/MediaBrowser.Controller/IO/ThrottledStream.cs index 1c01fa9e0..1df00b45a 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ThrottledStream.cs +++ b/MediaBrowser.Controller/IO/ThrottledStream.cs @@ -3,7 +3,7 @@ using System.IO; using System.Threading; using System.Threading.Tasks; -namespace MediaBrowser.Server.Implementations.HttpServer +namespace MediaBrowser.Controller.IO { /// <summary> /// Class for streaming data with throttling support. diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 9a4a2cb62..8c4154966 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -171,6 +171,7 @@ <Compile Include="Entities\UserView.cs" /> <Compile Include="Entities\UserViewBuilder.cs" /> <Compile Include="FileOrganization\IFileOrganizationService.cs" /> + <Compile Include="IO\ThrottledStream.cs" /> <Compile Include="Library\DeleteOptions.cs" /> <Compile Include="Library\ILibraryPostScanTask.cs" /> <Compile Include="Library\IMediaSourceManager.cs" /> @@ -212,6 +213,7 @@ <Compile Include="MediaEncoding\ImageEncodingOptions.cs" /> <Compile Include="MediaEncoding\IMediaEncoder.cs" /> <Compile Include="MediaEncoding\ISubtitleEncoder.cs" /> + <Compile Include="MediaEncoding\MediaInfoRequest.cs" /> <Compile Include="MediaEncoding\MediaStreamSelector.cs" /> <Compile Include="Net\AuthenticatedAttribute.cs" /> <Compile Include="Net\AuthorizationInfo.cs" /> @@ -393,6 +395,7 @@ <Compile Include="Subtitles\SubtitleResponse.cs" /> <Compile Include="Subtitles\SubtitleSearchRequest.cs" /> <Compile Include="Sync\IHasDynamicAccess.cs" /> + <Compile Include="Sync\IRemoteSyncProvider.cs" /> <Compile Include="Sync\IServerSyncProvider.cs" /> <Compile Include="Sync\ISyncDataProvider.cs" /> <Compile Include="Sync\ISyncManager.cs" /> diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index bb5674864..5bec7980a 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -67,14 +67,10 @@ namespace MediaBrowser.Controller.MediaEncoding /// <summary> /// Gets the media info. /// </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> /// <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> /// Gets the probe size argument. diff --git a/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs b/MediaBrowser.Controller/MediaEncoding/MediaInfoRequest.cs new file mode 100644 index 000000000..ca0c2fdbb --- /dev/null +++ b/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>(); + } + } +} diff --git a/MediaBrowser.Controller/Sync/IRemoteSyncProvider.cs b/MediaBrowser.Controller/Sync/IRemoteSyncProvider.cs new file mode 100644 index 000000000..aeb7a3bff --- /dev/null +++ b/MediaBrowser.Controller/Sync/IRemoteSyncProvider.cs @@ -0,0 +1,10 @@ + +namespace MediaBrowser.Controller.Sync +{ + /// <summary> + /// A marker interface + /// </summary> + public interface IRemoteSyncProvider + { + } +} diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 3b6e20edc..97591551c 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -174,6 +174,13 @@ namespace MediaBrowser.Controller.Sync /// <param name="targetId">The target identifier.</param> /// <returns>IEnumerable<SyncQualityOption>.</returns> 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<SyncQualityOption>.</returns> + IEnumerable<SyncQualityOption> GetQualityOptions(string targetId, User user); /// <summary> /// Gets the profile options. @@ -181,5 +188,12 @@ namespace MediaBrowser.Controller.Sync /// <param name="targetId">The target identifier.</param> /// <returns>IEnumerable<SyncQualityOption>.</returns> 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<SyncProfileOption>.</returns> + IEnumerable<SyncProfileOption> GetProfileOptions(string targetId, User user); } } diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 5ccea52ba..abd649ad7 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -223,7 +223,7 @@ namespace MediaBrowser.Dlna.ContentDirectory if (string.Equals(flag, "BrowseMetadata")) { totalCount = 1; - + if (item.IsFolder || serverItem.StubType.HasValue) { 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; @@ -389,7 +389,7 @@ namespace MediaBrowser.Dlna.ContentDirectory isFolder = true; } - return await folder.GetItems(new InternalItemsQuery + return folder.GetItems(new InternalItemsQuery { Limit = limit, StartIndex = startIndex, @@ -401,7 +401,7 @@ namespace MediaBrowser.Dlna.ContentDirectory IsFolder = isFolder, MediaTypes = mediaTypes.ToArray() - }).ConfigureAwait(false); + }); } private async Task<QueryResult<ServerItem>> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 18d9ccece..be636c0ba 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -6,6 +6,7 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Session; using MediaBrowser.MediaEncoding.Probing; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; @@ -103,18 +104,17 @@ namespace MediaBrowser.MediaEncoding.Encoder /// <summary> /// Gets the media info. /// </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> /// <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> @@ -152,7 +152,7 @@ namespace MediaBrowser.MediaEncoding.Encoder /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{MediaInfoResult}.</returns> /// <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, bool isAudio, CancellationToken cancellationToken) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 48e8b6ee2..7df3cb56f 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -25,9 +25,9 @@ namespace MediaBrowser.MediaEncoding.Probing _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, Protocol = protocol @@ -342,7 +342,7 @@ namespace MediaBrowser.MediaEncoding.Probing return null; } - private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.Entities.MediaInfo data) + private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.MediaInfo.MediaInfo data) { 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) { @@ -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"); @@ -591,7 +591,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// <param name="audio">The audio.</param> /// <param name="tags">The tags.</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); @@ -626,7 +626,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// </summary> /// <param name="info">The information.</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"); @@ -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 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) { @@ -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) { diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index fdedc51a2..c3ec911de 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -560,9 +560,6 @@ <Compile Include="..\MediaBrowser.Model\Entities\MBRegistrationRecord.cs"> <Link>Entities\MBRegistrationRecord.cs</Link> </Compile> - <Compile Include="..\MediaBrowser.Model\Entities\MediaInfo.cs"> - <Link>Entities\MediaInfo.cs</Link> - </Compile> <Compile Include="..\MediaBrowser.Model\Entities\MediaStream.cs"> <Link>Entities\MediaStream.cs</Link> </Compile> @@ -809,6 +806,9 @@ <Compile Include="..\MediaBrowser.Model\MediaInfo\LiveStreamResponse.cs"> <Link>MediaInfo\LiveStreamResponse.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaInfo.cs"> + <Link>MediaInfo\MediaInfo.cs</Link> + </Compile> <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaProtocol.cs"> <Link>MediaInfo\MediaProtocol.cs</Link> </Compile> diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 3618aa972..437fcc8ff 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -525,9 +525,6 @@ <Compile Include="..\MediaBrowser.Model\Entities\MBRegistrationRecord.cs"> <Link>Entities\MBRegistrationRecord.cs</Link> </Compile> - <Compile Include="..\MediaBrowser.Model\Entities\MediaInfo.cs"> - <Link>Entities\MediaInfo.cs</Link> - </Compile> <Compile Include="..\MediaBrowser.Model\Entities\MediaStream.cs"> <Link>Entities\MediaStream.cs</Link> </Compile> @@ -765,6 +762,9 @@ <Compile Include="..\MediaBrowser.Model\MediaInfo\LiveStreamResponse.cs"> <Link>MediaInfo\LiveStreamResponse.cs</Link> </Compile> + <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaInfo.cs"> + <Link>MediaInfo\MediaInfo.cs</Link> + </Compile> <Compile Include="..\MediaBrowser.Model\MediaInfo\MediaProtocol.cs"> <Link>MediaInfo\MediaProtocol.cs</Link> </Compile> diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 067309512..2a210b7a2 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -226,7 +226,7 @@ <Compile Include="Dto\RecommendationType.cs" /> <Compile Include="Dto\SubtitleDownloadOptions.cs" /> <Compile Include="Entities\IsoType.cs" /> - <Compile Include="Entities\MediaInfo.cs" /> + <Compile Include="MediaInfo\MediaInfo.cs" /> <Compile Include="Entities\MediaStreamType.cs" /> <Compile Include="Entities\PackageReviewInfo.cs" /> <Compile Include="Entities\ProviderIdsExtensions.cs" /> diff --git a/MediaBrowser.Model/Entities/MediaInfo.cs b/MediaBrowser.Model/MediaInfo/MediaInfo.cs index 67efe3108..21f258693 100644 --- a/MediaBrowser.Model/Entities/MediaInfo.cs +++ b/MediaBrowser.Model/MediaInfo/MediaInfo.cs @@ -1,8 +1,9 @@ using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; -namespace MediaBrowser.Model.Entities +namespace MediaBrowser.Model.MediaInfo { public class MediaInfo : MediaSourceInfo, IHasProviderIds { diff --git a/MediaBrowser.Model/Sync/SyncOptions.cs b/MediaBrowser.Model/Sync/SyncOptions.cs index 294f7bcef..765dea86b 100644 --- a/MediaBrowser.Model/Sync/SyncOptions.cs +++ b/MediaBrowser.Model/Sync/SyncOptions.cs @@ -4,5 +4,6 @@ namespace MediaBrowser.Model.Sync public class SyncOptions { public string TemporaryPath { get; set; } + public long UploadSpeedLimitBytes { get; set; } } } diff --git a/MediaBrowser.Model/Sync/SyncQualityOption.cs b/MediaBrowser.Model/Sync/SyncQualityOption.cs index 597b98727..6eff4b9a4 100644 --- a/MediaBrowser.Model/Sync/SyncQualityOption.cs +++ b/MediaBrowser.Model/Sync/SyncQualityOption.cs @@ -23,5 +23,10 @@ namespace MediaBrowser.Model.Sync /// </summary> /// <value><c>true</c> if this instance is default; otherwise, <c>false</c>.</value> 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; } } } diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 640f03e2a..b3c599496 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -39,6 +39,8 @@ namespace MediaBrowser.Model.Users public bool EnableLiveTvAccess { get; set; } public bool EnableMediaPlayback { get; set; } + public bool EnableMediaPlaybackTranscoding { get; set; } + public bool EnableContentDeletion { get; set; } public bool EnableContentDownloading { get; set; } @@ -47,6 +49,7 @@ namespace MediaBrowser.Model.Users /// </summary> /// <value><c>true</c> if [enable synchronize]; otherwise, <c>false</c>.</value> public bool EnableSync { get; set; } + public bool EnableSyncTranscoding { get; set; } public string[] EnabledDevices { get; set; } public bool EnableAllDevices { get; set; } @@ -62,9 +65,14 @@ namespace MediaBrowser.Model.Users public UserPolicy() { EnableSync = true; - EnableLiveTvManagement = true; + EnableSyncTranscoding = true; + EnableMediaPlayback = true; + EnableMediaPlaybackTranscoding = true; + + EnableLiveTvManagement = true; EnableLiveTvAccess = true; + EnableSharedDeviceControl = true; BlockedTags = new string[] { }; diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs index 3ac3cccb3..92327c9bc 100644 --- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs +++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; @@ -16,11 +15,8 @@ namespace MediaBrowser.Providers.BoxSets { 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> diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs index b1bed7310..3e816802e 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Entities; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; @@ -53,7 +54,7 @@ namespace MediaBrowser.Providers.MediaInfo 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(); @@ -64,7 +65,7 @@ namespace MediaBrowser.Providers.MediaInfo try { - return _json.DeserializeFromFile<Model.Entities.MediaInfo>(cachePath); + return _json.DeserializeFromFile<Model.MediaInfo.MediaInfo>(cachePath); } 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)); _json.SerializeToFile(result, cachePath); @@ -91,7 +96,7 @@ namespace MediaBrowser.Providers.MediaInfo /// <param name="cancellationToken">The cancellation token.</param> /// <param name="mediaInfo">The media information.</param> /// <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; @@ -115,7 +120,7 @@ namespace MediaBrowser.Providers.MediaInfo /// </summary> /// <param name="audio">The audio.</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 if (!string.IsNullOrEmpty(data.Title)) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index cec66f3c1..c433018c0 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -1,5 +1,6 @@ using DvdLib.Ifo; using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Chapters; @@ -129,9 +130,9 @@ namespace MediaBrowser.Providers.MediaInfo 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, CancellationToken cancellationToken) { @@ -144,7 +145,7 @@ namespace MediaBrowser.Providers.MediaInfo try { - return _json.DeserializeFromFile<Model.Entities.MediaInfo>(cachePath); + return _json.DeserializeFromFile<Model.MediaInfo.MediaInfo>(cachePath); } catch (FileNotFoundException) { @@ -158,9 +159,17 @@ namespace MediaBrowser.Providers.MediaInfo ? MediaProtocol.Http : 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)); _json.SerializeToFile(result, cachePath); @@ -170,7 +179,7 @@ namespace MediaBrowser.Providers.MediaInfo protected async Task Fetch(Video video, CancellationToken cancellationToken, - Model.Entities.MediaInfo mediaInfo, + Model.MediaInfo.MediaInfo mediaInfo, IIsoMount isoMount, BlurayDiscInfo blurayInfo, MetadataRefreshOptions options) @@ -348,7 +357,7 @@ namespace MediaBrowser.Providers.MediaInfo 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)) { 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/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; } diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index bfc95a296..0e9ab6001 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common.Internal</id> - <version>3.0.615</version> + <version>3.0.616</version> <title>MediaBrowser.Common.Internal</title> <authors>Luke</authors> <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> <copyright>Copyright © Emby 2013</copyright> <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="SimpleInjector" version="2.7.0" /> </dependencies> diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 77d5242a9..e1019e2e4 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common</id> - <version>3.0.615</version> + <version>3.0.616</version> <title>MediaBrowser.Common</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index 12b5eb442..24f43a75b 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Model.Signed</id> - <version>3.0.615</version> + <version>3.0.616</version> <title>MediaBrowser.Model - Signed Edition</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index cbf4e9579..2b8b9fc37 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MediaBrowser.Server.Core</id> - <version>3.0.615</version> + <version>3.0.616</version> <title>Media Browser.Server.Core</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains core components required to build plugins for Emby Server.</description> <copyright>Copyright © Emby 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.615" /> + <dependency id="MediaBrowser.Common" version="3.0.616" /> </dependencies> </metadata> <files> |
