live tv updates

This commit is contained in:
Luke Pulverenti 2013-12-16 13:44:03 -05:00
parent 7e8d11cb2a
commit cb9b570a2a
18 changed files with 179 additions and 168 deletions

View File

@ -260,20 +260,10 @@ namespace MediaBrowser.Api.Playback
{ {
var quality = ServerConfigurationManager.Configuration.EncodingQuality; var quality = ServerConfigurationManager.Configuration.EncodingQuality;
if (quality == EncodingQuality.Auto)
{
var cpuCount = Environment.ProcessorCount;
if (cpuCount >= 4)
{
return 0;
}
return cpuCount;
}
switch (quality) switch (quality)
{ {
case EncodingQuality.Auto:
return 0;
case EncodingQuality.HighSpeed: case EncodingQuality.HighSpeed:
return 2; return 2;
case EncodingQuality.HighQuality: case EncodingQuality.HighQuality:

View File

@ -172,9 +172,64 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
/// <returns>Task{HttpResponseInfo}.</returns> /// <returns>Task{HttpResponseInfo}.</returns>
/// <exception cref="HttpException"> /// <exception cref="HttpException">
/// </exception> /// </exception>
public async Task<HttpResponseInfo> GetResponse(HttpRequestOptions options) public Task<HttpResponseInfo> GetResponse(HttpRequestOptions options)
{ {
ValidateParams(options.Url, options.CancellationToken); return SendAsync(options, "GET");
}
/// <summary>
/// Performs a GET request and returns the resulting stream
/// </summary>
/// <param name="options">The options.</param>
/// <returns>Task{Stream}.</returns>
/// <exception cref="HttpException"></exception>
/// <exception cref="MediaBrowser.Model.Net.HttpException"></exception>
public async Task<Stream> Get(HttpRequestOptions options)
{
var response = await GetResponse(options).ConfigureAwait(false);
return response.Content;
}
/// <summary>
/// Performs a GET request and returns the resulting stream
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="resourcePool">The resource pool.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
public Task<Stream> Get(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
{
return Get(new HttpRequestOptions
{
Url = url,
ResourcePool = resourcePool,
CancellationToken = cancellationToken,
});
}
/// <summary>
/// Gets the specified URL.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
public Task<Stream> Get(string url, CancellationToken cancellationToken)
{
return Get(url, null, cancellationToken);
}
/// <summary>
/// send as an asynchronous operation.
/// </summary>
/// <param name="options">The options.</param>
/// <param name="httpMethod">The HTTP method.</param>
/// <returns>Task{HttpResponseInfo}.</returns>
/// <exception cref="HttpException">
/// </exception>
private async Task<HttpResponseInfo> SendAsync(HttpRequestOptions options, string httpMethod)
{
ValidateParams(options);
options.CancellationToken.ThrowIfCancellationRequested(); options.CancellationToken.ThrowIfCancellationRequested();
@ -185,7 +240,17 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url)) { IsTimedOut = true }; throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url)) { IsTimedOut = true };
} }
var httpWebRequest = GetRequest(options, "GET", options.EnableHttpCompression); var httpWebRequest = GetRequest(options, httpMethod, options.EnableHttpCompression);
if (!string.IsNullOrEmpty(options.RequestContent) || string.Equals(httpMethod, "post", StringComparison.OrdinalIgnoreCase))
{
var content = options.RequestContent ?? string.Empty;
var bytes = Encoding.UTF8.GetBytes(content);
httpWebRequest.ContentType = options.RequestContentType ?? "application/x-www-form-urlencoded";
httpWebRequest.ContentLength = bytes.Length;
httpWebRequest.GetRequestStream().Write(bytes, 0, bytes.Length);
}
if (options.ResourcePool != null) if (options.ResourcePool != null)
{ {
@ -202,7 +267,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true }; throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
} }
_logger.Info("HttpClientManager.GET url: {0}", options.Url); _logger.Info("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
try try
{ {
@ -275,46 +340,9 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
} }
} }
/// <summary> public Task<HttpResponseInfo> Post(HttpRequestOptions options)
/// Performs a GET request and returns the resulting stream
/// </summary>
/// <param name="options">The options.</param>
/// <returns>Task{Stream}.</returns>
/// <exception cref="HttpException"></exception>
/// <exception cref="MediaBrowser.Model.Net.HttpException"></exception>
public async Task<Stream> Get(HttpRequestOptions options)
{ {
var response = await GetResponse(options).ConfigureAwait(false); return SendAsync(options, "POST");
return response.Content;
}
/// <summary>
/// Performs a GET request and returns the resulting stream
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="resourcePool">The resource pool.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
public Task<Stream> Get(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
{
return Get(new HttpRequestOptions
{
Url = url,
ResourcePool = resourcePool,
CancellationToken = cancellationToken,
});
}
/// <summary>
/// Gets the specified URL.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
public Task<Stream> Get(string url, CancellationToken cancellationToken)
{
return Get(url, null, cancellationToken);
} }
/// <summary> /// <summary>
@ -329,82 +357,15 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
/// <exception cref="MediaBrowser.Model.Net.HttpException"></exception> /// <exception cref="MediaBrowser.Model.Net.HttpException"></exception>
public async Task<Stream> Post(HttpRequestOptions options, Dictionary<string, string> postData) public async Task<Stream> Post(HttpRequestOptions options, Dictionary<string, string> postData)
{ {
ValidateParams(options.Url, options.CancellationToken);
options.CancellationToken.ThrowIfCancellationRequested();
var httpWebRequest = GetRequest(options, "POST", options.EnableHttpCompression);
var strings = postData.Keys.Select(key => string.Format("{0}={1}", key, postData[key])); var strings = postData.Keys.Select(key => string.Format("{0}={1}", key, postData[key]));
var postContent = string.Join("&", strings.ToArray()); var postContent = string.Join("&", strings.ToArray());
var bytes = Encoding.UTF8.GetBytes(postContent);
httpWebRequest.ContentType = "application/x-www-form-urlencoded"; options.RequestContent = postContent;
httpWebRequest.ContentLength = bytes.Length; options.RequestContentType = "application/x-www-form-urlencoded";
httpWebRequest.GetRequestStream().Write(bytes, 0, bytes.Length);
if (options.ResourcePool != null) var response = await Post(options).ConfigureAwait(false);
{
await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
}
_logger.Info("HttpClientManager.POST url: {0}", options.Url); return response.Content;
try
{
options.CancellationToken.ThrowIfCancellationRequested();
using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false))
{
var httpResponse = (HttpWebResponse)response;
EnsureSuccessStatusCode(httpResponse);
options.CancellationToken.ThrowIfCancellationRequested();
using (var stream = httpResponse.GetResponseStream())
{
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
memoryStream.Position = 0;
return memoryStream;
}
}
}
catch (OperationCanceledException ex)
{
var exception = GetCancellationException(options.Url, options.CancellationToken, ex);
throw exception;
}
catch (HttpRequestException ex)
{
_logger.ErrorException("Error getting response from " + options.Url, ex);
throw new HttpException(ex.Message, ex);
}
catch (WebException ex)
{
_logger.ErrorException("Error getting response from " + options.Url, ex);
throw new HttpException(ex.Message, ex);
}
catch (Exception ex)
{
_logger.ErrorException("Error getting response from " + options.Url, ex);
throw;
}
finally
{
if (options.ResourcePool != null)
{
options.ResourcePool.Release();
}
}
} }
/// <summary> /// <summary>
@ -443,7 +404,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
public async Task<HttpResponseInfo> GetTempFileResponse(HttpRequestOptions options) public async Task<HttpResponseInfo> GetTempFileResponse(HttpRequestOptions options)
{ {
ValidateParams(options.Url, options.CancellationToken); ValidateParams(options);
Directory.CreateDirectory(_appPaths.TempDirectory); Directory.CreateDirectory(_appPaths.TempDirectory);
@ -608,17 +569,11 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
} }
} }
/// <summary> private void ValidateParams(HttpRequestOptions options)
/// Validates the params.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <exception cref="System.ArgumentNullException">url</exception>
private void ValidateParams(string url, CancellationToken cancellationToken)
{ {
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(options.Url))
{ {
throw new ArgumentNullException("url"); throw new ArgumentNullException("options");
} }
} }

