将 English 文本与 Arabic 或 Persian 字符组合时,我遇到了 FFmpeg 渲染的 ASS 字幕中字体大小不匹配的问题。
重现步骤:
1.字幕文件: 这是 ASS 字幕文件的示例:
[Script Info]
Title: Generated ASS
ScriptType: v4.00+
WrapStyle: 2
ScaledBorderAndShadow: yes
YCbCr Matrix: none
PlayResX: 1920
PlayResY: 1080
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default, ABeeZee, 40, &H00FFFFFF, &H000000FF, &H00000000, &H00000000, -1, 0, 0, 0, 100, 100, 0, 0, 1, 1, 0, 2, 10, 10, 10, 1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:01.00,0:00:05.00,Default,,0,0,0,,Hello! This is English text.
Dialogue: 0,0:00:05.00,0:00:10.00,Default,,0,0,0,,سلام! This is mixed Arabic/English text.
ffmpeg -i input.mp4 -vf "ass=subtitle.ass" output.mp4
• 使用主字体 (ABeeZee) 渲染的文本是正确的。
• 使用后备字体 (Cinema) 渲染的文本尺寸显得更大/更小。
[Parsed_ass_0 @ 0xb4000079f04f8210] libass API version: 0x1701000
[Parsed_ass_0 @ 0xb4000079f04f8210]
[Parsed_ass_0 @ 0xb4000079f04f8210] libass source: commit: 0.17.1-0-ge8ad72accd3a84268275a9385beb701c9284e5b3
[Parsed_ass_0 @ 0xb4000079f04f8210]
[Parsed_ass_0 @ 0xb4000079f04f8210] Shaper: FriBidi 1.0.13 (SIMPLE) HarfBuzz-ng 8.0.1 (COMPLEX)
[Parsed_ass_0 @ 0xb4000079f04f8210]
[Parsed_ass_0 @ 0xb4000079f04f8210] Using font provider fontconfig
[Parsed_ass_0 @ 0xb4000079f04f8210]
[Parsed_ass_0 @ 0xb4000079f04f8210] Added subtitle file: '/data/***/ass_file.ass' (4 styles, 29 events)
[Parsed_ass_0 @ 0xb4000079f04f8210]
[Parsed_ass_0 @ 0xb4000079f04f8210] fontselect: (ABeeZee, 400, 0) -> /data/***/ABeeZee_regular.ttf, 0, ABeeZee-Regular
[Parsed_ass_0 @ 0xb4000079f04f8210]
[Parsed_ass_0 @ 0xb4000079f04f8210] Glyph 0x633 not found, selecting one more font for (ABeeZee, 400, 0)
[Parsed_ass_0 @ 0xb4000079f04f8210]
[Parsed_ass_0 @ 0xb4000079f04f8210] fontselect: (ABeeZee, 400, 0) -> /data/***/Cinema.ttf, 0, Cinema
问题:
如何确保使用后备字体呈现的文本与主要字体具有相同的大小? FFmpeg 或 ASS 字幕格式中是否有可以解决此问题的特定设置?或者,有没有办法手动调整 FFmpeg 中后备字体的缩放比例?
此问题部分是由于字体造成的,部分是由于 ASS 渲染器中文本渲染的工作方式造成的。您的后备字体 Cinema(由 MaryamSoft 提供)有一个异常大的 win-descender,这很奇怪。
红线是字母“坐”的基线。低于基线的是胜利下降,高于基线是胜利上升。 Ascender space 用于上升(字母中延伸 x 高度的部分),而 win-ascender 是确定渲染字体上限的实际行。胜利下降具有相同的目的,但低于基线。
而且由于在 Cinema 字体中,win-descender 过大,因此会产生不必要的边距/填充,导致字体看起来比预期小。
这些指标对于 ASS 如何显示字体至关重要,假设文本在 ASS 中的字体大小为 40px(如您的示例中所示),那么它的使用方式如下:
OS/2表中的
usWinAscent
和 usWinDescent
值定义的线条进行渲染和约束。从技术上讲,单独使用 ASS 可以缓解这种情况(通过应用更大的
\fs
覆盖标签内联,人为调整行间距,使用大的 x 旋转原点 \org
,并使用 \frz
稍微旋转文本) )。然而,我不鼓励这样的黑客行为(除了它会导致更糟糕的渲染性能并导致文本微小失真这一事实之外,但说实话,如果没有并排比较,它是无法区分的)。
更好的方法是修改字体,使
usWinAscent
和 usWinDescent
值更加合理。如果字体缺少 OS/2 表,您需要调整 sTypoAscender
和 sTypoDescender
值。请小心不要过度,如果您将值设置得太低,可能会导致部分字形被剪切。
但是,最好的解决方案是简单地选择设计更好的不同后备字体。