live tv fixes

pull/702/head
Luke Pulverenti 10 years ago
parent 37f22e67f9
commit 9e0c73ef19

@ -158,22 +158,19 @@ namespace Emby.Drawing
} }
var dateModified = options.Image.DateModified; var dateModified = options.Image.DateModified;
var length = options.Image.Length;
if (options.CropWhiteSpace) if (options.CropWhiteSpace)
{ {
var tuple = await GetWhitespaceCroppedImage(originalImagePath, dateModified, length).ConfigureAwait(false); var tuple = await GetWhitespaceCroppedImage(originalImagePath, dateModified).ConfigureAwait(false);
originalImagePath = tuple.Item1; originalImagePath = tuple.Item1;
dateModified = tuple.Item2; dateModified = tuple.Item2;
length = tuple.Item3;
} }
if (options.Enhancers.Count > 0) if (options.Enhancers.Count > 0)
{ {
var tuple = await GetEnhancedImage(new ItemImageInfo var tuple = await GetEnhancedImage(new ItemImageInfo
{ {
Length = length,
DateModified = dateModified, DateModified = dateModified,
Type = options.Image.Type, Type = options.Image.Type,
Path = originalImagePath Path = originalImagePath
@ -182,7 +179,6 @@ namespace Emby.Drawing
originalImagePath = tuple.Item1; originalImagePath = tuple.Item1;
dateModified = tuple.Item2; dateModified = tuple.Item2;
length = tuple.Item3;
} }
var originalImageSize = GetImageSize(originalImagePath, dateModified); var originalImageSize = GetImageSize(originalImagePath, dateModified);
@ -199,7 +195,7 @@ namespace Emby.Drawing
var quality = options.Quality ?? 90; var quality = options.Quality ?? 90;
var outputFormat = GetOutputFormat(options.OutputFormat); 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); var semaphore = GetLock(cacheFilePath);
@ -240,11 +236,10 @@ namespace Emby.Drawing
/// <summary> /// <summary>
/// Crops whitespace from an image, caches the result, and returns the cached path /// Crops whitespace from an image, caches the result, and returns the cached path
/// </summary> /// </summary>
private async Task<Tuple<string, DateTime, long>> GetWhitespaceCroppedImage(string originalImagePath, DateTime dateModified, long length) private async Task<Tuple<string, DateTime>> GetWhitespaceCroppedImage(string originalImagePath, DateTime dateModified)
{ {
var name = originalImagePath; var name = originalImagePath;
name += "datemodified=" + dateModified.Ticks; name += "datemodified=" + dateModified.Ticks;
name += "length=" + length;
var croppedImagePath = GetCachePath(CroppedWhitespaceImageCachePath, name, Path.GetExtension(originalImagePath)); 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 // 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); _logger.ErrorException("Error cropping image {0}", ex, originalImagePath);
return new Tuple<string, DateTime, long>(originalImagePath, dateModified, length); return new Tuple<string, DateTime>(originalImagePath, dateModified);
} }
finally finally
{ {
@ -280,11 +275,9 @@ namespace Emby.Drawing
return GetResult(croppedImagePath); return GetResult(croppedImagePath);
} }
private Tuple<string, DateTime, long> GetResult(string path) private Tuple<string, DateTime> GetResult(string path)
{ {
var file = new FileInfo(path); return new Tuple<string, DateTime>(path, _fileSystem.GetLastWriteTimeUtc(path));
return new Tuple<string, DateTime, long>(path, _fileSystem.GetLastWriteTimeUtc(file), file.Length);
} }
/// <summary> /// <summary>
@ -295,7 +288,7 @@ namespace Emby.Drawing
/// <summary> /// <summary>
/// Gets the cache file path based on a set of parameters /// Gets the cache file path based on a set of parameters
/// </summary> /// </summary>
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; var filename = originalPath;
@ -306,7 +299,6 @@ namespace Emby.Drawing
filename += "quality=" + quality; filename += "quality=" + quality;
filename += "datemodified=" + dateModified.Ticks; filename += "datemodified=" + dateModified.Ticks;
filename += "length=" + length;
filename += "f=" + format; filename += "f=" + format;
@ -492,17 +484,16 @@ namespace Emby.Drawing
var originalImagePath = image.Path; var originalImagePath = image.Path;
var dateModified = image.DateModified; var dateModified = image.DateModified;
var imageType = image.Type; var imageType = image.Type;
var length = image.Length;
// Optimization // Optimization
if (imageEnhancers.Count == 0) 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 // 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(); 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"); return string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N");
} }
@ -525,7 +516,7 @@ namespace Emby.Drawing
return result.Item1; return result.Item1;
} }
private async Task<Tuple<string, DateTime, long>> GetEnhancedImage(ItemImageInfo image, private async Task<Tuple<string, DateTime>> GetEnhancedImage(ItemImageInfo image,
IHasImages item, IHasImages item,
int imageIndex, int imageIndex,
List<IImageEnhancer> enhancers) List<IImageEnhancer> enhancers)
@ -533,7 +524,6 @@ namespace Emby.Drawing
var originalImagePath = image.Path; var originalImagePath = image.Path;
var dateModified = image.DateModified; var dateModified = image.DateModified;
var imageType = image.Type; var imageType = image.Type;
var length = image.Length;
try try
{ {
@ -553,7 +543,7 @@ namespace Emby.Drawing
_logger.Error("Error enhancing image", ex); _logger.Error("Error enhancing image", ex);
} }
return new Tuple<string, DateTime, long>(originalImagePath, dateModified, length); return new Tuple<string, DateTime>(originalImagePath, dateModified);
} }
/// <summary> /// <summary>

