mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-30 15:01:54 +01:00
Fix attachment extraction of files without video or audio stream (#16312)
* Fix attachment extraction of files without video or audio stream * Apply review suggestions
This commit is contained in:
@@ -115,7 +115,6 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
await ExtractAllAttachmentsInternal(
|
||||
inputFile,
|
||||
mediaSource,
|
||||
false,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -123,7 +122,6 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
private async Task ExtractAllAttachmentsInternal(
|
||||
string inputFile,
|
||||
MediaSourceInfo mediaSource,
|
||||
bool isExternal,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var inputPath = _mediaEncoder.GetInputArgument(inputFile, mediaSource);
|
||||
@@ -142,11 +140,19 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
return;
|
||||
}
|
||||
|
||||
// Files without video/audio streams (e.g. MKS subtitle files) don't need a dummy
|
||||
// output since there are no streams to process. Omit "-t 0 -f null null" so ffmpeg
|
||||
// doesn't fail trying to open an output with no streams. It will exit with code 1
|
||||
// ("at least one output file must be specified") which is expected and harmless
|
||||
// since we only need the -dump_attachment side effect.
|
||||
var hasVideoOrAudioStream = mediaSource.MediaStreams
|
||||
.Any(s => s.Type == MediaStreamType.Video || s.Type == MediaStreamType.Audio);
|
||||
var processArgs = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"-dump_attachment:t \"\" -y {0} -i {1} -t 0 -f null null",
|
||||
"-dump_attachment:t \"\" -y {0} -i {1} {2}",
|
||||
inputPath.EndsWith(".concat\"", StringComparison.OrdinalIgnoreCase) ? "-f concat -safe 0" : string.Empty,
|
||||
inputPath);
|
||||
inputPath,
|
||||
hasVideoOrAudioStream ? "-t 0 -f null null" : string.Empty);
|
||||
|
||||
int exitCode;
|
||||
|
||||
@@ -185,12 +191,7 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
if (isExternal && exitCode == 1)
|
||||
{
|
||||
// ffmpeg returns exitCode 1 because there is no video or audio stream
|
||||
// this can be ignored
|
||||
}
|
||||
else
|
||||
if (hasVideoOrAudioStream || exitCode != 1)
|
||||
{
|
||||
failed = true;
|
||||
|
||||
@@ -205,7 +206,8 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!Directory.Exists(outputFolder))
|
||||
|
||||
if (!failed && !Directory.Exists(outputFolder))
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
@@ -246,6 +248,7 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
{
|
||||
await ExtractAttachmentInternal(
|
||||
_mediaEncoder.GetInputArgument(inputFile, mediaSource),
|
||||
mediaSource,
|
||||
mediaAttachment.Index,
|
||||
attachmentPath,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
@@ -257,6 +260,7 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
|
||||
private async Task ExtractAttachmentInternal(
|
||||
string inputPath,
|
||||
MediaSourceInfo mediaSource,
|
||||
int attachmentStreamIndex,
|
||||
string outputPath,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -267,12 +271,15 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new ArgumentException("Path can't be a root directory.", nameof(outputPath)));
|
||||
|
||||
var hasVideoOrAudioStream = mediaSource.MediaStreams
|
||||
.Any(s => s.Type == MediaStreamType.Video || s.Type == MediaStreamType.Audio);
|
||||
var processArgs = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"-dump_attachment:{1} \"{2}\" -i {0} -t 0 -f null null",
|
||||
"-dump_attachment:{1} \"{2}\" -i {0} {3}",
|
||||
inputPath,
|
||||
attachmentStreamIndex,
|
||||
EncodingUtils.NormalizePath(outputPath));
|
||||
EncodingUtils.NormalizePath(outputPath),
|
||||
hasVideoOrAudioStream ? "-t 0 -f null null" : string.Empty);
|
||||
|
||||
int exitCode;
|
||||
|
||||
@@ -310,22 +317,26 @@ namespace MediaBrowser.MediaEncoding.Attachments
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
failed = true;
|
||||
|
||||
_logger.LogWarning("Deleting extracted attachment {Path} due to failure: {ExitCode}", outputPath, exitCode);
|
||||
try
|
||||
if (hasVideoOrAudioStream || exitCode != 1)
|
||||
{
|
||||
if (File.Exists(outputPath))
|
||||
failed = true;
|
||||
|
||||
_logger.LogWarning("Deleting extracted attachment {Path} due to failure: {ExitCode}", outputPath, exitCode);
|
||||
try
|
||||
{
|
||||
_fileSystem.DeleteFile(outputPath);
|
||||
if (File.Exists(outputPath))
|
||||
{
|
||||
_fileSystem.DeleteFile(outputPath);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error deleting extracted attachment {Path}", outputPath);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error deleting extracted attachment {Path}", outputPath);
|
||||
}
|
||||
}
|
||||
else if (!File.Exists(outputPath))
|
||||
|
||||
if (!failed && !File.Exists(outputPath))
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user