rework active recordings
This commit is contained in:
parent
82ab91f209
commit
afd94407f9
|
@ -411,6 +411,21 @@ namespace Emby.Server.Implementations.Dto
|
|||
{
|
||||
liveTvManager.AddInfoToRecordingDto(item, dto, user);
|
||||
}
|
||||
else
|
||||
{
|
||||
var activeRecording = liveTvManager.GetActiveRecordingInfo(item.Path);
|
||||
if (activeRecording != null)
|
||||
{
|
||||
dto.Type = "Recording";
|
||||
dto.CanDownload = false;
|
||||
if (!string.IsNullOrWhiteSpace(dto.SeriesName))
|
||||
{
|
||||
dto.EpisodeTitle = dto.Name;
|
||||
dto.Name = dto.SeriesName;
|
||||
}
|
||||
liveTvManager.AddInfoToRecordingDto(item, dto, activeRecording, user);
|
||||
}
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
|
|
@ -830,6 +830,9 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
existingTimer.IsKids = updatedTimer.IsKids;
|
||||
existingTimer.IsNews = updatedTimer.IsNews;
|
||||
existingTimer.IsMovie = updatedTimer.IsMovie;
|
||||
existingTimer.IsSeries = updatedTimer.IsSeries;
|
||||
existingTimer.IsLive = updatedTimer.IsLive;
|
||||
existingTimer.IsPremiere = updatedTimer.IsPremiere;
|
||||
existingTimer.IsProgramSeries = updatedTimer.IsProgramSeries;
|
||||
existingTimer.IsRepeat = updatedTimer.IsRepeat;
|
||||
existingTimer.IsSports = updatedTimer.IsSports;
|
||||
|
@ -861,7 +864,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
|
||||
public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return _activeRecordings.Values.ToList().Select(GetRecordingInfo).ToList();
|
||||
return new List<RecordingInfo>();
|
||||
//return _activeRecordings.Values.ToList().Select(GetRecordingInfo).ToList();
|
||||
}
|
||||
|
||||
public string GetActiveRecordingPath(string id)
|
||||
|
@ -875,6 +879,28 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<ActiveRecordingInfo> GetAllActiveRecordings()
|
||||
{
|
||||
return _activeRecordings.Values;
|
||||
}
|
||||
|
||||
public ActiveRecordingInfo GetActiveRecordingInfo(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var recording in _activeRecordings.Values)
|
||||
{
|
||||
if (string.Equals(recording.Path, path, StringComparison.Ordinal))
|
||||
{
|
||||
return recording;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private RecordingInfo GetRecordingInfo(ActiveRecordingInfo info)
|
||||
{
|
||||
var timer = info.Timer;
|
||||
|
@ -1245,6 +1271,33 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
public async Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
var stream = new MediaSourceInfo
|
||||
{
|
||||
Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
|
||||
Id = info.Id,
|
||||
SupportsDirectPlay = false,
|
||||
SupportsDirectStream = true,
|
||||
SupportsTranscoding = true,
|
||||
IsInfiniteStream = true,
|
||||
RequiresOpening = false,
|
||||
RequiresClosing = false,
|
||||
Protocol = MediaBrowser.Model.MediaInfo.MediaProtocol.Http,
|
||||
BufferMs = 0,
|
||||
IgnoreDts = true,
|
||||
IgnoreIndex = true
|
||||
};
|
||||
|
||||
var isAudio = false;
|
||||
await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return new List<MediaSourceInfo>
|
||||
{
|
||||
stream
|
||||
};
|
||||
}
|
||||
|
||||
public async Task CloseLiveStream(string id, CancellationToken cancellationToken)
|
||||
{
|
||||
// Ignore the consumer id
|
||||
|
@ -1327,7 +1380,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
var activeRecordingInfo = new ActiveRecordingInfo
|
||||
{
|
||||
CancellationTokenSource = new CancellationTokenSource(),
|
||||
Timer = timer
|
||||
Timer = timer,
|
||||
Id = timer.Id
|
||||
};
|
||||
|
||||
if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo))
|
||||
|
@ -1493,7 +1547,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
recordPath = recorder.GetOutputPath(mediaStreamInfo, recordPath);
|
||||
recordPath = EnsureFileUnique(recordPath, timer.Id);
|
||||
|
||||
_libraryManager.RegisterIgnoredPath(recordPath);
|
||||
_libraryMonitor.ReportFileSystemChangeBeginning(recordPath);
|
||||
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(recordPath));
|
||||
activeRecordingInfo.Path = recordPath;
|
||||
|
@ -1512,6 +1565,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
_timerProvider.AddOrUpdate(timer, false);
|
||||
|
||||
SaveRecordingMetadata(timer, recordPath, seriesPath);
|
||||
TriggerRefresh(recordPath);
|
||||
EnforceKeepUpTo(timer, seriesPath);
|
||||
};
|
||||
|
||||
|
@ -1543,7 +1597,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
}
|
||||
}
|
||||
|
||||
_libraryManager.UnRegisterIgnoredPath(recordPath);
|
||||
TriggerRefresh(recordPath);
|
||||
_libraryMonitor.ReportFileSystemChangeComplete(recordPath, true);
|
||||
|
||||
ActiveRecordingInfo removed;
|
||||
|
@ -1574,6 +1628,44 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
OnRecordingStatusChanged();
|
||||
}
|
||||
|
||||
private void TriggerRefresh(string path)
|
||||
{
|
||||
var item = GetAffectedBaseItem(_fileSystem.GetDirectoryName(path));
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
item.ChangedExternally();
|
||||
}
|
||||
}
|
||||
|
||||
private BaseItem GetAffectedBaseItem(string path)
|
||||
{
|
||||
BaseItem item = null;
|
||||
|
||||
while (item == null && !string.IsNullOrEmpty(path))
|
||||
{
|
||||
item = _libraryManager.FindByPath(path, null);
|
||||
|
||||
path = _fileSystem.GetDirectoryName(path);
|
||||
}
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
// If the item has been deleted find the first valid parent that still exists
|
||||
while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
|
||||
{
|
||||
item = item.GetParent();
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void OnRecordingStatusChanged()
|
||||
{
|
||||
EventHelper.FireEventIfNotNull(RecordingStatusChanged, this, new RecordingStatusChangedEventArgs
|
||||
|
@ -2621,14 +2713,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
return list;
|
||||
}
|
||||
|
||||
class ActiveRecordingInfo
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public TimerInfo Timer { get; set; }
|
||||
public ProgramInfo Program { get; set; }
|
||||
public CancellationTokenSource CancellationTokenSource { get; set; }
|
||||
}
|
||||
|
||||
private const int TunerDiscoveryDurationMs = 3000;
|
||||
|
||||
public async Task<List<TunerHostInfo>> DiscoverTuners(bool newDevicesOnly, CancellationToken cancellationToken)
|
||||
|
|
|
@ -58,6 +58,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
|||
timerInfo.OriginalAirDate = programInfo.OriginalAirDate;
|
||||
timerInfo.IsProgramSeries = programInfo.IsSeries;
|
||||
|
||||
timerInfo.IsSeries = programInfo.IsSeries;
|
||||
timerInfo.IsLive = programInfo.IsLive;
|
||||
timerInfo.IsPremiere = programInfo.IsPremiere;
|
||||
|
||||
timerInfo.HomePageUrl = programInfo.HomePageUrl;
|
||||
timerInfo.CommunityRating = programInfo.CommunityRating;
|
||||
timerInfo.Overview = programInfo.Overview;
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
private readonly LiveTvDtoService _tvDtoService;
|
||||
|
||||
private readonly List<ILiveTvService> _services = new List<ILiveTvService>();
|
||||
private ILiveTvService[] _services = new ILiveTvService[] { };
|
||||
|
||||
private readonly SemaphoreSlim _refreshRecordingsLock = new SemaphoreSlim(1, 1);
|
||||
|
||||
|
@ -124,7 +124,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
/// <param name="listingProviders">The listing providers.</param>
|
||||
public void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders)
|
||||
{
|
||||
_services.AddRange(services);
|
||||
_services = services.ToArray();
|
||||
_tunerHosts.AddRange(tunerHosts);
|
||||
_listingProviders.AddRange(listingProviders);
|
||||
|
||||
|
@ -1221,9 +1221,9 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
await EmbyTV.EmbyTV.Current.ScanForTunerDeviceChanges(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var numComplete = 0;
|
||||
double progressPerService = _services.Count == 0
|
||||
double progressPerService = _services.Length == 0
|
||||
? 0
|
||||
: 1 / _services.Count;
|
||||
: 1 / _services.Length;
|
||||
|
||||
var newChannelIdList = new List<Guid>();
|
||||
var newProgramIdList = new List<Guid>();
|
||||
|
@ -1255,7 +1255,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
numComplete++;
|
||||
double percent = numComplete;
|
||||
percent /= _services.Count;
|
||||
percent /= _services.Length;
|
||||
|
||||
progress.Report(100 * percent);
|
||||
}
|
||||
|
@ -1561,11 +1561,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
return new QueryResult<BaseItem>();
|
||||
}
|
||||
|
||||
if ((query.IsInProgress ?? false))
|
||||
{
|
||||
return new QueryResult<BaseItem>();
|
||||
}
|
||||
|
||||
var folderIds = EmbyTV.EmbyTV.Current.GetRecordingFolders()
|
||||
.SelectMany(i => i.Locations)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
|
@ -1577,13 +1572,10 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
var excludeItemTypes = new List<string>();
|
||||
|
||||
if (!query.IsInProgress.HasValue)
|
||||
{
|
||||
folderIds.Add(internalLiveTvFolderId);
|
||||
folderIds.Add(internalLiveTvFolderId);
|
||||
|
||||
excludeItemTypes.Add(typeof(LiveTvChannel).Name);
|
||||
excludeItemTypes.Add(typeof(LiveTvProgram).Name);
|
||||
}
|
||||
excludeItemTypes.Add(typeof(LiveTvChannel).Name);
|
||||
excludeItemTypes.Add(typeof(LiveTvProgram).Name);
|
||||
|
||||
if (folderIds.Count == 0)
|
||||
{
|
||||
|
@ -1632,6 +1624,19 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
}
|
||||
}
|
||||
|
||||
if ((query.IsInProgress ?? false))
|
||||
{
|
||||
// TODO: filter
|
||||
var allActivePaths = EmbyTV.EmbyTV.Current.GetAllActiveRecordings().Select(i => i.Path).ToArray();
|
||||
var items = allActivePaths.Select(i => _libraryManager.FindByPath(i, false)).Where(i => i != null).ToArray();
|
||||
|
||||
return new QueryResult<BaseItem>
|
||||
{
|
||||
Items = items,
|
||||
TotalRecordCount = items.Length
|
||||
};
|
||||
}
|
||||
|
||||
return _libraryManager.GetItemsResult(new InternalItemsQuery(user)
|
||||
{
|
||||
MediaTypes = new[] { MediaType.Video },
|
||||
|
@ -1659,11 +1664,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
return new QueryResult<BaseItemDto>();
|
||||
}
|
||||
|
||||
if (_services.Count > 1)
|
||||
{
|
||||
return new QueryResult<BaseItemDto>();
|
||||
}
|
||||
|
||||
if (user == null || (query.IsInProgress ?? false))
|
||||
{
|
||||
return new QueryResult<BaseItemDto>();
|
||||
|
@ -1722,13 +1722,9 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (_services.Count == 1 && (!query.IsInProgress.HasValue || !query.IsInProgress.Value) && (!query.IsLibraryItem.HasValue || query.IsLibraryItem.Value))
|
||||
// TODO: Figure out how to merge emby recordings + service recordings
|
||||
if (_services.Length == 1)
|
||||
{
|
||||
if (!query.IsInProgress.HasValue)
|
||||
{
|
||||
await RefreshRecordings(folder.Id, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return GetEmbyRecordings(query, options, folder.Id, user);
|
||||
}
|
||||
|
||||
|
@ -1920,6 +1916,11 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public ActiveRecordingInfo GetActiveRecordingInfo(string path)
|
||||
{
|
||||
return EmbyTV.EmbyTV.Current.GetActiveRecordingInfo(path);
|
||||
}
|
||||
|
||||
public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null)
|
||||
{
|
||||
var recording = (ILiveTvRecording)item;
|
||||
|
@ -1949,20 +1950,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
dto.IsKids = info.IsKids;
|
||||
dto.IsPremiere = info.IsPremiere;
|
||||
|
||||
dto.CanDelete = user == null
|
||||
? recording.CanDelete()
|
||||
: recording.CanDelete(user);
|
||||
|
||||
if (dto.MediaSources == null)
|
||||
{
|
||||
dto.MediaSources = recording.GetMediaSources(true);
|
||||
}
|
||||
|
||||
if (dto.MediaStreams == null)
|
||||
{
|
||||
dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToArray();
|
||||
}
|
||||
|
||||
if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue)
|
||||
{
|
||||
var now = DateTime.UtcNow.Ticks;
|
||||
|
@ -1986,6 +1973,65 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
}
|
||||
}
|
||||
|
||||
public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, ActiveRecordingInfo activeRecordingInfo, User user = null)
|
||||
{
|
||||
var service = EmbyTV.EmbyTV.Current;
|
||||
|
||||
var info = activeRecordingInfo.Timer;
|
||||
|
||||
var channel = string.IsNullOrWhiteSpace(info.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, info.ChannelId));
|
||||
|
||||
dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId)
|
||||
? null
|
||||
: _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
|
||||
|
||||
dto.TimerId = string.IsNullOrEmpty(info.Id)
|
||||
? null
|
||||
: _tvDtoService.GetInternalTimerId(service.Name, info.Id).ToString("N");
|
||||
|
||||
var startDate = info.StartDate;
|
||||
var endDate = info.EndDate;
|
||||
|
||||
dto.StartDate = startDate;
|
||||
dto.EndDate = endDate;
|
||||
dto.Status = info.Status.ToString();
|
||||
dto.IsRepeat = info.IsRepeat;
|
||||
dto.EpisodeTitle = info.EpisodeTitle;
|
||||
dto.IsMovie = info.IsMovie;
|
||||
dto.IsSeries = info.IsSeries;
|
||||
dto.IsSports = info.IsSports;
|
||||
dto.IsLive = info.IsLive;
|
||||
dto.IsNews = info.IsNews;
|
||||
dto.IsKids = info.IsKids;
|
||||
dto.IsPremiere = info.IsPremiere;
|
||||
|
||||
if (info.Status == RecordingStatus.InProgress)
|
||||
{
|
||||
startDate = info.StartDate.AddSeconds(0 - info.PrePaddingSeconds);
|
||||
endDate = info.EndDate.AddSeconds(info.PostPaddingSeconds);
|
||||
|
||||
var now = DateTime.UtcNow.Ticks;
|
||||
var start = startDate.Ticks;
|
||||
var end = endDate.Ticks;
|
||||
|
||||
var pct = now - start;
|
||||
|
||||
pct /= end;
|
||||
pct *= 100;
|
||||
dto.CompletionPercentage = pct;
|
||||
}
|
||||
|
||||
if (channel != null)
|
||||
{
|
||||
dto.ChannelName = channel.Name;
|
||||
|
||||
if (channel.HasImage(ImageType.Primary))
|
||||
{
|
||||
dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<QueryResult<BaseItemDto>> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
||||
|
@ -2098,7 +2144,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
if (service is EmbyTV.EmbyTV)
|
||||
{
|
||||
// We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says
|
||||
return service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None);
|
||||
}
|
||||
|
||||
|
@ -2348,7 +2393,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
var currentChannelsDict = new Dictionary<string, BaseItemDto>();
|
||||
|
||||
var addCurrentProgram = options.AddCurrentProgram;
|
||||
var addMediaSources = options.Fields.Contains(ItemFields.MediaSources);
|
||||
var addServiceName = options.Fields.Contains(ItemFields.ServiceName);
|
||||
|
||||
foreach (var tuple in tuples)
|
||||
|
@ -2367,11 +2411,6 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
currentChannelsDict[dto.Id] = dto;
|
||||
|
||||
if (addMediaSources)
|
||||
{
|
||||
dto.MediaSources = channel.GetMediaSources(true);
|
||||
}
|
||||
|
||||
if (addCurrentProgram)
|
||||
{
|
||||
var channelIdString = channel.Id.ToString("N");
|
||||
|
|
|
@ -43,9 +43,11 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
|
||||
if (baseItem.SourceType == SourceType.LiveTV)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(baseItem.Path))
|
||||
var activeRecordingInfo = _liveTvManager.GetActiveRecordingInfo(item.Path);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(baseItem.Path) || activeRecordingInfo != null)
|
||||
{
|
||||
return GetMediaSourcesInternal(item, cancellationToken);
|
||||
return GetMediaSourcesInternal(item, activeRecordingInfo, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +58,7 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
private const char StreamIdDelimeter = '_';
|
||||
private const string StreamIdDelimeterString = "_";
|
||||
|
||||
private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(IHasMediaSources item, CancellationToken cancellationToken)
|
||||
private async Task<IEnumerable<MediaSourceInfo>> GetMediaSourcesInternal(IHasMediaSources item, ActiveRecordingInfo activeRecordingInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
IEnumerable<MediaSourceInfo> sources;
|
||||
|
||||
|
@ -67,12 +69,20 @@ namespace Emby.Server.Implementations.LiveTv
|
|||
if (item is ILiveTvRecording)
|
||||
{
|
||||
sources = await _liveTvManager.GetRecordingMediaSources(item, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
if (activeRecordingInfo != null)
|
||||
{
|
||||
sources = await EmbyTV.EmbyTV.Current.GetRecordingStreamMediaSources(activeRecordingInfo, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
|
|
|
@ -4,7 +4,7 @@ using MediaBrowser.Model.Entities;
|
|||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public interface IHasMediaSources : IHasUserData
|
||||
public interface IHasMediaSources : IHasMetadata
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the media sources.
|
||||
|
|
|
@ -160,7 +160,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
public string[] GetPlayableStreamFileNames()
|
||||
{
|
||||
return GetPlayableStreamFiles().Select(System.IO.Path.GetFileName).ToArray();
|
||||
return GetPlayableStreamFiles().Select(System.IO.Path.GetFileName).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -234,6 +234,35 @@ namespace MediaBrowser.Controller.Entities
|
|||
return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
public override SourceType SourceType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsActiveRecording())
|
||||
{
|
||||
return SourceType.LiveTV;
|
||||
}
|
||||
|
||||
return base.SourceType;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool IsActiveRecording()
|
||||
{
|
||||
return LiveTvManager.GetActiveRecordingInfo(Path) != null;
|
||||
}
|
||||
|
||||
public override bool CanDelete()
|
||||
{
|
||||
if (IsActiveRecording())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.CanDelete();
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
protected virtual bool EnableDefaultVideoUserDataKeys
|
||||
{
|
||||
|
@ -616,6 +645,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
var list = GetAllVideosForMediaSources();
|
||||
var result = list.Select(i => GetVersionInfo(enablePathSubstitution, i.Item1, i.Item2)).ToList();
|
||||
|
||||
if (IsActiveRecording())
|
||||
{
|
||||
foreach (var mediaSource in result)
|
||||
{
|
||||
mediaSource.Type = MediaSourceType.Placeholder;
|
||||
}
|
||||
}
|
||||
|
||||
return result.OrderBy(i =>
|
||||
{
|
||||
if (i.VideoType == VideoType.VideoFile)
|
||||
|
|
|
@ -384,5 +384,9 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
|
||||
string GetEmbyTvActiveRecordingPath(string id);
|
||||
Task<LiveStream> GetEmbyTvLiveStream(string id);
|
||||
|
||||
ActiveRecordingInfo GetActiveRecordingInfo(string path);
|
||||
|
||||
void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, ActiveRecordingInfo activeRecordingInfo, User user = null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,4 +36,13 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
DateTime? EndDate { get; set; }
|
||||
DateTime DateCreated { get; set; }
|
||||
}
|
||||
|
||||
public class ActiveRecordingInfo
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Path { get; set; }
|
||||
public TimerInfo Timer { get; set; }
|
||||
public ProgramInfo Program { get; set; }
|
||||
public CancellationTokenSource CancellationTokenSource { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,9 @@ namespace MediaBrowser.Controller.LiveTv
|
|||
public bool IsKids { get; set; }
|
||||
public bool IsSports { get; set; }
|
||||
public bool IsNews { get; set; }
|
||||
public bool IsSeries { get; set; }
|
||||
public bool IsLive { get; set; }
|
||||
public bool IsPremiere { get; set; }
|
||||
public int? ProductionYear { get; set; }
|
||||
public string EpisodeTitle { get; set; }
|
||||
public DateTime? OriginalAirDate { get; set; }
|
||||
|
|
Loading…
Reference in New Issue
Block a user