diff --git a/video-ai-system/CURRENT.hdlp b/video-ai-system/CURRENT.hdlp index aab9f70..967ef5b 100644 --- a/video-ai-system/CURRENT.hdlp +++ b/video-ai-system/CURRENT.hdlp @@ -126,7 +126,8 @@ JZAO外置盘: 产物存放地,不是状态主控。 | 固定道具合成路线 | ✅ 已建立 | `video-ai-system/plans/script-to-screen/EP01-LOCKED-PROP-COMPOSITING-ROUTE.hdlp` | | 苏白+牌匾合成小样 | 🟡 技术通过·位置失败 | `video-ai-system/outputs/tests/TEST-COMP-001-SUBAI-PLAQUE-OVERLAY-RUN-001-REPORT.hdlp` | | 牌匾固定贴图 | ✅ PNG已生成 | `video-ai-system/assets/props/PROP-TDZ-PLAQUE/texture/tdz-plaque-texture.png` | -| 字幕渲染合成 | ✅ 纯白样式RUN-003通过 | `video-ai-system/outputs/tests/TEST-SUBTITLE-003-CLEAN-WHITE-RUN002-REPORT.hdlp` | +| 字幕渲染合成 | ✅ 粗白短剧样式RUN-004通过 | `video-ai-system/outputs/tests/TEST-SUBTITLE-004-SHORT-DRAMA-BOLD-REPORT.hdlp` | +| 字幕样式标准 | ✅ 已建立 | `video-ai-system/knowledge/SUBTITLE-STYLE-STANDARD.hdlp` | | 百宗会人群底片 | 🟡 RUN-002可作氛围候选 | `video-ai-system/outputs/tests/TEST-PROP-001-TDZ-PLAQUE-RUN-002-REPORT.hdlp` | | 苏白TTS配音 | ✅ 工程测试通过 | `video-ai-system/outputs/tests/TEST-TTS-001-SUBAI-RUN-001-REPORT.hdlp` | | 模型/成本路线 | ✅ 已建立 | `video-ai-system/knowledge/D144-MODEL-COST-ROUTE.hdlp` | diff --git a/video-ai-system/engines/subtitle-renderer.py b/video-ai-system/engines/subtitle-renderer.py index f779b46..a8c9d38 100644 --- a/video-ai-system/engines/subtitle-renderer.py +++ b/video-ai-system/engines/subtitle-renderer.py @@ -27,7 +27,7 @@ Subtitle Renderer · 字幕渲染引擎 字幕样式配置: --font-size : 字体大小(默认 36) --font-color : 字体颜色(默认 white) - --style : 字幕样式(clean-white / black-box,默认 clean-white) + --style : 字幕样式(short-drama-bold / clean-white / black-box,默认 short-drama-bold) --position : 位置(top / middle / bottom,默认 bottom) --margin-bottom : 底部边距(默认 100px) @@ -60,35 +60,46 @@ except ImportError: # 默认字幕样式 DEFAULT_STYLE = { - "font_size": 36, + "font_size": 44, "font_color": "white", "bg_enabled": False, "position": "bottom", # top / middle / bottom - "margin_bottom": 100, + "margin_bottom": 84, "margin_horizontal": 60, "stroke_color": "black", - "stroke_width": 0, + "stroke_width": 1, + "bold_weight": 2, "video_width": 1080, "video_height": 1920, } SUBTITLE_STYLE_PRESETS = { + "short-drama-bold": { + "font_color": (255, 255, 255, 255), + "bg_enabled": False, + "stroke_width": 1, + "stroke_color": (18, 18, 18, 220), + "bold_weight": 2, + }, "clean-white": { - "font_color": "white", + "font_color": (255, 255, 255, 255), "bg_enabled": False, "stroke_width": 0, + "bold_weight": 1, }, "black-box": { - "font_color": "white", + "font_color": (255, 255, 255, 255), "bg_enabled": True, "bg_fill": (0, 0, 0, 160), "stroke_width": 0, + "bold_weight": 1, }, "outlined-white": { - "font_color": "white", + "font_color": (255, 255, 255, 255), "bg_enabled": False, "stroke_width": 2, - "stroke_color": "black", + "stroke_color": (0, 0, 0, 255), + "bold_weight": 1, }, } @@ -161,7 +172,7 @@ def render_subtitle_png( bg_y2 = y + text_height + bg_padding draw.rectangle([bg_x1, bg_y1, bg_x2, bg_y2], fill=style.get("bg_fill", (0, 0, 0, 160))) - # 可选描边。默认纯白字幕不描边。 + # 可选描边。短剧默认使用极细暗边,不使用投影。 stroke_width = style.get("stroke_width", 2) stroke_color = style.get("stroke_color", "black") if stroke_width > 0: @@ -169,9 +180,16 @@ def render_subtitle_png( draw.text((x + offset, y), text, font=font, fill=stroke_color) draw.text((x, y + offset), text, font=font, fill=stroke_color) - # 绘制主文本 + # 绘制主文本。bold_weight 用多次微偏移模拟加粗,避免依赖某台机器是否有粗体中文字体。 font_color = style.get("font_color", "white") - draw.text((x, y), text, font=font, fill=font_color) + bold_weight = max(1, int(style.get("bold_weight", 1))) + offsets = [(0, 0)] + if bold_weight >= 2: + offsets += [(-1, 0), (1, 0), (0, -1), (0, 1)] + if bold_weight >= 3: + offsets += [(-1, -1), (1, -1), (-1, 1), (1, 1)] + for dx, dy in offsets: + draw.text((x + dx, y + dy), text, font=font, fill=font_color) # 保存 os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True) @@ -330,7 +348,7 @@ def main(): parser.add_argument("--output", help="输出视频路径(配合 --video 使用)") parser.add_argument("--font-size", type=int, default=36, help="字体大小") parser.add_argument("--font-color", default="white", help="字体颜色") - parser.add_argument("--style", default="clean-white", choices=sorted(SUBTITLE_STYLE_PRESETS.keys()), help="字幕样式") + parser.add_argument("--style", default="short-drama-bold", choices=sorted(SUBTITLE_STYLE_PRESETS.keys()), help="字幕样式") parser.add_argument("--position", default="bottom", choices=["top", "middle", "bottom"], help="字幕位置") parser.add_argument("--video-width", type=int, default=1080, help="视频宽度") parser.add_argument("--video-height", type=int, default=1920, help="视频高度") diff --git a/video-ai-system/knowledge/SUBTITLE-STYLE-STANDARD.hdlp b/video-ai-system/knowledge/SUBTITLE-STYLE-STANDARD.hdlp new file mode 100644 index 0000000..48e6930 --- /dev/null +++ b/video-ai-system/knowledge/SUBTITLE-STYLE-STANDARD.hdlp @@ -0,0 +1,94 @@ +# 视频AI系统 · 字幕样式标准 + +> HLDP://video-ai-system/knowledge/SUBTITLE-STYLE-STANDARD +> 类型: 字幕可读性规范 · 竖屏短剧 +> 日期: D144 · 2026-06-24 +> 铸渊 ICE-GL-ZY001 + +--- + +## 调研结论 + +行业字幕共识: + +``` +白色字体 +居中对齐 +位于底部或顶部 +避开画面文字/重要主体 +保持安全区 +最多两行 +字号随分辨率和每行字数调整 +``` + +来源: + +``` +Netflix Timed Text Style Guide: +https://partnerhelp.netflixstudios.com/hc/en-us/articles/215758617-Timed-Text-Style-Guide-General-Requirements +https://partnerhelp.netflixstudios.com/hc/en-us/articles/217350977-English-USA-Timed-Text-Style-Guide + +BBC字幕安全区资料: +https://www.clevercast.com/bbc-subtitling-guidelines/ + +ATSC A/343 Safe Title Area: +https://www.atsc.org/wp-content/uploads/2024/04/A343-2024-04-Captions-and-Subtitles.pdf +``` + +--- + +## EP01竖屏短剧默认样式 + +``` +style_id: short-drama-bold +font_color: white / #FFFFFF / alpha 255 +font_weight: bold +background: none +shadow: none +stroke: 1px dark edge, only for readability +alignment: center +position: lower third, safe area inside +max_lines: 2 +``` + +说明: + +``` +用户反馈上一版字幕太细、太淡。 +因此默认不再使用clean-white细字。 +默认改为粗白字。 +``` + +--- + +## 为什么保留极细暗边 + +``` +纯白粗字在天空、白衣、雾气、浅石头上会丢失。 +极细暗边不是阴影,也不是黑底。 +它只用于保证手机观看时文字不发飘。 +``` + +如果某个镜头背景很暗: + +``` +stroke_width可降为0。 +``` + +--- + +## 质检标准 + +每次烧字幕后必须抽帧检查: + +``` +文字是否足够粗 +颜色是否足够白 +是否有黑底/阴影误启用 +是否遮脸 +是否遮关键道具 +是否在手机安全区内 +两行以内 +与角色对白时间轴同步 +``` + diff --git a/video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS.hdlp b/video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS.hdlp index 49f2758..6e42a97 100644 --- a/video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS.hdlp +++ b/video-ai-system/memory/zai-fu-fei-xiu-xian/STATUS.hdlp @@ -112,7 +112,8 @@ preview-003: 暂不生成。 | 固定道具合成路线 | ✅ | `plans/script-to-screen/EP01-LOCKED-PROP-COMPOSITING-ROUTE.hdlp` | | 苏白+牌匾合成小样 | 🟡 技术通过·位置失败 | `outputs/tests/TEST-COMP-001-SUBAI-PLAQUE-OVERLAY-RUN-001-REPORT.hdlp` | | 牌匾固定贴图 | ✅ PNG已生成 | `assets/props/PROP-TDZ-PLAQUE/texture/tdz-plaque-texture.png` | -| 字幕渲染合成 | ✅ 纯白样式RUN-003通过 | `outputs/tests/TEST-SUBTITLE-003-CLEAN-WHITE-RUN002-REPORT.hdlp` | +| 字幕渲染合成 | ✅ 粗白短剧样式RUN-004通过 | `outputs/tests/TEST-SUBTITLE-004-SHORT-DRAMA-BOLD-REPORT.hdlp` | +| 字幕样式标准 | ✅ 已建立 | `knowledge/SUBTITLE-STYLE-STANDARD.hdlp` | | 百宗会人群底片 | 🟡 RUN-002可作氛围候选 | `outputs/tests/TEST-PROP-001-TDZ-PLAQUE-RUN-002-REPORT.hdlp` | | 苏白TTS配音 | ✅ 工程测试通过 | `outputs/tests/TEST-TTS-001-SUBAI-RUN-001-REPORT.hdlp` | | 模型/成本路线 | ✅ 已建立 | `knowledge/D144-MODEL-COST-ROUTE.hdlp` | @@ -210,6 +211,8 @@ preview-003: 暂不生成。 - [x] 修复字幕管线: SRT→PNG→FFmpeg overlay合成 → `outputs/tests/TEST-SUBTITLE-001-RUN-001-REPORT.hdlp` - [x] 纠正字幕测试底片: 使用干净苏白视频重跑 → `outputs/tests/TEST-SUBTITLE-002-CLEAN-RUN-001-REPORT.hdlp` - [x] 调整字幕默认风格为纯白无黑底/无阴影 → `outputs/tests/TEST-SUBTITLE-003-CLEAN-WHITE-RUN002-REPORT.hdlp` +- [x] 调整字幕默认风格为粗白短剧字幕 → `outputs/tests/TEST-SUBTITLE-004-SHORT-DRAMA-BOLD-REPORT.hdlp` +- [x] 建立字幕样式标准 → `knowledge/SUBTITLE-STYLE-STANDARD.hdlp` - [x] 重定性 RUN-002: 牌匾一致性失败,但百宗会人群氛围可用 - [x] 测试苏白Edge-TTS工程配音 → `outputs/tests/TEST-TTS-001-SUBAI-RUN-001-REPORT.hdlp` - [x] 建立模型/成本路线 → `knowledge/D144-MODEL-COST-ROUTE.hdlp` diff --git a/video-ai-system/outputs/tests/TEST-SUBTITLE-004-SHORT-DRAMA-BOLD-REPORT.hdlp b/video-ai-system/outputs/tests/TEST-SUBTITLE-004-SHORT-DRAMA-BOLD-REPORT.hdlp new file mode 100644 index 0000000..8a41fa7 --- /dev/null +++ b/video-ai-system/outputs/tests/TEST-SUBTITLE-004-SHORT-DRAMA-BOLD-REPORT.hdlp @@ -0,0 +1,57 @@ +# TEST-SUBTITLE-004 · 粗白短剧字幕报告 + +> HLDP://video-ai-system/outputs/tests/TEST-SUBTITLE-004-SHORT-DRAMA-BOLD-REPORT +> 类型: 字幕样式测试 · short-drama-bold +> 日期: D144 · 2026-06-24 12:26 CST +> 铸渊 ICE-GL-ZY001 + +--- + +## 输入 + +``` +base_video: /Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/视频/zai-fu-fei-xiu-xian/ep01/tests/TEST-PROP-001-TDZ-PLAQUE-RUN-002-SUBAI-SAME-SCENE.mp4 +style: short-drama-bold +font_size: 52 +output: /Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/视频/zai-fu-fei-xiu-xian/ep01/tests/TEST-SUBTITLE-004-RUN002-SHORT-DRAMA-BOLD.mp4 +``` + +--- + +## 用户反馈对应 + +``` +上一版字幕字体太细、颜色太淡。 +需要按视频底部字幕标准调研后,改为更粗、更白、更清楚。 +``` + +--- + +## 调整 + +``` +subtitle-renderer.py: +- 默认style改为 short-drama-bold。 +- 默认字号提升。 +- 增加bold_weight模拟加粗。 +- 去掉黑底。 +- 去掉阴影。 +- 保留极细暗边保证浅背景可读。 +``` + +--- + +## 裁决 + +``` +status: PASS_FOR_CURRENT_SUBTITLE_DEFAULT +approved_for: 当前字幕默认候选风格 +not_approved_for: 所有镜头免检 +``` + +下一步: + +``` +每个镜头烧字幕后仍需抽帧检查可读性、遮挡和安全区。 +``` +