mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-22 10:04:44 +01:00
add chapter image error handling
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using System.IO;
|
||||
using CommonIO;
|
||||
using MediaBrowser.Controller.Collections;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Collections
|
||||
{
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Collections
|
||||
{
|
||||
public class ManualCollectionsFolder : BasePluginFolder, IHiddenFromDisplay
|
||||
{
|
||||
public ManualCollectionsFolder()
|
||||
{
|
||||
Name = "Collections";
|
||||
DisplayMediaType = "CollectionFolder";
|
||||
}
|
||||
|
||||
public override bool IsHidden
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsHiddenFromUser(User user)
|
||||
{
|
||||
return !ConfigurationManager.Configuration.DisplayCollectionsView;
|
||||
}
|
||||
|
||||
public override string CollectionType
|
||||
{
|
||||
get { return Model.Entities.CollectionType.BoxSets; }
|
||||
}
|
||||
|
||||
public override string GetClientTypeName()
|
||||
{
|
||||
return typeof(CollectionFolder).Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,11 +53,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||
|
||||
public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
|
||||
{
|
||||
if (mediaSource.Path.IndexOf("m3u8", StringComparison.OrdinalIgnoreCase) != -1)
|
||||
{
|
||||
await RecordWithoutTempFile(mediaSource, targetFile, duration, onStarted, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var tempfile = Path.Combine(_appPaths.TranscodingTempPath, Guid.NewGuid().ToString("N") + ".ts");
|
||||
|
||||
try
|
||||
{
|
||||
await RecordInternal(mediaSource, tempfile, targetFile, duration, onStarted, cancellationToken)
|
||||
await RecordWithTempFile(mediaSource, tempfile, targetFile, duration, onStarted, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
@@ -73,7 +81,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RecordInternal(MediaSourceInfo mediaSource, string tempFile, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
|
||||
private async Task RecordWithoutTempFile(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
|
||||
{
|
||||
var durationToken = new CancellationTokenSource(duration);
|
||||
cancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token;
|
||||
|
||||
await RecordFromFile(mediaSource, mediaSource.Path, targetFile, duration, onStarted, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
_logger.Info("Recording completed to file {0}", targetFile);
|
||||
}
|
||||
|
||||
private async Task RecordWithTempFile(MediaSourceInfo mediaSource, string tempFile, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
|
||||
{
|
||||
var httpRequestOptions = new HttpRequestOptions()
|
||||
{
|
||||
|
||||
@@ -124,7 +124,6 @@
|
||||
<Compile Include="Channels\RefreshChannelsScheduledTask.cs" />
|
||||
<Compile Include="Collections\CollectionManager.cs" />
|
||||
<Compile Include="Collections\CollectionsDynamicFolder.cs" />
|
||||
<Compile Include="Collections\ManualCollectionsFolder.cs" />
|
||||
<Compile Include="Collections\CollectionImageProvider.cs" />
|
||||
<Compile Include="Configuration\ServerConfigurationManager.cs" />
|
||||
<Compile Include="Connect\ConnectData.cs" />
|
||||
|
||||
@@ -149,16 +149,16 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
}
|
||||
}
|
||||
|
||||
// Add some time for the first chapter to make sure we don't end up with a black image
|
||||
var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(FirstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks);
|
||||
|
||||
var protocol = MediaProtocol.File;
|
||||
|
||||
var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, video.PlayableStreamFileNames);
|
||||
|
||||
try
|
||||
{
|
||||
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
|
||||
// Add some time for the first chapter to make sure we don't end up with a black image
|
||||
var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(FirstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks);
|
||||
|
||||
var protocol = MediaProtocol.File;
|
||||
|
||||
var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, video.PlayableStreamFileNames);
|
||||
|
||||
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
|
||||
|
||||
var tempFile = await _encoder.ExtractVideoImage(inputPath, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false);
|
||||
File.Copy(tempFile, path, true);
|
||||
@@ -178,7 +178,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error extracting chapter images for {0}", ex, string.Join(",", inputPath));
|
||||
_logger.ErrorException("Error extracting chapter images for {0}", ex, string.Join(",", video.Path));
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
using MediaBrowser.Controller.Collections;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.UserViews
|
||||
{
|
||||
@@ -109,4 +113,62 @@ namespace MediaBrowser.Server.Implementations.UserViews
|
||||
return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public class ManualCollectionFolderImageProvider : BaseDynamicImageProvider<ManualCollectionsFolder>
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public ManualCollectionFolderImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
public override IEnumerable<ImageType> GetSupportedImages(IHasImages item)
|
||||
{
|
||||
return new List<ImageType>
|
||||
{
|
||||
ImageType.Primary
|
||||
};
|
||||
}
|
||||
|
||||
protected override async Task<List<BaseItem>> GetItemsWithImages(IHasImages item)
|
||||
{
|
||||
var view = (ManualCollectionsFolder)item;
|
||||
|
||||
var recursive = !new[] { CollectionType.Playlists, CollectionType.Channels }.Contains(view.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var items = _libraryManager.GetItemList(new InternalItemsQuery
|
||||
{
|
||||
Recursive = recursive,
|
||||
IncludeItemTypes = new[] { typeof(BoxSet).Name },
|
||||
Limit = 20,
|
||||
SortBy = new[] { ItemSortBy.Random }
|
||||
});
|
||||
|
||||
return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8);
|
||||
}
|
||||
|
||||
protected override bool Supports(IHasImages item)
|
||||
{
|
||||
return item is ManualCollectionsFolder;
|
||||
}
|
||||
|
||||
protected override async Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex)
|
||||
{
|
||||
var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png");
|
||||
|
||||
if (imageType == ImageType.Primary)
|
||||
{
|
||||
if (itemsWithImages.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user