diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-10-09 03:18:43 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-10-09 03:18:43 -0400 |
| commit | daaae69df575f1d7692ba29d6f5ddd4c59516f82 (patch) | |
| tree | 24c818ece042d36808fd0a68834b2853bf4512e1 /MediaBrowser.Server.Implementations | |
| parent | b3595eab6a94fda4f81f637007b2ac79e8a85065 (diff) | |
add playback of in-progress recordings
Diffstat (limited to 'MediaBrowser.Server.Implementations')
13 files changed, 306 insertions, 169 deletions
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index b76cf46b0..1369efae1 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -1577,97 +1577,5 @@ namespace MediaBrowser.Server.Implementations.Channels return await _libraryManager.GetNamedView(name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false); } - - public async Task DownloadChannelItem(BaseItem item, string destination, - IProgress<double> progress, CancellationToken cancellationToken) - { - var sources = await GetDynamicMediaSources(item, cancellationToken) - .ConfigureAwait(false); - - var list = sources.Where(i => i.Protocol == MediaProtocol.Http).ToList(); - - foreach (var source in list) - { - await TryDownloadChannelItem(source, item, destination, progress, cancellationToken).ConfigureAwait(false); - return; - } - } - - private async Task TryDownloadChannelItem(MediaSourceInfo source, - BaseItem item, - string destination, - IProgress<double> progress, - CancellationToken cancellationToken) - { - var options = new HttpRequestOptions - { - CancellationToken = cancellationToken, - Url = source.Path, - Progress = new Progress<double>() - }; - - var channel = GetChannel(item.ChannelId); - var channelProvider = GetChannelProvider(channel); - var features = channelProvider.GetChannelFeatures(); - - if (!features.SupportsContentDownloading) - { - throw new ArgumentException("The channel does not support downloading."); - } - - var limit = features.DailyDownloadLimit; - - foreach (var header in source.RequiredHttpHeaders) - { - options.RequestHeaders[header.Key] = header.Value; - } - - _fileSystem.CreateDirectory(Path.GetDirectoryName(destination)); - - // Determine output extension - var response = await _httpClient.GetTempFileResponse(options).ConfigureAwait(false); - - if (response.ContentType.StartsWith("text/html")) - { - throw new HttpException("File not found") - { - StatusCode = HttpStatusCode.NotFound - }; - } - - if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) - { - var extension = response.ContentType.Split('/') - .Last() - .Replace("quicktime", "mov", StringComparison.OrdinalIgnoreCase); - - destination += "." + extension; - } - else if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) - { - var extension = response.ContentType.Replace("audio/mpeg", "audio/mp3", StringComparison.OrdinalIgnoreCase) - .Split('/') - .Last(); - - destination += "." + extension; - } - else - { - _fileSystem.DeleteFile(response.TempFilePath); - - throw new ApplicationException("Unexpected response type encountered: " + response.ContentType); - } - - _fileSystem.CopyFile(response.TempFilePath, destination, true); - - try - { - _fileSystem.DeleteFile(response.TempFilePath); - } - catch - { - - } - } } }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 47c1d8332..b878226de 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -907,15 +907,6 @@ namespace MediaBrowser.Server.Implementations.Dto dto.Keywords = item.Keywords; } - if (fields.Contains(ItemFields.PlaceOfBirth)) - { - var person = item as Person; - if (person != null) - { - dto.PlaceOfBirth = person.PlaceOfBirth; - } - } - var hasAspectRatio = item as IHasAspectRatio; if (hasAspectRatio != null) { @@ -1432,10 +1423,9 @@ namespace MediaBrowser.Server.Implementations.Dto SetBookProperties(dto, book); } - var movie = item as Movie; - if (movie != null) + if (item.ProductionLocations.Count > 0 || item is Movie) { - dto.ProductionLocations = new string[] { }; + dto.ProductionLocations = item.ProductionLocations.ToArray(); } var photo = item as Photo; diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 405b3114b..b5c8d0107 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp public Container Container { get; set; } private readonly HttpListenerRequest request; private readonly IHttpResponse response; - private IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamProvider _memoryStreamProvider; public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger, IMemoryStreamProvider memoryStreamProvider) { diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index f7661f55b..b2302cf86 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -335,15 +335,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - /// <summary> - /// Updates the item in library cache. - /// </summary> - /// <param name="item">The item.</param> - private void UpdateItemInLibraryCache(BaseItem item) - { - RegisterItem(item); - } - public void RegisterItem(BaseItem item) { if (item == null) @@ -1777,7 +1768,7 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var item in list) { - UpdateItemInLibraryCache(item); + RegisterItem(item); } if (ItemAdded != null) @@ -1818,7 +1809,7 @@ namespace MediaBrowser.Server.Implementations.Library await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false); - UpdateItemInLibraryCache(item); + RegisterItem(item); if (ItemUpdated != null) { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 1a8295800..7f35fc3ea 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -54,8 +54,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio if (!args.IsDirectory) return null; // Avoid mis-identifying top folders - if (args.Parent.IsRoot) return null; if (args.HasParent<MusicAlbum>()) return null; + if (args.Parent.IsRoot) return null; var collectionType = args.GetCollectionType(); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index dadcff877..686105ddb 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -51,9 +51,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio { if (!args.IsDirectory) return null; - // Avoid mis-identifying top folders - if (args.Parent.IsRoot) return null; - // Don't allow nested artists if (args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>()) { @@ -70,12 +67,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return null; } - if (args.IsDirectory) + if (args.ContainsFileSystemEntryByName("artist.nfo")) { - if (args.ContainsFileSystemEntryByName("artist.nfo")) - { - return new MusicArtist(); - } + return new MusicArtist(); } if (_config.Configuration.EnableSimpleArtistDetection) @@ -83,6 +77,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return null; } + // Avoid mis-identifying top folders + if (args.Parent.IsRoot) return null; + var directoryService = args.DirectoryService; var albumResolver = new MusicAlbumResolver(_logger, _fileSystem, _libraryManager); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs index 34237622d..ff07c5282 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs @@ -51,7 +51,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers base.SetInitialItemValues(item, args); item.IsRoot = args.Parent == null; - item.IsPhysicalRoot = args.IsPhysicalRoot; } } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 207486f26..c82825007 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -59,6 +59,15 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV return null; } + if (args.ContainsFileSystemEntryByName("tvshow.nfo")) + { + return new Series + { + Path = args.Path, + Name = Path.GetFileName(args.Path) + }; + } + var collectionType = args.GetCollectionType(); if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) { @@ -72,23 +81,20 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV }; } } - else + else if (string.IsNullOrWhiteSpace(collectionType)) { - if (string.IsNullOrWhiteSpace(collectionType)) + if (args.Parent.IsRoot) { - if (args.Parent.IsRoot) - { - return null; - } - if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false) || - args.ContainsFileSystemEntryByName("tvshow.nfo")) + return null; + } + + if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false)) + { + return new Series { - return new Series - { - Path = args.Path, - Name = Path.GetFileName(args.Path) - }; - } + Path = args.Path, + Name = Path.GetFileName(args.Path) + }; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 23066149a..ee8d40797 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -28,6 +28,7 @@ using System.Threading.Tasks; using System.Xml; using CommonIO; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Configuration; @@ -38,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { public class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNewTimerIds, IDisposable { - private readonly IApplicationHost _appHpst; + private readonly IServerApplicationHost _appHost; private readonly ILogger _logger; private readonly IHttpClient _httpClient; private readonly IServerConfigurationManager _config; @@ -64,11 +65,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings = new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase); - public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder) + public EmbyTV(IServerApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder) { Current = this; - _appHpst = appHost; + _appHost = appHost; _logger = logger; _httpClient = httpClient; _config = config; @@ -293,7 +294,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV status.Tuners = list; status.Status = LiveTvServiceStatus.Ok; - status.Version = _appHpst.ApplicationVersion.ToString(); + status.Version = _appHost.ApplicationVersion.ToString(); status.IsVisible = false; return status; } @@ -659,7 +660,63 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken) { - return new List<RecordingInfo>(); + return _activeRecordings.Values.ToList().Select(GetRecordingInfo).ToList(); + } + + public string GetActiveRecordingPath(string id) + { + ActiveRecordingInfo info; + + if (_activeRecordings.TryGetValue(id, out info)) + { + return info.Path; + } + return null; + } + + private RecordingInfo GetRecordingInfo(ActiveRecordingInfo info) + { + var timer = info.Timer; + var program = info.Program; + + var result = new RecordingInfo + { + ChannelId = timer.ChannelId, + CommunityRating = timer.CommunityRating, + DateLastUpdated = DateTime.UtcNow, + EndDate = timer.EndDate, + EpisodeTitle = timer.EpisodeTitle, + Genres = timer.Genres, + Id = "recording" + timer.Id, + IsKids = timer.IsKids, + IsMovie = timer.IsMovie, + IsNews = timer.IsNews, + IsRepeat = timer.IsRepeat, + IsSeries = timer.IsProgramSeries, + IsSports = timer.IsSports, + Name = timer.Name, + OfficialRating = timer.OfficialRating, + OriginalAirDate = timer.OriginalAirDate, + Overview = timer.Overview, + ProgramId = timer.ProgramId, + SeriesTimerId = timer.SeriesTimerId, + StartDate = timer.StartDate, + Status = RecordingStatus.InProgress, + TimerId = timer.Id + }; + + if (program != null) + { + result.Audio = program.Audio; + result.ImagePath = program.ImagePath; + result.ImageUrl = program.ImageUrl; + result.IsHD = program.IsHD; + result.IsLive = program.IsLive; + result.IsPremiere = program.IsPremiere; + result.ShowId = program.ShowId; + } + + return result; } public Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken) @@ -954,7 +1011,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken) { - throw new NotImplementedException(); + ActiveRecordingInfo info; + + recordingId = recordingId.Replace("recording", string.Empty); + + if (_activeRecordings.TryGetValue(recordingId, out info)) + { + return Task.FromResult(new List<MediaSourceInfo> + { + new MediaSourceInfo + { + Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveRecordings/" + recordingId + "/stream", + Id = recordingId, + SupportsDirectPlay = false, + SupportsDirectStream = true, + SupportsTranscoding = true, + IsInfiniteStream = true, + RequiresOpening = false, + RequiresClosing = false, + Protocol = Model.MediaInfo.MediaProtocol.Http, + BufferMs = 0 + } + }); + } + + throw new FileNotFoundException(); } public async Task CloseLiveStream(string id, CancellationToken cancellationToken) @@ -1031,7 +1112,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var activeRecordingInfo = new ActiveRecordingInfo { CancellationTokenSource = new CancellationTokenSource(), - TimerId = timer.Id + Timer = timer }; if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo)) @@ -1168,6 +1249,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (programInfo != null) { RecordingHelper.CopyProgramInfoToTimerInfo(programInfo, timer); + activeRecordingInfo.Program = programInfo; } string seriesPath = null; @@ -1394,7 +1476,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return true; } - var hasRecordingAtPath = _activeRecordings.Values.ToList().Any(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) && !string.Equals(i.TimerId, timerId, StringComparison.OrdinalIgnoreCase)); + var hasRecordingAtPath = _activeRecordings + .Values + .ToList() + .Any(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) && !string.Equals(i.Timer.Id, timerId, StringComparison.OrdinalIgnoreCase)); if (hasRecordingAtPath) { @@ -1878,7 +1963,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV class ActiveRecordingInfo { public string Path { get; set; } - public string TimerId { get; set; } + public TimerInfo Timer { get; set; } + public ProgramInfo Program { get; set; } public CancellationTokenSource CancellationTokenSource { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 2189cf627..8c46b4597 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -125,6 +126,34 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days); + if (!string.IsNullOrWhiteSpace(info.SeriesId)) + { + var program = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name }, + ExternalSeriesId = info.SeriesId, + Limit = 1, + ImageTypes = new ImageType[] { ImageType.Primary } + + }).FirstOrDefault(); + + if (program != null) + { + var image = program.GetImageInfo(ImageType.Primary, 0); + if (image != null) + { + try + { + dto.ParentPrimaryImageTag = _imageProcessor.GetImageCacheTag(program, image); + dto.ParentPrimaryImageItemId = program.Id.ToString("N"); + } + catch (Exception ex) + { + } + } + } + } + return dto; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 93d8f8ef4..cf441f58e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -235,20 +235,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv return await GetLiveStream(id, mediaSourceId, true, cancellationToken).ConfigureAwait(false); } - public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(string id, CancellationToken cancellationToken) + public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken) { - var item = await GetInternalRecording(id, cancellationToken).ConfigureAwait(false); - var service = GetService(item); + var baseItem = (BaseItem)item; + var service = GetService(baseItem); - return await service.GetRecordingStreamMediaSources(id, cancellationToken).ConfigureAwait(false); + return await service.GetRecordingStreamMediaSources(baseItem.ExternalId, cancellationToken).ConfigureAwait(false); } - public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(string id, CancellationToken cancellationToken) + public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken) { - var item = GetInternalChannel(id); - var service = GetService(item); + var baseItem = (LiveTvChannel)item; + var service = GetService(baseItem); - var sources = await service.GetChannelStreamMediaSources(item.ExternalId, cancellationToken).ConfigureAwait(false); + var sources = await service.GetChannelStreamMediaSources(baseItem.ExternalId, cancellationToken).ConfigureAwait(false); if (sources.Count == 0) { @@ -259,7 +259,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv foreach (var source in list) { - Normalize(source, service, item.ChannelType == ChannelType.TV); + Normalize(source, service, baseItem.ChannelType == ChannelType.TV); } return list; @@ -738,6 +738,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv recording.IsRepeat = info.IsRepeat; recording.IsSports = info.IsSports; recording.SeriesTimerId = info.SeriesTimerId; + recording.TimerId = info.TimerId; recording.StartDate = info.StartDate; if (!dataChanged) @@ -1083,10 +1084,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (timer != null) { - program.TimerId = _tvDtoService.GetInternalTimerId(serviceName, timer.Id) - .ToString("N"); + if (timer.Status != RecordingStatus.Cancelled && timer.Status != RecordingStatus.Error) + { + program.TimerId = _tvDtoService.GetInternalTimerId(serviceName, timer.Id) + .ToString("N"); - program.TimerStatus = timer.Status; + program.Status = timer.Status.ToString(); + } if (!string.IsNullOrEmpty(timer.SeriesTimerId)) { @@ -1432,7 +1436,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv private DateTime _lastRecordingRefreshTime; private async Task RefreshRecordings(CancellationToken cancellationToken) { - const int cacheMinutes = 5; + const int cacheMinutes = 3; if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes) { @@ -1482,7 +1486,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, User user) { - if (user == null || (query.IsInProgress ?? false)) + if (user == null) + { + return new QueryResult<BaseItem>(); + } + + if ((query.IsInProgress ?? false)) { return new QueryResult<BaseItem>(); } @@ -1628,7 +1637,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return new QueryResult<BaseItem>(); } - if (_services.Count == 1) + if (_services.Count == 1 && !(query.IsInProgress ?? false)) { return GetEmbyRecordings(query, new DtoOptions(), user); } @@ -1824,6 +1833,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv ? null : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"); + dto.TimerId = string.IsNullOrEmpty(info.TimerId) + ? null + : _tvDtoService.GetInternalTimerId(service.Name, info.TimerId).ToString("N"); + dto.StartDate = info.StartDate; dto.RecordingStatus = info.Status; dto.IsRepeat = info.IsRepeat; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index ff9b2a143..521f33e1c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -65,12 +65,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv { if (item is ILiveTvRecording) { - sources = await _liveTvManager.GetRecordingMediaSources(item.Id.ToString("N"), cancellationToken) + sources = await _liveTvManager.GetRecordingMediaSources(item, cancellationToken) .ConfigureAwait(false); } else { - sources = await _liveTvManager.GetChannelMediaSources(item.Id.ToString("N"), cancellationToken) + sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken) .ConfigureAwait(false); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 77e2c36e2..1e3ec22fd 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -21,10 +21,13 @@ using System.Threading.Tasks; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Playlists; using MediaBrowser.Model.Dto; using MediaBrowser.Model.LiveTv; +using MediaBrowser.Server.Implementations.Devices; +using MediaBrowser.Server.Implementations.Playlists; namespace MediaBrowser.Server.Implementations.Persistence { @@ -279,6 +282,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "Keywords", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "ProviderIds", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "Images", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "ProductionLocations", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "ThemeSongIds", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "ThemeVideoIds", "Text"); _connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT"); _connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text"); @@ -428,7 +434,10 @@ namespace MediaBrowser.Server.Implementations.Persistence "Tagline", "Keywords", "ProviderIds", - "Images" + "Images", + "ProductionLocations", + "ThemeSongIds", + "ThemeVideoIds" }; private readonly string[] _mediaStreamSaveColumns = @@ -556,7 +565,10 @@ namespace MediaBrowser.Server.Implementations.Persistence "Tagline", "Keywords", "ProviderIds", - "Images" + "Images", + "ProductionLocations", + "ThemeSongIds", + "ThemeVideoIds" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -1007,10 +1019,46 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.ExternalSeriesId; _saveItemCommand.GetParameter(index++).Value = item.ShortOverview; _saveItemCommand.GetParameter(index++).Value = item.Tagline; - _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Keywords.ToArray()); + + if (item.Keywords.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Keywords.ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.GetParameter(index++).Value = SerializeProviderIds(item); _saveItemCommand.GetParameter(index++).Value = SerializeImages(item); + if (item.ProductionLocations.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ProductionLocations.ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + + if (item.ThemeSongIds.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ThemeSongIds.Select(i => i.ToString("N")).ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + + if (item.ThemeVideoIds.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ThemeVideoIds.Select(i => i.ToString("N")).ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -1217,6 +1265,46 @@ namespace MediaBrowser.Server.Implementations.Persistence { return false; } + if (type == typeof(Person)) + { + return false; + } + if (type == typeof(RecordingGroup)) + { + return false; + } + if (type == typeof(Channel)) + { + return false; + } + if (type == typeof(ManualCollectionsFolder)) + { + return false; + } + if (type == typeof(CameraUploadsFolder)) + { + return false; + } + if (type == typeof(PlaylistsFolder)) + { + return false; + } + if (type == typeof(UserRootFolder)) + { + return false; + } + if (type == typeof(PhotoAlbum)) + { + return false; + } + if (type == typeof(Season)) + { + return false; + } + if (type == typeof(MusicArtist)) + { + return false; + } } if (_config.Configuration.SkipDeserializationForPrograms) { @@ -1775,6 +1863,27 @@ namespace MediaBrowser.Server.Implementations.Persistence } index++; + if (query.HasField(ItemFields.ProductionLocations)) + { + if (!reader.IsDBNull(index)) + { + item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + } + index++; + } + + if (!reader.IsDBNull(index)) + { + item.ThemeSongIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList(); + } + index++; + + if (!reader.IsDBNull(index)) + { + item.ThemeVideoIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList(); + } + index++; + if (string.IsNullOrWhiteSpace(item.Tagline)) { var movie = item as Movie; @@ -1784,6 +1893,15 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + if (type == typeof(Person) && item.ProductionLocations.Count == 0) + { + var person = (Person)item; + if (!string.IsNullOrWhiteSpace(person.PlaceOfBirth)) + { + item.ProductionLocations = new List<string> { person.PlaceOfBirth }; + } + } + return item; } |
