added out of network bitrate limit

pull/702/head
Luke Pulverenti 9 years ago
parent 6e6ce82cf6
commit b9c656e859

@ -1,5 +1,4 @@
using System.Linq;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Logging;
@ -8,6 +7,7 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using ImageFormat = MediaBrowser.Model.Drawing.ImageFormat;
namespace Emby.Drawing.GDI
@ -245,5 +245,10 @@ namespace Emby.Drawing.GDI
public void Dispose()
{
}
public string Name
{
get { return "GDI"; }
}
}
}

@ -44,5 +44,10 @@ namespace Emby.Drawing
/// </summary>
/// <param name="options">The options.</param>
void CreateImageCollage(ImageCollageOptions options);
/// <summary>
/// Gets the name.
/// </summary>
/// <value>The name.</value>
string Name { get; }
}
}

@ -206,6 +206,11 @@ namespace Emby.Drawing.ImageMagick
}
}
public string Name
{
get { return "ImageMagick"; }
}
private bool _disposed;
public void Dispose()
{

@ -433,7 +433,7 @@ namespace MediaBrowser.Api.LiveTv
var result = await _liveTvManager.GetPrograms(query, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedSerializedResultUsingCache(result);
return ToOptimizedResult(result);
}
public async Task<object> Get(GetRecommendedPrograms request)
@ -450,7 +450,7 @@ namespace MediaBrowser.Api.LiveTv
var result = await _liveTvManager.GetRecommendedPrograms(query, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedSerializedResultUsingCache(result);
return ToOptimizedResult(result);
}
public object Post(GetPrograms request)
@ -473,7 +473,7 @@ namespace MediaBrowser.Api.LiveTv
}, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedSerializedResultUsingCache(result);
return ToOptimizedResult(result);
}
public async Task<object> Get(GetRecording request)