@ -341,14 +341,17 @@ namespace MediaBrowser.Api
timerDuration = 60000; timerDuration = 60000;
} }
job.PingTimeout = timerDuration;
job.LastPingDate = DateTime.UtcNow;
// Don't start the timer for playback checkins with progressive streaming // Don't start the timer for playback checkins with progressive streaming
if (job.Type != TranscodingJobType.Progressive || !isProgressCheckIn) if (job.Type != TranscodingJobType.Progressive || !isProgressCheckIn)
{ {
job.StartKillTimer(timerDuration, OnTranscodeKillTimerStopped); job.StartKillTimer(OnTranscodeKillTimerStopped);
} }
else else
{ {
job.ChangeKillTimerIfStarted(timerDuration); job.ChangeKillTimerIfStarted();
} }
} }
@ -360,6 +363,15 @@ namespace MediaBrowser.Api
{ {
var job = (TranscodingJob)state; 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); Logger.Debug("Transcoding kill timer stopped for JobId {0} PlaySessionId {1}. Killing transcoding", job.Id, job.PlaySessionId);
KillTranscodingJob(job, path => true); KillTranscodingJob(job, path => true);
@ -626,6 +638,9 @@ namespace MediaBrowser.Api
private readonly object _timerLock = new object(); private readonly object _timerLock = new object();
public DateTime LastPingDate { get; set; }
public int PingTimeout { get; set; }
public TranscodingJob(ILogger logger) public TranscodingJob(ILogger logger)
{ {
Logger = logger; Logger = logger;
@ -654,12 +669,14 @@ namespace MediaBrowser.Api
} }
} }
public void StartKillTimer(int intervalMs, TimerCallback callback) public void StartKillTimer(TimerCallback callback)
{ {
CheckHasExited(); CheckHasExited();
lock (_timerLock) lock (_timerLock)
{ {
var intervalMs = PingTimeout;
if (KillTimer == null) if (KillTimer == null)
{ {
Logger.Debug("Starting kill timer at {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId); 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(); CheckHasExited();
@ -681,6 +698,8 @@ namespace MediaBrowser.Api
{ {
if (KillTimer != null) if (KillTimer != null)
{ {
var intervalMs = PingTimeout;
Logger.Debug("Changing kill timer to {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId); Logger.Debug("Changing kill timer to {0}ms. JobId {1} PlaySessionId {2}", intervalMs, Id, PlaySessionId);
KillTimer.Change(intervalMs, Timeout.Infinite); KillTimer.Change(intervalMs, Timeout.Infinite);
} }

@ -1512,7 +1512,6 @@ namespace MediaBrowser.Controller.Entities
image.Path = file.FullName; image.Path = file.FullName;
image.DateModified = imageInfo.DateModified; image.DateModified = imageInfo.DateModified;
image.Length = imageInfo.Length;
} }
} }
@ -1622,14 +1621,11 @@ namespace MediaBrowser.Controller.Entities
return null; return null;
} }
var fileInfo = new FileInfo(path);
return new ItemImageInfo return new ItemImageInfo
{ {
Path = path, Path = path,
DateModified = FileSystem.GetLastWriteTimeUtc(fileInfo), DateModified = FileSystem.GetLastWriteTimeUtc(path),
Type = imageType, Type = imageType
Length = fileInfo.Length
}; };
} }
@ -1690,7 +1686,6 @@ namespace MediaBrowser.Controller.Entities
else else
{ {
existing.DateModified = FileSystem.GetLastWriteTimeUtc(newImage); existing.DateModified = FileSystem.GetLastWriteTimeUtc(newImage);
existing.Length = ((FileInfo)newImage).Length;
} }
} }
@ -1716,8 +1711,7 @@ namespace MediaBrowser.Controller.Entities
{ {
Path = file.FullName, Path = file.FullName,
Type = type, Type = type,
DateModified = FileSystem.GetLastWriteTimeUtc(file), DateModified = FileSystem.GetLastWriteTimeUtc(file)
Length = ((FileInfo)file).Length
}; };
} }
@ -1756,15 +1750,9 @@ namespace MediaBrowser.Controller.Entities
FileSystem.SwapFiles(path1, path2); FileSystem.SwapFiles(path1, path2);
var file1 = new FileInfo(info1.Path);
var file2 = new FileInfo(info2.Path);
// Refresh these values // Refresh these values
info1.DateModified = FileSystem.GetLastWriteTimeUtc(file1); info1.DateModified = FileSystem.GetLastWriteTimeUtc(info1.Path);
info2.DateModified = FileSystem.GetLastWriteTimeUtc(file2); info2.DateModified = FileSystem.GetLastWriteTimeUtc(info2.Path);
info1.Length = file1.Length;
info2.Length = file2.Length;
return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None); return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
} }

