added music and game genre image downloading

pull/702/head
Luke Pulverenti 11 years ago
parent b50fc351a1
commit a5be2523c5

@ -194,20 +194,6 @@ namespace MediaBrowser.Api.LiveTv
{
}
[Route("/LiveTv/Recordings/{Id}/Stream", "GET")]
public class GetInternalRecordingStream
{
[ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
[Route("/LiveTv/Channels/{Id}/Stream", "GET")]
public class GetInternalChannelStream
{
[ApiMember(Name = "Id", Description = "Channel Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
[Route("/LiveTv/Recordings/Groups/{Id}", "GET")]
[Api(Description = "Gets a recording group")]
public class GetRecordingGroup : IReturn<RecordingGroupDto>
@ -411,20 +397,6 @@ namespace MediaBrowser.Api.LiveTv
Task.WaitAll(task);
}
public object Get(GetInternalRecordingStream request)
{
var stream = _liveTvManager.GetRecordingStream(request.Id, CancellationToken.None).Result;
return ToStreamResult(stream.Stream, stream.MimeType);
}
public object Get(GetInternalChannelStream request)
{
var stream = _liveTvManager.GetChannelStream(request.Id, CancellationToken.None).Result;
return ToStreamResult(stream.Stream, stream.MimeType);
}
public object Get(GetRecordingGroups request)
{
var result = _liveTvManager.GetRecordingGroups(new RecordingGroupQuery

@ -888,11 +888,18 @@ namespace MediaBrowser.Api.Playback
}
else
{
state.MediaPath = string.Format("http://localhost:{0}/mediabrowser/LiveTv/Recordings/{1}/Stream",
ServerConfigurationManager.Configuration.HttpServerPortNumber,
request.Id);
var streamInfo = await LiveTvManager.GetRecordingStream(request.Id, cancellationToken).ConfigureAwait(false);
state.IsRemote = true;
if (!string.IsNullOrEmpty(streamInfo.Path) && File.Exists(streamInfo.Path))
{
state.MediaPath = streamInfo.Path;
state.IsRemote = false;
}
else if (!string.IsNullOrEmpty(streamInfo.Url))
{
state.MediaPath = streamInfo.Url;
state.IsRemote = true;
}
}
itemId = recording.Id;
@ -905,11 +912,18 @@ namespace MediaBrowser.Api.Playback
state.IsInputVideo = string.Equals(channel.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
state.PlayableStreamFileNames = new List<string>();
state.MediaPath = string.Format("http://localhost:{0}/mediabrowser/LiveTv/Channels/{1}/Stream",
ServerConfigurationManager.Configuration.HttpServerPortNumber,
request.Id);
var streamInfo = await LiveTvManager.GetChannelStream(request.Id, cancellationToken).ConfigureAwait(false);
state.IsRemote = true;
if (!string.IsNullOrEmpty(streamInfo.Path) && File.Exists(streamInfo.Path))
{
state.MediaPath = streamInfo.Path;
state.IsRemote = false;
}
else if (!string.IsNullOrEmpty(streamInfo.Url))
{
state.MediaPath = streamInfo.Url;
state.IsRemote = true;
}
itemId = channel.Id;
}

@ -161,7 +161,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="id">The identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
Task<StreamResponseInfo> GetRecordingStream(string id, CancellationToken cancellationToken);
Task<LiveStreamInfo> GetRecordingStream(string id, CancellationToken cancellationToken);
/// <summary>
/// Gets the channel stream.
@ -169,7 +169,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="id">The identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{StreamResponseInfo}.</returns>
Task<StreamResponseInfo> GetChannelStream(string id, CancellationToken cancellationToken);
Task<LiveStreamInfo> GetChannelStream(string id, CancellationToken cancellationToken);
/// <summary>
/// Gets the program.

@ -145,7 +145,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="recordingId">The recording identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
Task<StreamResponseInfo> GetRecordingStream(string recordingId, CancellationToken cancellationToken);
Task<LiveStreamInfo> GetRecordingStream(string recordingId, CancellationToken cancellationToken);
/// <summary>
/// Gets the channel stream.
@ -153,6 +153,6 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="channelId">The channel identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
Task<StreamResponseInfo> GetChannelStream(string channelId, CancellationToken cancellationToken);
Task<LiveStreamInfo> GetChannelStream(string channelId, CancellationToken cancellationToken);
}
}

@ -0,0 +1,18 @@

namespace MediaBrowser.Controller.LiveTv
{
public class LiveStreamInfo
{
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
/// <summary>
/// Gets or sets the URL.
/// </summary>
/// <value>The URL.</value>
public string Url { get; set; }
}
}

@ -109,6 +109,7 @@
<Compile Include="Library\IUserDataManager.cs" />
<Compile Include="Library\UserDataSaveEventArgs.cs" />
<Compile Include="LiveTv\ILiveTvRecording.cs" />
<Compile Include="LiveTv\LiveStreamInfo.cs" />
<Compile Include="LiveTv\LiveTvAudioRecording.cs" />
<Compile Include="LiveTv\LiveTvChannel.cs" />
<Compile Include="LiveTv\ChannelInfo.cs" />

@ -3,7 +3,7 @@
<MonoDevelop.Ide.Workbench ActiveDocument="MediaBrowser.Server.Mono\Networking\NetworkManager.cs">
<Files>
<File FileName="MediaBrowser.Server.Mono\app.config" Line="1" Column="1" />
<File FileName="MediaBrowser.Server.Mono\Networking\NetworkManager.cs" Line="6" Column="34" />
<File FileName="MediaBrowser.Server.Mono\Networking\NetworkManager.cs" Line="7" Column="26" />
</Files>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>

@ -0,0 +1,160 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.ImagesByName
{
public class GameGenreImageProvider : BaseMetadataProvider
{
private readonly IProviderManager _providerManager;
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(5, 5);
public GameGenreImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
: base(logManager, configurationManager)
{
_providerManager = providerManager;
}
public override bool Supports(BaseItem item)
{
return item is GameGenre;
}
public override bool RequiresInternet
{
get
{
return true;
}
}
public override ItemUpdateType ItemUpdateType
{
get
{
return ItemUpdateType.ImageUpdate;
}
}
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Thumb))
{
return false;
}
// Try again periodically in case new images were added
if ((DateTime.UtcNow - providerInfo.LastRefreshed).TotalDays > 7)
{
return true;
}
return base.NeedsRefreshInternal(item, providerInfo);
}
protected override bool RefreshOnVersionChange
{
get
{
return true;
}
}
protected override string ProviderVersion
{
get
{
return "8";
}
}
public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
{
if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Thumb))
{
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
return true;
}
var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, GameGenresManualImageProvider.ProviderName).ConfigureAwait(false);
await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false);
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
return true;
}
private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, CancellationToken cancellationToken)
{
if (!item.LockedFields.Contains(MetadataFields.Images))
{
cancellationToken.ThrowIfCancellationRequested();
if (!item.HasImage(ImageType.Primary))
{
await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (!item.HasImage(ImageType.Thumb))
{
await SaveImage(item, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false);
}
}
if (!item.LockedFields.Contains(MetadataFields.Backdrops))
{
cancellationToken.ThrowIfCancellationRequested();
if (item.BackdropImagePaths.Count == 0)
{
foreach (var image in images.Where(i => i.Type == ImageType.Backdrop))
{
await _providerManager.SaveImage(item, image.Url, _resourcePool, ImageType.Backdrop, null, cancellationToken)
.ConfigureAwait(false);
break;
}
}
}
}
private async Task SaveImage(BaseItem item, IEnumerable<RemoteImageInfo> images, ImageType type, CancellationToken cancellationToken)
{
foreach (var image in images.Where(i => i.Type == type))
{
try
{
await _providerManager.SaveImage(item, image.Url, _resourcePool, type, null, cancellationToken).ConfigureAwait(false);
break;
}
catch (HttpException ex)
{
// Sometimes fanart has bad url's in their xml
if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
{
continue;
}
break;
}
}
}
public override MetadataProviderPriority Priority
{
get { return MetadataProviderPriority.Third; }
}
}
}