@ -1627,7 +1627,7 @@ namespace MediaBrowser.Api.Playback
MediaSourceInfo mediaSource;
if (string.IsNullOrWhiteSpace(request.LiveStreamId))
{
var mediaSources = (await MediaSourceManager.GetPlayackMediaSources(request.Id, false, cancellationToken).ConfigureAwait(false)).ToList();
var mediaSources = (await MediaSourceManager.GetPlayackMediaSources(request.Id, null, false, new[] { MediaType.Audio, MediaType.Video }, cancellationToken).ConfigureAwait(false)).ToList();
mediaSource = string.IsNullOrEmpty(request.MediaSourceId)
? mediaSources.First()

@ -1,4 +1,6 @@
using MediaBrowser.Controller.Devices;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
@ -59,23 +61,27 @@ namespace MediaBrowser.Api.Playback
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IDeviceManager _deviceManager;
private readonly ILibraryManager _libraryManager;
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager)
public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager)
{
_mediaSourceManager = mediaSourceManager;
_deviceManager = deviceManager;
_libraryManager = libraryManager;
_config = config;
_networkManager = networkManager;
}
public async Task<object> Get(GetPlaybackInfo request)
{
var result = await GetPlaybackInfo(request.Id, request.UserId).ConfigureAwait(false);
var result = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }).ConfigureAwait(false);
return ToOptimizedResult(result);
}
public async Task<object> Get(GetLiveMediaInfo request)
{
var result = await GetPlaybackInfo(request.Id, request.UserId).ConfigureAwait(false);
var result = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }).ConfigureAwait(false);
return ToOptimizedResult(result);
}
@ -122,29 +128,38 @@ namespace MediaBrowser.Api.Playback
public async Task<object> Post(GetPostedPlaybackInfo request)
{
var info = await GetPlaybackInfo(request.Id, request.UserId, request.MediaSourceId, request.LiveStreamId).ConfigureAwait(false);
var authInfo = AuthorizationContext.GetAuthorizationInfo(Request);
var profile = request.DeviceProfile;
if (profile == null)
var caps = _deviceManager.GetCapabilities(authInfo.DeviceId);
if (caps != null)
{
var caps = _deviceManager.GetCapabilities(authInfo.DeviceId);
if (caps != null)
if (profile == null)
{
profile = caps.DeviceProfile;
}
}
var maxBitrate = request.MaxStreamingBitrate;
if (_config.Configuration.RemoteClientBitrateLimit > 0 && !_networkManager.IsInLocalNetwork(Request.RemoteIp))
{
maxBitrate = Math.Min(maxBitrate ?? _config.Configuration.RemoteClientBitrateLimit, _config.Configuration.RemoteClientBitrateLimit);
}
var info = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }, request.MediaSourceId, request.LiveStreamId).ConfigureAwait(false);
if (profile != null)
{
var mediaSourceId = request.MediaSourceId;
SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex);
SetDeviceSpecificData(request.Id, info, profile, authInfo, maxBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex);
}
return ToOptimizedResult(info);
}
private async Task<PlaybackInfoResponse> GetPlaybackInfo(string id, string userId, string mediaSourceId = null, string liveStreamId = null)
private async Task<PlaybackInfoResponse> GetPlaybackInfo(string id, string userId, string[] supportedLiveMediaTypes, string mediaSourceId = null, string liveStreamId = null)
{
var result = new PlaybackInfoResponse();
@ -153,7 +168,7 @@ namespace MediaBrowser.Api.Playback
IEnumerable<MediaSourceInfo> mediaSources;
try
{
mediaSources = await _mediaSourceManager.GetPlayackMediaSources(id, userId, true, CancellationToken.None).ConfigureAwait(false);
mediaSources = await _mediaSourceManager.GetPlayackMediaSources(id, userId, true, supportedLiveMediaTypes, CancellationToken.None).ConfigureAwait(false);
}
catch (PlaybackException ex)
{

@ -136,11 +136,11 @@ namespace MediaBrowser.Api.Subtitles
_providerManager = providerManager;
}
public object Get(GetSubtitlePlaylist request)
public async Task<object> Get(GetSubtitlePlaylist request)
{
var item = (Video)_libraryManager.GetItemById(new Guid(request.Id));
var mediaSource = _mediaSourceManager.GetStaticMediaSource(item, request.MediaSourceId, false);
var mediaSource = await _mediaSourceManager.GetMediaSource(item, request.MediaSourceId, false).ConfigureAwait(false);
var builder = new StringBuilder();

@ -101,12 +101,6 @@ namespace MediaBrowser.Common.Implementations
/// <value>The failed assemblies.</value>
public List<string> FailedAssemblies { get; protected set; }
/// <summary>
/// Gets all types within all running assemblies
/// </summary>
/// <value>All types.</value>
public Type[] AllTypes { get; protected set; }
/// <summary>
/// Gets all concrete types.
/// </summary>
@ -438,9 +432,10 @@ namespace MediaBrowser.Common.Implementations
Logger.Info("Loading {0}", assembly.FullName);
}
AllTypes = assemblies.SelectMany(GetTypes).ToArray();
AllConcreteTypes = AllTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray();
AllConcreteTypes = assemblies
.SelectMany(GetTypes)
.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType)
.ToArray();
}
/// <summary>

@ -172,11 +172,11 @@ namespace MediaBrowser.Common.Implementations.Networking
Uri uri;
if (Uri.TryCreate(endpoint, UriKind.RelativeOrAbsolute, out uri))
{
var host = uri.DnsSafeHost;
Logger.Debug("Resolving host {0}", host);
try
{
var host = uri.DnsSafeHost;
Logger.Debug("Resolving host {0}", host);
address = GetIpAddresses(host).FirstOrDefault();
if (address != null)
@ -186,9 +186,13 @@ namespace MediaBrowser.Common.Implementations.Networking
return IsInLocalNetworkInternal(address.ToString(), false);
}
}
catch (InvalidOperationException)
{
// Can happen with reverse proxy or IIS url rewriting
}
catch (Exception ex)
{
Logger.ErrorException("Error resovling hostname {0}", ex, host);
Logger.ErrorException("Error resovling hostname", ex);
}
}
}