@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Entities
/// <value>The path.</value> /// <value>The path.</value>
public string Path { get; set; } public string Path { get; set; }
/// <summary>
/// Gets or sets the length.
/// </summary>
/// <value>The length.</value>
public long Length { get; set; }
/// <summary> /// <summary>
/// Gets or sets the type. /// Gets or sets the type.
/// </summary> /// </summary>

@ -384,7 +384,6 @@ namespace MediaBrowser.Providers.Manager
else else
{ {
currentImage.DateModified = _fileSystem.GetLastWriteTimeUtc(image.FileInfo); currentImage.DateModified = _fileSystem.GetLastWriteTimeUtc(image.FileInfo);
currentImage.Length = ((FileInfo) image.FileInfo).Length;
} }
} }
else else

@ -828,14 +828,11 @@ namespace MediaBrowser.Server.Implementations.Dto
if (!string.IsNullOrEmpty(chapterInfo.ImagePath)) if (!string.IsNullOrEmpty(chapterInfo.ImagePath))
{ {
var file = new FileInfo(chapterInfo.ImagePath);
dto.ImageTag = GetImageCacheTag(item, new ItemImageInfo dto.ImageTag = GetImageCacheTag(item, new ItemImageInfo
{ {
Path = chapterInfo.ImagePath, Path = chapterInfo.ImagePath,
Type = ImageType.Chapter, Type = ImageType.Chapter,
DateModified = _fileSystem.GetLastWriteTimeUtc(file), DateModified = _fileSystem.GetLastWriteTimeUtc(chapterInfo.ImagePath)
Length = file.Length
}); });
} }

@ -202,9 +202,15 @@ namespace MediaBrowser.Server.Implementations.Library
public async Task<UserView> GetUserView(List<ICollectionFolder> parents, string viewType, string sortName, User user, CancellationToken cancellationToken) public async Task<UserView> GetUserView(List<ICollectionFolder> 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))) 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 parentId = parents[0].Id;
var enableRichView = !user.Configuration.PlainFolderViews.Contains(parentId.ToString("N"), StringComparer.OrdinalIgnoreCase); var enableRichView = !user.Configuration.PlainFolderViews.Contains(parentId.ToString("N"), StringComparer.OrdinalIgnoreCase);
@ -226,8 +232,6 @@ namespace MediaBrowser.Server.Implementations.Library
} }
else else
{ {
var name = _localizationManager.GetLocalizedString("ViewType" + viewType);
return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false); return await _libraryManager.GetNamedView(user, name, viewType, sortName, cancellationToken).ConfigureAwait(false);
} }
} }

@ -122,7 +122,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private async Task AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken) 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 var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
{ {
@ -131,8 +131,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
ExtractChapters = false ExtractChapters = false
}, cancellationToken) }, cancellationToken).ConfigureAwait(false);
.ConfigureAwait(false);
mediaSource.Bitrate = info.Bitrate; mediaSource.Bitrate = info.Bitrate;
mediaSource.Container = info.Container; mediaSource.Container = info.Container;
@ -146,6 +145,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
mediaSource.DefaultSubtitleStreamIndex = null; 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); var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Audio);
if (audioStream == null || audioStream.Index == -1) if (audioStream == null || audioStream.Index == -1)

Loading…
Cancel
Save