improve live tv direct play
This commit is contained in:
parent
2d63bdea94
commit
164e7dc896
|
@ -792,6 +792,11 @@ namespace Emby.Server.Implementations
|
||||||
|
|
||||||
protected abstract IConnectManager CreateConnectManager();
|
protected abstract IConnectManager CreateConnectManager();
|
||||||
protected abstract ISyncManager CreateSyncManager();
|
protected abstract ISyncManager CreateSyncManager();
|
||||||
|
|
||||||
|
protected virtual IHttpClient CreateHttpClient()
|
||||||
|
{
|
||||||
|
return new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamFactory, GetDefaultUserAgent);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers resources that classes will depend on
|
/// Registers resources that classes will depend on
|
||||||
|
@ -814,7 +819,7 @@ namespace Emby.Server.Implementations
|
||||||
|
|
||||||
RegisterSingleInstance(FileSystemManager);
|
RegisterSingleInstance(FileSystemManager);
|
||||||
|
|
||||||
HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, LogManager.GetLogger("HttpClient"), FileSystemManager, MemoryStreamFactory, GetDefaultUserAgent);
|
HttpClient = CreateHttpClient();
|
||||||
RegisterSingleInstance(HttpClient);
|
RegisterSingleInstance(HttpClient);
|
||||||
|
|
||||||
RegisterSingleInstance(NetworkManager);
|
RegisterSingleInstance(NetworkManager);
|
||||||
|
@ -1118,7 +1123,7 @@ namespace Emby.Server.Implementations
|
||||||
IsoManager.AddParts(list);
|
IsoManager.AddParts(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetDefaultUserAgent()
|
protected string GetDefaultUserAgent()
|
||||||
{
|
{
|
||||||
var name = FormatAttribute(Name);
|
var name = FormatAttribute(Name);
|
||||||
|
|
||||||
|
|
|
@ -72,10 +72,18 @@ namespace Emby.Server.Implementations.Devices
|
||||||
|
|
||||||
private void MigrateDevices()
|
private void MigrateDevices()
|
||||||
{
|
{
|
||||||
var files = FileSystem
|
List<string> files;
|
||||||
.GetFilePaths(GetDevicesPath(), true)
|
try
|
||||||
.Where(i => string.Equals(Path.GetFileName(i), "device.json", StringComparison.OrdinalIgnoreCase))
|
{
|
||||||
.ToList();
|
files = FileSystem
|
||||||
|
.GetFilePaths(GetDevicesPath(), true)
|
||||||
|
.Where(i => string.Equals(Path.GetFileName(i), "device.json", StringComparison.OrdinalIgnoreCase))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.HttpClientManager
|
namespace Emby.Server.Implementations.HttpClientManager
|
||||||
{
|
{
|
||||||
|
@ -12,5 +13,6 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The last timeout.</value>
|
/// <value>The last timeout.</value>
|
||||||
public DateTime LastTimeout { get; set; }
|
public DateTime LastTimeout { get; set; }
|
||||||
|
public HttpClient HttpClient { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
private readonly IHttpClient _httpClient;
|
private readonly IHttpClient _httpClient;
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
|
||||||
private readonly CancellationTokenSource _liveStreamCancellationTokenSource = new CancellationTokenSource();
|
|
||||||
private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
|
private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
public HdHomerunHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
|
public HdHomerunHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
|
||||||
|
@ -35,7 +34,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
|
|
||||||
protected override Task OpenInternal(CancellationToken openCancellationToken)
|
protected override Task OpenInternal(CancellationToken openCancellationToken)
|
||||||
{
|
{
|
||||||
_liveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested();
|
LiveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var mediaSource = OriginalMediaSource;
|
var mediaSource = OriginalMediaSource;
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
|
|
||||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
StartStreaming(url, taskCompletionSource, _liveStreamCancellationTokenSource.Token);
|
StartStreaming(url, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
|
||||||
|
|
||||||
//OpenedMediaSource.Protocol = MediaProtocol.File;
|
//OpenedMediaSource.Protocol = MediaProtocol.File;
|
||||||
//OpenedMediaSource.Path = tempFile;
|
//OpenedMediaSource.Path = tempFile;
|
||||||
|
@ -65,12 +64,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
//await Task.Delay(5000).ConfigureAwait(false);
|
//await Task.Delay(5000).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task Close()
|
public override async Task Close()
|
||||||
{
|
{
|
||||||
Logger.Info("Closing HDHR live stream");
|
Logger.Info("Closing HDHR live stream");
|
||||||
_liveStreamCancellationTokenSource.Cancel();
|
LiveStreamCancellationTokenSource.Cancel();
|
||||||
|
|
||||||
return _liveStreamTaskCompletionSource.Task;
|
await _liveStreamTaskCompletionSource.Task.ConfigureAwait(false);
|
||||||
|
await DeleteTempFile(TempFilePath).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task StartStreaming(string url, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
|
private Task StartStreaming(string url, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
|
||||||
|
@ -112,7 +112,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
}
|
}
|
||||||
|
|
||||||
_liveStreamTaskCompletionSource.TrySetResult(true);
|
_liveStreamTaskCompletionSource.TrySetResult(true);
|
||||||
await DeleteTempFile(TempFilePath).ConfigureAwait(false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
private readonly ISocketFactory _socketFactory;
|
private readonly ISocketFactory _socketFactory;
|
||||||
|
|
||||||
private readonly CancellationTokenSource _liveStreamCancellationTokenSource = new CancellationTokenSource();
|
|
||||||
private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
|
private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
private readonly IHdHomerunChannelCommands _channelCommands;
|
private readonly IHdHomerunChannelCommands _channelCommands;
|
||||||
private readonly int _numTuners;
|
private readonly int _numTuners;
|
||||||
|
@ -45,7 +44,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
|
|
||||||
protected override Task OpenInternal(CancellationToken openCancellationToken)
|
protected override Task OpenInternal(CancellationToken openCancellationToken)
|
||||||
{
|
{
|
||||||
_liveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested();
|
LiveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var mediaSource = OriginalMediaSource;
|
var mediaSource = OriginalMediaSource;
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
|
|
||||||
var taskCompletionSource = new TaskCompletionSource<bool>();
|
var taskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
StartStreaming(uri.Host, localPort, taskCompletionSource, _liveStreamCancellationTokenSource.Token);
|
StartStreaming(uri.Host, localPort, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
|
||||||
|
|
||||||
//OpenedMediaSource.Protocol = MediaProtocol.File;
|
//OpenedMediaSource.Protocol = MediaProtocol.File;
|
||||||
//OpenedMediaSource.Path = tempFile;
|
//OpenedMediaSource.Path = tempFile;
|
||||||
|
@ -76,7 +75,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
public override Task Close()
|
public override Task Close()
|
||||||
{
|
{
|
||||||
Logger.Info("Closing HDHR UDP live stream");
|
Logger.Info("Closing HDHR UDP live stream");
|
||||||
_liveStreamCancellationTokenSource.Cancel();
|
LiveStreamCancellationTokenSource.Cancel();
|
||||||
|
|
||||||
return _liveStreamTaskCompletionSource.Task;
|
return _liveStreamTaskCompletionSource.Task;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
|
|
||||||
protected readonly string TempFilePath;
|
protected readonly string TempFilePath;
|
||||||
protected readonly ILogger Logger;
|
protected readonly ILogger Logger;
|
||||||
|
protected readonly CancellationTokenSource LiveStreamCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
public LiveStream(MediaSourceInfo mediaSource, IEnvironmentInfo environment, IFileSystem fileSystem, ILogger logger, IServerApplicationPaths appPaths)
|
public LiveStream(MediaSourceInfo mediaSource, IEnvironmentInfo environment, IFileSystem fileSystem, ILogger logger, IServerApplicationPaths appPaths)
|
||||||
{
|
{
|
||||||
|
@ -80,6 +81,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
FileSystem.DeleteFile(path);
|
FileSystem.DeleteFile(path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
catch (DirectoryNotFoundException)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -96,6 +105,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
|
|
||||||
public async Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
|
public async Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, LiveStreamCancellationTokenSource.Token).Token;
|
||||||
|
|
||||||
var allowAsync = false;//Environment.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows;
|
var allowAsync = false;//Environment.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows;
|
||||||
// use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
|
// use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
|
||||||
|
|
||||||
|
@ -110,16 +121,27 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
private static async Task CopyTo(Stream source, Stream destination, int bufferSize, Action onStarted, CancellationToken cancellationToken)
|
private static async Task CopyTo(Stream source, Stream destination, int bufferSize, Action onStarted, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[bufferSize];
|
byte[] buffer = new byte[bufferSize];
|
||||||
while (true)
|
|
||||||
|
var eofCount = 0;
|
||||||
|
var emptyReadLimit = 1000;
|
||||||
|
|
||||||
|
while (eofCount < emptyReadLimit)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var read = source.Read(buffer, 0, buffer.Length);
|
var bytesRead = source.Read(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
if (read > 0)
|
if (bytesRead == 0)
|
||||||
{
|
{
|
||||||
|
eofCount++;
|
||||||
|
await Task.Delay(10, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eofCount = 0;
|
||||||
|
|
||||||
//await destination.WriteAsync(buffer, 0, read).ConfigureAwait(false);
|
//await destination.WriteAsync(buffer, 0, read).ConfigureAwait(false);
|
||||||
destination.Write(buffer, 0, read);
|
destination.Write(buffer, 0, bytesRead);
|
||||||
|
|
||||||
if (onStarted != null)
|
if (onStarted != null)
|
||||||
{
|
{
|
||||||
|
@ -127,10 +149,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
onStarted = null;
|
onStarted = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
await Task.Delay(10).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -734,7 +734,7 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
|
|
||||||
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path);
|
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path);
|
||||||
|
|
||||||
return new ProgressiveFileCopier(_fileSystem, path, outputHeaders, Logger, _environment, CancellationToken.None)
|
return new ProgressiveFileCopier(_fileSystem, path, outputHeaders, Logger, _environment)
|
||||||
{
|
{
|
||||||
AllowEndOfFile = false
|
AllowEndOfFile = false
|
||||||
};
|
};
|
||||||
|
@ -753,7 +753,7 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
|
|
||||||
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container);
|
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container);
|
||||||
|
|
||||||
return new ProgressiveFileCopier(directStreamProvider, outputHeaders, Logger, _environment, CancellationToken.None)
|
return new ProgressiveFileCopier(directStreamProvider, outputHeaders, Logger, _environment)
|
||||||
{
|
{
|
||||||
AllowEndOfFile = false
|
AllowEndOfFile = false
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,6 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly string _path;
|
private readonly string _path;
|
||||||
private readonly CancellationToken _cancellationToken;
|
|
||||||
private readonly Dictionary<string, string> _outputHeaders;
|
private readonly Dictionary<string, string> _outputHeaders;
|
||||||
|
|
||||||
const int StreamCopyToBufferSize = 81920;
|
const int StreamCopyToBufferSize = 81920;
|
||||||
|
@ -28,22 +27,20 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
private readonly IDirectStreamProvider _directStreamProvider;
|
private readonly IDirectStreamProvider _directStreamProvider;
|
||||||
private readonly IEnvironmentInfo _environment;
|
private readonly IEnvironmentInfo _environment;
|
||||||
|
|
||||||
public ProgressiveFileCopier(IFileSystem fileSystem, string path, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment, CancellationToken cancellationToken)
|
public ProgressiveFileCopier(IFileSystem fileSystem, string path, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment)
|
||||||
{
|
{
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_path = path;
|
_path = path;
|
||||||
_outputHeaders = outputHeaders;
|
_outputHeaders = outputHeaders;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_cancellationToken = cancellationToken;
|
|
||||||
_environment = environment;
|
_environment = environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProgressiveFileCopier(IDirectStreamProvider directStreamProvider, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment, CancellationToken cancellationToken)
|
public ProgressiveFileCopier(IDirectStreamProvider directStreamProvider, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment)
|
||||||
{
|
{
|
||||||
_directStreamProvider = directStreamProvider;
|
_directStreamProvider = directStreamProvider;
|
||||||
_outputHeaders = outputHeaders;
|
_outputHeaders = outputHeaders;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_cancellationToken = cancellationToken;
|
|
||||||
_environment = environment;
|
_environment = environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,8 +66,6 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
|
|
||||||
public async Task WriteToAsync(Stream outputStream, CancellationToken cancellationToken)
|
public async Task WriteToAsync(Stream outputStream, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _cancellationToken).Token;
|
|
||||||
|
|
||||||
if (_directStreamProvider != null)
|
if (_directStreamProvider != null)
|
||||||
{
|
{
|
||||||
await _directStreamProvider.CopyToAsync(outputStream, cancellationToken).ConfigureAwait(false);
|
await _directStreamProvider.CopyToAsync(outputStream, cancellationToken).ConfigureAwait(false);
|
||||||
|
@ -89,7 +84,9 @@ namespace MediaBrowser.Api.LiveTv
|
||||||
inputStream.Position = StartPosition;
|
inputStream.Position = StartPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (eofCount < 20 || !AllowEndOfFile)
|
var emptyReadLimit = AllowEndOfFile ? 20 : 100;
|
||||||
|
|
||||||
|
while (eofCount < emptyReadLimit)
|
||||||
{
|
{
|
||||||
int bytesRead;
|
int bytesRead;
|
||||||
if (allowAsyncFileRead)
|
if (allowAsyncFileRead)
|
||||||
|
|
|
@ -13,6 +13,7 @@ using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Providers;
|
using MediaBrowser.Model.Providers;
|
||||||
|
using MediaBrowser.Providers.MediaInfo;
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Manager
|
namespace MediaBrowser.Providers.Manager
|
||||||
{
|
{
|
||||||
|
@ -37,6 +38,28 @@ namespace MediaBrowser.Providers.Manager
|
||||||
LibraryManager = libraryManager;
|
LibraryManager = libraryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool RequiresRefresh(IHasMetadata item, IDirectoryService directoryService)
|
||||||
|
{
|
||||||
|
if (item.RequiresRefresh())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.SupportsLocalMetadata)
|
||||||
|
{
|
||||||
|
var video = item as Video;
|
||||||
|
|
||||||
|
if (video != null && !video.IsPlaceHolder)
|
||||||
|
{
|
||||||
|
return !video.SubtitleFiles
|
||||||
|
.SequenceEqual(SubtitleResolver.GetSubtitleFiles(video, directoryService, FileSystem, false)
|
||||||
|
.OrderBy(i => i), StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<ItemUpdateType> RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
|
public async Task<ItemUpdateType> RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var itemOfType = (TItemType)item;
|
var itemOfType = (TItemType)item;
|
||||||
|
@ -47,19 +70,35 @@ namespace MediaBrowser.Providers.Manager
|
||||||
|
|
||||||
var libraryOptions = LibraryManager.GetLibraryOptions((BaseItem)item);
|
var libraryOptions = LibraryManager.GetLibraryOptions((BaseItem)item);
|
||||||
|
|
||||||
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
|
DateTime? newDateModified = null;
|
||||||
|
if (item.LocationType == LocationType.FileSystem)
|
||||||
{
|
{
|
||||||
// TODO: If this returns true, should we instead just change metadata refresh mode to Full?
|
var file = refreshOptions.DirectoryService.GetFile(item.Path);
|
||||||
requiresRefresh = item.RequiresRefresh();
|
if (file != null)
|
||||||
|
{
|
||||||
|
newDateModified = file.LastWriteTimeUtc;
|
||||||
|
if (item.EnableRefreshOnDateModifiedChange)
|
||||||
|
{
|
||||||
|
if (newDateModified != item.DateModified)
|
||||||
|
{
|
||||||
|
Logger.Debug("Date modified for {0}. Old date {1} new date {2} Id {3}", item.Path, item.DateModified, newDateModified, item.Id);
|
||||||
|
requiresRefresh = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!requiresRefresh &&
|
if (!requiresRefresh && libraryOptions.AutomaticRefreshIntervalDays > 0 && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= libraryOptions.AutomaticRefreshIntervalDays)
|
||||||
libraryOptions.AutomaticRefreshIntervalDays > 0 &&
|
|
||||||
(DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= libraryOptions.AutomaticRefreshIntervalDays)
|
|
||||||
{
|
{
|
||||||
requiresRefresh = true;
|
requiresRefresh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!requiresRefresh && refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
|
||||||
|
{
|
||||||
|
// TODO: If this returns true, should we instead just change metadata refresh mode to Full?
|
||||||
|
requiresRefresh = RequiresRefresh(item, refreshOptions.DirectoryService);
|
||||||
|
}
|
||||||
|
|
||||||
var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem);
|
var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem);
|
||||||
var localImagesFailed = false;
|
var localImagesFailed = false;
|
||||||
|
|
||||||
|
@ -145,20 +184,9 @@ namespace MediaBrowser.Providers.Manager
|
||||||
var beforeSaveResult = BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh, updateType);
|
var beforeSaveResult = BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh, updateType);
|
||||||
updateType = updateType | beforeSaveResult;
|
updateType = updateType | beforeSaveResult;
|
||||||
|
|
||||||
if (item.LocationType == LocationType.FileSystem)
|
if (newDateModified.HasValue)
|
||||||
{
|
{
|
||||||
var file = refreshOptions.DirectoryService.GetFile(item.Path);
|
item.DateModified = newDateModified.Value;
|
||||||
if (file != null)
|
|
||||||
{
|
|
||||||
var fileLastWriteTime = file.LastWriteTimeUtc;
|
|
||||||
if (item.EnableRefreshOnDateModifiedChange && fileLastWriteTime != item.DateModified)
|
|
||||||
{
|
|
||||||
Logger.Debug("Date modified for {0}. Old date {1} new date {2} Id {3}", item.Path, item.DateModified, fileLastWriteTime, item.Id);
|
|
||||||
requiresRefresh = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
item.DateModified = fileLastWriteTime;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save if changes were made, or it's never been saved before
|
// Save if changes were made, or it's never been saved before
|
||||||
|
|
|
@ -350,8 +350,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
|
|
||||||
foreach (var episodeToRemove in episodesToRemove.Select(e => e.Episode))
|
foreach (var episodeToRemove in episodesToRemove.Select(e => e.Episode))
|
||||||
{
|
{
|
||||||
_logger.Info("Removing missing/unaired episode {0} {1}x{2}", episodeToRemove.Series.Name, episodeToRemove.ParentIndexNumber, episodeToRemove.IndexNumber);
|
|
||||||
|
|
||||||
await episodeToRemove.Delete(new DeleteOptions
|
await episodeToRemove.Delete(new DeleteOptions
|
||||||
{
|
{
|
||||||
DeleteFileLocation = true
|
DeleteFileLocation = true
|
||||||
|
@ -418,8 +416,6 @@ namespace MediaBrowser.Providers.TV
|
||||||
|
|
||||||
foreach (var seasonToRemove in seasonsToRemove)
|
foreach (var seasonToRemove in seasonsToRemove)
|
||||||
{
|
{
|
||||||
_logger.Info("Removing virtual season {0} {1}", seasonToRemove.Series.Name, seasonToRemove.IndexNumber);
|
|
||||||
|
|
||||||
await seasonToRemove.Delete(new DeleteOptions
|
await seasonToRemove.Delete(new DeleteOptions
|
||||||
{
|
{
|
||||||
DeleteFileLocation = true
|
DeleteFileLocation = true
|
||||||
|
|
Loading…
Reference in New Issue
Block a user