aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.MediaEncoding
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-10-24 09:56:04 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-10-24 09:56:04 +0200
commitd95c2e1425d0d902e8191260ba9151f686aa2650 (patch)
tree3bc937664dcf9fe8d7659b00d92fc3a6c61be805 /MediaBrowser.MediaEncoding
parentd3a92c69f8c1c5d1cda803a35f03175d6ba3b091 (diff)
parentc7ce6a1b56ee7dcc1896250df0f2f9deaa828a81 (diff)
Merge branch 'master' into port-async-migration-routines
# Conflicts: # Jellyfin.Server/Migrations/Routines/20260915120000_MigrateRatingLevels.cs
Diffstat (limited to 'MediaBrowser.MediaEncoding')
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs8
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs9
-rw-r--r--MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs6
-rw-r--r--MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs6
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs8
5 files changed, 29 insertions, 8 deletions
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index 91d0c3d5a6..99c08eb9a1 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -193,8 +193,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly string _encoderPath;
- private readonly Version _minFFmpegMultiThreadedCli = new Version(7, 0);
-
public EncoderValidator(ILogger logger, string encoderPath)
{
_logger = logger;
@@ -552,9 +550,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
string output;
try
{
- // With multi-threaded cli support, FFmpeg 7 is less sensitive to keyboard input
- var duration = ffmpegVersion >= _minFFmpegMultiThreadedCli ? 10000 : 1000;
- output = GetProcessOutput(_encoderPath, $"-hide_banner -f lavfi -i nullsrc=s=1x1:d={duration} -f null -", true, "?");
+ // Start a dummy encode of 1x1@1fps. Send '?' to stdin to get the help/keybind text, followed by 'q' to stop the job immediately
+ // As a safeguard in case 'q' doesn't stop the job, the dummy input has a max duration of 5 (realtime) seconds
+ output = GetProcessOutput(_encoderPath, $"-hide_banner -re -f lavfi -i nullsrc=s=1x1:r=1:d=5 -f null -", true, "?q");
}
catch (Exception ex)
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index f64fd73763..fa43d756a4 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -922,6 +922,15 @@ namespace MediaBrowser.MediaEncoding.Encoder
inputArg = "-hwaccel_flags +low_priority " + inputArg;
}
+ // Force the video stream, otherwise ffmpeg may pick a cover image.
+ var streamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, imageStream);
+ if (streamIndex < 0)
+ {
+ throw new InvalidOperationException($"Unable to locate requested stream {imageStream.Title}");
+ }
+
+ inputArg += " -map 0:" + streamIndex;
+
var filterParam = encodingHelper.GetVideoProcessingFilterParam(jobState, options, vidEncoder).Trim();
if (string.IsNullOrWhiteSpace(filterParam))
{
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
index f631c471f6..17ab378ef7 100644
--- a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
+++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
@@ -198,10 +198,10 @@ namespace MediaBrowser.MediaEncoding.Probing
public string? CodecTag { get; set; }
/// <summary>
- /// Gets or sets the codec_tag_string?.
+ /// Gets or sets the codec_tag_string.
/// </summary>
- /// <value>The codec_tag_string?.</value>
- [JsonPropertyName("codec_tag_string?")]
+ /// <value>The codec_tag_string.</value>
+ [JsonPropertyName("codec_tag_string")]
public string? CodecTagString { get; set; }
/// <summary>
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index 5533e55223..c9d618c84a 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -1110,6 +1110,12 @@ namespace MediaBrowser.MediaEncoding.Probing
&& width > 0
&& height > 0))
{
+ // Live TV and other early probes can report neither a usable display aspect ratio nor the frame size
+ if (info.Width is not > 0 || info.Height is not > 0)
+ {
+ return original;
+ }
+
width = info.Width.Value;
height = info.Height.Value;
}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index fba644b74a..27a987fefe 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -188,6 +188,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_logger.LogDebug("charset {CharSet} detected for {Path}", detected.EncodingName, fileInfo.Path);
+ // If encoding is not supported by .NET (e.g., ISO-8859-16), return stream as-is
+ // The charset name will be passed to ffmpeg via -sub_charenc if needed
+ if (detected.Encoding is null)
+ {
+ _logger.LogWarning("Encoding {Encoding} is not supported by .NET for {Path}, returning stream as-is", detected.EncodingName, fileInfo.Path);
+ return stream;
+ }
+
await using (stream.ConfigureAwait(false))
{
using var reader = new StreamReader(stream, detected.Encoding);