From 631a314d24bd2c7e1b3e0b81aa65437586794ccd Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Fri, 10 Jul 2026 14:46:27 +0800 Subject: Fix potential garbled text in FFmpeg logs on Windows Explicitly set StandardErrorEncoding and StandardOutputEncoding to Encoding.UTF8 when invoking the FFmpeg subprocess. This prevents log encoding issues and character corruption on Windows environments that default to non-UTF8 ANSI code pages. This fixes garbled metadata and font names in the FFmpeg logs. Signed-off-by: nyanmisaka --- MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs | 3 +++ MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 2 ++ 2 files changed, 5 insertions(+) (limited to 'MediaBrowser.MediaEncoding/Encoder') diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 68d6d215b2..c8670c67cc 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Globalization; using System.Linq; using System.Runtime.Versioning; +using System.Text; using System.Text.RegularExpressions; using MediaBrowser.Controller.MediaEncoding; using Microsoft.Extensions.Logging; @@ -645,7 +646,9 @@ namespace MediaBrowser.MediaEncoding.Encoder WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, RedirectStandardInput = redirectStandardIn, + StandardOutputEncoding = Encoding.UTF8, RedirectStandardOutput = true, + StandardErrorEncoding = Encoding.UTF8, RedirectStandardError = true } }) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 66bf6ebd24..1199fd7d70 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; +using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading; @@ -528,6 +529,7 @@ namespace MediaBrowser.MediaEncoding.Encoder UseShellExecute = false, // Must consume both or ffmpeg may hang due to deadlocks. + StandardOutputEncoding = Encoding.UTF8, RedirectStandardOutput = true, FileName = _ffprobePath, -- cgit v1.2.3 From 9fa9d263412ae0195a4e1725877df02d3a8d4c1d Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Sat, 18 Jul 2026 15:44:34 +0800 Subject: Normalize invalid PTS from containers for Trickplay generation This change does not affect the keyframe only mode. Signed-off-by: nyanmisaka --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'MediaBrowser.MediaEncoding/Encoder') diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 66bf6ebd24..f8a9e98e7a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -926,6 +926,25 @@ namespace MediaBrowser.MediaEncoding.Encoder throw new InvalidOperationException("EncodingHelper returned empty or invalid filter parameters."); } + // Normalize invalid PTS from containers for non keyframe only mode + if (!enableKeyFrameOnlyExtraction) + { + var fpsFilterIndex = filterParam.IndexOf("fps=", StringComparison.Ordinal); + if (fpsFilterIndex >= 0) + { + var inputFrameRate = (imageStream.ReferenceFrameRate.HasValue && imageStream.ReferenceFrameRate > 0) + ? imageStream.ReferenceFrameRate.Value : 30; + + var setPtsFilter = string.Create(CultureInfo.InvariantCulture, $"setpts=N/{inputFrameRate:F3}/TB,"); + + filterParam = filterParam.Insert(fpsFilterIndex, setPtsFilter); + } + else + { + throw new InvalidOperationException("EncodingHelper returned invalid filter parameters."); + } + } + try { return await ExtractVideoImagesOnIntervalInternal( -- cgit v1.2.3 From a238d59a0702363671dfcfcac36a1881172200a8 Mon Sep 17 00:00:00 2001 From: gnattu Date: Mon, 20 Jul 2026 18:16:37 +0800 Subject: Remove libpostproc check for ffmpeg version validation (#17384) Remove libpostproc check for ffmpeg version validation --- MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs | 3 +-- tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs | 2 ++ tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs | 9 +++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.MediaEncoding/Encoder') diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index c8670c67cc..1f84b46a2b 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -185,8 +185,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { "libavdevice", new Version(58, 13) }, { "libavfilter", new Version(7, 110) }, { "libswscale", new Version(5, 9) }, - { "libswresample", new Version(3, 9) }, - { "libpostproc", new Version(55, 9) } + { "libswresample", new Version(3, 9) } }; private readonly ILogger _logger; diff --git a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs index 988073074b..bfe6ade1fe 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs @@ -24,6 +24,7 @@ namespace Jellyfin.MediaEncoding.Tests [InlineData(EncoderValidatorTestsData.FFmpegV44Output, true)] [InlineData(EncoderValidatorTestsData.FFmpegV432Output, false)] [InlineData(EncoderValidatorTestsData.FFmpegGitUnknownOutput2, true)] + [InlineData(EncoderValidatorTestsData.FFmpegGitWithoutLibpostprocOutput, true)] [InlineData(EncoderValidatorTestsData.FFmpegGitUnknownOutput, false)] public void ValidateVersionInternalTest(string versionOutput, bool valid) { @@ -41,6 +42,7 @@ namespace Jellyfin.MediaEncoding.Tests Add(EncoderValidatorTestsData.FFmpegV44Output, new Version(4, 4)); Add(EncoderValidatorTestsData.FFmpegV432Output, new Version(4, 3, 2)); Add(EncoderValidatorTestsData.FFmpegGitUnknownOutput2, new Version(4, 4)); + Add(EncoderValidatorTestsData.FFmpegGitWithoutLibpostprocOutput, new Version(4, 4)); Add(EncoderValidatorTestsData.FFmpegGitUnknownOutput, null); } } diff --git a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs index 1f2d618aa4..604b862fbe 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs @@ -86,6 +86,15 @@ libswscale 5. 9.100 / 5. 9.100 libswresample 3. 9.100 / 3. 9.100 libpostproc 55. 9.100 / 55. 9.100"; + public const string FFmpegGitWithoutLibpostprocOutput = @"ffmpeg version N-122128-gdeadbeef Copyright (c) 2000-2026 the FFmpeg developers +libavutil 60. 26.102 / 60. 26.102 +libavcodec 62. 28.102 / 62. 28.102 +libavformat 62. 12.102 / 62. 12.102 +libavdevice 62. 3.102 / 62. 3.102 +libavfilter 11. 14.102 / 11. 14.102 +libswscale 9. 5.102 / 9. 5.102 +libswresample 6. 3.102 / 6. 3.102"; + public const string FFmpegGitUnknownOutput = @"ffmpeg version N-45325-gb173e0353-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2018 the FFmpeg developers built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516 configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg -- cgit v1.2.3