fix(backend): #1896 修复字体映射补充开源字体文件 #1912

Merged
xiaoxia merged 1 commits from fix/1896-font-mapping-open-source into develop 2026-09-14 21:43:30 +08:00
Owner

背景

Issue #1896:后端 DRAWTEXT_FONT_MAP 把所有前端字体选项(思源宋体/苹方/微软雅黑/楷体/华康俪金黑)全部映射到 NotoSansSC,导致成片无论选什么字体都渲染为思源黑体。FONT_NAME_MAP 也将楷体错误映射到 Noto Serif CJK SC(宋体),ASS 字幕楷体显示为宋体。

修复

1. 字体映射修复

  • packages/domain/video_filter_builder.py:
    • DRAWTEXT_FONT_MAP 每个字体映射到独立关键字:思源宋体→NotoSerifCJKsc,楷体→LXGWWenKai,苹方/PingFang/微软雅黑/Microsoft YaHei 明确标注 fallback NotoSansSC(macOS/Windows 系统字体服务器 Linux 不存在),华康俪金黑→NotoSansSC(商业字体版权风险,前端已按 #1896 删除选项,保留映射兼容老数据)
    • DRAWTEXT_FONT_SEARCH_PATHS 新增 NotoSerifCJKsc-VF.otf(第2位)和 LXGWWenKai-Regular.ttf(第3位)路径
  • packages/domain/ass_subtitle_builder.py:
    • FONT_NAME_MAP 楷体映射到 "LXGW WenKai"(已通过 fc-list 验证注册名),思源宋体已正确映射 "Noto Serif CJK SC"(fonts-noto-cjk 包自带 + VF.otf)
    • 新增 Microsoft YaHei、霞鹜文楷、华康俪金黑别名映射

2. 开源字体文件补充(SIL OFL / Apache 2.0 免费可商用)

  • infra/fonts/NotoSerifCJKsc-VF.otf(53MB):思源宋体 Noto Serif CJK SC 可变字体,含多字重
  • infra/fonts/LXGWWenKai-Regular.ttf(25MB):霞鹜文楷 v1.522 开源楷体,SIL OFL
  • 原 NotoSansSC-VF.ttf(17MB)保留
  • 字体目录总大小 95MB(新增 78MB),Docker 分层缓存不显著拉长构建

3. Dockerfile 更新

  • infra/docker/worker-base.Dockerfile + api-base.Dockerfile:
    • 删除 Sans .ttc(Mono 变体问题),保留 Serif .ttc 作为宋体 fallback
    • mkdir -p /usr/share/fonts/truetype/lxgw 创建楷体目录
    • COPY 两个新字体到对应目录
    • fc-cache -fv 重建字体缓存

字体选型说明

前端选项 后端映射 字体文件 License 备注
思源黑体 NotoSansSC NotoSansSC-VF.ttf SIL OFL 已存在,主默认字体
思源宋体 NotoSerifCJKsc NotoSerifCJKsc-VF.otf (+ ttc fallback) SIL OFL #1896 新增 VF
楷体 LXGWWenKai LXGWWenKai-Regular.ttf SIL OFL #1896 新增,霞鹜文楷
苹方/PingFang NotoSansSC (fallback) NotoSansSC-VF.ttf - macOS 系统字体,Linux 不存在
微软雅黑 NotoSansSC (fallback) NotoSansSC-VF.ttf - Windows 系统字体,Linux 不存在
华康俪金黑 NotoSansSC (fallback) NotoSansSC-VF.ttf - 商业字体有版权风险,前端已删除,兼容老数据
霞鹜文楷 LXGWWenKai LXGWWenKai-Regular.ttf SIL OFL 新增别名,便于扩展

前端需按 #1896 同步:删除"华康俪金黑"选项(或替换为"思源黑体粗体"用 font_weight 控制)。

测试

  • fc-list 本地实测:LXGW WenKai,霞鹜文楷:style=Regular 和 Noto Serif CJK SC 注册名均可被 fontconfig 识别
  • FFmpeg drawtext/ASS/libass 三条渲染路径字体映射均独立正确
  • _resolve_font_path 通过 os.path.isfile 动态查找,新路径无文件时自动 fallback
  • 899 个字幕/滤镜/合成相关单测全通过;190 个 writeback/filter/compose 单测全通过
  • 苹方/微软雅黑等系统字体通过 NotoSansSC fallback 正常显示中文
  • 存量数据(老数据选华康俪金黑/苹方等)继续渲染不中断

Refs: #1896

## 背景 Issue #1896:后端 DRAWTEXT_FONT_MAP 把所有前端字体选项(思源宋体/苹方/微软雅黑/楷体/华康俪金黑)全部映射到 NotoSansSC,导致成片无论选什么字体都渲染为思源黑体。FONT_NAME_MAP 也将楷体错误映射到 Noto Serif CJK SC(宋体),ASS 字幕楷体显示为宋体。 ## 修复 ### 1. 字体映射修复 - `packages/domain/video_filter_builder.py`: - DRAWTEXT_FONT_MAP 每个字体映射到独立关键字:思源宋体→NotoSerifCJKsc,楷体→LXGWWenKai,苹方/PingFang/微软雅黑/Microsoft YaHei 明确标注 fallback NotoSansSC(macOS/Windows 系统字体服务器 Linux 不存在),华康俪金黑→NotoSansSC(商业字体版权风险,前端已按 #1896 删除选项,保留映射兼容老数据) - DRAWTEXT_FONT_SEARCH_PATHS 新增 NotoSerifCJKsc-VF.otf(第2位)和 LXGWWenKai-Regular.ttf(第3位)路径 - `packages/domain/ass_subtitle_builder.py`: - FONT_NAME_MAP 楷体映射到 `"LXGW WenKai"`(已通过 fc-list 验证注册名),思源宋体已正确映射 `"Noto Serif CJK SC"`(fonts-noto-cjk 包自带 + VF.otf) - 新增 Microsoft YaHei、霞鹜文楷、华康俪金黑别名映射 ### 2. 开源字体文件补充(SIL OFL / Apache 2.0 免费可商用) - `infra/fonts/NotoSerifCJKsc-VF.otf`(53MB):思源宋体 Noto Serif CJK SC 可变字体,含多字重 - `infra/fonts/LXGWWenKai-Regular.ttf`(25MB):霞鹜文楷 v1.522 开源楷体,SIL OFL - 原 NotoSansSC-VF.ttf(17MB)保留 - 字体目录总大小 95MB(新增 78MB),Docker 分层缓存不显著拉长构建 ### 3. Dockerfile 更新 - `infra/docker/worker-base.Dockerfile` + `api-base.Dockerfile`: - 删除 Sans .ttc(Mono 变体问题),**保留 Serif .ttc** 作为宋体 fallback - `mkdir -p /usr/share/fonts/truetype/lxgw` 创建楷体目录 - COPY 两个新字体到对应目录 - fc-cache -fv 重建字体缓存 ## 字体选型说明 | 前端选项 | 后端映射 | 字体文件 | License | 备注 | |---|---|---|---|---| | 思源黑体 | NotoSansSC | NotoSansSC-VF.ttf | SIL OFL | 已存在,主默认字体 | | 思源宋体 | NotoSerifCJKsc | NotoSerifCJKsc-VF.otf (+ ttc fallback) | SIL OFL | #1896 新增 VF | | 楷体 | LXGWWenKai | LXGWWenKai-Regular.ttf | SIL OFL | #1896 新增,霞鹜文楷 | | 苹方/PingFang | NotoSansSC (fallback) | NotoSansSC-VF.ttf | - | macOS 系统字体,Linux 不存在 | | 微软雅黑 | NotoSansSC (fallback) | NotoSansSC-VF.ttf | - | Windows 系统字体,Linux 不存在 | | 华康俪金黑 | NotoSansSC (fallback) | NotoSansSC-VF.ttf | - | 商业字体有版权风险,前端已删除,兼容老数据 | | 霞鹜文楷 | LXGWWenKai | LXGWWenKai-Regular.ttf | SIL OFL | 新增别名,便于扩展 | 前端需按 #1896 同步:删除"华康俪金黑"选项(或替换为"思源黑体粗体"用 font_weight 控制)。 ## 测试 - fc-list 本地实测:`LXGW WenKai,霞鹜文楷:style=Regular` 和 `Noto Serif CJK SC` 注册名均可被 fontconfig 识别 - FFmpeg drawtext/ASS/libass 三条渲染路径字体映射均独立正确 - _resolve_font_path 通过 os.path.isfile 动态查找,新路径无文件时自动 fallback - 899 个字幕/滤镜/合成相关单测全通过;190 个 writeback/filter/compose 单测全通过 - 苹方/微软雅黑等系统字体通过 NotoSansSC fallback 正常显示中文 - 存量数据(老数据选华康俪金黑/苹方等)继续渲染不中断 Refs: #1896
xiaoxia added 1 commit 2026-09-14 20:57:32 +08:00
fix(backend): #1896 修复字体映射补充开源字体文件
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 4s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 4s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m10s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 11s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 11s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m19s
AI Code Review / AI Code Review (pull_request) Successful in 6m50s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 9m8s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 10m8s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 10m34s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 12m41s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 11m23s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 33m11s
CI/CD Pipeline / CI Gate (pull_request) Successful in 6s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 20s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m44s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 41h52m48s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 42h23m34s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 42h23m50s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 42h26m4s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 42h26m11s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 42h25m34s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 42h25m34s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 42h25m41s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 42h25m42s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 42h25m44s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 41h52m23s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 41h52m23s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 41h52m24s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 41h52m17s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 42h23m4s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 42h23m4s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 42h23m8s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 42h23m31s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 42h23m31s
dc5165bd5f
问题:DRAWTEXT_FONT_MAP把所有前端字体(思源宋体/苹方/微软雅黑/楷体/华康俪金黑)全部映射到 NotoSansSC,导致无论选什么字体成片都渲染为思源黑体;FONT_NAME_MAP 将楷体错误映射到 Noto Serif CJK SC(宋体)。

修复:
- packages/domain/video_filter_builder.py:
  * DRAWTEXT_FONT_MAP 每个字体映射到独立关键字:思源宋体→NotoSerifCJKsc,楷体→LXGWWenKai,苹方/微软雅黑/PingFang 明确标注fallback NotoSansSC(macOS/Windows 系统字体服务器不存在),华康俪金黑→NotoSansSC(商业字体版权风险,前端已移除,兼容老数据)
  * DRAWTEXT_FONT_SEARCH_PATHS 新增 NotoSerifCJKsc-VF.otf 和 LXGWWenKai-Regular.ttf 路径
- packages/domain/ass_subtitle_builder.py:
  * FONT_NAME_MAP 楷体映射到 'LXGW WenKai'(fc-list 验证注册名),思源宋体已正确映射 'Noto Serif CJK SC'(fonts-noto-cjk 包自带);新增 Microsoft YaHei/霞鹜文楷/华康俪金黑别名
- infra/fonts/ 新增两个开源字体文件(SIL Open Font License/Apache 2.0 免费可商用):
  * NotoSerifCJKsc-VF.otf(53MB,思源宋体可变字体,含多字重)
  * LXGWWenKai-Regular.ttf(25MB,霞鹜文楷开源楷体,v1.522)
- infra/docker/worker-base.Dockerfile + api-base.Dockerfile:
  * 保留 Serif .ttc(宋体fallback),仅删除 Sans .ttc(Mono变体问题)
  * COPY 新字体到镜像对应目录,fc-cache -fv 重建字体缓存
  * mkdir -p /usr/share/fonts/truetype/lxgw 确保楷体目录存在
- 字体大小总增量约 78MB(17M→95M),Docker 镜像分层缓存不会显著拉长构建时间

验证:
- 视频合成/ASS字幕/字幕滤镜三条渲染路径字体映射均独立正确
- fc-list 在本地实测可正确识别 'LXGW WenKai' / 'Noto Serif CJK SC' 注册名
- 苹方/微软雅黑等系统字体通过 NotoSansSC fallback 正常显示中文
- 存量数据(老数据选华康俪金黑/苹方等)继续渲染不中断
- 899 个字幕/滤镜/合成相关单测全通过,190 个writeback/filter/compose单测全通过

🚀 预览环境已部署

项目 详情
PR号 #1912
预览链接 https://pr-1912.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1912 | | 预览链接 | [https://pr-1912.preview.xiaoxiajianji.com](https://pr-1912.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia merged commit 2fb987bbee into develop 2026-09-14 21:43:30 +08:00

🗑️ 预览环境已清理

PR #1912 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1912 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.