mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 05:47:14 -04:00
fixes #2121 - background roku thumbnail generation (or maybe... any scheduled task?) should be "niced"
This commit is contained in:
parent
30e673a467
commit
b89af7af43
@ -142,7 +142,7 @@ namespace Emby.Server.Implementations.MediaEncoder
|
|||||||
|
|
||||||
var container = video.Container;
|
var container = video.Container;
|
||||||
|
|
||||||
var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false);
|
var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.GetDefaultVideoStream(), video.Video3DFormat, time, cancellationToken).ConfigureAwait(false);
|
||||||
_fileSystem.CopyFile(tempFile, path, true);
|
_fileSystem.CopyFile(tempFile, path, true);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -95,7 +95,7 @@ namespace MediaBrowser.Api.Playback
|
|||||||
LibraryManager = libraryManager;
|
LibraryManager = libraryManager;
|
||||||
IsoManager = isoManager;
|
IsoManager = isoManager;
|
||||||
MediaEncoder = mediaEncoder;
|
MediaEncoder = mediaEncoder;
|
||||||
EncodingHelper = new EncodingHelper(MediaEncoder, serverConfig, FileSystem, SubtitleEncoder);
|
EncodingHelper = new EncodingHelper(MediaEncoder, FileSystem, SubtitleEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -4,7 +4,6 @@ using System.Globalization;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Controller.Configuration;
|
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
@ -19,14 +18,12 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
private readonly IMediaEncoder _mediaEncoder;
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ISubtitleEncoder _subtitleEncoder;
|
private readonly ISubtitleEncoder _subtitleEncoder;
|
||||||
|
|
||||||
public EncodingHelper(IMediaEncoder mediaEncoder, IServerConfigurationManager config, IFileSystem fileSystem, ISubtitleEncoder subtitleEncoder)
|
public EncodingHelper(IMediaEncoder mediaEncoder, IFileSystem fileSystem, ISubtitleEncoder subtitleEncoder)
|
||||||
{
|
{
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
_config = config;
|
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_subtitleEncoder = subtitleEncoder;
|
_subtitleEncoder = subtitleEncoder;
|
||||||
}
|
}
|
||||||
@ -1771,29 +1768,34 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GetVideoDecoder(state.MediaSource.VideoType ?? VideoType.VideoFile, state.VideoStream, encodingOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetVideoDecoder(VideoType videoType, MediaStream videoStream, EncodingOptions encodingOptions)
|
||||||
|
{
|
||||||
// Only use alternative encoders for video files.
|
// Only use alternative encoders for video files.
|
||||||
// When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully
|
// When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully
|
||||||
// Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this.
|
// Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this.
|
||||||
if (state.VideoType != VideoType.VideoFile)
|
if (videoType != VideoType.VideoFile)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.VideoStream != null &&
|
if (videoStream != null &&
|
||||||
!string.IsNullOrWhiteSpace(state.VideoStream.Codec) &&
|
!string.IsNullOrWhiteSpace(videoStream.Codec) &&
|
||||||
!string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType) &&
|
!string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType) &&
|
||||||
encodingOptions.EnableHardwareDecoding)
|
encodingOptions.EnableHardwareDecoding)
|
||||||
{
|
{
|
||||||
if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
switch (state.MediaSource.VideoStream.Codec.ToLower())
|
switch (videoStream.Codec.ToLower())
|
||||||
{
|
{
|
||||||
case "avc":
|
case "avc":
|
||||||
case "h264":
|
case "h264":
|
||||||
if (_mediaEncoder.SupportsDecoder("h264_qsv"))
|
if (_mediaEncoder.SupportsDecoder("h264_qsv"))
|
||||||
{
|
{
|
||||||
// qsv decoder does not support 10-bit input
|
// qsv decoder does not support 10-bit input
|
||||||
if ((state.VideoStream.BitDepth ?? 8) > 8)
|
if ((videoStream.BitDepth ?? 8) > 8)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1824,7 +1826,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
|
|
||||||
else if (string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
else if (string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
switch (state.MediaSource.VideoStream.Codec.ToLower())
|
switch (videoStream.Codec.ToLower())
|
||||||
{
|
{
|
||||||
case "avc":
|
case "avc":
|
||||||
case "h264":
|
case "h264":
|
||||||
|
@ -39,29 +39,16 @@ namespace MediaBrowser.Controller.MediaEncoding
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extracts the video image.
|
/// Extracts the video image.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inputFiles">The input files.</param>
|
Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream videoStream, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
|
||||||
/// <param name="protocol">The protocol.</param>
|
|
||||||
/// <param name="threedFormat">The threed format.</param>
|
|
||||||
/// <param name="offset">The offset.</param>
|
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task{Stream}.</returns>
|
|
||||||
Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken);
|
Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream imageStream, int? imageStreamIndex, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extracts the video images on interval.
|
/// Extracts the video images on interval.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="inputFiles">The input files.</param>
|
|
||||||
/// <param name="protocol">The protocol.</param>
|
|
||||||
/// <param name="threedFormat">The threed format.</param>
|
|
||||||
/// <param name="interval">The interval.</param>
|
|
||||||
/// <param name="targetDirectory">The target directory.</param>
|
|
||||||
/// <param name="filenamePrefix">The filename prefix.</param>
|
|
||||||
/// <param name="maxWidth">The maximum width.</param>
|
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns>Task.</returns>
|
|
||||||
Task ExtractVideoImagesOnInterval(string[] inputFiles,
|
Task ExtractVideoImagesOnInterval(string[] inputFiles,
|
||||||
|
string container,
|
||||||
|
MediaStream videoStream,
|
||||||
MediaProtocol protocol,
|
MediaProtocol protocol,
|
||||||
Video3DFormat? threedFormat,
|
Video3DFormat? threedFormat,
|
||||||
TimeSpan interval,
|
TimeSpan interval,
|
||||||
|
@ -59,7 +59,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
MediaSourceManager = mediaSourceManager;
|
MediaSourceManager = mediaSourceManager;
|
||||||
ProcessFactory = processFactory;
|
ProcessFactory = processFactory;
|
||||||
|
|
||||||
EncodingHelper = new EncodingHelper(MediaEncoder, ConfigurationManager, FileSystem, SubtitleEncoder);
|
EncodingHelper = new EncodingHelper(MediaEncoder, FileSystem, SubtitleEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<EncodingJob> Start(EncodingJobOptions options,
|
public async Task<EncodingJob> Start(EncodingJobOptions options,
|
||||||
|
@ -615,20 +615,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
|
|
||||||
public Task<string> ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken)
|
public Task<string> ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return ExtractImage(new[] { path }, null, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken);
|
return ExtractImage(new[] { path }, null, null, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
|
public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream videoStream, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return ExtractImage(inputFiles, container, null, protocol, false, threedFormat, offset, cancellationToken);
|
return ExtractImage(inputFiles, container, videoStream, null, protocol, false, threedFormat, offset, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken)
|
public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream imageStream, int? imageStreamIndex, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return ExtractImage(inputFiles, container, imageStreamIndex, protocol, false, null, null, cancellationToken);
|
return ExtractImage(inputFiles, container, imageStream, imageStreamIndex, protocol, false, null, null, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ExtractImage(string[] inputFiles, string container, int? imageStreamIndex, MediaProtocol protocol, bool isAudio,
|
private async Task<string> ExtractImage(string[] inputFiles, string container, MediaStream videoStream, int? imageStreamIndex, MediaProtocol protocol, bool isAudio,
|
||||||
Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
|
Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var inputArgument = GetInputArgument(inputFiles, protocol);
|
var inputArgument = GetInputArgument(inputFiles, protocol);
|
||||||
@ -645,7 +645,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await ExtractImageInternal(inputArgument, container, imageStreamIndex, protocol, threedFormat, offset, true, cancellationToken).ConfigureAwait(false);
|
return await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, true, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
@ -657,10 +657,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return await ExtractImageInternal(inputArgument, container, imageStreamIndex, protocol, threedFormat, offset, false, cancellationToken).ConfigureAwait(false);
|
return await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, false, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ExtractImageInternal(string inputPath, string container, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, CancellationToken cancellationToken)
|
private async Task<string> ExtractImageInternal(string inputPath, string container, MediaStream videoStream, int? imageStreamIndex, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(inputPath))
|
if (string.IsNullOrEmpty(inputPath))
|
||||||
{
|
{
|
||||||
@ -726,6 +726,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
args = string.Format("-ss {0} ", GetTimeParameter(offset.Value)) + args;
|
args = string.Format("-ss {0} ", GetTimeParameter(offset.Value)) + args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var encodinghelper = new EncodingHelper(this, FileSystem, SubtitleEncoder());
|
||||||
|
if (videoStream != null)
|
||||||
|
{
|
||||||
|
var decoder = encodinghelper.GetVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions());
|
||||||
|
if (!string.IsNullOrWhiteSpace(decoder))
|
||||||
|
{
|
||||||
|
args = decoder + " " + args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(container))
|
||||||
|
{
|
||||||
|
var inputFormat = encodinghelper.GetInputFormat(container);
|
||||||
|
if (!string.IsNullOrWhiteSpace(inputFormat))
|
||||||
|
{
|
||||||
|
args = "-f " + inputFormat + " " + args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var process = _processFactory.Create(new ProcessOptions
|
var process = _processFactory.Create(new ProcessOptions
|
||||||
{
|
{
|
||||||
CreateNoWindow = true,
|
CreateNoWindow = true,
|
||||||
@ -786,6 +805,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task ExtractVideoImagesOnInterval(string[] inputFiles,
|
public async Task ExtractVideoImagesOnInterval(string[] inputFiles,
|
||||||
|
string container,
|
||||||
|
MediaStream videoStream,
|
||||||
MediaProtocol protocol,
|
MediaProtocol protocol,
|
||||||
Video3DFormat? threedFormat,
|
Video3DFormat? threedFormat,
|
||||||
TimeSpan interval,
|
TimeSpan interval,
|
||||||
@ -825,6 +846,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||||||
args = analyzeDurationArgument + " " + args;
|
args = analyzeDurationArgument + " " + args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var encodinghelper = new EncodingHelper(this, FileSystem, SubtitleEncoder());
|
||||||
|
if (videoStream != null)
|
||||||
|
{
|
||||||
|
var decoder = encodinghelper.GetVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions());
|
||||||
|
if (!string.IsNullOrWhiteSpace(decoder))
|
||||||
|
{
|
||||||
|
args = decoder + " " + args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(container))
|
||||||
|
{
|
||||||
|
var inputFormat = encodinghelper.GetInputFormat(container);
|
||||||
|
if (!string.IsNullOrWhiteSpace(inputFormat))
|
||||||
|
{
|
||||||
|
args = "-f " + inputFormat + " " + args;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var process = _processFactory.Create(new ProcessOptions
|
var process = _processFactory.Create(new ProcessOptions
|
||||||
{
|
{
|
||||||
CreateNoWindow = true,
|
CreateNoWindow = true,
|
||||||
|
@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoIndex, cancellationToken).ConfigureAwait(false);
|
extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, imageStream, videoIndex, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -144,7 +144,9 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||||||
? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1))
|
? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1))
|
||||||
: TimeSpan.FromSeconds(10);
|
: TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
|
var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
|
||||||
|
|
||||||
|
extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoStream, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DynamicImageResponse
|
return new DynamicImageResponse
|
||||||
|
Loading…
Reference in New Issue
Block a user