@ -0,0 +1,128 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.ImagesByName
{
public class GameGenresManualImageProvider : IImageProvider
{
private readonly IServerConfigurationManager _config;
private readonly IHttpClient _httpClient;
private readonly IFileSystem _fileSystem;
private readonly SemaphoreSlim _listResourcePool = new SemaphoreSlim(1, 1);
public GameGenresManualImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
}
public string Name
{
get { return ProviderName; }
}
public static string ProviderName
{
get { return "Media Browser"; }
}
public bool Supports(IHasImages item)
{
return item is GameGenre;
}
public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
return GetImages(item, imageType == ImageType.Primary, imageType == ImageType.Thumb, cancellationToken);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
return GetImages(item, true, true, cancellationToken);
}
private async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, bool posters, bool thumbs, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
if (posters)
{
var posterPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotegamegenreposters.txt");
await EnsurePosterList(posterPath, cancellationToken).ConfigureAwait(false);
list.Add(GetImage(item, posterPath, ImageType.Primary, "folder"));
}
cancellationToken.ThrowIfCancellationRequested();
if (thumbs)
{
var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotegamegenrethumbs.txt");
await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false);
list.Add(GetImage(item, thumbsPath, ImageType.Thumb, "thumb"));
}
return list.Where(i => i != null);
}
private RemoteImageInfo GetImage(IHasImages item, string filename, ImageType type, string remoteFilename)
{
var list = ImageUtils.GetAvailableImages(filename);
var match = ImageUtils.FindMatch(item, list);
if (!string.IsNullOrEmpty(match))
{
var url = GetUrl(match, remoteFilename);
return new RemoteImageInfo
{
ProviderName = Name,
Type = type,
Url = url
};
}
return null;
}
private string GetUrl(string image, string filename)
{
return string.Format("https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/gamegenres/{0}/{1}.jpg", image, filename);
}
private Task EnsureThumbsList(string file, CancellationToken cancellationToken)
{
const string url = "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/gamegenrethumbs.txt";
return ImageUtils.EnsureList(url, file, _httpClient, _fileSystem, _listResourcePool, cancellationToken);
}
private Task EnsurePosterList(string file, CancellationToken cancellationToken)
{
const string url = "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/gamegenreposters.txt";
return ImageUtils.EnsureList(url, file, _httpClient, _fileSystem, _listResourcePool, cancellationToken);
}
public int Priority
{
get { return 0; }
}
}
}