@ -43,18 +43,10 @@ namespace MediaBrowser.Controller.Library
/// <param name="id">The identifier.</param>
/// <param name="userId">The user identifier.</param>
/// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
/// <param name="supportedLiveMediaTypes">The supported live media types.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>IEnumerable&lt;MediaSourceInfo&gt;.</returns>
Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, CancellationToken cancellationToken);
/// <summary>
/// Gets the playack media sources.
/// </summary>
/// <param name="id">The identifier.</param>
/// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task&lt;IEnumerable&lt;MediaSourceInfo&gt;&gt;.</returns>
Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, bool enablePathSubstitution, CancellationToken cancellationToken);
Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, string[] supportedLiveMediaTypes, CancellationToken cancellationToken);
/// <summary>
/// Gets the static media sources.
@ -64,7 +56,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="user">The user.</param>
/// <returns>IEnumerable&lt;MediaSourceInfo&gt;.</returns>
IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null);
/// <summary>
/// Gets the static media source.
/// </summary>
@ -72,7 +64,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="mediaSourceId">The media source identifier.</param>
/// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
/// <returns>MediaSourceInfo.</returns>
MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution);
Task<MediaSourceInfo> GetMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution);
/// <summary>
/// Opens the media source.

@ -1,5 +1,4 @@
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using System.Threading.Tasks;

@ -892,7 +892,7 @@ namespace MediaBrowser.Dlna.PlayTo
request.MediaSource = hasMediaSources == null ?
null :
mediaSourceManager.GetStaticMediaSource(hasMediaSources, request.MediaSourceId, false);
mediaSourceManager.GetMediaSource(hasMediaSources, request.MediaSourceId, false).Result;

@ -59,7 +59,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, false, cancellationToken).ConfigureAwait(false);
var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(request.ItemId, null, false, new[] { MediaType.Audio, MediaType.Video }, cancellationToken).ConfigureAwait(false);
var mediaSource = string.IsNullOrEmpty(request.MediaSourceId)
? mediaSources.First()

@ -132,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
int subtitleStreamIndex,
CancellationToken cancellationToken)
{
var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(itemId, false, cancellationToken).ConfigureAwait(false);
var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(itemId, null, false, new[] { MediaType.Audio, MediaType.Video }, cancellationToken).ConfigureAwait(false);
var mediaSource = mediaSources
.First(i => string.Equals(i.Id, mediaSourceId));

@ -208,6 +208,7 @@ namespace MediaBrowser.Model.Configuration
public bool EnableAudioArchiveFiles { get; set; }
public bool EnableVideoArchiveFiles { get; set; }
public int RemoteClientBitrateLimit { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.

@ -19,12 +19,14 @@ namespace MediaBrowser.Model.Session
public bool SupportsOfflineAccess { get; set; }
public DeviceProfile DeviceProfile { get; set; }
public List<string> SupportedLiveMediaTypes { get; set; }
public ClientCapabilities()
{
PlayableMediaTypes = new List<string>();
SupportedCommands = new List<string>();
SupportsPersistentIdentifier = true;
SupportedLiveMediaTypes = new List<string>();
}
}
}

@ -39,8 +39,9 @@ namespace MediaBrowser.Model.Users
public bool EnableLiveTvAccess { get; set; }
public bool EnableMediaPlayback { get; set; }
public bool EnableMediaPlaybackTranscoding { get; set; }
public bool EnableAudioPlaybackTranscoding { get; set; }
public bool EnableVideoPlaybackTranscoding { get; set; }
public bool EnableContentDeletion { get; set; }
public bool EnableContentDownloading { get; set; }
@ -68,8 +69,9 @@ namespace MediaBrowser.Model.Users
EnableSyncTranscoding = true;
EnableMediaPlayback = true;
EnableMediaPlaybackTranscoding = true;
EnableAudioPlaybackTranscoding = true;
EnableVideoPlaybackTranscoding = true;
EnableLiveTvManagement = true;
EnableLiveTvAccess = true;

