diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index f60a106dac..ce3691095c 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -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))
{
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index f4ecf36934..e029d4e99a 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -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);
- }
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index 2d9cc40c0a..0b989784c0 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/MediaBrowser.Api/Playback/MediaInfoService.cs
@@ -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) :
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index 862d95f7ee..7a9589c982 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -346,8 +346,8 @@
Dlna\HttpHeaderInfo.cs
-
- Dlna\ILocalPlayer.cs
+
+ Dlna\ITranscoderSupport.cs
Dlna\MediaFormatProfile.cs
@@ -355,9 +355,6 @@
Dlna\MediaFormatProfileResolver.cs
-
- Dlna\NullLocalPlayer.cs
-
Dlna\PlaybackErrorCode.cs
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index 953e5b7bef..420b536ae4 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -318,8 +318,8 @@
Dlna\HttpHeaderInfo.cs
-
- Dlna\ILocalPlayer.cs
+
+ Dlna\ITranscoderSupport.cs
Dlna\MediaFormatProfile.cs
@@ -327,9 +327,6 @@
Dlna\MediaFormatProfileResolver.cs
-
- Dlna\NullLocalPlayer.cs
-
Dlna\PlaybackErrorCode.cs
diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs
index 162b88c981..c208e8ab0b 100644
--- a/MediaBrowser.Model/Dlna/AudioOptions.cs
+++ b/MediaBrowser.Model/Dlna/AudioOptions.cs
@@ -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 MediaSources { get; set; }
diff --git a/MediaBrowser.Model/Dlna/ILocalPlayer.cs b/MediaBrowser.Model/Dlna/ILocalPlayer.cs
deleted file mode 100644
index 9de360023e..0000000000
--- a/MediaBrowser.Model/Dlna/ILocalPlayer.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-
-namespace MediaBrowser.Model.Dlna
-{
- public interface ILocalPlayer
- {
- ///
- /// Determines whether this instance [can access file] the specified path.
- ///
- /// The path.
- /// true if this instance [can access file] the specified path; otherwise, false.
- bool CanAccessFile(string path);
- ///
- /// Determines whether this instance [can access directory] the specified path.
- ///
- /// The path.
- /// true if this instance [can access directory] the specified path; otherwise, false.
- bool CanAccessDirectory(string path);
- ///
- /// Determines whether this instance [can access URL] the specified URL.
- ///
- /// The URL.
- /// if set to true [requires custom request headers].
- /// true if this instance [can access URL] the specified URL; otherwise, false.
- bool CanAccessUrl(string url, bool requiresCustomRequestHeaders);
- }
-
- public interface ITranscoderSupport
- {
- bool CanEncodeToAudioCodec(string codec);
- }
-
- public class FullTranscoderSupport : ITranscoderSupport
- {
- public bool CanEncodeToAudioCodec(string codec)
- {
- return true;
- }
- }
-}
diff --git a/MediaBrowser.Model/Dlna/ITranscoderSupport.cs b/MediaBrowser.Model/Dlna/ITranscoderSupport.cs
new file mode 100644
index 0000000000..0dac234032
--- /dev/null
+++ b/MediaBrowser.Model/Dlna/ITranscoderSupport.cs
@@ -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;
+ }
+ }
+}
diff --git a/MediaBrowser.Model/Dlna/NullLocalPlayer.cs b/MediaBrowser.Model/Dlna/NullLocalPlayer.cs
deleted file mode 100644
index c34b638871..0000000000
--- a/MediaBrowser.Model/Dlna/NullLocalPlayer.cs
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 2863eba2e0..c05ca41878 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -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 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;
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 931b2ebcb2..e3c1e52a53 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -118,9 +118,8 @@
-
+
-
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index a6b6de7e51..1bf4ed6c00 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -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))
diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
index 4c353c413e..b7b1f1dfd7 100644
--- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs
+++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
@@ -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("", s);
- }
- return string.Format("", s);
-
- }).ToArray();
+ var tags = files.Select(s => string.Format("", s)).ToArray();
builder.Append(string.Join(string.Empty, tags));
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 44be96aa8d..e4150d85cf 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -113,6 +113,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
@@ -140,12 +143,6 @@
PreserveNewest
-
- PreserveNewest
-
-
- PreserveNewest
-
PreserveNewest
@@ -230,12 +227,6 @@
PreserveNewest
-
- PreserveNewest
-
-
- PreserveNewest
-
PreserveNewest
@@ -1512,9 +1503,6 @@
-
- PreserveNewest
-
PreserveNewest
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index dc92b318e7..21173feaad 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common.Internal
- 3.0.652
+ 3.0.653
MediaBrowser.Common.Internal
Luke
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.
Copyright © Emby 2013
-
+
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index a8b78b4e3d..2946858472 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.652
+ 3.0.653
MediaBrowser.Common
Emby Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 105d2c4784..18e8a5c13b 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.652
+ 3.0.653
Media Browser.Server.Core
Emby Team
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains core components required to build plugins for Emby Server.
Copyright © Emby 2013
-
+