Merge pull request #1983 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-07-25 12:57:32 -04:00 committed by GitHub
commit 2b2bae2966
17 changed files with 106 additions and 175 deletions

View File

@ -1669,7 +1669,7 @@ namespace MediaBrowser.Api.Playback
RequestedUrl = url,
UserAgent = Request.UserAgent
};
//if ((Request.UserAgent ?? string.Empty).IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 ||
// (Request.UserAgent ?? string.Empty).IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 ||
// (Request.UserAgent ?? string.Empty).IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1)
@ -1770,6 +1770,19 @@ namespace MediaBrowser.Api.Playback
{
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))
{

View File

@ -942,17 +942,5 @@ namespace MediaBrowser.Api.Playback.Hls
{
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);
}
}
}

View File

@ -15,6 +15,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.MediaEncoding;
namespace MediaBrowser.Api.Playback
@ -68,8 +69,9 @@ namespace MediaBrowser.Api.Playback
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
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;
_deviceManager = deviceManager;
@ -77,6 +79,7 @@ namespace MediaBrowser.Api.Playback
_config = config;
_networkManager = networkManager;
_mediaEncoder = mediaEncoder;
_userManager = userManager;
}
public object Get(GetBitrateTestBytes request)
@ -119,7 +122,7 @@ namespace MediaBrowser.Api.Playback
SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate,
request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex,
request.SubtitleStreamIndex, request.PlaySessionId);
request.SubtitleStreamIndex, request.PlaySessionId, request.UserId);
}
else
{
@ -159,7 +162,7 @@ namespace MediaBrowser.Api.Playback
{
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);
@ -221,13 +224,14 @@ namespace MediaBrowser.Api.Playback
long startTimeTicks,
string mediaSourceId,
int? audioStreamIndex,
int? subtitleStreamIndex)
int? subtitleStreamIndex,
string userId)
{
var item = _libraryManager.GetItemById(itemId);
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);
@ -242,7 +246,8 @@ namespace MediaBrowser.Api.Playback
string mediaSourceId,
int? audioStreamIndex,
int? subtitleStreamIndex,
string playSessionId)
string playSessionId,
string userId)
{
var streamBuilder = new StreamBuilder(_mediaEncoder, Logger);
@ -262,6 +267,8 @@ namespace MediaBrowser.Api.Playback
options.SubtitleStreamIndex = subtitleStreamIndex;
}
var user = _userManager.GetUserById(userId);
if (mediaSource.SupportsDirectPlay)
{
var supportsDirectStream = mediaSource.SupportsDirectStream;
@ -270,6 +277,14 @@ namespace MediaBrowser.Api.Playback
mediaSource.SupportsDirectStream = true;
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
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
streamBuilder.BuildAudioItem(options) :
@ -293,6 +308,14 @@ namespace MediaBrowser.Api.Playback
{
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
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
streamBuilder.BuildAudioItem(options) :

View File

@ -346,8 +346,8 @@
<Compile Include="..\MediaBrowser.Model\Dlna\HttpHeaderInfo.cs">
<Link>Dlna\HttpHeaderInfo.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\ILocalPlayer.cs">
<Link>Dlna\ILocalPlayer.cs</Link>
<Compile Include="..\MediaBrowser.Model\Dlna\ITranscoderSupport.cs">
<Link>Dlna\ITranscoderSupport.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfile.cs">
<Link>Dlna\MediaFormatProfile.cs</Link>
@ -355,9 +355,6 @@
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfileResolver.cs">
<Link>Dlna\MediaFormatProfileResolver.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\NullLocalPlayer.cs">
<Link>Dlna\NullLocalPlayer.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\PlaybackErrorCode.cs">
<Link>Dlna\PlaybackErrorCode.cs</Link>
</Compile>

View File

@ -318,8 +318,8 @@
<Compile Include="..\MediaBrowser.Model\Dlna\HttpHeaderInfo.cs">
<Link>Dlna\HttpHeaderInfo.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\ILocalPlayer.cs">
<Link>Dlna\ILocalPlayer.cs</Link>
<Compile Include="..\MediaBrowser.Model\Dlna\ITranscoderSupport.cs">
<Link>Dlna\ITranscoderSupport.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfile.cs">
<Link>Dlna\MediaFormatProfile.cs</Link>
@ -327,9 +327,6 @@
<Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfileResolver.cs">
<Link>Dlna\MediaFormatProfileResolver.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\NullLocalPlayer.cs">
<Link>Dlna\NullLocalPlayer.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\PlaybackErrorCode.cs">
<Link>Dlna\PlaybackErrorCode.cs</Link>
</Compile>

View File

@ -18,6 +18,8 @@ namespace MediaBrowser.Model.Dlna
public bool EnableDirectPlay { get; set; }
public bool EnableDirectStream { get; set; }
public bool ForceDirectPlay { get; set; }
public bool ForceDirectStream { get; set; }
public string ItemId { get; set; }
public List<MediaSourceInfo> MediaSources { get; set; }

View File

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

View File

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

View File

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

View File

@ -11,29 +11,17 @@ namespace MediaBrowser.Model.Dlna
{
public class StreamBuilder
{
private readonly ILocalPlayer _localPlayer;
private readonly ILogger _logger;
private readonly ITranscoderSupport _transcoderSupport;
public StreamBuilder(ILocalPlayer localPlayer, ITranscoderSupport transcoderSupport, ILogger logger)
public StreamBuilder(ITranscoderSupport transcoderSupport, ILogger logger)
{
_transcoderSupport = transcoderSupport;
_localPlayer = localPlayer;
_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)
: this(new NullLocalPlayer(), new FullTranscoderSupport(), logger)
: this(new FullTranscoderSupport(), logger)
{
}
@ -127,6 +115,20 @@ namespace MediaBrowser.Model.Dlna
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);
List<PlayMethod> directPlayMethods = GetAudioDirectPlayMethods(item, audioStream, options);
@ -182,19 +184,7 @@ namespace MediaBrowser.Model.Dlna
if (all)
{
if (item.Protocol == MediaProtocol.File &&
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))
if (directPlayMethods.Contains(PlayMethod.DirectStream))
{
playlistItem.PlayMethod = PlayMethod.DirectStream;
}
@ -413,8 +403,8 @@ namespace MediaBrowser.Model.Dlna
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
bool isEligibleForDirectPlay = options.EnableDirectPlay && IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay);
bool isEligibleForDirectStream = options.EnableDirectStream && IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream);
bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay));
bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream));
_logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
options.Profile.Name ?? "Unknown Profile",
@ -425,7 +415,7 @@ namespace MediaBrowser.Model.Dlna
if (isEligibleForDirectPlay || isEligibleForDirectStream)
{
// 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)
{
@ -645,13 +635,24 @@ namespace MediaBrowser.Model.Dlna
return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
}
private PlayMethod? GetVideoDirectPlayProfile(DeviceProfile profile,
private PlayMethod? GetVideoDirectPlayProfile(VideoOptions options,
MediaSourceInfo mediaSource,
MediaStream videoStream,
MediaStream audioStream,
bool isEligibleForDirectPlay,
bool isEligibleForDirectStream)
{
DeviceProfile profile = options.Profile;
if (options.ForceDirectPlay)
{
return PlayMethod.DirectPlay;
}
if (options.ForceDirectStream)
{
return PlayMethod.DirectStream;
}
if (videoStream == null)
{
_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)
{
return PlayMethod.DirectStream;

View File

@ -118,9 +118,8 @@
<Compile Include="Devices\DeviceInfo.cs" />
<Compile Include="Devices\DevicesOptions.cs" />
<Compile Include="Dlna\EncodingContext.cs" />
<Compile Include="Dlna\ILocalPlayer.cs" />
<Compile Include="Dlna\ITranscoderSupport.cs" />
<Compile Include="Dlna\StreamInfoSorter.cs" />
<Compile Include="Dlna\NullLocalPlayer.cs" />
<Compile Include="Dlna\PlaybackErrorCode.cs" />
<Compile Include="Dlna\PlaybackException.cs" />
<Compile Include="Dlna\ResolutionConfiguration.cs" />

View File

@ -199,7 +199,6 @@ namespace MediaBrowser.Providers.Movies
var ourRelease = releases.FirstOrDefault(c => c.iso_3166_1.Equals(preferredCountryCode, StringComparison.OrdinalIgnoreCase));
var usRelease = releases.FirstOrDefault(c => c.iso_3166_1.Equals("US", StringComparison.OrdinalIgnoreCase));
var minimunRelease = releases.OrderBy(c => c.release_date).FirstOrDefault();
if (ourRelease != null)
{
@ -210,10 +209,6 @@ namespace MediaBrowser.Providers.Movies
{
movie.OfficialRating = usRelease.certification;
}
else if (minimunRelease != null)
{
movie.OfficialRating = minimunRelease.iso_3166_1 + "-" + minimunRelease.certification;
}
}
if (!string.IsNullOrWhiteSpace(movieData.release_date))

View File

@ -440,15 +440,7 @@ namespace MediaBrowser.WebDashboard.Api
files.Insert(0, "cordova.js");
}
var tags = files.Select(s =>
{
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();
var tags = files.Select(s => string.Format("<script src=\"{0}\" defer></script>", s)).ToArray();
builder.Append(string.Join(string.Empty, tags));

View File

@ -113,6 +113,9 @@
<Content Include="dashboard-ui\components\chromecasthelpers.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\directorybrowser\directorybrowser.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\favoriteitems.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -140,12 +143,6 @@
<Content Include="dashboard-ui\components\guestinviter\guestinviter.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\metadataeditor\metadataeditor.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\metadataeditor\personeditor.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\navdrawer\navdrawer.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -230,12 +227,6 @@
<Content Include="dashboard-ui\components\medialibraryeditor\medialibraryeditor.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\metadataeditor\personeditor.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\components\metadataeditor\metadataeditor.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\ani_equalizer_black.gif">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -1512,9 +1503,6 @@
</Content>
</ItemGroup>
<ItemGroup>
<None Include="dashboard-ui\css\fonts\Montserrat.woff">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<Content Include="dashboard-ui\strings\ar.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View File

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

View File

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

View File

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