Fixing Missing Chinese Subtitles in Jellyfin Android TV
Problem Discovery
I had previously deployed a Docker version of Jellyfin on my NAS. The issue of Chinese subtitles not displaying could be resolved by setting up a fallback font in Jellyfin.
In short:
- Download the
Noto Sans CJKfont package. - In the Jellyfin Dashboard → Playback → Transcoding, enable
Enable Fallback Fontand place the downloaded font package in the fallback font file path.
Recently, I purchased a Fire TV Stick to pair with my projector. After downloading Jellyfin on it, I found that the Chinese subtitles — which displayed correctly on the browser and mobile clients — failed to render properly on the Android TV version of Jellyfin.
Investigation
After the first round of searching online, I initially thought the issue was that the Android TV version didn't support subtitle burn-in, causing problems with external .ass subtitles. However, the latest Android TV version seems to have already fixed this issue.
Additionally, when I tried playing Kannagi with external .ass subtitles, the subtitles didn't display. But playing Owarimonogatari, which had subtitles muxed into the .mkv file, worked fine. By inspecting the .mkv file of Owarimonogatari, I discovered that the fonts specified in the subtitle file were also embedded as attachments inside the .mkv. So I tried using MKVToolNix to mux Kannagi's specified fonts and subtitles into the .mkv as well, but the Chinese characters still failed to display.
By analyzing the Jellyfin logs, I found some clues.
Owarimonogatari — partial log:ffmpeg version 7.0.2-Jellyfin Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 12 (Debian 12.2.0-14)
configuration: --prefix=/usr/lib/jellyfin-ffmpeg --target-os=linux --extra-version=Jellyfin --disable-doc --disable-ffplay --disable-ptx-compression --disable-static --disable-libxcb --disable-sdl2 --disable-xlib --enable-lto=auto --enable-gpl --enable-version3 --enable-shared --enable-gmp --enable-gnutls --enable-chromaprint --enable-opencl --enable-libdrm --enable-libxml2 --enable-libass --enable-libfreetype --enable-libfribidi --enable-libfontconfig --enable-libharfbuzz --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libopenmpt --enable-libdav1d --enable-libsvtav1 --enable-libwebp --enable-libvpx --enable-libx264 --enable-libx265 --enable-libzvbi --enable-libzimg --enable-libfdk-aac --arch=amd64 --enable-libshaderc --enable-libplacebo --enable-vulkan --enable-vaapi --enable-amf --enable-libvpl --enable-ffnvcodec --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvdec --enable-nvenc
libavutil 59. 8.100 / 59. 8.100
libavcodec 61. 3.100 / 61. 3.100
libavformat 61. 1.100 / 61. 1.100
libavdevice 61. 1.100 / 61. 1.100
libavfilter 10. 1.100 / 10. 1.100
libswscale 8. 1.100 / 8. 1.100
libswresample 5. 1.100 / 5. 1.100
libpostproc 58. 1.100 / 58. 1.100
[Parsed_subtitles_2 @ 0x55d1b14d8ec0] libass API version: 0x1703000
[Parsed_subtitles_2 @ 0x55d1b14d8ec0] libass source: commit: 0.17.3-0-ge46aedea0a0d17da4c4ef49d84b94a7994664ab5
[Parsed_subtitles_2 @ 0x55d1b14d8ec0] Shaper: FriBidi 1.0.16 (SIMPLE) HarfBuzz-ng 10.2.0 (COMPLEX)
[Parsed_subtitles_2 @ 0x55d1b14d8ec0] Loading font file '/cache/attachments/a73e2ec42fa9f3014c86bcc6c27b1f80/FOT-MatissePro-DB.otf'
[Parsed_subtitles_2 @ 0x55d1b14d8ec0] Loading font file '/cache/attachments/a73e2ec42fa9f3014c86bcc6c27b1f80/FZZYSK.TTF'
[Parsed_subtitles_2 @ 0x55d1b14d8ec0] Loading font file '/cache/attachments/a73e2ec42fa9f3014c86bcc6c27b1f80/方正粗宋_GBK.ttf'
[Parsed_subtitles_2 @ 0x55d1b14d8ec0] Loading font file '/cache/attachments/a73e2ec42fa9f3014c86bcc6c27b1f80/方正准圆_GBK.ttf'
[Parsed_subtitles_2 @ 0x55d1b14d8ec0] Using font provider fontconfig
Input #0, matroska,webm, from 'file:/video/终物语/终物语 E10.mkv':
Metadata:
encoder : libebml v1.4.0 + libmatroska v1.6.0
creation_time : 2020-07-22T07:55:35.000000Z
Duration: 00:24:13.12, start: 0.000000, bitrate: 2972 kb/s
Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn (default)
Metadata:
BPS-eng : 2317138
DURATION-eng : 00:24:13.119000000
NUMBER_OF_FRAMES-eng: 34840
NUMBER_OF_BYTES-eng: 420884760
_STATISTICS_WRITING_APP-eng: mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-07-22 07:55:35
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:1(jpn): Audio: opus, 48000 Hz, stereo, fltp (default)
Metadata:
BPS-eng : 264135
DURATION-eng : 00:24:13.120000000
NUMBER_OF_FRAMES-eng: 72656
NUMBER_OF_BYTES-eng: 47977509
_STATISTICS_WRITING_APP-eng: mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-07-22 07:55:35
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:2(jpn): Audio: opus, 48000 Hz, stereo, fltp
Metadata:
title : Commentary
BPS-eng : 186030
DURATION-eng : 00:24:13.120000000
NUMBER_OF_FRAMES-eng: 72656
NUMBER_OF_BYTES-eng: 33790607
_STATISTICS_WRITING_APP-eng: mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-07-22 07:55:35
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:3: Subtitle: ass (ssa) (default)
Metadata:
title : SC
BPS-eng : 135
DURATION-eng : 00:24:04.420000000
NUMBER_OF_FRAMES-eng: 347
NUMBER_OF_BYTES-eng: 24530
_STATISTICS_WRITING_APP-eng: mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-07-22 07:55:35
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:4: Subtitle: ass (ssa)
Metadata:
title : TC
BPS-eng : 135
DURATION-eng : 00:24:04.420000000
NUMBER_OF_FRAMES-eng: 347
NUMBER_OF_BYTES-eng: 24536
_STATISTICS_WRITING_APP-eng: mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-07-22 07:55:35
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:5: Subtitle: ass (ssa)
Metadata:
title : Commentary SC
BPS-eng : 179
DURATION-eng : 00:24:07.880000000
NUMBER_OF_FRAMES-eng: 389
NUMBER_OF_BYTES-eng: 32502
_STATISTICS_WRITING_APP-eng: mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-07-22 07:55:35
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:6: Subtitle: ass (ssa)
Metadata:
title : Commentary TC
BPS-eng : 181
DURATION-eng : 00:24:07.880000000
NUMBER_OF_FRAMES-eng: 389
NUMBER_OF_BYTES-eng: 32885
_STATISTICS_WRITING_APP-eng: mkvmerge v48.0.0 ('Fortress Around Your Heart') 64-bit
_STATISTICS_WRITING_DATE_UTC-eng: 2020-07-22 07:55:35
_STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:7: Attachment: otf
Metadata:
filename : FOT-MatissePro-DB.otf
mimetype : application/vnd.ms-opentype
Stream #0:8: Attachment: ttf
Metadata:
filename : FZZYSK.TTF
mimetype : application/x-truetype-font
Stream #0:9: Attachment: ttf
Metadata:
filename : 方正粗宋_GBK.ttf
mimetype : application/x-truetype-font
Stream #0:10: Attachment: ttf
Metadata:
filename : 方正准圆_GBK.ttf
mimetype : application/x-truetype-font
Stream mapping:
Stream #0:0 (hevc) -> setparams:default (graph 0)
overlay_vaapi:default (graph 0) -> Stream #0:0 (hevc_vaapi)
Stream #0:1 -> #0:1 (opus (native) -> aac (libfdk_aac))
Press [q] to stop, [?] for help
[Parsed_subtitles_2 @ 0x7fc0f0006a80] libass API version: 0x1703000
[Parsed_subtitles_2 @ 0x7fc0f0006a80] libass source: commit: 0.17.3-0-ge46aedea0a0d17da4c4ef49d84b94a7994664ab5
[Parsed_subtitles_2 @ 0x7fc0f0006a80] Shaper: FriBidi 1.0.16 (SIMPLE) HarfBuzz-ng 10.2.0 (COMPLEX)
[Parsed_subtitles_2 @ 0x7fc0f0006a80] Loading font file '/cache/attachments/a73e2ec42fa9f3014c86bcc6c27b1f80/FOT-MatissePro-DB.otf'
[Parsed_subtitles_2 @ 0x7fc0f0006a80] Loading font file '/cache/attachments/a73e2ec42fa9f3014c86bcc6c27b1f80/FZZYSK.TTF'
[Parsed_subtitles_2 @ 0x7fc0f0006a80] Loading font file '/cache/attachments/a73e2ec42fa9f3014c86bcc6c27b1f80/方正粗宋_GBK.ttf'
[Parsed_subtitles_2 @ 0x7fc0f0006a80] Loading font file '/cache/attachments/a73e2ec42fa9f3014c86bcc6c27b1f80/方正准圆_GBK.ttf'
[Parsed_subtitles_2 @ 0x7fc0f0006a80] Using font provider fontconfig
[Parsed_subtitles_2 @ 0x7fc0f0006a80] fontselect: (方正准圆_GBK, 700, 0) -> FZY3K--GBK1-0, 0, FZY3K--GBK1-0
Output #0, hls, to '/cache/transcodes/36df184ee5eeb6c0c6299ceb87021897.m3u8':
Metadata:
encoder : Lavf61.1.100
Stream #0:0: Video: hevc (Main) (hvc1 / 0x31637668), vaapi(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 5945 kb/s, 23.98 fps, 90k tbn
Metadata:
encoder : Lavc61.3.100 hevc_vaapi
Stream #0:1: Audio: aac, 48000 Hz, stereo, s16, 256 kb/s (default)
Metadata:
encoder : Lavc61.3.100 libfdk_aac
frame= 20 fps=0.0 q=-0.0 size=N/A time=00:00:00.00 bitrate=N/A speed= 0x
[Parsed_subtitles_2 @ 0x7fc0f0006a80] fontselect: (方正准圆_GBK, 400, 0) -> FZY3K--GBK1-0, 0, FZY3K--GBK1-0
frame= 48 fps= 48 q=-0.0 size=N/A time=00:00:01.16 bitrate=N/A speed=1.17x
[hls @ 0x55d1b1514700] Opening '/cache/transcodes/36df184ee5eeb6c0c6299ceb870218970.ts' for writing
frame= 75 fps= 50 q=-0.0 size=N/A time=00:00:02.29 bitrate=N/A speed=1.53x
frame= 102 fps= 51 q=-0.0 size=N/A time=00:00:03.42 bitrate=N/A speed=1.71x
frame= 129 fps= 52 q=-0.0 size=N/A time=00:00:04.54 bitrate=N/A speed=1.82x
[hls @ 0x55d1b1514700] Opening '/cache/transcodes/36df184ee5eeb6c0c6299ceb870218971.ts' for writing
frame= 157 fps= 52 q=-0.0 size=N/A time=00:00:05.71 bitrate=N/A speed= 1.9x
frame= 190 fps= 54 q=-0.0 size=N/A time=00:00:07.09 bitrate=N/A speed=2.03x
[hls @ 0x55d1b1514700] Opening '/cache/transcodes/36df184ee5eeb6c0c6299ceb870218972.ts' for writing
frame= 223 fps= 56 q=-0.0 size=N/A time=00:00:08.46 bitrate=N/A speed=2.12x
frame= 249 fps= 55 q=-0.0 size=N/A time=00:00:09.55 bitrate=N/A speed=2.12x
frame= 284 fps= 57 q=-0.0 size=N/A time=00:00:11.01 bitrate=N/A speed= 2.2x Owarimonogatari - partial log
ffmpeg version 7.0.2-Jellyfin Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 12 (Debian 12.2.0-14)
configuration: --prefix=/usr/lib/jellyfin-ffmpeg --target-os=linux --extra-version=Jellyfin --disable-doc --disable-ffplay --disable-ptx-compression --disable-static --disable-libxcb --disable-sdl2 --disable-xlib --enable-lto=auto --enable-gpl --enable-version3 --enable-shared --enable-gmp --enable-gnutls --enable-chromaprint --enable-opencl --enable-libdrm --enable-libxml2 --enable-libass --enable-libfreetype --enable-libfribidi --enable-libfontconfig --enable-libharfbuzz --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libopenmpt --enable-libdav1d --enable-libsvtav1 --enable-libwebp --enable-libvpx --enable-libx264 --enable-libx265 --enable-libzvbi --enable-libzimg --enable-libfdk-aac --arch=amd64 --enable-libshaderc --enable-libplacebo --enable-vulkan --enable-vaapi --enable-amf --enable-libvpl --enable-ffnvcodec --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvdec --enable-nvenc
libavutil 59. 8.100 / 59. 8.100
libavcodec 61. 3.100 / 61. 3.100
libavformat 61. 1.100 / 61. 1.100
libavdevice 61. 1.100 / 61. 1.100
libavfilter 10. 1.100 / 10. 1.100
libswscale 8. 1.100 / 8. 1.100
libswresample 5. 1.100 / 5. 1.100
libpostproc 58. 1.100 / 58. 1.100
[Parsed_subtitles_2 @ 0x55c596fb1f00] libass API version: 0x1703000
[Parsed_subtitles_2 @ 0x55c596fb1f00] libass source: commit: 0.17.3-0-ge46aedea0a0d17da4c4ef49d84b94a7994664ab5
[Parsed_subtitles_2 @ 0x55c596fb1f00] Shaper: FriBidi 1.0.16 (SIMPLE) HarfBuzz-ng 10.2.0 (COMPLEX)
[Parsed_subtitles_2 @ 0x55c596fb1f00] Using font provider fontconfig
Input #0, matroska,webm, from 'file:/video/神薙/[VCB-Studio] Kannagi [01][Ma10p_1080p][x265_flac_2aac].mkv':
Metadata:
encoder : libebml v1.4.4 + libmatroska v1.7.1
creation_time : 2025-08-28T07:04:44.000000Z
Duration: 00:23:41.03, start: 0.000000, bitrate: 6448 kb/s
Chapters:
Chapter #0:0: start 0.000000, end 117.017000
Metadata:
title : Chapter 01
Chapter #0:1: start 117.017000, end 207.040000
Metadata:
title : Chapter 02
Chapter #0:2: start 207.040000, end 864.997000
Metadata:
title : Chapter 03
Chapter #0:3: start 864.997000, end 1324.990000
Metadata:
title : Chapter 04
Chapter #0:4: start 1324.990000, end 1421.034000
Metadata:
title : Chapter 05
Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv, bt709/unknown/unknown), 1920x1080, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn (default)
Metadata:
BPS : 5423267
DURATION : 00:23:41.026000000
NUMBER_OF_FRAMES: 35185
NUMBER_OF_BYTES : 963325545
_STATISTICS_WRITING_APP: mkvmerge v80.0 ('Roundabout') 64-bit
_STATISTICS_WRITING_DATE_UTC: 2025-08-28 07:04:44
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:1(jpn): Audio: flac, 48000 Hz, stereo, s16 (default)
Metadata:
BPS : 583827
DURATION : 00:23:41.020000000
NUMBER_OF_FRAMES: 16653
NUMBER_OF_BYTES : 103703864
_STATISTICS_WRITING_APP: mkvmerge v80.0 ('Roundabout') 64-bit
_STATISTICS_WRITING_DATE_UTC: 2025-08-28 07:04:44
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:2(jpn): Audio: aac (LC), 48000 Hz, stereo, fltp
Metadata:
BPS : 169647
DURATION : 00:23:41.034000000
NUMBER_OF_FRAMES: 66611
NUMBER_OF_BYTES : 30134360
_STATISTICS_WRITING_APP: mkvmerge v80.0 ('Roundabout') 64-bit
_STATISTICS_WRITING_DATE_UTC: 2025-08-28 07:04:44
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:3(jpn): Audio: aac (LC), 48000 Hz, stereo, fltp
Metadata:
BPS : 169785
DURATION : 00:23:41.034000000
NUMBER_OF_FRAMES: 66611
NUMBER_OF_BYTES : 30158858
_STATISTICS_WRITING_APP: mkvmerge v80.0 ('Roundabout') 64-bit
_STATISTICS_WRITING_DATE_UTC: 2025-08-28 07:04:44
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:4(srd): Subtitle: ass (ssa) (default)
Metadata:
BPS : 108
DURATION : 00:23:09.900000000
NUMBER_OF_FRAMES: 343
NUMBER_OF_BYTES : 18791
_STATISTICS_WRITING_APP: mkvmerge v80.0 ('Roundabout') 64-bit
_STATISTICS_WRITING_DATE_UTC: 2025-08-28 07:04:44
_STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:5: Attachment: ttf
Metadata:
filename : 方正行楷_GBK.ttf
mimetype : application/x-truetype-font
Stream #0:6: Attachment: ttf
Metadata:
filename : 方正准圆_GBK.TTF
mimetype : application/x-truetype-font
Stream mapping:
Stream #0:0 (hevc) -> setparams:default (graph 0)
overlay_vaapi:default (graph 0) -> Stream #0:0 (hevc_vaapi)
Stream #0:1 -> #0:1 (flac (native) -> aac (libfdk_aac))
Press [q] to stop, [?] for help
[Parsed_subtitles_2 @ 0x7fc0cc006a80] libass API version: 0x1703000
[Parsed_subtitles_2 @ 0x7fc0cc006a80] libass source: commit: 0.17.3-0-ge46aedea0a0d17da4c4ef49d84b94a7994664ab5
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Shaper: FriBidi 1.0.16 (SIMPLE) HarfBuzz-ng 10.2.0 (COMPLEX)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Using font provider fontconfig
Output #0, hls, to '/cache/transcodes/62249dc233533765607b5d0c01e5893a.m3u8':
Metadata:
encoder : Lavf61.1.100
Stream #0:0: Video: hevc (Main) (hvc1 / 0x31637668), vaapi(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 6448 kb/s, 23.98 fps, 90k tbn
Metadata:
encoder : Lavc61.3.100 hevc_vaapi
Stream #0:1: Audio: aac, 48000 Hz, stereo, s16, 256 kb/s (default)
Metadata:
encoder : Lavc61.3.100 libfdk_aac
frame= 0 fps=0.0 q=0.0 size=N/A time=N/A bitrate=N/A speed=N/A
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: (方正准圆_GBK, 700, 0) -> /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf, 0, DejaVuSans-Bold
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Glyph 0x6293 not found, selecting one more font for (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: failed to find any fallback with glyph 0x6293 for font: (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Glyph 0x5230 not found, selecting one more font for (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: failed to find any fallback with glyph 0x5230 for font: (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Glyph 0x4E86 not found, selecting one more font for (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: failed to find any fallback with glyph 0x4E86 for font: (方正准圆_GBK, 700, 0)
frame= 24 fps= 24 q=-0.0 size=N/A time=00:00:00.00 bitrate=N/A speed= 0x
frame= 58 fps= 39 q=-0.0 size=N/A time=00:00:01.41 bitrate=N/A speed=0.945x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a0.ts' for writing
frame= 88 fps= 44 q=-0.0 size=N/A time=00:00:02.66 bitrate=N/A speed=1.33x
frame= 115 fps= 46 q=-0.0 size=N/A time=00:00:03.79 bitrate=N/A speed=1.52x
frame= 142 fps= 47 q=-0.0 size=N/A time=00:00:04.92 bitrate=N/A speed=1.64x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a1.ts' for writing
frame= 168 fps= 48 q=-0.0 size=N/A time=00:00:06.00 bitrate=N/A speed=1.72x
frame= 194 fps= 48 q=-0.0 size=N/A time=00:00:07.09 bitrate=N/A speed=1.77x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a2.ts' for writing
frame= 219 fps= 49 q=-0.0 size=N/A time=00:00:08.13 bitrate=N/A speed=1.81x
frame= 250 fps= 50 q=-0.0 size=N/A time=00:00:09.42 bitrate=N/A speed=1.88x
frame= 276 fps= 50 q=-0.0 size=N/A time=00:00:10.51 bitrate=N/A speed=1.91x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a3.ts' for writing
frame= 300 fps= 50 q=-0.0 size=N/A time=00:00:11.51 bitrate=N/A speed=1.92x
frame= 329 fps= 51 q=-0.0 size=N/A time=00:00:12.72 bitrate=N/A speed=1.96x
frame= 354 fps= 51 q=-0.0 size=N/A time=00:00:13.76 bitrate=N/A speed=1.97x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a4.ts' for writing
frame= 376 fps= 50 q=-0.0 size=N/A time=00:00:14.68 bitrate=N/A speed=1.96x
frame= 400 fps= 50 q=-0.0 size=N/A time=00:00:15.68 bitrate=N/A speed=1.96x
frame= 424 fps= 50 q=-0.0 size=N/A time=00:00:16.68 bitrate=N/A speed=1.96x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a5.ts' for writing
frame= 448 fps= 50 q=-0.0 size=N/A time=00:00:17.68 bitrate=N/A speed=1.96x
frame= 471 fps= 50 q=-0.0 size=N/A time=00:00:18.64 bitrate=N/A speed=1.96x
frame= 495 fps= 49 q=-0.0 size=N/A time=00:00:19.64 bitrate=N/A speed=1.96x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a6.ts' for writing
frame= 518 fps= 49 q=-0.0 size=N/A time=00:00:20.60 bitrate=N/A speed=1.96x
frame= 543 fps= 49 q=-0.0 size=N/A time=00:00:21.64 bitrate=N/A speed=1.97x
frame= 569 fps= 49 q=-0.0 size=N/A time=00:00:22.73 bitrate=N/A speed=1.98x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a7.ts' for writing
frame= 596 fps= 50 q=-0.0 size=N/A time=00:00:23.85 bitrate=N/A speed=1.99x
frame= 624 fps= 50 q=-0.0 size=N/A time=00:00:25.02 bitrate=N/A speed= 2x
[hls @ 0x55c596f0f880] Opening '/cache/transcodes/62249dc233533765607b5d0c01e5893a8.ts' for writing
frame= 652 fps= 50 q=-0.0 size=N/A time=00:00:26.19 bitrate=N/A speed=2.01x
frame= 680 fps= 50 q=-0.0 size=N/A time=00:00:27.36 bitrate=N/A speed=2.03x
frame= 709 fps= 51 q=-0.0 size=N/A time=00:00:28.57 bitrate=N/A speed=2.04x
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Glyph 0x6293 not found, selecting one more font for (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: failed to find any fallback with glyph 0x6293 for font: (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Glyph 0x5230 not found, selecting one more font for (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: failed to find any fallback with glyph 0x5230 for font: (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Glyph 0x4E86 not found, selecting one more font for (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: failed to find any fallback with glyph 0x4E86 for font: (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Glyph 0x6293 not found, selecting one more font for (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: failed to find any fallback with glyph 0x6293 for font: (方正准圆_GBK, 700, 0)
[Parsed_subtitles_2 @ 0x7fc0cc006a80] Glyph 0x5230 not found, selecting one more font for (方正准圆_GBK, 700, 0)Kannagi - partial log
By comparing the two, we can see that in Owarimonogatari, which displayed subtitles successfully:
[Parsed_subtitles_2 @ 0x7fc0f0006a80] fontselect: (方正准圆_GBK, 700, 0) -> FZY3K--GBK1-0, 0, FZY3K--GBK1-0
The system successfully found the font specified by the subtitle file from the attachments.
Whereas in Kannagi:
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: (方正准圆_GBK, 700, 0) -> /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf, 0, DejaVuSans-Bold
[Parsed_subtitles_2 @ 0x7fc0cc006a80] fontselect: failed to find any fallback with glyph 0x5230 for font: (方正准圆_GBK, 700, 0)
The system did not attempt to find the font from the attachments and instead went straight to the fonts inside the Jellyfin container. Since the Jellyfin container doesn't come with any fonts that support Chinese characters, the subtitles could not be rendered properly.
Unlike clients on other platforms, the Android TV version of Jellyfin apparently does not look for fonts in the fallback font directory.
Solution
Now that we know the issue is caused by missing fonts, the fix is straightforward — just add the Noto Sans CJK font package to the /usr/share/fonts/truetype/ path as well. We can use symbolic links so that when the system looks for fonts in /usr/share/fonts/truetype/, it automatically redirects to our fallback font path.
- Install fontconfig to manage fonts:
# Enter the container (use sudo if you have permission issues)
docker exec -it jellyfin-jellyfin-1 bash
# Install
apt-get update
apt-get install -y fontconfig- Create the font directory and set up symbolic links:
mkdir -p /usr/share/fonts/custom
ln -sf /config/config/font/* /usr/share/fonts/custom/- Configure fontconfig to prioritize Simplified Chinese fonts:
cat > /etc/fonts/local.conf <<'XML'
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/usr/share/fonts/custom</dir>
<alias>
<family>sans-serif</family>
<prefer>
<family>Noto Sans CJK SC</family>
<family>Noto Sans CJK TC</family>
</prefer>
</alias>
</fontconfig>
XML- Refresh the cache and verify:
# Refresh font cache
fc-cache -f -v
# Exit the Docker container
exit
# Verify
docker exec jellyfin-jellyfin-1 fc-match "方正准圆_GBK"
docker exec jellyfin-jellyfin-1 fc-match "Noto Sans CJK SC"
docker exec jellyfin-jellyfin-1 fc-match ":lang=zh,sans-serif"
If the output shows a NotoSansCJK font, it means the setup was successful.
Now play the video again on the Android TV Jellyfin client, and the Chinese subtitles should display correctly.
Note that these changes may be lost after a Jellyfin version upgrade. You can either redo the steps manually or combine them into a script to run when needed.
Hope this blog post helps anyone who ran into the same issue as me :)
Thanks for reading~