@ -129,12 +129,7 @@ namespace MediaBrowser.Server.Implementations.Library
return list;
}
public Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, bool enablePathSubstitution, CancellationToken cancellationToken)
{
return GetPlayackMediaSources(id, null, enablePathSubstitution, cancellationToken);
}
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, string[] supportedLiveMediaTypes, CancellationToken cancellationToken)
{
var item = _libraryManager.GetItemById(id);
@ -184,9 +179,19 @@ namespace MediaBrowser.Server.Implementations.Library
{
if (user != null)
{
if (!user.Policy.EnableMediaPlaybackTranscoding)
if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase))
{
source.SupportsTranscoding = false;
if (!user.Policy.EnableAudioPlaybackTranscoding)
{
source.SupportsTranscoding = false;
}
}
else if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
{
if (!user.Policy.EnableVideoPlaybackTranscoding)
{
source.SupportsTranscoding = false;
}
}
}
}
@ -238,9 +243,12 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
public MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution)
public async Task<MediaSourceInfo> GetMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution)
{
return GetStaticMediaSources(item, enablePathSubstitution).FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase));
var sources = await GetPlayackMediaSources(item.Id.ToString("N"), null, enablePathSubstitution, new[] { MediaType.Audio, MediaType.Video },
CancellationToken.None).ConfigureAwait(false);
return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase));
}
public IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user = null)

@ -122,7 +122,7 @@
"LabelFree": "Free",
"HeaderPlaybackError": "Playback Error",
"MessagePlaybackErrorNotAllowed": "You're currently not authorized to play this content. Please contact your system administrator for details.",
"MessagePlaybackErrorNoCompatibleStream": "No compatible streams are currently available. Please try again later.",
"MessagePlaybackErrorNoCompatibleStream": "No compatible streams are currently available. Please try again later or contact your system administrator for details.",
"MessagePlaybackErrorRateLimitExceeded": "Your playback rate limit has been exceeded. Please contact your system administrator for details.",
"MessagePlaybackErrorPlaceHolder": "The content chosen is not playable from this device.",
"HeaderSelectAudio": "Select Audio",

@ -1410,6 +1410,10 @@
"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."
"OptionAllowAudioPlaybackTranscoding": "Allow audio playback that requires transcoding",
"OptionAllowVideoPlaybackTranscoding": "Allow video playback that requires transcoding",
"OptionAllowMediaPlaybackTranscodingHelp": "Users will receive friendly messages when content is unplayable based on policy.",
"TabStreaming": "Streaming",
"LabelRemoteClientBitrateLimit": "Remote client bitrate limit (mbps):",
"LabelRemoteClientBitrateLimitHelp": "An optional streaming bitrate limit for all remote clients. This is useful to prevent clients from requesting a higher bitrate than your connection can handle."
}

@ -305,12 +305,9 @@ namespace MediaBrowser.Server.Implementations.Session
}
}
private async Task<MediaSourceInfo> GetMediaSource(IHasMediaSources item, string mediaSourceId)
private Task<MediaSourceInfo> GetMediaSource(IHasMediaSources item, string mediaSourceId)
{
var sources = await _mediaSourceManager.GetPlayackMediaSources(item.Id.ToString("N"), false, CancellationToken.None)
.ConfigureAwait(false);
return sources.FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase));
return _mediaSourceManager.GetMediaSource(item, mediaSourceId, false);
}
/// <summary>

@ -195,17 +195,39 @@ namespace MediaBrowser.Server.Implementations.Sync
}
};
var maxAudioChannels = supportsAc3 || supportsDca ? "5" : "2";
codecProfiles.Add(new CodecProfile
{
Type = CodecType.VideoAudio,
Codec = "ac3",
Conditions = new[]
{
new ProfileCondition
{
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.AudioChannels,
Value = maxAudioChannels,
Value = "5",
IsRequired = true
},
new ProfileCondition
{
Condition = ProfileConditionType.Equals,
Property = ProfileConditionValue.IsSecondaryAudio,
Value = "false",
IsRequired = false
}
}
});
codecProfiles.Add(new CodecProfile
{
Type = CodecType.VideoAudio,
Codec = "ac3",
Conditions = new[]
{
new ProfileCondition
{
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.AudioChannels,
Value = "2",
IsRequired = true
},
new ProfileCondition

@ -482,6 +482,7 @@ namespace MediaBrowser.WebDashboard.Api
"selectserver.js",
"serversecurity.js",
"songs.js",
"streamingsettings.js",
"supporterkeypage.js",
"supporterpage.js",
"syncactivity.js",

@ -150,6 +150,9 @@
<Content Include="dashboard-ui\scripts\selectserver.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\streamingsettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\syncjob.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -174,6 +177,9 @@
<Content Include="dashboard-ui\selectserver.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\streamingsettings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\syncjob.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

Loading…
Cancel
Save