live tv updates

pull/702/head
Luke Pulverenti 11 years ago
parent cb6350728d
commit 4b2b36d1a3

@ -5,6 +5,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaInfo;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Configuration;
@ -62,6 +63,7 @@ namespace MediaBrowser.Api.Playback
protected IFileSystem FileSystem { get; private set; }
protected IItemRepository ItemRepository { get; private set; }
protected ILiveTvManager LiveTvManager { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
@ -74,8 +76,9 @@ namespace MediaBrowser.Api.Playback
/// <param name="dtoService">The dto service.</param>
/// <param name="fileSystem">The file system.</param>
/// <param name="itemRepository">The item repository.</param>
protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository)
protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager)
{
LiveTvManager = liveTvManager;
ItemRepository = itemRepository;
FileSystem = fileSystem;
DtoService = dtoService;
@ -194,6 +197,10 @@ namespace MediaBrowser.Api.Playback
{
args += string.Format("-map 0:{0}", state.VideoStream.Index);
}
else if (!state.HasMediaStreams)
{
args += string.Format("-map 0:{0}", 0);
}
else
{
args += "-map -0:v";
@ -203,6 +210,10 @@ namespace MediaBrowser.Api.Playback
{
args += string.Format(" -map 0:{0}", state.AudioStream.Index);
}
else if (!state.HasMediaStreams)
{
args += string.Format(" -map 0:{0}", 1);
}
else
{
@ -336,7 +347,10 @@ namespace MediaBrowser.Api.Playback
// If fixed dimensions were supplied
if (request.Width.HasValue && request.Height.HasValue)
{
return string.Format(" -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", request.Width.Value, request.Height.Value, assSubtitleParam);
var widthParam = request.Width.Value.ToString(UsCulture);
var heightParam = request.Height.Value.ToString(UsCulture);
return string.Format(" -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", widthParam, heightParam, assSubtitleParam);
}
var isH264Output = outputVideoCodec.Equals("libx264", StringComparison.OrdinalIgnoreCase);
@ -344,33 +358,41 @@ namespace MediaBrowser.Api.Playback
// If a fixed width was requested
if (request.Width.HasValue)
{
var widthParam = request.Width.Value.ToString(UsCulture);
return isH264Output ?
string.Format(" -vf \"scale={0}:trunc(ow/a/2)*2{1}\"", request.Width.Value, assSubtitleParam) :
string.Format(" -vf \"scale={0}:-1{1}\"", request.Width.Value, assSubtitleParam);
string.Format(" -vf \"scale={0}:trunc(ow/a/2)*2{1}\"", widthParam, assSubtitleParam) :
string.Format(" -vf \"scale={0}:-1{1}\"", widthParam, assSubtitleParam);
}
// If a fixed height was requested
if (request.Height.HasValue)
{
var heightParam = request.Height.Value.ToString(UsCulture);
return isH264Output ?
string.Format(" -vf \"scale=trunc(oh*a*2)/2:{0}{1}\"", request.Height.Value, assSubtitleParam) :
string.Format(" -vf \"scale=-1:{0}{1}\"", request.Height.Value, assSubtitleParam);
string.Format(" -vf \"scale=trunc(oh*a*2)/2:{0}{1}\"", heightParam, assSubtitleParam) :
string.Format(" -vf \"scale=-1:{0}{1}\"", heightParam, assSubtitleParam);
}
// If a max width was requested
if (request.MaxWidth.HasValue && (!request.MaxHeight.HasValue || state.VideoStream == null))
{
var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
return isH264Output ?
string.Format(" -vf \"scale=min(iw\\,{0}):trunc(ow/a/2)*2{1}\"", request.MaxWidth.Value, assSubtitleParam) :
string.Format(" -vf \"scale=min(iw\\,{0}):-1{1}\"", request.MaxWidth.Value, assSubtitleParam);
string.Format(" -vf \"scale=min(iw\\,{0}):trunc(ow/a/2)*2{1}\"", maxWidthParam, assSubtitleParam) :
string.Format(" -vf \"scale=min(iw\\,{0}):-1{1}\"", maxWidthParam, assSubtitleParam);
}
// If a max height was requested
if (request.MaxHeight.HasValue && (!request.MaxWidth.HasValue || state.VideoStream == null))
{
var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
return isH264Output ?
string.Format(" -vf \"scale=trunc(oh*a*2)/2:min(ih\\,{0}){1}\"", request.MaxHeight.Value, assSubtitleParam) :
string.Format(" -vf \"scale=-1:min(ih\\,{0}){1}\"", request.MaxHeight.Value, assSubtitleParam);
string.Format(" -vf \"scale=trunc(oh*a*2)/2:min(ih\\,{0}){1}\"", maxHeightParam, assSubtitleParam) :
string.Format(" -vf \"scale=-1:min(ih\\,{0}){1}\"", maxHeightParam, assSubtitleParam);
}
if (state.VideoStream == null)
@ -390,7 +412,10 @@ namespace MediaBrowser.Api.Playback
// If we're encoding with libx264, it can't handle odd numbered widths or heights, so we'll have to fix that
if (isH264Output)
{
return string.Format(" -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", outputSize.Width, outputSize.Height, assSubtitleParam);
var widthParam = outputSize.Width.ToString(UsCulture);
var heightParam = outputSize.Height.ToString(UsCulture);
return string.Format(" -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", widthParam, heightParam, assSubtitleParam);
}
// Otherwise use -vf scale since ffmpeg will ensure internally that the aspect ratio is preserved
@ -823,11 +848,10 @@ namespace MediaBrowser.Api.Playback
/// Gets the state.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>StreamState.</returns>
protected StreamState GetState(StreamRequest request)
protected async Task<StreamState> GetState(StreamRequest request, CancellationToken cancellationToken)
{
var item = DtoService.GetItemByDtoId(request.Id);
var url = Request.PathInfo;
if (!request.AudioCodec.HasValue)
@ -838,22 +862,48 @@ namespace MediaBrowser.Api.Playback
var state = new StreamState
{
Request = request,
RequestedUrl = url,
MediaPath = item.Path,
IsRemote = item.LocationType == LocationType.Remote
RequestedUrl = url
};
var video = item as Video;
BaseItem item;
if (string.Equals(request.Type, "Recording", StringComparison.OrdinalIgnoreCase))
{
var recording = await LiveTvManager.GetInternalRecording(request.Id, cancellationToken).ConfigureAwait(false);
state.VideoType = VideoType.VideoFile;
state.IsInputVideo = string.Equals(recording.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
state.PlayableStreamFileNames = new List<string>();
if (!string.IsNullOrEmpty(recording.RecordingInfo.Path) && File.Exists(recording.RecordingInfo.Path))
{
state.MediaPath = recording.RecordingInfo.Path;
state.IsRemote = false;
}
else if (!string.IsNullOrEmpty(recording.RecordingInfo.Url))
{
state.MediaPath = recording.RecordingInfo.Url;
state.IsRemote = true;
}
if (video != null)
item = recording;
}
else
{
state.IsInputVideo = true;
state.VideoType = video.VideoType;
state.IsoType = video.IsoType;
item = DtoService.GetItemByDtoId(request.Id);
state.PlayableStreamFileNames = video.PlayableStreamFileNames == null
? new List<string>()
: video.PlayableStreamFileNames.ToList();
var video = item as Video;
if (video != null)
{
state.IsInputVideo = true;
state.VideoType = video.VideoType;
state.IsoType = video.IsoType;
state.PlayableStreamFileNames = video.PlayableStreamFileNames == null
? new List<string>()
: video.PlayableStreamFileNames.ToList();
}
}
var videoRequest = request as VideoStreamRequest;
@ -880,6 +930,8 @@ namespace MediaBrowser.Api.Playback
state.AudioStream = GetMediaStream(mediaStreams, null, MediaStreamType.Audio, true);
}
state.HasMediaStreams = mediaStreams.Count > 0;
return state;
}

@ -3,6 +3,7 @@ using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
@ -26,8 +27,8 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public class AudioHlsService : BaseHlsService
{
public AudioHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository)
public AudioHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
{
}

@ -5,6 +5,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
@ -12,6 +13,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Api.Playback.Hls
@ -21,8 +23,8 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public abstract class BaseHlsService : BaseStreamingService
{
protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository)
protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
{
}
@ -72,7 +74,7 @@ namespace MediaBrowser.Api.Playback.Hls
/// <returns>System.Object.</returns>
protected object ProcessRequest(StreamRequest request)
{
var state = GetState(request);
var state = GetState(request, CancellationToken.None).Result;
return ProcessRequestAsync(state).Result;
}

@ -3,6 +3,7 @@ using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.IO;
using ServiceStack;
@ -32,8 +33,8 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public class VideoHlsService : BaseHlsService
{
public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository)
public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
{
}

@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.IO;
using ServiceStack;
@ -41,8 +42,8 @@ namespace MediaBrowser.Api.Playback.Progressive
/// </summary>
public class AudioService : BaseProgressiveStreamingService
{
public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, IImageProcessor imageProcessor)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, imageProcessor)
public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IImageProcessor imageProcessor)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, imageProcessor)
{
}

