mirror of https://github.com/jellyfin/jellyfin.git
update behavior with restricted transcoding access
This commit is contained in:
parent
b878dc1537
commit
8328f39834
|
@ -1770,6 +1770,19 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
state.OutputVideoCodec = "copy";
|
state.OutputVideoCodec = "copy";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the user doesn't have access to transcoding, then force stream copy, regardless of whether it will be compatible or not
|
||||||
|
var auth = AuthorizationContext.GetAuthorizationInfo(Request);
|
||||||
|
if (!string.IsNullOrWhiteSpace(auth.UserId))
|
||||||
|
{
|
||||||
|
var user = UserManager.GetUserById(auth.UserId);
|
||||||
|
if (!user.Policy.EnableVideoPlaybackTranscoding)
|
||||||
|
{
|
||||||
|
state.OutputVideoCodec = "copy";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (state.AudioStream != null && CanStreamCopyAudio(state, state.SupportedAudioCodecs))
|
if (state.AudioStream != null && CanStreamCopyAudio(state, state.SupportedAudioCodecs))
|
||||||
{
|
{
|
||||||
|
|
|
@ -942,17 +942,5 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||||
{
|
{
|
||||||
return isOutputVideo ? ".ts" : ".ts";
|
return isOutputVideo ? ".ts" : ".ts";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CanStreamCopyVideo(StreamState state)
|
|
||||||
{
|
|
||||||
var isLiveStream = IsLiveStream(state);
|
|
||||||
|
|
||||||
//if (!isLiveStream && Request.QueryString["AllowCustomSegmenting"] != "true")
|
|
||||||
//{
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
return base.CanStreamCopyVideo(state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.Playback
|
namespace MediaBrowser.Api.Playback
|
||||||
|
@ -68,8 +69,9 @@ namespace MediaBrowser.Api.Playback
|
||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly INetworkManager _networkManager;
|
private readonly INetworkManager _networkManager;
|
||||||
private readonly IMediaEncoder _mediaEncoder;
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager, IMediaEncoder mediaEncoder)
|
public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager, IMediaEncoder mediaEncoder, IUserManager userManager)
|
||||||
{
|
{
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
_deviceManager = deviceManager;
|
_deviceManager = deviceManager;
|
||||||
|
@ -77,6 +79,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
_config = config;
|
_config = config;
|
||||||
_networkManager = networkManager;
|
_networkManager = networkManager;
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Get(GetBitrateTestBytes request)
|
public object Get(GetBitrateTestBytes request)
|
||||||
|
@ -119,7 +122,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
|
|
||||||
SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate,
|
SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate,
|
||||||
request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex,
|
request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex,
|
||||||
request.SubtitleStreamIndex, request.PlaySessionId);
|
request.SubtitleStreamIndex, request.PlaySessionId, request.UserId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -159,7 +162,7 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
var mediaSourceId = request.MediaSourceId;
|
var mediaSourceId = request.MediaSourceId;
|
||||||
|
|
||||||
SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex);
|
SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.UserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ToOptimizedResult(info);
|
return ToOptimizedResult(info);
|
||||||
|
@ -221,13 +224,14 @@ namespace MediaBrowser.Api.Playback
|
||||||
long startTimeTicks,
|
long startTimeTicks,
|
||||||
string mediaSourceId,
|
string mediaSourceId,
|
||||||
int? audioStreamIndex,
|
int? audioStreamIndex,
|
||||||
int? subtitleStreamIndex)
|
int? subtitleStreamIndex,
|
||||||
|
string userId)
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(itemId);
|
var item = _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
foreach (var mediaSource in result.MediaSources)
|
foreach (var mediaSource in result.MediaSources)
|
||||||
{
|
{
|
||||||
SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId);
|
SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
SortMediaSources(result, maxBitrate);
|
SortMediaSources(result, maxBitrate);
|
||||||
|
@ -242,7 +246,8 @@ namespace MediaBrowser.Api.Playback
|
||||||
string mediaSourceId,
|
string mediaSourceId,
|
||||||
int? audioStreamIndex,
|
int? audioStreamIndex,
|
||||||
int? subtitleStreamIndex,
|
int? subtitleStreamIndex,
|
||||||
string playSessionId)
|
string playSessionId,
|
||||||
|
string userId)
|
||||||
{
|
{
|
||||||
var streamBuilder = new StreamBuilder(_mediaEncoder, Logger);
|
var streamBuilder = new StreamBuilder(_mediaEncoder, Logger);
|
||||||
|
|
||||||
|
@ -262,6 +267,8 @@ namespace MediaBrowser.Api.Playback
|
||||||
options.SubtitleStreamIndex = subtitleStreamIndex;
|
options.SubtitleStreamIndex = subtitleStreamIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var user = _userManager.GetUserById(userId);
|
||||||
|
|
||||||
if (mediaSource.SupportsDirectPlay)
|
if (mediaSource.SupportsDirectPlay)
|
||||||
{
|
{
|
||||||
var supportsDirectStream = mediaSource.SupportsDirectStream;
|
var supportsDirectStream = mediaSource.SupportsDirectStream;
|
||||||
|
@ -270,6 +277,14 @@ namespace MediaBrowser.Api.Playback
|
||||||
mediaSource.SupportsDirectStream = true;
|
mediaSource.SupportsDirectStream = true;
|
||||||
options.MaxBitrate = maxBitrate;
|
options.MaxBitrate = maxBitrate;
|
||||||
|
|
||||||
|
if (item is Audio)
|
||||||
|
{
|
||||||
|
if (!user.Policy.EnableAudioPlaybackTranscoding)
|
||||||
|
{
|
||||||
|
options.ForceDirectPlay = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The MediaSource supports direct stream, now test to see if the client supports it
|
// The MediaSource supports direct stream, now test to see if the client supports it
|
||||||
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
|
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
|
||||||
streamBuilder.BuildAudioItem(options) :
|
streamBuilder.BuildAudioItem(options) :
|
||||||
|
@ -293,6 +308,14 @@ namespace MediaBrowser.Api.Playback
|
||||||
{
|
{
|
||||||
options.MaxBitrate = GetMaxBitrate(maxBitrate);
|
options.MaxBitrate = GetMaxBitrate(maxBitrate);
|
||||||
|
|
||||||
|
if (item is Audio)
|
||||||
|
{
|
||||||
|
if (!user.Policy.EnableAudioPlaybackTranscoding)
|
||||||
|
{
|
||||||
|
options.ForceDirectStream = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The MediaSource supports direct stream, now test to see if the client supports it
|
// The MediaSource supports direct stream, now test to see if the client supports it
|
||||||
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
|
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
|
||||||
streamBuilder.BuildAudioItem(options) :
|
streamBuilder.BuildAudioItem(options) :
|
||||||
|
|
|
@ -346,8 +346,8 @@
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\HttpHeaderInfo.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\HttpHeaderInfo.cs">
|
||||||
<Link>Dlna\HttpHeaderInfo.cs</Link>
|
<Link>Dlna\HttpHeaderInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\ILocalPlayer.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\ITranscoderSupport.cs">
|
||||||
<Link>Dlna\ILocalPlayer.cs</Link>
|
<Link>Dlna\ITranscoderSupport.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfile.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfile.cs">
|
||||||
<Link>Dlna\MediaFormatProfile.cs</Link>
|
<Link>Dlna\MediaFormatProfile.cs</Link>
|
||||||
|
@ -355,9 +355,6 @@
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfileResolver.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfileResolver.cs">
|
||||||
<Link>Dlna\MediaFormatProfileResolver.cs</Link>
|
<Link>Dlna\MediaFormatProfileResolver.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\NullLocalPlayer.cs">
|
|
||||||
<Link>Dlna\NullLocalPlayer.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\PlaybackErrorCode.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\PlaybackErrorCode.cs">
|
||||||
<Link>Dlna\PlaybackErrorCode.cs</Link>
|
<Link>Dlna\PlaybackErrorCode.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
|
@ -318,8 +318,8 @@
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\HttpHeaderInfo.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\HttpHeaderInfo.cs">
|
||||||
<Link>Dlna\HttpHeaderInfo.cs</Link>
|
<Link>Dlna\HttpHeaderInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\ILocalPlayer.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\ITranscoderSupport.cs">
|
||||||
<Link>Dlna\ILocalPlayer.cs</Link>
|
<Link>Dlna\ITranscoderSupport.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfile.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfile.cs">
|
||||||
<Link>Dlna\MediaFormatProfile.cs</Link>
|
<Link>Dlna\MediaFormatProfile.cs</Link>
|
||||||
|
@ -327,9 +327,6 @@
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfileResolver.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfileResolver.cs">
|
||||||
<Link>Dlna\MediaFormatProfileResolver.cs</Link>
|
<Link>Dlna\MediaFormatProfileResolver.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\NullLocalPlayer.cs">
|
|
||||||
<Link>Dlna\NullLocalPlayer.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\MediaBrowser.Model\Dlna\PlaybackErrorCode.cs">
|
<Compile Include="..\MediaBrowser.Model\Dlna\PlaybackErrorCode.cs">
|
||||||
<Link>Dlna\PlaybackErrorCode.cs</Link>
|
<Link>Dlna\PlaybackErrorCode.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
|
@ -18,6 +18,8 @@ namespace MediaBrowser.Model.Dlna
|
||||||
|
|
||||||
public bool EnableDirectPlay { get; set; }
|
public bool EnableDirectPlay { get; set; }
|
||||||
public bool EnableDirectStream { get; set; }
|
public bool EnableDirectStream { get; set; }
|
||||||
|
public bool ForceDirectPlay { get; set; }
|
||||||
|
public bool ForceDirectStream { get; set; }
|
||||||
|
|
||||||
public string ItemId { get; set; }
|
public string ItemId { get; set; }
|
||||||
public List<MediaSourceInfo> MediaSources { get; set; }
|
public List<MediaSourceInfo> MediaSources { get; set; }
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Dlna
|
|
||||||
{
|
|
||||||
public interface ILocalPlayer
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether this instance [can access file] the specified path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The path.</param>
|
|
||||||
/// <returns><c>true</c> if this instance [can access file] the specified path; otherwise, <c>false</c>.</returns>
|
|
||||||
bool CanAccessFile(string path);
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether this instance [can access directory] the specified path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The path.</param>
|
|
||||||
/// <returns><c>true</c> if this instance [can access directory] the specified path; otherwise, <c>false</c>.</returns>
|
|
||||||
bool CanAccessDirectory(string path);
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether this instance [can access URL] the specified URL.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="url">The URL.</param>
|
|
||||||
/// <param name="requiresCustomRequestHeaders">if set to <c>true</c> [requires custom request headers].</param>
|
|
||||||
/// <returns><c>true</c> if this instance [can access URL] the specified URL; otherwise, <c>false</c>.</returns>
|
|
||||||
bool CanAccessUrl(string url, bool requiresCustomRequestHeaders);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ITranscoderSupport
|
|
||||||
{
|
|
||||||
bool CanEncodeToAudioCodec(string codec);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FullTranscoderSupport : ITranscoderSupport
|
|
||||||
{
|
|
||||||
public bool CanEncodeToAudioCodec(string codec)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
namespace MediaBrowser.Model.Dlna
|
||||||
|
{
|
||||||
|
public interface ITranscoderSupport
|
||||||
|
{
|
||||||
|
bool CanEncodeToAudioCodec(string codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FullTranscoderSupport : ITranscoderSupport
|
||||||
|
{
|
||||||
|
public bool CanEncodeToAudioCodec(string codec)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Dlna
|
|
||||||
{
|
|
||||||
public class NullLocalPlayer : ILocalPlayer
|
|
||||||
{
|
|
||||||
public bool CanAccessFile(string path)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanAccessDirectory(string path)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanAccessUrl(string url, bool requiresCustomRequestHeaders)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,29 +11,17 @@ namespace MediaBrowser.Model.Dlna
|
||||||
{
|
{
|
||||||
public class StreamBuilder
|
public class StreamBuilder
|
||||||
{
|
{
|
||||||
private readonly ILocalPlayer _localPlayer;
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly ITranscoderSupport _transcoderSupport;
|
private readonly ITranscoderSupport _transcoderSupport;
|
||||||
|
|
||||||
public StreamBuilder(ILocalPlayer localPlayer, ITranscoderSupport transcoderSupport, ILogger logger)
|
public StreamBuilder(ITranscoderSupport transcoderSupport, ILogger logger)
|
||||||
{
|
{
|
||||||
_transcoderSupport = transcoderSupport;
|
_transcoderSupport = transcoderSupport;
|
||||||
_localPlayer = localPlayer;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamBuilder(ITranscoderSupport transcoderSupport, ILogger logger)
|
|
||||||
: this(new NullLocalPlayer(), transcoderSupport, logger)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public StreamBuilder(ILocalPlayer localPlayer, ILogger logger)
|
|
||||||
: this(localPlayer, new FullTranscoderSupport(), logger)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public StreamBuilder(ILogger logger)
|
public StreamBuilder(ILogger logger)
|
||||||
: this(new NullLocalPlayer(), new FullTranscoderSupport(), logger)
|
: this(new FullTranscoderSupport(), logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +115,20 @@ namespace MediaBrowser.Model.Dlna
|
||||||
DeviceProfile = options.Profile
|
DeviceProfile = options.Profile
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (options.ForceDirectPlay)
|
||||||
|
{
|
||||||
|
playlistItem.PlayMethod = PlayMethod.DirectPlay;
|
||||||
|
playlistItem.Container = item.Container;
|
||||||
|
return playlistItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.ForceDirectStream)
|
||||||
|
{
|
||||||
|
playlistItem.PlayMethod = PlayMethod.DirectStream;
|
||||||
|
playlistItem.Container = item.Container;
|
||||||
|
return playlistItem;
|
||||||
|
}
|
||||||
|
|
||||||
MediaStream audioStream = item.GetDefaultAudioStream(null);
|
MediaStream audioStream = item.GetDefaultAudioStream(null);
|
||||||
|
|
||||||
List<PlayMethod> directPlayMethods = GetAudioDirectPlayMethods(item, audioStream, options);
|
List<PlayMethod> directPlayMethods = GetAudioDirectPlayMethods(item, audioStream, options);
|
||||||
|
@ -182,19 +184,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
|
|
||||||
if (all)
|
if (all)
|
||||||
{
|
{
|
||||||
if (item.Protocol == MediaProtocol.File &&
|
if (directPlayMethods.Contains(PlayMethod.DirectStream))
|
||||||
directPlayMethods.Contains(PlayMethod.DirectPlay) &&
|
|
||||||
_localPlayer.CanAccessFile(item.Path))
|
|
||||||
{
|
|
||||||
playlistItem.PlayMethod = PlayMethod.DirectPlay;
|
|
||||||
}
|
|
||||||
else if (item.Protocol == MediaProtocol.Http &&
|
|
||||||
directPlayMethods.Contains(PlayMethod.DirectPlay) &&
|
|
||||||
_localPlayer.CanAccessUrl(item.Path, item.RequiredHttpHeaders.Count > 0))
|
|
||||||
{
|
|
||||||
playlistItem.PlayMethod = PlayMethod.DirectPlay;
|
|
||||||
}
|
|
||||||
else if (directPlayMethods.Contains(PlayMethod.DirectStream))
|
|
||||||
{
|
{
|
||||||
playlistItem.PlayMethod = PlayMethod.DirectStream;
|
playlistItem.PlayMethod = PlayMethod.DirectStream;
|
||||||
}
|
}
|
||||||
|
@ -413,8 +403,8 @@ namespace MediaBrowser.Model.Dlna
|
||||||
MediaStream videoStream = item.VideoStream;
|
MediaStream videoStream = item.VideoStream;
|
||||||
|
|
||||||
// TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough
|
// TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough
|
||||||
bool isEligibleForDirectPlay = options.EnableDirectPlay && IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay);
|
bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay));
|
||||||
bool isEligibleForDirectStream = options.EnableDirectStream && IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream);
|
bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream));
|
||||||
|
|
||||||
_logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
|
_logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
|
||||||
options.Profile.Name ?? "Unknown Profile",
|
options.Profile.Name ?? "Unknown Profile",
|
||||||
|
@ -425,7 +415,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
||||||
{
|
{
|
||||||
// See if it can be direct played
|
// See if it can be direct played
|
||||||
PlayMethod? directPlay = GetVideoDirectPlayProfile(options.Profile, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
|
PlayMethod? directPlay = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
|
||||||
|
|
||||||
if (directPlay != null)
|
if (directPlay != null)
|
||||||
{
|
{
|
||||||
|
@ -645,13 +635,24 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
|
return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlayMethod? GetVideoDirectPlayProfile(DeviceProfile profile,
|
private PlayMethod? GetVideoDirectPlayProfile(VideoOptions options,
|
||||||
MediaSourceInfo mediaSource,
|
MediaSourceInfo mediaSource,
|
||||||
MediaStream videoStream,
|
MediaStream videoStream,
|
||||||
MediaStream audioStream,
|
MediaStream audioStream,
|
||||||
bool isEligibleForDirectPlay,
|
bool isEligibleForDirectPlay,
|
||||||
bool isEligibleForDirectStream)
|
bool isEligibleForDirectStream)
|
||||||
{
|
{
|
||||||
|
DeviceProfile profile = options.Profile;
|
||||||
|
|
||||||
|
if (options.ForceDirectPlay)
|
||||||
|
{
|
||||||
|
return PlayMethod.DirectPlay;
|
||||||
|
}
|
||||||
|
if (options.ForceDirectStream)
|
||||||
|
{
|
||||||
|
return PlayMethod.DirectStream;
|
||||||
|
}
|
||||||
|
|
||||||
if (videoStream == null)
|
if (videoStream == null)
|
||||||
{
|
{
|
||||||
_logger.Info("Profile: {0}, Cannot direct stream with no known video stream. Path: {1}",
|
_logger.Info("Profile: {0}, Cannot direct stream with no known video stream. Path: {1}",
|
||||||
|
@ -829,25 +830,6 @@ namespace MediaBrowser.Model.Dlna
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEligibleForDirectPlay && mediaSource.SupportsDirectPlay)
|
|
||||||
{
|
|
||||||
if (mediaSource.Protocol == MediaProtocol.Http)
|
|
||||||
{
|
|
||||||
if (_localPlayer.CanAccessUrl(mediaSource.Path, mediaSource.RequiredHttpHeaders.Count > 0))
|
|
||||||
{
|
|
||||||
return PlayMethod.DirectPlay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (mediaSource.Protocol == MediaProtocol.File)
|
|
||||||
{
|
|
||||||
if (_localPlayer.CanAccessFile(mediaSource.Path))
|
|
||||||
{
|
|
||||||
return PlayMethod.DirectPlay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEligibleForDirectStream && mediaSource.SupportsDirectStream)
|
if (isEligibleForDirectStream && mediaSource.SupportsDirectStream)
|
||||||
{
|
{
|
||||||
return PlayMethod.DirectStream;
|
return PlayMethod.DirectStream;
|
||||||
|
|
|
@ -118,9 +118,8 @@
|
||||||
<Compile Include="Devices\DeviceInfo.cs" />
|
<Compile Include="Devices\DeviceInfo.cs" />
|
||||||
<Compile Include="Devices\DevicesOptions.cs" />
|
<Compile Include="Devices\DevicesOptions.cs" />
|
||||||
<Compile Include="Dlna\EncodingContext.cs" />
|
<Compile Include="Dlna\EncodingContext.cs" />
|
||||||
<Compile Include="Dlna\ILocalPlayer.cs" />
|
<Compile Include="Dlna\ITranscoderSupport.cs" />
|
||||||
<Compile Include="Dlna\StreamInfoSorter.cs" />
|
<Compile Include="Dlna\StreamInfoSorter.cs" />
|
||||||
<Compile Include="Dlna\NullLocalPlayer.cs" />
|
|
||||||
<Compile Include="Dlna\PlaybackErrorCode.cs" />
|
<Compile Include="Dlna\PlaybackErrorCode.cs" />
|
||||||
<Compile Include="Dlna\PlaybackException.cs" />
|
<Compile Include="Dlna\PlaybackException.cs" />
|
||||||
<Compile Include="Dlna\ResolutionConfiguration.cs" />
|
<Compile Include="Dlna\ResolutionConfiguration.cs" />
|
||||||
|
|
|
@ -440,15 +440,7 @@ namespace MediaBrowser.WebDashboard.Api
|
||||||
files.Insert(0, "cordova.js");
|
files.Insert(0, "cordova.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
var tags = files.Select(s =>
|
var tags = files.Select(s => string.Format("<script src=\"{0}\" defer></script>", s)).ToArray();
|
||||||
{
|
|
||||||
if (s.IndexOf("require", StringComparison.OrdinalIgnoreCase) == -1 && s.IndexOf("alameda", StringComparison.OrdinalIgnoreCase) == -1)
|
|
||||||
{
|
|
||||||
return string.Format("<script src=\"{0}\" async></script>", s);
|
|
||||||
}
|
|
||||||
return string.Format("<script src=\"{0}\"></script>", s);
|
|
||||||
|
|
||||||
}).ToArray();
|
|
||||||
|
|
||||||
builder.Append(string.Join(string.Empty, tags));
|
builder.Append(string.Join(string.Empty, tags));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue