[PR #15502] [MERGED] Fix font extraction for certain transcoding settings #14336

Closed
opened 2026-02-07 07:28:08 +03:00 by OVERLORD · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/jellyfin/jellyfin/pull/15502
Author: @Iksas
Created: 11/13/2025
Status: Merged
Merged: 11/14/2025
Merged by: @crobibero

Base: release-10.11.zHead: attachment-extractor-fix


📝 Commits (1)

  • 0fa952f fix missing font extraction for certain transcoding settings

📊 Changes

1 file changed (+1 additions, -1 deletions)

View changed files

📝 MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs (+1 -1)

📄 Description

This PR fixes an issue where attached fonts are not extracted under certain conditions.

This can cause affected subtitles to be rendered in a default font, if the fonts are not present in the attachment cache.

Steps to reproduce

  1. In the user settings of the web interface, set Burn subtitles to Auto, and enable the Always burn in subtitle when transcoding checkbox.
  2. Open a video in the web interface, enable subtitles, and lower the bitrate to force transcoding. Close the video.
  3. Exec into the container, and empty the attachment cache with rm -rf /config/data/attachments/*
  4. Open the same video as before in the web interface. Jellyfin won't extract the fonts to the font cache, and the subtitles will be displayed in a default font.

In the logs, output from MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor is missing when the bug occurs:

# Broken
[TIME] [INF] [26] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for root. EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[TIME] [INF] [25] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[TIME] [INF] [25] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -probesize 1G -f matroska -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -noautorotate -hwaccel_flags +unsafe_output -threads 1 -i file:"/media/FILE.mkv" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:0 -codec:v:0 hevc_nvenc -tag:v:0 hvc1 -preset p1 -b:v 315839 -maxrate 315839 -bufsize 631678 -profile:v:0 main -g:v:0 72 -keyint_min:v:0 72 -filter_complex "alphasrc=s=960x540:r=23.976025:start='0',format=yuva420p,subtitles=f='/config/data/subtitles/UU/UUID/3.ass':alpha=1:sub2video=1:fontsdir='/config/data/attachments/UU/UUID',hwupload=derive_device=cuda[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=w=960:h=540:format=yuv420p[main];[main][sub]overlay_cuda=eof_action=pass:repeatlast=0:alpha_format=premultiplied" -start_at_zero -codec:a:0 copy -strict -2 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename "XXXX-1.mp4" -start_number 0 -hls_segment_filename "/cache/transcodes/XXXX%d.mp4" -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y "/cache/transcodes/XXXX.m3u8"
[TIME] [INF] [14] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for /cache/transcodes/XXXX.m3u8
[TIME] [INF] [14] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0

# Working
[TIME] [INF] [7] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for root. EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[TIME] [INF] [26] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[TIME] [INF] [26] MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor: /usr/lib/jellyfin-ffmpeg/ffmpeg -dump_attachment:t "" -y  -i file:"/media/FILE.mkv" -t 0 -f null null
[TIME] [INF] [26] MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor: ffmpeg attachment extraction completed for file:"/media/FILE.mkv" to /config/data/attachments/UU/UUID
[TIME] [INF] [26] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -probesize 1G -f matroska -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -noautorotate -hwaccel_flags +unsafe_output -threads 1 -i file:"/media/FILE.mkv" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:0 -codec:v:0 hevc_nvenc -tag:v:0 hvc1 -preset p1 -b:v 315839 -maxrate 315839 -bufsize 631678 -profile:v:0 main -g:v:0 72 -keyint_min:v:0 72 -filter_complex "alphasrc=s=960x540:r=23.976025:start='0',format=yuva420p,subtitles=f='/config/data/subtitles/UU/UUID/3.ass':alpha=1:sub2video=1:fontsdir='/config/data/attachments/UU/UUID',hwupload=derive_device=cuda[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=w=960:h=540:format=yuv420p[main];[main][sub]overlay_cuda=eof_action=pass:repeatlast=0:alpha_format=premultiplied" -start_at_zero -codec:a:0 copy -strict -2 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename "XXXX-1.mp4" -start_number 0 -hls_segment_filename "/cache/transcodes/XXXX%d.mp4" -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y "/cache/transcodes/XXXX.m3u8"
[TIME] [INF] [7] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for /cache/transcodes/XXXX.m3u8
[TIME] [INF] [7] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0

Changes

As a fix, this PR adds an additional check to TranscodeManager to extract attachments if a subtitle is active, and the AlwaysBurnInSubtitleWhenTranscoding setting is set.

Because TranscodeManager is only used while transcoding, it's not necessary to explicitly check if we're transcoding.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/jellyfin/jellyfin/pull/15502 **Author:** [@Iksas](https://github.com/Iksas) **Created:** 11/13/2025 **Status:** ✅ Merged **Merged:** 11/14/2025 **Merged by:** [@crobibero](https://github.com/crobibero) **Base:** `release-10.11.z` ← **Head:** `attachment-extractor-fix` --- ### 📝 Commits (1) - [`0fa952f`](https://github.com/jellyfin/jellyfin/commit/0fa952f8886cf0526c80910a33b9a84b666f50b2) fix missing font extraction for certain transcoding settings ### 📊 Changes **1 file changed** (+1 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs` (+1 -1) </details> ### 📄 Description <!-- Ensure your title is short, descriptive, and in the imperative mood (Fix X, Change Y, instead of Fixed X, Changed Y). For a good inspiration of what to write in commit messages and PRs please review https://chris.beams.io/posts/git-commit/ and our documentation. --> This PR fixes an issue where attached fonts are not extracted under certain conditions. This can cause affected subtitles to be rendered in a default font, if the fonts are not present in the attachment cache. **Steps to reproduce** 1. In the user settings of the web interface, set `Burn subtitles` to `Auto`, and enable the `Always burn in subtitle when transcoding` checkbox. 2. Open a video in the web interface, enable subtitles, and lower the bitrate to force transcoding. Close the video. 3. Exec into the container, and empty the attachment cache with `rm -rf /config/data/attachments/*` 4. Open the same video as before in the web interface. Jellyfin won't extract the fonts to the font cache, and the subtitles will be displayed in a default font. In the logs, output from `MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor` is missing when the bug occurs: ``` # Broken [TIME] [INF] [26] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for root. EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True [TIME] [INF] [25] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request [TIME] [INF] [25] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -probesize 1G -f matroska -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -noautorotate -hwaccel_flags +unsafe_output -threads 1 -i file:"/media/FILE.mkv" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:0 -codec:v:0 hevc_nvenc -tag:v:0 hvc1 -preset p1 -b:v 315839 -maxrate 315839 -bufsize 631678 -profile:v:0 main -g:v:0 72 -keyint_min:v:0 72 -filter_complex "alphasrc=s=960x540:r=23.976025:start='0',format=yuva420p,subtitles=f='/config/data/subtitles/UU/UUID/3.ass':alpha=1:sub2video=1:fontsdir='/config/data/attachments/UU/UUID',hwupload=derive_device=cuda[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=w=960:h=540:format=yuv420p[main];[main][sub]overlay_cuda=eof_action=pass:repeatlast=0:alpha_format=premultiplied" -start_at_zero -codec:a:0 copy -strict -2 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename "XXXX-1.mp4" -start_number 0 -hls_segment_filename "/cache/transcodes/XXXX%d.mp4" -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y "/cache/transcodes/XXXX.m3u8" [TIME] [INF] [14] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for /cache/transcodes/XXXX.m3u8 [TIME] [INF] [14] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0 # Working [TIME] [INF] [7] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for root. EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True [TIME] [INF] [26] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request [TIME] [INF] [26] MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor: /usr/lib/jellyfin-ffmpeg/ffmpeg -dump_attachment:t "" -y -i file:"/media/FILE.mkv" -t 0 -f null null [TIME] [INF] [26] MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor: ffmpeg attachment extraction completed for file:"/media/FILE.mkv" to /config/data/attachments/UU/UUID [TIME] [INF] [26] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: /usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -probesize 1G -f matroska -init_hw_device cuda=cu:0 -filter_hw_device cu -hwaccel cuda -hwaccel_output_format cuda -noautorotate -hwaccel_flags +unsafe_output -threads 1 -i file:"/media/FILE.mkv" -noautoscale -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:0 -codec:v:0 hevc_nvenc -tag:v:0 hvc1 -preset p1 -b:v 315839 -maxrate 315839 -bufsize 631678 -profile:v:0 main -g:v:0 72 -keyint_min:v:0 72 -filter_complex "alphasrc=s=960x540:r=23.976025:start='0',format=yuva420p,subtitles=f='/config/data/subtitles/UU/UUID/3.ass':alpha=1:sub2video=1:fontsdir='/config/data/attachments/UU/UUID',hwupload=derive_device=cuda[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_cuda=w=960:h=540:format=yuv420p[main];[main][sub]overlay_cuda=eof_action=pass:repeatlast=0:alpha_format=premultiplied" -start_at_zero -codec:a:0 copy -strict -2 -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type fmp4 -hls_fmp4_init_filename "XXXX-1.mp4" -start_number 0 -hls_segment_filename "/cache/transcodes/XXXX%d.mp4" -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y "/cache/transcodes/XXXX.m3u8" [TIME] [INF] [7] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for /cache/transcodes/XXXX.m3u8 [TIME] [INF] [7] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: FFmpeg exited with code 0 ``` **Changes** <!-- Describe your changes here in 1-5 sentences. --> As a fix, this PR adds an additional check to `TranscodeManager` to extract attachments if a subtitle is active, and the `AlwaysBurnInSubtitleWhenTranscoding` setting is set. Because `TranscodeManager` is only used while transcoding, it's not necessary to explicitly check if we're transcoding. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
OVERLORD added the pull-request label 2026-02-07 07:28:08 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/jellyfin#14336