@ -5,12 +5,14 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.IO;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Api.Playback.Progressive
@ -22,8 +24,8 @@ namespace MediaBrowser.Api.Playback.Progressive
{
protected readonly IImageProcessor ImageProcessor;
protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, IImageProcessor imageProcessor)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository)
protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IImageProcessor imageProcessor)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager)
{
ImageProcessor = imageProcessor;
}
@ -178,7 +180,7 @@ namespace MediaBrowser.Api.Playback.Progressive
/// <returns>Task.</returns>
protected object ProcessRequest(StreamRequest request, bool isHeadRequest)
{
var state = GetState(request);
var state = GetState(request, CancellationToken.None).Result;
var responseHeaders = new Dictionary<string, string>();

@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.IO;
using ServiceStack;
@ -54,8 +55,8 @@ namespace MediaBrowser.Api.Playback.Progressive
/// </summary>
public class VideoService : BaseProgressiveStreamingService
{
public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, IImageProcessor imageProcessor)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, imageProcessor)
public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IImageProcessor imageProcessor)
: base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, imageProcessor)
{
}

@ -65,6 +65,12 @@ namespace MediaBrowser.Api.Playback
/// No need to put this in api docs since it's dlna only
/// </summary>
public bool AlbumArt { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
public string Type { get; set; }
}
public class VideoStreamRequest : StreamRequest