@ -0,0 +1,161 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.ImagesByName
{
public class MusicGenreImageProvider : BaseMetadataProvider
{
private readonly IProviderManager _providerManager;
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(5, 5);
public MusicGenreImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager)
: base(logManager, configurationManager)
{
_providerManager = providerManager;
}
public override bool Supports(BaseItem item)
{
return item is MusicGenre;
}
public override bool RequiresInternet
{
get
{
return true;
}
}
public override ItemUpdateType ItemUpdateType
{
get
{
return ItemUpdateType.ImageUpdate;
}
}
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Thumb))
{
return false;
}
// Try again periodically in case new images were added
if ((DateTime.UtcNow - providerInfo.LastRefreshed).TotalDays > 7)
{
return true;
}
return base.NeedsRefreshInternal(item, providerInfo);
}
protected override bool RefreshOnVersionChange
{
get
{
return true;
}
}
protected override string ProviderVersion
{
get
{
return "8";
}
}
public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
{
if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Thumb))
{
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
return true;
}
var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, MusicGenresManualImageProvider.ProviderName).ConfigureAwait(false);
await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false);
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
return true;
}
private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, CancellationToken cancellationToken)
{
if (!item.LockedFields.Contains(MetadataFields.Images))
{
cancellationToken.ThrowIfCancellationRequested();
if (!item.HasImage(ImageType.Primary))
{
await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (!item.HasImage(ImageType.Thumb))
{
await SaveImage(item, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false);
}
}
if (!item.LockedFields.Contains(MetadataFields.Backdrops))
{
cancellationToken.ThrowIfCancellationRequested();
if (item.BackdropImagePaths.Count == 0)
{
foreach (var image in images.Where(i => i.Type == ImageType.Backdrop))
{
await _providerManager.SaveImage(item, image.Url, _resourcePool, ImageType.Backdrop, null, cancellationToken)
.ConfigureAwait(false);
break;
}
}
}
}
private async Task SaveImage(BaseItem item, IEnumerable<RemoteImageInfo> images, ImageType type, CancellationToken cancellationToken)
{
foreach (var image in images.Where(i => i.Type == type))
{
try
{
await _providerManager.SaveImage(item, image.Url, _resourcePool, type, null, cancellationToken).ConfigureAwait(false);
break;
}
catch (HttpException ex)
{
// Sometimes fanart has bad url's in their xml
if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
{
continue;
}
break;
}
}
}
public override MetadataProviderPriority Priority
{
get { return MetadataProviderPriority.Third; }
}
}
}

