前言#
對視頻播放有所研究的朋友應該都對mpv這個功能豐富,配置靈活的播放器不陌生,其中的Conditional auto profiles功能甚得我心,比如說你可以通過下面的配置實現不同語言的字幕使用不同的字體:
[zh-Hans]
profile-cond=string.sub(get("current-tracks/sub/lang"), 1, 7) == "zh-Hans"
sub-font='Source Han Sans SC'
[zh-Hant]
profile-cond=string.sub(get("current-tracks/sub/lang"), 1, 7) == "zh-Hant"
sub-font='Source Han Sans HC'
mpv 同時也是許多其他播放器的內置模塊,比如IINA和Jellyfin Media Player,這兩個播放器也支持自定義的 mpv 配置。
關於 mpv 的更多配置項,可參考VCB-S 的入門教程。
問題#
mpv 使用libass渲染 SRT 等純文本字體,而 libass 在 macOS 上默認使用 CoreText 作為 font provider 讀取字體,這帶來了一些問題。
首先是可變字體,libass 只能讀取到最細的樣式,--sub-bold=yes
參數也無法生效(測試了 Noto Sans CJK 系列和 Fira Code 都是如此)。
其次是字幕中的 Emoji,libass 無法顯示,我猜是因為 fallback 到了一个彩色的 Emoji 字體,而 libass 只支持單色(monochrome)字體(相關 issue)。
查閱了資料發現 libass 在 Linux 上使用的 Fontconfig 也是支持 macOS 的,而 Fontconfig 有著豐富的自定義配置功能。抱著死馬當活馬醫的想法,我試了試用 Fontconfig 替換掉 CoreText,結果確實可以解決上述兩個問題。
實操#
以下使用 Homebrew 安裝啟用 Fontconfig 支持的 libass。
首先安裝 Fontconfig:
brew install fontconfig
Homebrew 上的 libass 默認是不會在 macOS 上啟用 Fontconfig 的,我們需要先修改編譯腳本。
最新版的 Homebrew 默認使用 API 的方式獲取安裝腳本,而不是克隆 tap 倉庫,這會導致對安裝腳本的修改無法生效,這裡先暫時禁用 API 模式。
export HOMEBREW_NO_INSTALL_FROM_API=1
brew update
brew edit libass
把 formula code 裡 fontconfig 相關的 Linux 條件刪除,再刪除--disable-fontconfig
參數,然後重新從源碼安裝 libass:
brew reinstall --build-from-source libass
到這一步 Homebrew 安裝的 mpv 已經可以使用--sub-font-provider=fontconfig
參數來啟用 Fontconfig 了。
修改~/.config/fontconfig/fonts.conf
,將 mpv 中使用的字體名設置為一系列字體的別名,就可以自定義 fallback 順序了:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "/opt/homebrew/share/xml/fontconfig/fonts.dtd">
<fontconfig>
<include ignore_missing="yes">/opt/homebrew/etc/fonts/fonts.conf</include>
<alias>
<family>Source Han Sans HC</family>
<prefer>
<family>Noto Sans CJK HK</family>
<family>Noto Emoji</family>
</prefer>
</alias>
</fontconfig>
這裡使用的是 monochrome 的 Emoji 字體Noto Emoji。
最後,IINA 和 Jellyfin Media Player 使用的是自帶的 libmpv 和 libass,需要使用/opt/homebrew/lib/libass.9.dylib
替換掉各自包內的libass.9.dylib
。
本文章發布在以下多個網站:
GitHub Pages
xLog(可評論)