probe live streams after opening

This commit is contained in:
Luke Pulverenti 2015-04-05 11:01:57 -04:00
parent 2b7a80cfb5
commit 30104bd8de
41 changed files with 294 additions and 132 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -174,18 +174,18 @@ 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"); var userId = user.Id.ToString("N");
// Need to check Count > 0 for boxsets created prior to the introduction of Shares // 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))) if (Shares.Count > 0 && Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)))
{ {
//return false; return true;
} }
return true; if (base.IsVisible(user))
{
return GetChildren(user, true).Any();
} }
return false; return false;

View File

@ -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);
}
} }
} }

View File

@ -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));

View File

@ -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.

View File

@ -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" />

View File

@ -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="request">The request.</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="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.

View File

@ -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>();
}
}
}

View File

@ -0,0 +1,10 @@

namespace MediaBrowser.Controller.Sync
{
/// <summary>
/// A marker interface
/// </summary>
public interface IRemoteSyncProvider
{
}
}

View File

@ -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);
} }
} }

View File

@ -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)

View File

@ -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="request">The request.</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="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, public Task<Model.MediaInfo.MediaInfo> GetMediaInfo(MediaInfoRequest request, CancellationToken cancellationToken)
bool extractChapters, CancellationToken cancellationToken)
{ {
return GetMediaInfoInternal(GetInputArgument(inputFiles, protocol), primaryPath, protocol, !isAudio && extractChapters, var extractChapters = request.MediaType == DlnaProfileType.Video && request.ExtractChapters;
GetProbeSizeArgument(inputFiles, protocol), isAudio, cancellationToken);
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)

View File

@ -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)
{ {

View File

@ -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>

View File

@ -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>

View File

@ -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" />

View File

@ -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
{ {

View File

@ -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; }
} }
} }

View File

@ -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; }
} }
} }

View File

@ -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[] { };

View File

@ -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) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILocalizationManager iLocalizationManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
{ {
_iLocalizationManager = iLocalizationManager;
} }
/// <summary> /// <summary>

View File

@ -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))

View File

@ -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))
{ {

View File

@ -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) return base.IsVisible(user) && GetChildren(user, false).Any();
.OfType<BoxSet>()
.Any(i => i.IsVisible(user));
} }
public override bool IsHidden public override bool IsHidden

View File

@ -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)) if (!string.IsNullOrWhiteSpace(userId))
{
mediaSources = hasMediaSources.GetMediaSources(enablePathSubstitution);
}
else
{ {
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))

View File

@ -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))

View File

@ -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;

View File

@ -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."
} }

View File

@ -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" />

View File

@ -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);
} }

View File

@ -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()

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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);
} }

View File

@ -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,6 +1268,8 @@ namespace MediaBrowser.Server.Implementations.Sync
EnableQualityOptions = false EnableQualityOptions = false
}); });
if (user == null || user.Policy.EnableSyncTranscoding)
{
list.Add(new SyncProfileOption list.Add(new SyncProfileOption
{ {
Name = "Baseline", Name = "Baseline",
@ -1265,6 +1284,7 @@ namespace MediaBrowser.Server.Implementations.Sync
Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices. Targets H264/AAC/AC3 video and MP3 audio.", Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices. Targets H264/AAC/AC3 video and MP3 audio.",
IsDefault = true IsDefault = true
}); });
}
return list; return list;
} }

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>