View File

@ -66,6 +66,10 @@ namespace MediaBrowser.Common.Net
public Dictionary<string, string> RequestHeaders { get; private set; } public Dictionary<string, string> RequestHeaders { get; private set; }
public string RequestContentType { get; set; }
public string RequestContent { get; set; }
private string GetHeaderValue(string name) private string GetHeaderValue(string name)
{ {
string value; string value;

View File

@ -64,6 +64,13 @@ namespace MediaBrowser.Common.Net
/// <returns>Task{Stream}.</returns> /// <returns>Task{Stream}.</returns>
Task<Stream> Post(string url, Dictionary<string, string> postData, CancellationToken cancellationToken); Task<Stream> Post(string url, Dictionary<string, string> postData, CancellationToken cancellationToken);
/// <summary>
/// Posts the specified options.
/// </summary>
/// <param name="options">The options.</param>
/// <returns>Task{HttpResponseInfo}.</returns>
Task<HttpResponseInfo> Post(HttpRequestOptions options);
/// <summary> /// <summary>
/// Downloads the contents of a given url into a temporary location /// Downloads the contents of a given url into a temporary location
/// </summary> /// </summary>

View File

@ -17,6 +17,12 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The channel identifier.</value> /// <value>The channel identifier.</value>
public string ChannelId { get; set; } public string ChannelId { get; set; }
/// <summary>
/// Gets or sets the name of the channel.
/// </summary>
/// <value>The name of the channel.</value>
public string ChannelName { get; set; }
/// <summary> /// <summary>
/// Name of the program /// Name of the program
/// </summary> /// </summary>

View File

@ -38,6 +38,12 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The path.</value> /// <value>The path.</value>
public string Path { get; set; } public string Path { get; set; }
/// <summary>
/// Gets or sets the URL.
/// </summary>
/// <value>The URL.</value>
public string Url { get; set; }
/// <summary> /// <summary>
/// Gets or sets the overview. /// Gets or sets the overview.
/// </summary> /// </summary>

View File

@ -48,10 +48,22 @@ namespace MediaBrowser.Controller.LiveTv
public DateTime EndDate { get; set; } public DateTime EndDate { get; set; }
/// <summary> /// <summary>
/// Gets or sets the type of the recurrence. /// Gets or sets a value indicating whether [record any time].
/// </summary> /// </summary>
/// <value>The type of the recurrence.</value> /// <value><c>true</c> if [record any time]; otherwise, <c>false</c>.</value>
public RecurrenceType RecurrenceType { get; set; } public bool RecordAnyTime { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [record any channel].
/// </summary>
/// <value><c>true</c> if [record any channel]; otherwise, <c>false</c>.</value>
public bool RecordAnyChannel { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [record new only].
/// </summary>
/// <value><c>true</c> if [record new only]; otherwise, <c>false</c>.</value>
public bool RecordNewOnly { get; set; }
/// <summary> /// <summary>
/// Gets or sets the days. /// Gets or sets the days.

View File

@ -23,6 +23,12 @@ namespace MediaBrowser.Model.LiveTv
/// <value>The channel identifier.</value> /// <value>The channel identifier.</value>
public string ChannelId { get; set; } public string ChannelId { get; set; }
/// <summary>
/// Gets or sets the name of the channel.
/// </summary>
/// <value>The name of the channel.</value>
public string ChannelName { get; set; }
/// <summary> /// <summary>
/// Gets or sets the community rating. /// Gets or sets the community rating.
/// </summary> /// </summary>

View File

@ -50,6 +50,12 @@ namespace MediaBrowser.Model.LiveTv
/// <value>The path.</value> /// <value>The path.</value>
public string Path { get; set; } public string Path { get; set; }
/// <summary>
/// Gets or sets the URL.
/// </summary>
/// <value>The URL.</value>
public string Url { get; set; }
/// <summary> /// <summary>
/// Overview of the recording. /// Overview of the recording.
/// </summary> /// </summary>

View File

@ -14,15 +14,6 @@ namespace MediaBrowser.Model.LiveTv
Error Error
} }
public enum RecurrenceType
{
Manual,
NewProgramEventsOneChannel,
AllProgramEventsOneChannel,
NewProgramEventsAllChannels,
AllProgramEventsAllChannels
}
public enum DayPattern public enum DayPattern
{ {
Daily, Daily,

View File

@ -71,10 +71,22 @@ namespace MediaBrowser.Model.LiveTv
public DateTime EndDate { get; set; } public DateTime EndDate { get; set; }
/// <summary> /// <summary>
/// Gets or sets the type of the recurrence. /// Gets or sets a value indicating whether [record any time].
/// </summary> /// </summary>
/// <value>The type of the recurrence.</value> /// <value><c>true</c> if [record any time]; otherwise, <c>false</c>.</value>
public RecurrenceType RecurrenceType { get; set; } public bool RecordAnyTime { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [record any channel].
/// </summary>
/// <value><c>true</c> if [record any channel]; otherwise, <c>false</c>.</value>
public bool RecordAnyChannel { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [record new only].
/// </summary>
/// <value><c>true</c> if [record new only]; otherwise, <c>false</c>.</value>
public bool RecordNewOnly { get; set; }
/// <summary> /// <summary>
/// Gets or sets the days. /// Gets or sets the days.

View File

@ -43,6 +43,12 @@ namespace MediaBrowser.Model.LiveTv
/// <value>The program identifier.</value> /// <value>The program identifier.</value>
public string ProgramId { get; set; } public string ProgramId { get; set; }
/// <summary>
/// Gets or sets the external program identifier.
/// </summary>
/// <value>The external program identifier.</value>
public string ExternalProgramId { get; set; }
/// <summary> /// <summary>
/// Name of the recording. /// Name of the recording.
/// </summary> /// </summary>

View File

@ -47,7 +47,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds, RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds,
ExternalChannelId = info.ChannelId, ExternalChannelId = info.ChannelId,
ExternalSeriesTimerId = info.SeriesTimerId, ExternalSeriesTimerId = info.SeriesTimerId,
ServiceName = service.Name ServiceName = service.Name,
ExternalProgramId = info.ProgramId
}; };
var duration = info.EndDate - info.StartDate; var duration = info.EndDate - info.StartDate;
@ -78,7 +79,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds, RequiredPrePaddingSeconds = info.RequiredPrePaddingSeconds,
Days = info.Days, Days = info.Days,
Priority = info.Priority, Priority = info.Priority,
RecurrenceType = info.RecurrenceType, RecordAnyChannel = info.RecordAnyChannel,
RecordAnyTime = info.RecordAnyTime,
RecordNewOnly = info.RecordNewOnly,
ExternalChannelId = info.ChannelId, ExternalChannelId = info.ChannelId,
ExternalProgramId = info.ProgramId, ExternalProgramId = info.ProgramId,
ServiceName = service.Name ServiceName = service.Name
@ -146,7 +149,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
OfficialRating = info.OfficialRating, OfficialRating = info.OfficialRating,
Audio = info.Audio, Audio = info.Audio,
IsHD = info.IsHD, IsHD = info.IsHD,
ServiceName = service.Name ServiceName = service.Name,
Url = info.Url
}; };
if (user != null) if (user != null)
@ -219,7 +223,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
CommunityRating = program.CommunityRating, CommunityRating = program.CommunityRating,
AspectRatio = program.AspectRatio, AspectRatio = program.AspectRatio,
IsRepeat = program.IsRepeat, IsRepeat = program.IsRepeat,
EpisodeTitle = program.EpisodeTitle EpisodeTitle = program.EpisodeTitle,
ChannelName = program.ChannelName
}; };
if (user != null) if (user != null)
@ -302,7 +307,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
RequestedPostPaddingSeconds = dto.RequestedPostPaddingSeconds, RequestedPostPaddingSeconds = dto.RequestedPostPaddingSeconds,
RequestedPrePaddingSeconds = dto.RequestedPrePaddingSeconds, RequestedPrePaddingSeconds = dto.RequestedPrePaddingSeconds,
RequiredPostPaddingSeconds = dto.RequiredPostPaddingSeconds, RequiredPostPaddingSeconds = dto.RequiredPostPaddingSeconds,
RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds,
ProgramId = dto.ExternalProgramId
}; };
} }
@ -323,8 +329,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds, RequiredPrePaddingSeconds = dto.RequiredPrePaddingSeconds,
Days = dto.Days, Days = dto.Days,
Priority = dto.Priority, Priority = dto.Priority,
RecurrenceType = dto.RecurrenceType, ProgramId = dto.ExternalProgramId,
ProgramId = dto.ExternalProgramId RecordAnyChannel = dto.RecordAnyChannel,
RecordAnyTime = dto.RecordAnyTime,
RecordNewOnly = dto.RecordNewOnly
}; };
} }
} }

