aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-09 03:18:43 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-09 03:18:43 -0400
commitdaaae69df575f1d7692ba29d6f5ddd4c59516f82 (patch)
tree24c818ece042d36808fd0a68834b2853bf4512e1 /MediaBrowser.Server.Implementations
parentb3595eab6a94fda4f81f637007b2ac79e8a85065 (diff)
add playback of in-progress recordings
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelManager.cs92
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs14
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs13
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs13
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs1
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs34
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs104
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs29
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs43
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs124
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;
}