support streaming of tv recordings
This commit is contained in:
parent
cac101cc21
commit
4c2623d540
|
@ -29,12 +29,16 @@ namespace MediaBrowser.Api
|
|||
/// <value>The logger.</value>
|
||||
private ILogger Logger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The application paths
|
||||
/// </summary>
|
||||
private readonly IServerApplicationPaths AppPaths;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApiEntryPoint" /> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="appPaths">The application paths.</param>
|
||||
public ApiEntryPoint(ILogger logger, IServerApplicationPaths appPaths)
|
||||
{
|
||||
Logger = logger;
|
||||
|
@ -52,6 +56,10 @@ namespace MediaBrowser.Api
|
|||
{
|
||||
DeleteEncodedMediaCache();
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
// Don't clutter the log
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Logger.ErrorException("Error deleting encoded media cache", ex);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Net;
|
||||
|
@ -51,6 +52,11 @@ namespace MediaBrowser.Api
|
|||
return ResultFactory.GetOptimizedResult(Request, result);
|
||||
}
|
||||
|
||||
protected object ToStreamResult(Stream stream, string contentType)
|
||||
{
|
||||
return ResultFactory.GetResult(stream, contentType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To the optimized result using cache.
|
||||
/// </summary>
|
||||
|
|
|
@ -174,6 +174,13 @@ 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; }
|
||||
}
|
||||
|
||||
public class LiveTvService : BaseApiService
|
||||
{
|
||||
private readonly ILiveTvManager _liveTvManager;
|
||||
|
@ -364,5 +371,12 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -359,7 +359,7 @@ namespace MediaBrowser.Api.Playback
|
|||
if (request.Width.HasValue)
|
||||
{
|
||||
var widthParam = request.Width.Value.ToString(UsCulture);
|
||||
|
||||
|
||||
return isH264Output ?
|
||||
string.Format(" -vf \"scale={0}:trunc(ow/a/2)*2{1}\"", widthParam, assSubtitleParam) :
|
||||
string.Format(" -vf \"scale={0}:-1{1}\"", widthParam, assSubtitleParam);
|
||||
|
@ -369,7 +369,7 @@ namespace MediaBrowser.Api.Playback
|
|||
if (request.Height.HasValue)
|
||||
{
|
||||
var heightParam = request.Height.Value.ToString(UsCulture);
|
||||
|
||||
|
||||
return isH264Output ?
|
||||
string.Format(" -vf \"scale=trunc(oh*a*2)/2:{0}{1}\"", heightParam, assSubtitleParam) :
|
||||
string.Format(" -vf \"scale=-1:{0}{1}\"", heightParam, assSubtitleParam);
|
||||
|
@ -379,7 +379,7 @@ namespace MediaBrowser.Api.Playback
|
|||
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}\"", maxWidthParam, assSubtitleParam) :
|
||||
string.Format(" -vf \"scale=min(iw\\,{0}):-1{1}\"", maxWidthParam, assSubtitleParam);
|
||||
|
@ -389,7 +389,7 @@ namespace MediaBrowser.Api.Playback
|
|||
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}\"", maxHeightParam, assSubtitleParam) :
|
||||
string.Format(" -vf \"scale=-1:min(ih\\,{0}){1}\"", maxHeightParam, assSubtitleParam);
|
||||
|
@ -890,6 +890,14 @@ namespace MediaBrowser.Api.Playback
|
|||
state.MediaPath = recording.RecordingInfo.Url;
|
||||
state.IsRemote = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.MediaPath = string.Format("http://localhost:{0}/mediabrowser/LiveTv/Recordings/{1}/Stream",
|
||||
ServerConfigurationManager.Configuration.HttpServerPortNumber,
|
||||
request.Id);
|
||||
|
||||
state.IsRemote = true;
|
||||
}
|
||||
|
||||
item = recording;
|
||||
}
|
||||
|
@ -899,7 +907,7 @@ namespace MediaBrowser.Api.Playback
|
|||
|
||||
state.MediaPath = item.Path;
|
||||
state.IsRemote = item.LocationType == LocationType.Remote;
|
||||
|
||||
|
||||
var video = item as Video;
|
||||
|
||||
if (video != null)
|
||||
|
|
|
@ -124,6 +124,11 @@ namespace MediaBrowser.Controller.Library
|
|||
{
|
||||
var filename = Path.GetFileName(path);
|
||||
|
||||
if (string.Equals(path, "specials", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Look for one of the season folder names
|
||||
foreach (var name in SeasonFolderNames)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using System.Collections.Generic;
|
||||
|
@ -153,6 +154,14 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>LiveTvRecording.</returns>
|
||||
Task<LiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the recording stream.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
Task<StreamResponseInfo> GetRecordingStream(string id, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the program.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -85,7 +84,7 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <param name="channelId">The channel identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
Task<ImageResponseInfo> GetChannelImageAsync(string channelId, CancellationToken cancellationToken);
|
||||
Task<StreamResponseInfo> GetChannelImageAsync(string channelId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the recording image asynchronous. This only needs to be implemented if an image path or url cannot be supplied to RecordingInfo
|
||||
|
@ -93,7 +92,7 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <param name="recordingId">The recording identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{ImageResponseInfo}.</returns>
|
||||
Task<ImageResponseInfo> GetRecordingImageAsync(string recordingId, CancellationToken cancellationToken);
|
||||
Task<StreamResponseInfo> GetRecordingImageAsync(string recordingId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the program image asynchronous. This only needs to be implemented if an image path or url cannot be supplied to ProgramInfo
|
||||
|
@ -102,7 +101,7 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <param name="channelId">The channel identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{ImageResponseInfo}.</returns>
|
||||
Task<ImageResponseInfo> GetProgramImageAsync(string programId, string channelId, CancellationToken cancellationToken);
|
||||
Task<StreamResponseInfo> GetProgramImageAsync(string programId, string channelId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the recordings asynchronous.
|
||||
|
@ -146,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<Stream> GetRecordingStream(string recordingId, CancellationToken cancellationToken);
|
||||
Task<StreamResponseInfo> GetRecordingStream(string recordingId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel stream.
|
||||
|
@ -154,6 +153,6 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <param name="recordingId">The recording identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
Task<Stream> GetChannelStream(string recordingId, CancellationToken cancellationToken);
|
||||
Task<StreamResponseInfo> GetChannelStream(string recordingId, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.LiveTv;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
|
@ -15,13 +16,15 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
|
||||
public ProgramInfo ProgramInfo { get; set; }
|
||||
|
||||
public ChannelType ChannelType { get; set; }
|
||||
|
||||
public string ServiceName { get; set; }
|
||||
|
||||
public override string MediaType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ProgramInfo.IsVideo ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio;
|
||||
return ChannelType == ChannelType.TV ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,12 +127,6 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
/// <value><c>true</c> if this instance is series; otherwise, <c>false</c>.</value>
|
||||
public bool IsSeries { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is video.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is video; otherwise, <c>false</c>.</value>
|
||||
public bool IsVideo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is live.
|
||||
/// </summary>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
public class ImageResponseInfo
|
||||
public class StreamResponseInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the stream.
|
|
@ -112,7 +112,7 @@
|
|||
<Compile Include="LiveTv\ChannelInfo.cs" />
|
||||
<Compile Include="LiveTv\ILiveTvManager.cs" />
|
||||
<Compile Include="LiveTv\ILiveTvService.cs" />
|
||||
<Compile Include="LiveTv\ImageResponseInfo.cs" />
|
||||
<Compile Include="LiveTv\StreamResponseInfo.cs" />
|
||||
<Compile Include="LiveTv\LiveTvProgram.cs" />
|
||||
<Compile Include="LiveTv\LiveTvRecording.cs" />
|
||||
<Compile Include="LiveTv\ProgramInfo.cs" />
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
<Compile Include="TV\ManualTvdbPersonImageProvider.cs" />
|
||||
<Compile Include="TV\ManualTvdbSeasonImageProvider.cs" />
|
||||
<Compile Include="TV\ManualTvdbSeriesImageProvider.cs" />
|
||||
<Compile Include="TV\SeasonIndexNumberProvider.cs" />
|
||||
<Compile Include="TV\TvdbEpisodeProvider.cs" />
|
||||
<Compile Include="TV\TvdbSeasonProvider.cs" />
|
||||
<Compile Include="TV\TvdbSeriesProvider.cs" />
|
||||
|
|
|
@ -50,7 +50,12 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
return item is Episode && item.LocationType != LocationType.Virtual && item.LocationType != LocationType.Remote;
|
||||
if (item is Episode)
|
||||
{
|
||||
var locationType = item.LocationType;
|
||||
return locationType != LocationType.Virtual && locationType != LocationType.Remote;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
83
MediaBrowser.Providers/TV/SeasonIndexNumberProvider.cs
Normal file
83
MediaBrowser.Providers/TV/SeasonIndexNumberProvider.cs
Normal file
|
@ -0,0 +1,83 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
class SeasonIndexNumberProvider : BaseMetadataProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseMetadataProvider" /> class.
|
||||
/// </summary>
|
||||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
public SeasonIndexNumberProvider(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool RefreshOnVersionChange
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string ProviderVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return "2";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supportses the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
public override bool Supports(BaseItem item)
|
||||
{
|
||||
if (item is Season)
|
||||
{
|
||||
var locationType = item.LocationType;
|
||||
return locationType != LocationType.Virtual && locationType != LocationType.Remote;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="force">if set to <c>true</c> [force].</param>
|
||||
/// <param name="providerInfo">The provider information.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{System.Boolean}.</returns>
|
||||
public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
item.IndexNumber = TVUtils.GetSeasonNumberFromPath(item.Path);
|
||||
|
||||
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
|
||||
|
||||
return TrueTaskResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the priority.
|
||||
/// </summary>
|
||||
/// <value>The priority.</value>
|
||||
public override MetadataProviderPriority Priority
|
||||
{
|
||||
get { return MetadataProviderPriority.First; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.TV
|
|||
/// <value>The priority.</value>
|
||||
public override MetadataProviderPriority Priority
|
||||
{
|
||||
get { return MetadataProviderPriority.First; }
|
||||
get { return MetadataProviderPriority.Second; }
|
||||
}
|
||||
|
||||
private const string XmlFileName = "season.xml";
|
||||
|
|
|
@ -152,6 +152,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
return await GetRecording(recording, service.Name, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<StreamResponseInfo> 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));
|
||||
|
||||
return await service.GetRecordingStream(recording.Id, 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));
|
||||
|
@ -202,7 +213,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
return item;
|
||||
}
|
||||
|
||||
private async Task<LiveTvProgram> GetProgram(ProgramInfo info, string serviceName, CancellationToken cancellationToken)
|
||||
private async Task<LiveTvProgram> GetProgram(ProgramInfo info, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
var isNew = false;
|
||||
|
||||
|
@ -223,6 +234,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
isNew = true;
|
||||
}
|
||||
|
||||
item.ChannelType = channelType;
|
||||
item.ProgramInfo = info;
|
||||
item.ServiceName = serviceName;
|
||||
|
||||
|
@ -283,7 +295,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
programs = programs.Where(i =>
|
||||
{
|
||||
var programChannelId = i.ProgramInfo.ChannelId;
|
||||
|
||||
|
||||
var internalProgramChannelId = _tvDtoService.GetInternalChannelId(serviceName, programChannelId, i.ProgramInfo.ChannelName);
|
||||
|
||||
return guids.Contains(internalProgramChannelId);
|
||||
|
@ -366,7 +378,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
var channelPrograms = await service.GetProgramsAsync(channelInfo.Item2.Id, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var programTasks = channelPrograms.Select(program => GetProgram(program, service.Name, cancellationToken));
|
||||
var programTasks = channelPrograms.Select(program => GetProgram(program, item.ChannelInfo.ChannelType, service.Name, cancellationToken));
|
||||
var programEntities = await Task.WhenAll(programTasks).ConfigureAwait(false);
|
||||
|
||||
programs.AddRange(programEntities);
|
||||
|
@ -433,7 +445,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
}
|
||||
|
||||
var returnArray = entities
|
||||
.Select(i => _tvDtoService.GetRecordingInfoDto(i, ActiveService, user))
|
||||
.Select(i => _tvDtoService.GetRecordingInfoDto(i, service, user))
|
||||
.OrderByDescending(i => i.StartDate)
|
||||
.ToArray();
|
||||
|
||||
|
@ -489,7 +501,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
{
|
||||
var program = string.IsNullOrEmpty(i.ProgramId) ? null : GetInternalProgram(_tvDtoService.GetInternalProgramId(service.Name, i.ProgramId).ToString("N"));
|
||||
|
||||
return _tvDtoService.GetTimerInfoDto(i, ActiveService, program);
|
||||
return _tvDtoService.GetTimerInfoDto(i, service, program);
|
||||
})
|
||||
.OrderBy(i => i.StartDate)
|
||||
.ToArray();
|
||||
|
@ -574,18 +586,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
public async Task<QueryResult<SeriesTimerInfoDto>> GetSeriesTimers(SeriesTimerQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = new List<SeriesTimerInfoDto>();
|
||||
var service = ActiveService;
|
||||
|
||||
if (ActiveService != null)
|
||||
{
|
||||
var timers = await ActiveService.GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false);
|
||||
var timers = await service.GetSeriesTimersAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var dtos = timers.Select(i => _tvDtoService.GetSeriesTimerInfoDto(i, ActiveService));
|
||||
|
||||
list.AddRange(dtos);
|
||||
}
|
||||
|
||||
var returnArray = list.OrderByDescending(i => i.StartDate)
|
||||
var returnArray = timers
|
||||
.Select(i => _tvDtoService.GetSeriesTimerInfoDto(i, service))
|
||||
.OrderByDescending(i => i.StartDate)
|
||||
.ToArray();
|
||||
|
||||
return new QueryResult<SeriesTimerInfoDto>
|
||||
|
@ -606,9 +613,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
public async Task<SeriesTimerInfoDto> GetNewTimerDefaults(CancellationToken cancellationToken)
|
||||
{
|
||||
var info = await ActiveService.GetNewTimerDefaultsAsync(cancellationToken).ConfigureAwait(false);
|
||||
var service = ActiveService;
|
||||
|
||||
var obj = _tvDtoService.GetSeriesTimerInfoDto(info, ActiveService);
|
||||
var info = await service.GetNewTimerDefaultsAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var obj = _tvDtoService.GetSeriesTimerInfoDto(info, service);
|
||||
|
||||
obj.Id = obj.ExternalId = string.Empty;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>MediaBrowser.Common.Internal</id>
|
||||
<version>3.0.288</version>
|
||||
<version>3.0.289</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.288" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.289" />
|
||||
<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.288</version>
|
||||
<version>3.0.289</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.288</version>
|
||||
<version>3.0.289</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.288" />
|
||||
<dependency id="MediaBrowser.Common" version="3.0.289" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
|
Loading…
Reference in New Issue
Block a user