View File

@ -336,7 +336,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
.ToList(); .ToList();
} }
var returnArray = list.OrderByDescending(i => i.StartDate) var returnArray = list.OrderBy(i => i.StartDate)
.ToArray(); .ToArray();
return new QueryResult<TimerInfoDto> return new QueryResult<TimerInfoDto>

View File

@ -275,7 +275,9 @@ namespace MediaBrowser.WebDashboard.Api
// Don't cache if not configured to do so // Don't cache if not configured to do so
// But always cache images to simulate production // But always cache images to simulate production
if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching && !contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching &&
!contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) &&
!contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase))
{ {
return ResultFactory.GetResult(GetResourceStream(path).Result, contentType); return ResultFactory.GetResult(GetResourceStream(path).Result, contentType);
} }
@ -284,7 +286,7 @@ namespace MediaBrowser.WebDashboard.Api
// Cache images unconditionally - updates to image files will require new filename // Cache images unconditionally - updates to image files will require new filename
// If there's a version number in the query string we can cache this unconditionally // If there's a version number in the query string we can cache this unconditionally
if (contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) || !string.IsNullOrEmpty(request.V)) if (contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase) || !string.IsNullOrEmpty(request.V))
{ {
cacheDuration = TimeSpan.FromDays(365); cacheDuration = TimeSpan.FromDays(365);
} }

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.273</version> <version>3.0.275</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 Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description> <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright> <copyright>Copyright © Media Browser 2013</copyright>
<dependencies> <dependencies>
<dependency id="MediaBrowser.Common" version="3.0.273" /> <dependency id="MediaBrowser.Common" version="3.0.275" />
<dependency id="NLog" version="2.1.0" /> <dependency id="NLog" version="2.1.0" />
<dependency id="SimpleInjector" version="2.4.0" /> <dependency id="SimpleInjector" version="2.4.0" />
<dependency id="sharpcompress" version="0.10.2" /> <dependency id="sharpcompress" version="0.10.2" />

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.273</version> <version>3.0.275</version>
<title>MediaBrowser.Common</title> <title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors> <authors>Media Browser 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.273</version> <version>3.0.275</version>
<title>Media Browser.Server.Core</title> <title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors> <authors>Media Browser 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 Media Browser Server.</description> <description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright> <copyright>Copyright © Media Browser 2013</copyright>
<dependencies> <dependencies>
<dependency id="MediaBrowser.Common" version="3.0.273" /> <dependency id="MediaBrowser.Common" version="3.0.275" />
</dependencies> </dependencies>
</metadata> </metadata>
<files> <files>