diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index 6d600c646b..55c6f6455e 100644
--- a/Emby.Drawing/ImageProcessor.cs
+++ b/Emby.Drawing/ImageProcessor.cs
@@ -158,22 +158,19 @@ namespace Emby.Drawing
}
var dateModified = options.Image.DateModified;
- var length = options.Image.Length;
if (options.CropWhiteSpace)
{
- var tuple = await GetWhitespaceCroppedImage(originalImagePath, dateModified, length).ConfigureAwait(false);
+ var tuple = await GetWhitespaceCroppedImage(originalImagePath, dateModified).ConfigureAwait(false);
originalImagePath = tuple.Item1;
dateModified = tuple.Item2;
- length = tuple.Item3;
}
if (options.Enhancers.Count > 0)
{
var tuple = await GetEnhancedImage(new ItemImageInfo
{
- Length = length,
DateModified = dateModified,
Type = options.Image.Type,
Path = originalImagePath
@@ -182,7 +179,6 @@ namespace Emby.Drawing
originalImagePath = tuple.Item1;
dateModified = tuple.Item2;
- length = tuple.Item3;
}
var originalImageSize = GetImageSize(originalImagePath, dateModified);
@@ -199,7 +195,7 @@ namespace Emby.Drawing
var quality = options.Quality ?? 90;
var outputFormat = GetOutputFormat(options.OutputFormat);
- var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, length, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor);
+ var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor);
var semaphore = GetLock(cacheFilePath);
@@ -240,11 +236,10 @@ namespace Emby.Drawing
///
/// Crops whitespace from an image, caches the result, and returns the cached path
///
- private async Task> GetWhitespaceCroppedImage(string originalImagePath, DateTime dateModified, long length)
+ private async Task> GetWhitespaceCroppedImage(string originalImagePath, DateTime dateModified)
{
var name = originalImagePath;
name += "datemodified=" + dateModified.Ticks;
- name += "length=" + length;
var croppedImagePath = GetCachePath(CroppedWhitespaceImageCachePath, name, Path.GetExtension(originalImagePath));
@@ -270,7 +265,7 @@ namespace Emby.Drawing
// We have to have a catch-all here because some of the .net image methods throw a plain old Exception
_logger.ErrorException("Error cropping image {0}", ex, originalImagePath);
- return new Tuple(originalImagePath, dateModified, length);
+ return new Tuple(originalImagePath, dateModified);
}
finally
{
@@ -280,11 +275,9 @@ namespace Emby.Drawing
return GetResult(croppedImagePath);
}
- private Tuple GetResult(string path)
+ private Tuple GetResult(string path)
{
- var file = new FileInfo(path);
-
- return new Tuple(path, _fileSystem.GetLastWriteTimeUtc(file), file.Length);
+ return new Tuple(path, _fileSystem.GetLastWriteTimeUtc(path));
}
///
@@ -295,7 +288,7 @@ namespace Emby.Drawing
///
/// Gets the cache file path based on a set of parameters
///
- private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, long length, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor)
+ private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor)
{
var filename = originalPath;
@@ -306,7 +299,6 @@ namespace Emby.Drawing
filename += "quality=" + quality;
filename += "datemodified=" + dateModified.Ticks;
- filename += "length=" + length;
filename += "f=" + format;
@@ -492,17 +484,16 @@ namespace Emby.Drawing
var originalImagePath = image.Path;
var dateModified = image.DateModified;
var imageType = image.Type;
- var length = image.Length;
// Optimization
if (imageEnhancers.Count == 0)
{
- return (originalImagePath + dateModified.Ticks + string.Empty + length).GetMD5().ToString("N");
+ return (originalImagePath + dateModified.Ticks).GetMD5().ToString("N");
}
// Cache name is created with supported enhancers combined with the last config change so we pick up new config changes
var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList();
- cacheKeys.Add(originalImagePath + dateModified.Ticks + string.Empty + length);
+ cacheKeys.Add(originalImagePath + dateModified.Ticks);
return string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N");
}
@@ -525,7 +516,7 @@ namespace Emby.Drawing
return result.Item1;
}
- private async Task> GetEnhancedImage(ItemImageInfo image,
+ private async Task> GetEnhancedImage(ItemImageInfo image,
IHasImages item,
int imageIndex,
List enhancers)
@@ -533,7 +524,6 @@ namespace Emby.Drawing
var originalImagePath = image.Path;
var dateModified = image.DateModified;
var imageType = image.Type;
- var length = image.Length;
try
{
@@ -553,7 +543,7 @@ namespace Emby.Drawing
_logger.Error("Error enhancing image", ex);
}
- return new Tuple(originalImagePath, dateModified, length);
+ return new Tuple(originalImagePath, dateModified);
}
///
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index 26d3c6200f..f59b1b7df2 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -341,14 +341,17 @@ namespace MediaBrowser.Api
timerDuration = 60000;
}
+ job.PingTimeout = timerDuration;
+ job.LastPingDate = DateTime.UtcNow;
+
// Don't start the timer for playback checkins with progressive streaming
if (job.Type != TranscodingJobType.Progressive || !isProgressCheckIn)
{
- job.StartKillTimer(timerDuration, OnTranscodeKillTimerStopped);
+ job.StartKillTimer(OnTranscodeKillTimerStopped);
}
else
{
- job.ChangeKillTimerIfStarted(timerDuration);
+ job.ChangeKillTimerIfStarted();
}
}
@@ -360,6 +363,15 @@ namespace MediaBrowser.Api
{
var job = (TranscodingJob)state;
+ if (!job.HasExited && job.Type != TranscodingJobType.Progressive)
+ {
+ if ((DateTime.UtcNow - job.LastPingDate).TotalMilliseconds < job.PingTimeout)
+ {
+ job.StartKillTimer(OnTranscodeKillTimerStopped);
+ return;
+ }
+ }
+
Logger.Debug("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId);
KillTranscodingJob(job, path => true);
@@ -626,6 +638,9 @@ namespace MediaBrowser.Api
private readonly object _timerLock = new object();
+ public DateTime LastPingDate { get; set; }
+ public int PingTimeout { get; set; }
+
public TranscodingJob(ILogger logger)
{
Logger = logger;
@@ -654,12 +669,14 @@ namespace MediaBrowser.Api
}
}
- public void StartKillTimer(int intervalMs, TimerCallback callback)
+ public void StartKillTimer(TimerCallback callback)
{
CheckHasExited();
lock (_timerLock)
{
+ var intervalMs = PingTimeout;
+
if (KillTimer == null)
{
Logger.Debug("Starting kill timer at {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
@@ -673,7 +690,7 @@ namespace MediaBrowser.Api
}
}
- public void ChangeKillTimerIfStarted(int intervalMs)
+ public void ChangeKillTimerIfStarted()
{
CheckHasExited();
@@ -681,6 +698,8 @@ namespace MediaBrowser.Api
{
if (KillTimer != null)
{
+ var intervalMs = PingTimeout;
+
Logger.Debug("Changing kill timer to {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
KillTimer.Change(intervalMs, Timeout.Infinite);
}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 73ede8179b..22efd3fba7 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -1512,7 +1512,6 @@ namespace MediaBrowser.Controller.Entities
image.Path = file.FullName;
image.DateModified = imageInfo.DateModified;
- image.Length = imageInfo.Length;
}
}
@@ -1622,14 +1621,11 @@ namespace MediaBrowser.Controller.Entities
return null;
}
- var fileInfo = new FileInfo(path);
-
return new ItemImageInfo
{
Path = path,
- DateModified = FileSystem.GetLastWriteTimeUtc(fileInfo),
- Type = imageType,
- Length = fileInfo.Length
+ DateModified = FileSystem.GetLastWriteTimeUtc(path),
+ Type = imageType
};
}
@@ -1690,7 +1686,6 @@ namespace MediaBrowser.Controller.Entities
else
{
existing.DateModified = FileSystem.GetLastWriteTimeUtc(newImage);
- existing.Length = ((FileInfo)newImage).Length;
}
}
@@ -1716,8 +1711,7 @@ namespace MediaBrowser.Controller.Entities
{
Path = file.FullName,
Type = type,
- DateModified = FileSystem.GetLastWriteTimeUtc(file),
- Length = ((FileInfo)file).Length
+ DateModified = FileSystem.GetLastWriteTimeUtc(file)
};
}
@@ -1756,15 +1750,9 @@ namespace MediaBrowser.Controller.Entities
FileSystem.SwapFiles(path1, path2);
- var file1 = new FileInfo(info1.Path);
- var file2 = new FileInfo(info2.Path);
-
// Refresh these values
- info1.DateModified = FileSystem.GetLastWriteTimeUtc(file1);
- info2.DateModified = FileSystem.GetLastWriteTimeUtc(file2);
-
- info1.Length = file1.Length;
- info2.Length = file2.Length;
+ info1.DateModified = FileSystem.GetLastWriteTimeUtc(info1.Path);
+ info2.DateModified = FileSystem.GetLastWriteTimeUtc(info2.Path);
return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
}
diff --git a/MediaBrowser.Controller/Entities/ItemImageInfo.cs b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
index 1122de4032..b36b818ffe 100644
--- a/MediaBrowser.Controller/Entities/ItemImageInfo.cs
+++ b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
@@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Entities
/// The path.
public string Path { get; set; }
- ///
- /// Gets or sets the length.
- ///
- /// The length.
- public long Length { get; set; }
-
///
/// Gets or sets the type.
///
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index a3b5691500..fc47b0259a 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -384,7 +384,6 @@ namespace MediaBrowser.Providers.Manager
else
{
currentImage.DateModified = _fileSystem.GetLastWriteTimeUtc(image.FileInfo);
- currentImage.Length = ((FileInfo) image.FileInfo).Length;
}
}
else
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index 190b8fcf4c..f44b7b5a84 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -828,14 +828,11 @@ namespace MediaBrowser.Server.Implementations.Dto
if (!string.IsNullOrEmpty(chapterInfo.ImagePath))
{
- var file = new FileInfo(chapterInfo.ImagePath);
-
dto.ImageTag = GetImageCacheTag(item, new ItemImageInfo
{
Path = chapterInfo.ImagePath,
Type = ImageType.Chapter,
- DateModified = _fileSystem.GetLastWriteTimeUtc(file),
- Length = file.Length
+ DateModified = _fileSystem.GetLastWriteTimeUtc(chapterInfo.ImagePath)
});
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
index a21b19e04c..823599fe51 100644
--- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
@@ -202,9 +202,15 @@ namespace MediaBrowser.Server.Implementations.Library
public async Task GetUserView(List parents, string viewType, string sortName, User user, CancellationToken cancellationToken)
{
+ var name = _localizationManager.GetLocalizedString("ViewType" + viewType);
+
if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase)))
{
- var name = parents[0].Name;
+ if (!string.IsNullOrWhiteSpace(parents[0].Name))
+ {
+ name = parents[0].Name;
+ }
+
var parentId = parents[0].Id;
var enableRichView = !user.Configuration.PlainFolderViews.Contains(parentId.ToString("N"), StringComparer.OrdinalIgnoreCase);
@@ -226,8 +232,6 @@ namespace MediaBrowser.Server.Implementations.Library
}
else
{
- var name = _localizationManager.GetLocalizedString("ViewType" + viewType);
-
return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index 84b4053a19..38c93a6964 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -122,7 +122,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private async Task AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken)
{
- var inputPaths = new[] { mediaSource.Path };
+ var originalRuntime = mediaSource.RunTimeTicks;
var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
{
@@ -131,8 +131,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
ExtractChapters = false
- }, cancellationToken)
- .ConfigureAwait(false);
+ }, cancellationToken).ConfigureAwait(false);
mediaSource.Bitrate = info.Bitrate;
mediaSource.Container = info.Container;
@@ -146,6 +145,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
mediaSource.DefaultSubtitleStreamIndex = null;
+ // Null this out so that it will be treated like a live stream
+ if (!originalRuntime.HasValue)
+ {
+ mediaSource.RunTimeTicks = null;
+ }
+
var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Audio);
if (audioStream == null || audioStream.Index == -1)