@ -0,0 +1,129 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.ImagesByName
{
public class MusicGenresManualImageProvider : IImageProvider
{
private readonly IServerConfigurationManager _config;
private readonly IHttpClient _httpClient;
private readonly IFileSystem _fileSystem;
private readonly SemaphoreSlim _listResourcePool = new SemaphoreSlim(1, 1);
public MusicGenresManualImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
}
public string Name
{
get { return ProviderName; }
}
public static string ProviderName
{
get { return "Media Browser"; }
}
public bool Supports(IHasImages item)
{
return item is MusicGenre;
}
public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
return GetImages(item, imageType == ImageType.Primary, imageType == ImageType.Thumb, cancellationToken);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
return GetImages(item, true, true, cancellationToken);
}
private async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, bool posters, bool thumbs, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
if (posters)
{
var posterPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotemusicgenreposters.txt");
await EnsurePosterList(posterPath, cancellationToken).ConfigureAwait(false);
list.Add(GetImage(item, posterPath, ImageType.Primary, "folder"));
}
cancellationToken.ThrowIfCancellationRequested();
if (thumbs)
{
var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotemusicgenrethumbs.txt");
await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false);
list.Add(GetImage(item, thumbsPath, ImageType.Thumb, "thumb"));
}
return list.Where(i => i != null);
}
private RemoteImageInfo GetImage(IHasImages item, string filename, ImageType type, string remoteFilename)
{
var list = ImageUtils.GetAvailableImages(filename);
var match = ImageUtils.FindMatch(item, list);
if (!string.IsNullOrEmpty(match))
{
var url = GetUrl(match, remoteFilename);
return new RemoteImageInfo
{
ProviderName = Name,
Type = type,
Url = url
};
}
return null;
}
private string GetUrl(string image, string filename)
{
return string.Format("https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/musicgenres/{0}/{1}.jpg", image, filename);
}
private Task EnsureThumbsList(string file, CancellationToken cancellationToken)
{
const string url = "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/musicgenrethumbs.txt";
return ImageUtils.EnsureList(url, file, _httpClient, _fileSystem, _listResourcePool, cancellationToken);
}
private Task EnsurePosterList(string file, CancellationToken cancellationToken)
{
const string url = "https://raw.github.com/MediaBrowser/MediaBrowser.Resources/master/images/imagesbyname/musicgenreposters.txt";
return ImageUtils.EnsureList(url, file, _httpClient, _fileSystem, _listResourcePool, cancellationToken);
}
public int Priority
{
get { return 0; }
}
}
}

@ -66,6 +66,10 @@
<Compile Include="Games\GameSystemProviderFromXml.cs" />
<Compile Include="ImageFromMediaLocationProvider.cs" />
<Compile Include="ImagesByNameProvider.cs" />
<Compile Include="ImagesByName\MusicGenreImageProvider.cs" />
<Compile Include="ImagesByName\MusicGenresManualImageProvider.cs" />
<Compile Include="ImagesByName\GameGenreImageProvider.cs" />
<Compile Include="ImagesByName\GameGenresManualImageProvider.cs" />
<Compile Include="ImagesByName\GenreImageProvider.cs" />
<Compile Include="ImagesByName\GenresManualImageProvider.cs" />
<Compile Include="ImagesByName\ImageUtils.cs" />

@ -40,9 +40,6 @@ namespace MediaBrowser.Server.Implementations.Library
public void Dispose()
{
//BaseItem.LibraryManager.LibraryChanged -= LibraryChanged;
//LuceneSearch.CloseAll();
}
/// <summary>

@ -153,18 +153,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return await GetRecording(recording, service.Name, cancellationToken).ConfigureAwait(false);
}
public async Task<StreamResponseInfo> GetRecordingStream(string id, CancellationToken cancellationToken)
public async Task<LiveStreamInfo> GetRecordingStream(string id, CancellationToken cancellationToken)
{
var service = ActiveService;
var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
var recording = recordings.FirstOrDefault(i => _tvDtoService.GetInternalRecordingId(service.Name, i.Id) == new Guid(id));
var recording = recordings.First(i => _tvDtoService.GetInternalRecordingId(service.Name, i.Id) == new Guid(id));
return await service.GetRecordingStream(recording.Id, cancellationToken).ConfigureAwait(false);
}
public async Task<StreamResponseInfo> GetChannelStream(string id, CancellationToken cancellationToken)
public async Task<LiveStreamInfo> GetChannelStream(string id, CancellationToken cancellationToken)
{
var service = ActiveService;

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
<version>3.0.294</version>
<version>3.0.295</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<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>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.294" />
<dependency id="MediaBrowser.Common" version="3.0.295" />
<dependency id="NLog" version="2.1.0" />
<dependency id="SimpleInjector" version="2.4.0" />
<dependency id="sharpcompress" version="0.10.2" />

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

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

Loading…
Cancel
Save