@ -45,5 +45,7 @@ namespace MediaBrowser.Api.Playback
public IsoType? IsoType { get; set; }
public List<string> PlayableStreamFileNames { get; set; }
public bool HasMediaStreams { get; set; }
}
}

@ -96,7 +96,7 @@ namespace MediaBrowser.Controller.Entities.Audio
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public static string GetUserDataKey(BaseItem item)
private static string GetUserDataKey(MusicArtist item)
{
var id = item.GetProviderId(MetadataProviders.Musicbrainz);

@ -63,6 +63,18 @@ namespace MediaBrowser.Controller.Entities
/// <param name="index2">The index2.</param>
/// <returns>Task.</returns>
Task SwapImages(ImageType type, int index1, int index2);
/// <summary>
/// Gets the display type of the media.
/// </summary>
/// <value>The display type of the media.</value>
string DisplayMediaType { get; set; }
/// <summary>
/// Gets or sets the primary image path.
/// </summary>
/// <value>The primary image path.</value>
string PrimaryImagePath { get; set; }
}
public static class HasImagesExtensions

@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.Providers
/// </summary>
/// <param name="item">The item.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
bool Supports(BaseItem item);
bool Supports(IHasImages item);
/// <summary>
/// Gets the images.
@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Providers
/// <param name="imageType">Type of the image.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{IEnumerable{RemoteImageInfo}}.</returns>
Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken);
Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken);
/// <summary>
/// Gets the images.
@ -40,7 +40,7 @@ namespace MediaBrowser.Controller.Providers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{IEnumerable{RemoteImageInfo}}.</returns>
Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken);
Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken);
/// <summary>
/// Gets the priority.

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
namespace MediaBrowser.Model.LiveTv
{
@ -12,6 +12,18 @@ namespace MediaBrowser.Model.LiveTv
/// </summary>
public string Id { get; set; }
/// <summary>
/// Gets or sets the timer identifier.
/// </summary>
/// <value>The timer identifier.</value>
public string TimerId { get; set; }
/// <summary>
/// Gets or sets the series timer identifier.
/// </summary>
/// <value>The series timer identifier.</value>
public string SeriesTimerId { get; set; }
/// <summary>
/// Gets or sets the external identifier.
/// </summary>

@ -146,6 +146,7 @@
<Compile Include="TV\TvdbPrescanTask.cs" />
<Compile Include="TV\TvdbSeriesImageProvider.cs" />
<Compile Include="UserRootFolderNameProvider.cs" />
<Compile Include="VirtualItemImageValidator.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">

@ -111,6 +111,11 @@ namespace MediaBrowser.Providers.Movies
/// <param name="item">The item.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
public override bool Supports(BaseItem item)
{
return SupportsItem(item);
}
internal static bool SupportsItem(IHasImages item)
{
var trailer = item as Trailer;

@ -36,23 +36,24 @@ namespace MediaBrowser.Providers.Movies
get { return "FanArt"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return FanArtMovieProvider.Current.Supports(item);
return FanArtMovieProvider.SupportsItem(item);
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var baseItem = (BaseItem)item;
var list = new List<RemoteImageInfo>();
var movieId = item.GetProviderId(MetadataProviders.Tmdb);
var movieId = baseItem.GetProviderId(MetadataProviders.Tmdb);
if (!string.IsNullOrEmpty(movieId))
{
@ -71,7 +72,7 @@ namespace MediaBrowser.Providers.Movies
var language = _config.Configuration.PreferredMetadataLanguage;
var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase);
// Sort first by width to prioritize HD versions
list = list.OrderByDescending(i => i.Width ?? 0)
.ThenByDescending(i =>

@ -35,19 +35,19 @@ namespace MediaBrowser.Providers.Movies
get { return "TheMovieDb"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return MovieDbImagesProvider.SupportsItem(item);
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public async Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
@ -114,14 +114,14 @@ namespace MediaBrowser.Providers.Movies
.ThenByDescending(i => i.VoteCount ?? 0)
.ToList();
}
/// <summary>
/// Gets the posters.
/// </summary>
/// <param name="images">The images.</param>
/// <param name="item">The item.</param>
/// <returns>IEnumerable{MovieDbProvider.Poster}.</returns>
private IEnumerable<MovieDbProvider.Poster> GetPosters(MovieDbProvider.Images images, BaseItem item)
private IEnumerable<MovieDbProvider.Poster> GetPosters(MovieDbProvider.Images images, IHasImages item)
{
var language = _config.Configuration.PreferredMetadataLanguage;
@ -134,7 +134,7 @@ namespace MediaBrowser.Providers.Movies
/// <param name="images">The images.</param>
/// <param name="item">The item.</param>
/// <returns>IEnumerable{MovieDbProvider.Backdrop}.</returns>
private IEnumerable<MovieDbProvider.Backdrop> GetBackdrops(MovieDbProvider.Images images, BaseItem item)
private IEnumerable<MovieDbProvider.Backdrop> GetBackdrops(MovieDbProvider.Images images, IHasImages item)
{
var eligibleBackdrops = images.backdrops == null ? new List<MovieDbProvider.Backdrop>() :
images.backdrops
@ -150,9 +150,9 @@ namespace MediaBrowser.Providers.Movies
/// <param name="item">The item.</param>
/// <param name="jsonSerializer">The json serializer.</param>
/// <returns>Task{MovieImages}.</returns>
private MovieDbProvider.Images FetchImages(BaseItem item, IJsonSerializer jsonSerializer)
private MovieDbProvider.Images FetchImages(IHasImages item, IJsonSerializer jsonSerializer)
{
var path = MovieDbProvider.Current.GetImagesDataFilePath(item);
var path = MovieDbProvider.Current.GetImagesDataFilePath((BaseItem)item);
if (!string.IsNullOrEmpty(path))
{

@ -34,26 +34,27 @@ namespace MediaBrowser.Providers.Movies
get { return "TheMovieDb"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is Person;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
return GetAllImagesInternal(item, true, cancellationToken);
}
public async Task<IEnumerable<RemoteImageInfo>> GetAllImagesInternal(BaseItem item, bool retryOnMissingData, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetAllImagesInternal(IHasImages item, bool retryOnMissingData, CancellationToken cancellationToken)
{
var id = item.GetProviderId(MetadataProviders.Tmdb);
var person = (Person)item;
var id = person.GetProviderId(MetadataProviders.Tmdb);
if (!string.IsNullOrEmpty(id))
{
@ -86,7 +87,7 @@ namespace MediaBrowser.Providers.Movies
return new List<RemoteImageInfo>();
}
private IEnumerable<RemoteImageInfo> GetImages(MovieDbPersonProvider.Images images, string baseImageUrl)
{
var list = new List<RemoteImageInfo>();

@ -61,7 +61,7 @@ namespace MediaBrowser.Providers.Movies
return SupportsItem(item);
}
public static bool SupportsItem(BaseItem item)
internal static bool SupportsItem(IHasImages item)
{
var trailer = item as Trailer;

@ -37,32 +37,34 @@ namespace MediaBrowser.Providers.Music
get { return "FanArt"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is MusicAlbum;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var album = (MusicAlbum)item;
var list = new List<RemoteImageInfo>();
var artistMusicBrainzId = item.Parent.GetProviderId(MetadataProviders.Musicbrainz);
var artistMusicBrainzId = album.Parent.GetProviderId(MetadataProviders.Musicbrainz);
if (!string.IsNullOrEmpty(artistMusicBrainzId))
{
var artistXmlPath = FanArtArtistProvider.GetArtistDataPath(_config.CommonApplicationPaths, artistMusicBrainzId);
artistXmlPath = Path.Combine(artistXmlPath, "fanart.xml");
var musicBrainzReleaseGroupId = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
var musicBrainzReleaseGroupId = album.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
var musicBrainzId = item.GetProviderId(MetadataProviders.Musicbrainz);
var musicBrainzId = album.GetProviderId(MetadataProviders.Musicbrainz);
try
{

@ -37,23 +37,25 @@ namespace MediaBrowser.Providers.Music
get { return "FanArt"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is MusicArtist;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var artist = (MusicArtist)item;
var list = new List<RemoteImageInfo>();
var artistMusicBrainzId = item.GetProviderId(MetadataProviders.Musicbrainz);
var artistMusicBrainzId = artist.GetProviderId(MetadataProviders.Musicbrainz);
if (!string.IsNullOrEmpty(artistMusicBrainzId))
{

@ -23,19 +23,19 @@ namespace MediaBrowser.Providers.Music
get { return "last.fm"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is MusicAlbum || item is MusicArtist;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();

@ -37,35 +37,36 @@ namespace MediaBrowser.Providers.TV
get { return "FanArt"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is Season;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
var series = ((Season)item).Series;
var season = (Season)item;
var series = season.Series;
if (series != null)
{
var id = series.GetProviderId(MetadataProviders.Tvdb);
if (!string.IsNullOrEmpty(id) && item.IndexNumber.HasValue)
if (!string.IsNullOrEmpty(id) && season.IndexNumber.HasValue)
{
var xmlPath = FanArtTvProvider.Current.GetFanartXmlPath(id);
try
{
AddImages(list, item.IndexNumber.Value, xmlPath, cancellationToken);
AddImages(list, season.IndexNumber.Value, xmlPath, cancellationToken);
}
catch (FileNotFoundException)
{

@ -37,19 +37,19 @@ namespace MediaBrowser.Providers.TV
get { return "FanArt"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is Series;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();

@ -31,19 +31,19 @@ namespace MediaBrowser.Providers.TV
get { return "TheTVDB"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is Episode;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var episode = (Episode)item;

@ -37,19 +37,19 @@ namespace MediaBrowser.Providers.TV
get { return "TheTVDB"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is Person;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var seriesWithPerson = _library.RootFolder
.RecursiveChildren

@ -38,19 +38,19 @@ namespace MediaBrowser.Providers.TV
get { return "TheTVDB"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is Season;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var season = (Season)item;

@ -38,21 +38,22 @@ namespace MediaBrowser.Providers.TV
get { return "TheTVDB"; }
}
public bool Supports(BaseItem item)
public bool Supports(IHasImages item)
{
return item is Series;
}
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, ImageType imageType, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
return images.Where(i => i.Type == imageType);
}
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var seriesId = item.GetProviderId(MetadataProviders.Tvdb);
var series = (Series)item;
var seriesId = series.GetProviderId(MetadataProviders.Tvdb);
if (!string.IsNullOrEmpty(seriesId))
{

@ -0,0 +1,48 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers
{
public class VirtualItemImageValidator : BaseMetadataProvider
{
public VirtualItemImageValidator(ILogManager logManager, IServerConfigurationManager configurationManager)
: base(logManager, configurationManager)
{
}
public override bool Supports(BaseItem item)
{
var locationType = item.LocationType;
return locationType == LocationType.Virtual ||
locationType == LocationType.Remote;
}
public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
{
item.ValidateImages();
item.ValidateBackdrops();
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
{
hasScreenshots.ValidateScreenshots();
}
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
return TrueTaskResult;
}
public override MetadataProviderPriority Priority
{
get { return MetadataProviderPriority.First; }
}
}
}

@ -243,18 +243,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return dto;
}
public ProgramInfoDto GetProgramInfoDto(ProgramInfo program, LiveTvChannel channel, User user = null)
public ProgramInfoDto GetProgramInfoDto(LiveTvProgram item, User user = null)
{
var program = item.ProgramInfo;
var dto = new ProgramInfoDto
{
Id = GetInternalProgramId(channel.ServiceName, program.Id).ToString("N"),
ChannelId = channel.Id.ToString("N"),
Id = GetInternalProgramId(item.ServiceName, program.Id).ToString("N"),
ChannelId = GetInternalChannelId(item.ServiceName, program.ChannelId, program.ChannelName).ToString("N"),
Overview = program.Overview,
EndDate = program.EndDate,
Genres = program.Genres,
ExternalId = program.Id,
Name = program.Name,
ServiceName = channel.ServiceName,
ServiceName = item.ServiceName,
StartDate = program.StartDate,
OfficialRating = program.OfficialRating,
IsHD = program.IsHD,
@ -277,7 +279,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (user != null)
{
//dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, info.GetUserDataKey()));
dto.UserData = _dtoService.GetUserItemDataDto(_userDataManager.GetUserData(user.Id, item.GetUserDataKey()));
}
return dto;

@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly List<ILiveTvService> _services = new List<ILiveTvService>();
private List<LiveTvChannel> _channels = new List<LiveTvChannel>();
private List<ProgramInfoDto> _programs = new List<ProgramInfoDto>();
private List<LiveTvProgram> _programs = new List<LiveTvProgram>();
public LiveTvManager(IServerApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, ILocalizationManager localization, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager)
{
@ -138,7 +138,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return await GetRecording(recording, service.Name, cancellationToken).ConfigureAwait(false);
}
private async Task<LiveTvChannel> GetChannel(ChannelInfo channelInfo, string serviceName, CancellationToken cancellationToken)
{
var path = Path.Combine(_appPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(serviceName), _fileSystem.GetValidFilename(channelInfo.Name));
@ -189,6 +189,35 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return item;
}
private async Task<LiveTvProgram> GetProgram(ProgramInfo info, string serviceName, CancellationToken cancellationToken)
{
var isNew = false;
var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
var item = _itemRepo.RetrieveItem(id) as LiveTvProgram;
if (item == null)
{
item = new LiveTvProgram
{
Name = info.Name,
Id = id,
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow
};
isNew = true;
}
item.ProgramInfo = info;
item.ServiceName = serviceName;
await item.RefreshMetadata(cancellationToken, forceSave: isNew, resetResolveArgs: false);
return item;
}
private async Task<LiveTvRecording> GetRecording(RecordingInfo info, string serviceName, CancellationToken cancellationToken)
{
var isNew = false;
@ -218,27 +247,50 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return item;
}
public Task<ProgramInfoDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
public async Task<ProgramInfoDto> GetProgram(string id, CancellationToken cancellationToken, User user = null)
{
var program = _programs.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase));
var guid = new Guid(id);
var program = _programs.FirstOrDefault(i => guid == i.Id);
var dto = _tvDtoService.GetProgramInfoDto(program, user);
await AddRecordingInfo(new[] { dto }, cancellationToken).ConfigureAwait(false);
return Task.FromResult(program);
return dto;
}
public Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken)
public async Task<QueryResult<ProgramInfoDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken)
{
IEnumerable<ProgramInfoDto> programs = _programs
.OrderBy(i => i.StartDate)
.ThenBy(i => i.EndDate);
IEnumerable<LiveTvProgram> programs = _programs;
if (query.ChannelIdList.Length > 0)
{
var guids = query.ChannelIdList.Select(i => new Guid(i)).ToList();
var serviceName = ActiveService.Name;
programs = programs.Where(i =>
{
var programChannelId = i.ProgramInfo.ChannelId;
var internalProgramChannelId = _tvDtoService.GetInternalChannelId(serviceName, programChannelId, i.ProgramInfo.ChannelName);
programs = programs.Where(i => guids.Contains(new Guid(i.ChannelId)));
return guids.Contains(internalProgramChannelId);
});
}
var returnArray = programs.ToArray();
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
if (user != null)
{
programs = programs.Where(i => i.IsParentalAllowed(user, _localization));
}
var returnArray = programs
.OrderBy(i => i.ProgramInfo.StartDate)
.Select(i => _tvDtoService.GetProgramInfoDto(i, user))
.ToArray();
await AddRecordingInfo(returnArray, cancellationToken).ConfigureAwait(false);
var result = new QueryResult<ProgramInfoDto>
{
@ -246,7 +298,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv
TotalRecordCount = returnArray.Length
};
return Task.FromResult(result);
return result;
}
private async Task AddRecordingInfo(IEnumerable<ProgramInfoDto> programs, CancellationToken cancellationToken)
{
var timers = await ActiveService.GetTimersAsync(cancellationToken).ConfigureAwait(false);
var timerList = timers.ToList();
foreach (var program in programs)
{
var timer = timerList.FirstOrDefault(i => string.Equals(i.ProgramId, program.ExternalId, StringComparison.OrdinalIgnoreCase));
if (timer != null)
{
program.TimerId = _tvDtoService.GetInternalTimerId(program.ServiceName, timer.Id)
.ToString("N");
if (!string.IsNullOrEmpty(timer.SeriesTimerId))
{
program.SeriesTimerId = _tvDtoService.GetInternalSeriesTimerId(program.ServiceName, timer.SeriesTimerId)
.ToString("N");
}
}
}
}
internal async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
@ -266,7 +342,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var allChannelsList = allChannels.ToList();
var list = new List<LiveTvChannel>();
var programs = new List<ProgramInfoDto>();
var programs = new List<LiveTvProgram>();
var numComplete = 0;
@ -278,7 +354,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var channelPrograms = await service.GetProgramsAsync(channelInfo.Item2.Id, cancellationToken).ConfigureAwait(false);
programs.AddRange(channelPrograms.Select(program => _tvDtoService.GetProgramInfoDto(program, item)));
var programTasks = channelPrograms.Select(program => GetProgram(program, service.Name, cancellationToken));
var programEntities = await Task.WhenAll(programTasks).ConfigureAwait(false);
programs.AddRange(programEntities);
list.Add(item);
}
@ -336,6 +415,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var entities = await GetEntities(list, service.Name, cancellationToken).ConfigureAwait(false);
if (user != null)
{
entities = entities.Where(i => i.IsParentalAllowed(user, _localization)).ToArray();
}
var returnArray = entities
.Select(i => _tvDtoService.GetRecordingInfoDto(i, ActiveService, user))
.OrderByDescending(i => i.StartDate)
@ -504,15 +588,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
};
}
public async Task<ChannelInfoDto> GetChannel(string id, CancellationToken cancellationToken, User user = null)
public Task<ChannelInfoDto> GetChannel(string id, CancellationToken cancellationToken, User user = null)
{
var results = await GetChannels(new ChannelQuery
{
UserId = user == null ? null : user.Id.ToString("N")
var guid = new Guid(id);
var channel = _channels.FirstOrDefault(i => guid == i.Id);
}, cancellationToken).ConfigureAwait(false);
var dto = _tvDtoService.GetChannelInfoDto(channel, user);
return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.CurrentCulture));
return Task.FromResult(dto);
}
public async Task<SeriesTimerInfoDto> GetNewTimerDefaults(CancellationToken cancellationToken)

@ -85,6 +85,9 @@
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ApiClient.js" />
<Content Include="dashboard-ui\css\images\clients\xbmc.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\editor.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
<version>3.0.284</version>
<version>3.0.285</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.284" />
<dependency id="MediaBrowser.Common" version="3.0.285" />
<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.284</version>
<version>3.0.285</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.284</version>
<version>3.0.285</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.284" />
<dependency id="MediaBrowser.Common" version="3.0.285" />
</dependencies>
</metadata>
<files>

Loading…
Cancel
Save