为小视频渲染像素完美的字幕
Posted
技术标签:
【中文标题】为小视频渲染像素完美的字幕【英文标题】:Rendering pixel perfect subtitles for small videos 【发布时间】:2017-08-27 10:45:18 【问题描述】:我想在小尺寸视频上刻录字体尽可能小(但可读)的字幕,如第一张图片所示。 FFmpeg 使尝试的任何字体大小的字体都变得模糊(第二张图片)。
ffmpeg -i in.jpg -vf "scale=160x128,subtitles=in.srt:force_style='OutlineColour=&H80000000,BorderStyle=3,Fontsize=15,Fontname=Silkscreen'" out.png
有没有什么方法可以使用 FFmpeg 或其他现成的命令行工具来实现像素完美的小字体字幕? (我找到的最小字体是Silkscreen,虽然它只是ASCII!)
【问题讨论】:
the officialsubtitles
video filter documentation 有帮助吗?
光栅化是libass完成的,不是ffmpeg和AFAICT,抗锯齿不能跳过。
另请注意,除非做错了,否则抗锯齿应该不降低可读性(这不是它正在做的,理论上的信号)
@MarcusMüller:非常小的字体上的抗锯齿会破坏它。我可以说没有绕过这个的选项。
值得try,尽管我不关注该库的开发。一种解决方法可能是在大型透明画布上渲染字幕,然后将其缩小并覆盖在小视频上。
【参考方案1】:
您可以通过在 libass 中启用字体提示来获得更好的结果,但是 appears FFmpeg 目前不支持设置此选项。用mpv试试这个:
mpv in.jpg --vf=scale=160:128 --sub-file=in.srt --sub-ass-hinting=light --sub-font=Silkscreen --sub-font-size=54 --sub-back-color=0/0/0/0.5 --sub-color=1/1/1 --o=out.png
(还有--sub-ass-force-style=FontName=Silkscreen,etc.
,如果您需要它或者只是更喜欢直接使用 ASS 语法。)
--sub-ass-hinting=normal
或 --sub-ass-hinting=native
可能会更好,但值 light
为我提供了问题中图像的最佳结果。
这是我得到的:
(我在网上找到的源图像的宽高比是 3:2,但您的示例是 4:3。在左侧,我必须使用 --vf=scale=160:120,dsize=160:120
来匹配您的尺寸和宽高比。在右侧,我用--vf=scale=180:120
来匹配你的图像高度但保持原来的纵横比。)
为了获得更好的结果,您可能需要调整字体大小,因为据我所知,相关字体已针对特定大小进行了优化。 ASS“字体大小”不是以磅为单位的传统字体大小(而是以像素为单位的上升高度和下降高度之和),所以这并非完全无关紧要,但一些实验可能会让你到达那里。
与您的旧方法相比,这也为您在字幕周围/后面提供了一个更干净的框。当您像现在这样使用带有半透明 OutlineColour
的 BorderStyle=3
时,每行文本都有一个单独的框,并且这些框略有重叠;因此,您可以在每两行文本之间看到一个颜色较深/颜色较深的薄区域。这在你的尺寸下可能不是很明显,但如果你足够努力的话,你会看到它。作为 ASS 格式的扩展,libass 支持自定义 BorderStyle=4
,它会在整个文本周围生成一个框。在 mpv 中设置--sub-back-color
时,它会自动选择它。 (如果多个文本同时出现,每个文本仍然有自己的框,并且框可能重叠。但根据我非常简短的搜索,似乎这种情况在 SRT 文件中很少见。)你想恢复到BorderStyle=3
,我认为您需要添加--sub-ass-force-style=BorderStyle=3
并将--sub-back-color
替换为--sub-border-color
。
【讨论】:
以上是关于为小视频渲染像素完美的字幕的主要内容,如果未能解决你的问题,请参考以下文章