---
name: local-property-video-edit
display_name: 一键视频剪辑
display_name_en: One-Click Video Editing
description_zh: '一句话出片：本地 FFmpeg 直出成片 MP4，自动单行字幕、卖点横幅、BGM 侧链闪避，附横版/竖版智能封面与片头元数据内嵌；不消耗 ChatCut 额度。'
version: 1.0.0
category: engineering
allowed-tools: Read,Write,Edit,Bash,Glob,Grep,WebFetch,WebSearch
description: '本地 FFmpeg 房产实探/带看视频剪辑通道（不依赖 ChatCut，不消耗 credits，效率更高），并含「智能封面 + 片头 + MP4 元数据封面内嵌」扩展。当用户提供本地房产视频（实探/探盘/带看）并要做「成片剪辑」——含字幕、重点高亮、贴图文字说明、低音量氛围 BGM、周边配套（商场/学校/医院/公园/地铁）叠加、删卡顿/语气词——且用户希望直接产出「可用的成片 MP4」（而非 ChatCut 可编辑时间线）时使用；也用于「给视频加封面、封面抠图白描边、封面做片头、封面内嵌进 MP4 元数据、封面背景模糊透明/毛玻璃/照片级浅景深虚化/散景光斑、竖版封面 / 9:16 封面 / 小红书抖音视频号封面 / 单独做张封面图」。触发短语：一键视频剪辑、本地剪辑、直接成片、ffmpeg 剪辑、不用 chatcut、避开额度、实探视频剪辑成片、视频封面、竖版封面、9:16 封面、单独做张封面、封面内嵌、片头封面、毛玻璃封面、背景再虚化一点、像照片背景虚化、bokeh、浅景深。与 chatcut-property-merge 的区别：本技能走本地 FFmpeg 直出 MP4，自带 BGM 侧链闪避，不需云端额度。'
agent_created: true
metadata:
  packageName: '@369988105/local-property-video-edit'
  version: 1.0.0
  title: 一键视频剪辑
  icon: '🎬'
---

# 本地 FFmpeg 房产实探视频剪辑（直出成片）

## Overview

将本地房产实探 / 带看 / 探盘视频剪辑为一段结构清晰、重点突出、**可直接使用**的成片 MP4。自动完成：智能断句字幕（强制单行）→ 关键词金色高亮 → 顶部卖点/配套横幅贴图 → 低音量氛围 BGM（侧链闪避低于人声）→ 周边配套（POI）识别叠加 → 删卡顿/语气词保节奏 → 直出母版 + 发布版 MP4。

**可选扩展（Step 6/6B/7）**：智能封面（人物抠图 + 白描边 + **摄影级浅景深背景**：双层景深模糊 + 窗外融光 + 柔圆散景光斑 + 高通透玻璃 + **无卡片多字体花字** + 合规标题）→ 把封面做成 2s 片头 → 再以 `attached_pic` 内嵌进 MP4 元数据，让播放器缩略图直接显示封面。封面脚本支持**横版 16:9 与竖版 9:16 双布局**：横版「左文右人」，竖版「上文下人」，竖版可单独出图、完全不改动横版交付物。整个扩展同样纯本地（抠图那一步走云端 matting，见 `references/cover.md`）。

**核心优势**：纯本地 FFmpeg 渲染，**不消耗 ChatCut credits**，BGM 原生可加，交付即播放器/平台可直接用的 MP4（H.264 1080p）。适合「要直接可用成片」的目标；若要「可编辑时间线」则改用 `chatcut-property-merge`。

## When To Use

- 用户给 `video(2).mp4` / `1.mp4 9.mp4 3.mp4` 等本地素材，要求「剪辑成片」「直接可用」。
- 要求同时含：字幕、重点高亮、贴图/文字说明、BGM、周边配套（POI）叠加、删卡顿/语气词。
- 用户明确不想走 ChatCut（额度不足 / 要效率 / 要直出 MP4）。
- 用户要「视频封面 / 抠图白描边 / 封面文字智能生成 / 封面做片头 / 封面内嵌 MP4 元数据 / 模糊透明毛玻璃背景 / 毛玻璃再透一点 / 花字 / 去掉文字卡片 / 字体形态丰富 / 背景再虚一点 / 像照片那种背景虚化 / 散景光斑」→ 直接走 **Step 6 + Step 7**（可独立于剪辑主流程运行）。
- 用户要「竖版封面 / 9:16 封面 / 小红书·抖音·视频号封面 / 单独做张封面图」→ 走 **Step 6B**（只出图，不改横版、不做片头）。
- 单条或多条素材均可；多条时先按用户给的序号拼成一条时间轴再处理（或在 config 里把多条 SRC 自行预拼接）。

## 硬规则（必守）

1. **字幕强制单行**：任何一条字幕都**不得折成两排**（禁止 `\N` 换行）。过长句子由 `build.py` 的 `fit_line()` 整体缩小字号（`{\fsN}`）适配 1920 安全宽度（1600px），绝不换行。原因：两排字幕易与顶部横幅冲突、观感杂乱、移动端更易溢出。
2. **断句由 Agent 负责**：`config.py` 里的 `SENTS` 每条即一条字幕，**按语义切短**（≤ ~26 中文字/条最佳），不要把一大段塞进一条。口语冗余（「哎」「就是」「嗯」等语气词、重复句）直接**不写进 SENTS**（被删的语气词用空字符串 `""` 占位以占住时间、防时间轴漂移）。
3. **POI 不硬编**：只叠加口播里**实际提到**的配套；未提及的类别不编造横幅。
4. **横幅锚定关键词**：`BANNERS` 的 `anchor` 用口播里的词，build 阶段按该词在字幕里的出现时间自动定位（`find_time`），重剪后不漂移。
5. **合规红线（广告法 / 平台审核）**：禁用「赠送、赠面、不进产权、不进入产权、稀缺、热销、最好、第一、顶级、绝版、抄底、必涨」等极限词与赠送面积承诺。**审核会同时扫画面横幅 + 字幕 + 封面标题三处**，任何一处命中都会被驳回。`cover.py` 已内置 `BANNED` 扫描，命中即拒绝生成；改横幅/字幕文案时同样要逐词自查。安全替法：「主卧赠面」→「主卧空间」、「不进入产权」→「实际使用空间很充裕」、「稀缺房源/小区热销」→「优质房源/小区口碑佳」。
6. **封面抽帧必须从原始素材**：抠图用的表情帧、毛玻璃用的底片，**都不能从已合成字幕/横幅的成片里抽**，否则叠加层会被 matting 当前景一起抠出、或被糊成背景色块。源片与成片时长一致时可直接按同一时间点对位抽帧。
7. **封面不放文字卡片 / 底板**：文字一律用「花字」——渐变字芯 + 深色粗描边 + 柔投影 + 几何点缀（菱形 bullet、金色竖条），至少 3 种字体形态混排（粗黑 / 等线粗 / 宋体衬线 / 等线细 / 常规 / 楷体）。可读性由**描边与投影**承担，不靠半透明色块垫底；`cover.py` 已移除左栏圆角玻璃板，`GLASS.left_boost` 默认 0。
8. **背景虚化要有「镜头感」**：用户说「再虚一点 / 像照片背景虚化」时，**不能只调大 `GLASS.blur`**（会退化成没有层次的一块磨砂纯色）。必须保留 `DEPTH` 的双层景深（焦平面附近稍清晰、越远越化开）+ 柔圆散景光斑 + 窗外融光晕；人物始终锐利，光斑避开文字区且不过曝。
9. **竖版构图 = 上文下人**：1080×1920，文字区占上部约 45%、人物区占下部约 45%、中间留 8–10% 呼吸空间。横幅底片必须 `SRC_FIT="cover"`（等比放大中心裁切），**绝不把 16:9 拉伸成 9:16**；焦点下移到人物（`focus_y≈0.74`），并用 `bokeh_y_range` 把光斑限制在中下部、避开占满宽度的上部花字；人物用 `PERSON_X_MODE="center"` 居中略偏右，字号放大时 `STROKE_SCALE` 同步加粗描边。竖版**只单独出图**，不做片头、不写 `attached_pic`。

## Prerequisites（环境）

本机已确认可用路径（脚本默认值，无需每次配置）：

- **FFmpeg / FFprobe**：脚本自动探测，优先级 `FFMPEG_DIR` 环境变量 → PATH → WorkBuddy 内置 `~/.workbuddy/binaries/ffmpeg/*/bin` → 系统目录。**换机器不用改代码**，探测失败会打印明确提示。
- **Python 3.9+**：使用 PATH 中的 `python`（可用 `PYTHON_BIN` 覆写）；需 `pip install pillow numpy`。
- 中文字体（工作目录 `fonts/`）：剪辑用 `msyh.ttc`（常规）、`msyhbd.ttc`（粗体）；花字封面建议再备 `Dengb.ttf`（等线粗）、`Dengl.ttf`（等线细）、`simsun.ttc`（宋体衬线）、`simkai.ttf`（楷体），均从 `C:/Windows/Fonts/` 复制。**`simsunb.ttf` 中文缺字会渲染成空心方框（tofu），禁用**。
- 背景音乐（工作目录 `bgm.wav`）：共享资产根同目录下的 `bgm.wav`（轻氛围垫乐，已授权可用）。

> 每个项目工作目录需自备：`config.py`、`fonts/msyh.ttc`、`fonts/msyhbd.ttc`、`bgm.wav`。

## Workflow

### Step 0 — 准备工作目录
建一个空工作目录，放入：
- 把本技能 `scripts/` 下的 `build.py`、`gen_filter.py`、`pass.sh` **复制进该工作目录**（流水线按"脚本在工作目录内"设计，避免路径错乱）。
- `config.py`（见下，Agent 填写 SENTS/KEYWORDS/BANNERS/SRC）
- `fonts/msyh.ttc`、`fonts/msyhbd.ttc`（复制自 Windows 字体或共享资产根）
- `bgm.wav`（复制自共享资产根）

### Step 1 — 写 `config.py`
Agent 按视频口播整理以下内容（示例结构）：

```python
SRC = r"D:/.../video(2).mp4"      # 源视频绝对路径
DUR = None                        # 留 None，build.py 用 ffprobe 实测；也可手动填
SENTS = [                         # 每条 = 一条【单行】字幕；语气词用 "" 占位
    "卧龙谷一号，",
    "",                           # 占位：被删的语气词，占住时长不显示
    "卧龙谷一号里面卖的最好的户型就是这个118平的，",
    ...
]
KEYWORDS = ["卧龙谷一号", "118平", "电梯直接入户", ...]   # 金色高亮词（须原样出现在句子里）
BANNERS = [                       # 顶部横幅：(文件, 主标题, 副标题, 配色RGB, 锚定词)
    ("b1.png", "118㎡主力户型", "电梯直接入户 · 独门独户", (240,192,0), "118平的"),
    ("b4.png", "13号线地铁口", "仅600米 · 交通配套", (79,195,247), "地铁口"),
    ...
]
```
- `SENTS` 用 `AudioTranscribe` 转写 + 人工/模型整理断句；句与句用句号/逗号切。
- `BANNERS` 配色建议：卖点/主推用金 `(240,192,0)`，交通/地铁用青 `(79,195,247)`，收纳/书房用紫 `(171,124,246)`，公园/视野用绿 `(102,187,106)`，诚邀/收尾用橙 `(255,138,101)`。

### Step 2 — 构建（字幕 + 横幅）
```bash
cd <工作目录>
python build.py
```
`build.py` 会：抽音轨 → `silencedetect` 取语音区间 → 句级比例对齐 + 停顿中点吸附 → 写 `sub.ass`（**单行**+金色高亮）→ 写 `overlays.json` + 渲染 `ov/*.png` 横幅 + 写 `run_meta.json`。
**核验**：`grep -c '\\N' sub.ass` 必须为 `0`（确认无两排字幕）。

### Step 3 — 生成滤镜
```bash
python gen_filter.py
```
产出 `filter_v.txt`（视频+横幅+字幕，单线程友好）与 `filter_a.txt`（人声+bgm 侧链闪避）。

### Step 4 — 渲染成片
```bash
bash pass.sh [输出母版路径]    # 默认 ../media/成片.mp4
```
流水线：① 预渲染 `bgm_full.wav`（循环铺满 + 音量0.13 + 首尾淡变）；② 渲染 `video_only.mp4`（单线程，防叠加层预缓冲炸内存）；③ 渲染 `audio_only.wav`（侧链闪避）；④ mux 母版（crf19/ultrafast）→ ⑤ 发布版（crf24/veryfast，音画复制）。末尾打印 video/audio 时长核验（应严格对齐）。

### Step 5 — 抽帧验收
用 PowerShell/ffmpeg 抽几帧（优先选 `overlays.json` 里横幅时间段如 38s、78s），**肉眼确认**：① 字幕均为单行、无两排；② 横幅正常显示且与对应讲解片段对齐；③ 字幕黑底条清晰可读；④ 横幅/字幕均无极限词与赠送说法。

### Step 6 — 智能封面（可选，横版 16:9）
先按 `references/cover.md` 完成「原始素材抽帧 → 云端 matting 得透明人物 → 视觉选最有吸引力表情」，在工作目录写 `cover_config.py`（字段见下），然后：
```bash
cd <工作目录>
python <skill>/scripts/cover.py                        # 默认读 cover_config.py
python <skill>/scripts/cover.py cover_config_vertical  # 指定别的配置模块（见 Step 6B）
```
产出三份：`<OUT_BASE>_透明.png`（RGBA，背景半透明，可叠任意底图）、`<OUT_BASE>.png`（亮底成品）、`<OUT_BASE>.jpg`（平台上传版）。
- **摄影级浅景深背景**（不是整块磨砂玻璃）：`DEPTH` 用双层模糊（`blur_near=20` / `blur_far=72`）按焦点 `(focus_x, focus_y)` 的径向权重混合——焦平面附近稍清晰、越远越化开；再从亮区撒**柔圆离焦光斑（bokeh）** + 窗外融光晕，人物背后一片焦外暖光，人物本身始终锐利。底片必须选无人物空镜（本次源片 88s 卧室窗景）。完整参数表见 `references/cover.md` 第 3 节。
- **高通透且无卡片**：`GLASS.scene_mix=0.80`（通透主开关）、`alpha=145`（越小越透）、`darken=0.92`、`desat=0.20`、`blur=32`（基准半径）；`left_boost=0` 表示左栏完全不加实；`FLAT_BG=(16,30,52)` 提亮合成底。核验 `alpha range` 约 124–255。
- **花字**：`flower_text()` 生成纵向渐变字芯 + 深色粗描边环 + 柔投影，配菱形点阵、金色竖条、楷体落款。中文副标题轻微倾斜 -2.2°，与粗黑主标题形成形态对比。数字/面积段用 `TITLE.sub_num` 单独配等线粗字体（宋体会把 `㎡` 渲染成 `m²`）。
- **字体字段**：`FONT_TITLE`（粗黑）、`FONT_HEAVY`（宋体衬线）、`FONT_DIGIT`（等线粗）、`FONT_LIGHT`（等线细）、`FONT_REG`（常规）、`FONT_SCRIPT`（楷体）；字号用 `FLOWER_SIZES`，描边/投影用 `FLOWER`。
- 人物白描边用纯 PIL `MaxFilter(17)` 膨胀 alpha 取差，绕开 cv2；标题文案内置 `BANNED` 合规扫描。
- `cover_config.py` 关键字段：`PERSON`（透明人物 PNG）、`GLASS_SRC`（干净源片帧）、`OUT_BASE`、`GLASS`（通透度）、`DEPTH`（景深+散景）、`FLOWER`、`FLOWER_SIZES`、`TITLE`（tag/main/sub_num/sub/sells/foot）。
- **照片虚化感的三个开关**：`DEPTH.blur_far`（背景多糊）、`bokeh_gain`/`halo_gain`（光斑与融光多亮）、`bokeh_soft`（圆盘边缘软硬）。只调大 `GLASS.blur` 会退化成纯色磨砂，必须配合景深双层与光斑才像镜头。
- **布局参数**（默认值全部等于横版历史行为）：`SRC_FIT`、`TEXT_X/TEXT_Y`、`PERSON_MAX_W/PERSON_HEIGHT/PERSON_X_MODE/PERSON_X_OFFSET/PERSON_BOTTOM_PAD`、`DIAMOND_STEP/SELL_BULLET_DY/SELL_GAP/STROKE_SCALE`、`GLASS.glow_xy`、`DEPTH.bokeh_y_range`。改脚本后务必做一次横版逐像素回归（见 Gotchas）。

### Step 6B — 竖版封面 9:16（可选，单独出图）
把 `references/cover_vertical.example.py` 复制成工作目录的 `cover_config_vertical.py`，改 `OUT_BASE`（换项目再改 `TITLE`），其余参数可直接沿用；它 `from cover_config import *` 复用横版已过审的字体 / `PERSON` / `GLASS_SRC` / 文案。然后：
```bash
cd <工作目录>
python <skill>/scripts/cover.py cover_config_vertical
```
产出 1080×1920 的 `<OUT_BASE>.png` / `.jpg` / `_透明.png` 三份，**横版交付物完全不变**。
- 构图：**上文下人**。文字区上部约 45%（标签→主标题→菱形点阵→面积副标题→两条卖点→楷体落款），人物区下部约 45%（贴底渐隐、白描边完整、居中略偏右），中间留呼吸空间；文字左对齐 `TEXT_X=78`。
- 底片 `SRC_FIT="cover"`：横幅空镜等比放大后中心裁切，**绝不拉伸**。`GLASS.glow_xy=(0.62,0.30)` 把柔光挪到中上。
- 景深下移：`focus_y=0.74`、`blur_near/blur_far=24/88`；`bokeh_y_range=(0.44,0.98)` 让光斑只落在中下部焦外、`bokeh_x_range=(0.10,0.96)` 可放宽（竖版文字只占上部）。
- 字号比横版大（`FLOWER_SIZES` main 118 / sub 90 / sell 36），`STROKE_SCALE=1.15` 同步加粗描边——无卡片时大字更依赖描边保可读性。
- 竖版**只出图**：小红书 / 抖音 / 视频号直接上传用，不做 2s 片头、不写 `attached_pic`（那是横版视频的 Step 7）。两条交付互不干扰。
- 验收：尺寸 1080×1920、文字无越界/重叠、人物头与手完整、无卡片底板、光斑未侵入文字区、透明版 `alpha range` 约 124–255、标题过 `BANNED` 扫描。详细构图与参数见 `references/cover.md` 第 6 节。

### Step 7 — 封面片头 + 元数据内嵌（可选）
```bash
bash <skill>/scripts/embed_cover.sh <封面.png> <正片.mp4> <输出.mp4> [片头秒数=2] [封面.jpg]
# 可选：VIDEO_TITLE="..." 会写入 MP4 的 title 元数据
```
脚本自动探测正片分辨率/帧率/采样率/声道/时长，做两件事：① 封面静止 N 秒作片头，正片音频整体后移 N 秒保持音画对齐（重编码一次，原发布版不动）；② 把封面作为第二路视频流以 `disposition=attached_pic` 写入 MP4，播放器/平台缩略图直接取用。
**核验**：`ffprobe -show_streams` 应看到 3 条流（video 主 / audio / video 封面且 `attached_pic=1`），总时长 = 原片 + N 秒；抽 1s 帧确认片头是封面。

## Critical Gotchas（必看）

- **中文路径 `Illegal byte sequence`**：Git Bash 传含中文的路径参数给 ffmpeg 会报编码错。解决：把源/母版复制为 ASCII 文件名（如 `master.mp4`），或用 PowerShell 调 ffmpeg，或让 `build.py` 以 Python `subprocess` 列表传参（本技能已采用，安全）。当前工具集可能没有 PowerShell 工具，此时用 Python `glob` + Unicode 转义定位中文文件 → `os.link()` 建同盘 ASCII 硬链接 → `subprocess.run([...])` 传 str → 用完 `os.remove(link)`。
- **全片 HEVC 静音探测太慢/被杀**：`silencedetect` 直接解 HEVC 视频极慢。`build.py` 已先抽单声道 AAC/wav 音轨 `_audio.wav`，再对音频跑探测，速度正常。
- **叠加层内存炸**：looped 图片若不 `-ss` 偏移 + `setpts` 重定位 0 基，ffmpeg 会把整段图片预缓冲进内存导致 OOM。`gen_filter.py` 已用 `-ss <start>` + `setpts=PTS-STARTPTS+<start>/TB` + `fade` 锚定 0 基解决；渲染必须 `-threads 1 -filter_complex_threads 1`。
- **libass 透明底条不渲染**：`BorderStyle=3` + 半透明 `BackColour`（如 `&H78000000`）在 libass 下**不显示底条**。本技能字幕改用**不透明黑底条** `&H00000000`（BackColour 字段第4段 `&HFF000000` 已实现）+ 粗描边 `Outline=7`，确保可读。
- **抽帧误判横幅缺失**：抽帧时间点若落在横幅空档（横幅仅 3–9s 窗口）会误以为没渲染。验收时务必按 `overlays.json` 的 `start/end` 选帧（如取 `start+2s`）。
- **字幕与时间轴漂移**：删语气词后必须留空字符串占位（见 Step 1），否则后续句子会提前跨停顿。本技能 `align()` 已用停顿中点吸附（±0.33s）防漂移。
- **BGM 音量**：`volume=0.13` + `sidechaincompress(threshold=0.05:ratio=5)` 保证 BGM 始终低于人声；如仍偏响可调低 `volume` 或提高 `threshold`。
- **时长对齐**：母版 video/audio 时长差应 < 0.05s；发布版用 `-c:a copy` 保证音画一致。
- **本机不要走本地 AI 去背**：Python 3.13 + numpy 2 环境下，`rembg`/`onnxruntime` 段错误(139)、`cv2 grabCut` bad allocation、numpy 降不到 1.x（3.13 强制 ≥2），本地 AI 抠图是死路。用云端 matting（见 `references/cover.md`），白描边用纯 PIL。
- **抠图素材必须是「无字幕无横幅」的原始帧**：从成片抽帧会把顶部横幅残角、底部字幕条一起抠进人物 PNG。
- **毛玻璃底片要选无人物空镜**：若底片含讲解员，虚化后会在抠图人物背后留下"分身"暗影。挑一帧干净室内/窗景（本次源片 88s 卧室窗景）。
- **整面亮窗 ≠ 点光源**：房源空镜高光多为大片窗户，直接对高光做 DoG/MaxFilter 只会抠出**窗框条状亮纹**，糊上去像玻璃刮痕，不像镜头散景。改用「亮区采样 + 合成柔圆离焦圆盘 + 大半径融光晕」；光斑要带最小间距（否则堆成云团）、用 `bokeh_x_range` 限制在中右侧避开左侧花字。
- **散景增益要克制**：`halo_gain=0.18` / `bokeh_gain=0.36` 已验证不过曝；再大就会 clip 成白饼并冲淡花字。
- **柔光增益要小**：金色柔光乘数过大会 clip 成过曝黄块；`glow * [14,10,3]` 已验证安全。
- **无卡片时文字靠描边保命**：撤掉玻璃板后，花字必须有足够粗的深色描边（主标题 8px、副标题 8px、卖点 6px）+ 柔投影，否则在明亮虚化背景上会糊掉。
- **字体 tofu 陷阱**：`simsunb.ttf` 不含完整中文字形，PIL `getbbox()` 仍会返回正常宽度，但渲染出来全是空心方框。换字体后**必须渲染一张字样本目视确认**（可用 `references/cover.md` 里的对照表法）；推荐 `simsun.ttc` / `simfang.ttf` / `simkai.ttf` / `Dengb.ttf`。
- **宋体把 ㎡ 渲染成 m²**：面积数字段用 `TITLE.sub_num` 拆出来配无衬线字体（等线粗），中文副标题才用宋体衬线，避免上标 ² 突兀。
- **PowerShell 路径用正斜杠**：`"$out\f_9.jpg"` 里的 `\f` 会被当转义符导致文件写不出去；用 `"$out/f_9.jpg"`。单帧输出加 `-update 1` 消除 image2 序列告警。
- **中文路径**：Git Bash 传中文路径给 ffmpeg 偶发 `Illegal byte sequence`；若报错就把输入复制成 ASCII 名再跑，或用 PowerShell 调 ffmpeg。
- **attached_pic 兼容性**：少数平台会把封面流当第二视频轨而拒收；此时只保留片头版（跳过 `embed_cover.sh` 第 2 步），封面另以独立图片上传。
- **竖版别照搬横版人物定位公式**：横版 `px = min(max(W-pw-66,1000), W-pw-20)` 里的常量 1000 是按 1920 宽写死的，在 1080 宽竖版会算出负值、把人物推出画面。竖版必须设 `PERSON_X_MODE="center"`。
- **竖版底片不能拉伸**：`SRC_FIT` 默认 `legacy`（放大 12% 裁切）只适合横版同比例底片；竖版必须 `"cover"` 等比填满后中心裁，否则整面亮窗被压成竖条、散景圆盘也会变形。
- **竖版光斑要按 y 轴避开文字**：横版只用 `bokeh_x_range` 避左栏；竖版文字占满上部宽度，必须同时设 `bokeh_y_range`（如 `(0.44,0.98)`），否则光斑会糊在标题上。
- **改 cover.py 必做横版回归**：布局参数默认值全部等于横版历史值。改脚本后写一个只覆盖 `OUT_BASE` 的临时配置模块，重跑横版并用 numpy 逐像素比对既有成品，确认 `maxdiff=0` 再交付，避免悄悄改坏已验收的横版封面。

## 资源

- `scripts/build.py` — 配置驱动：抽音轨→silencedetect→句级对齐→写 `sub.ass`（单行+高亮）→`overlays.json`+横幅 PNG。
- `scripts/gen_filter.py` — 读 `overlays.json` 写视频/音频滤镜图（侧链闪避）。
- `scripts/pass.sh` — ffmpeg 渲染流水线（预渲染 bgm→video_only→audio_only→mux 母版+发布版）。
- `scripts/cover.py` — 智能封面（**横版 + 竖版双布局**）：摄影级浅景深（双层景深模糊 + 窗外融光 + 柔圆散景光斑）+ 高通透玻璃（无卡片）+ 抠图人物白描边 + 多字体花字 + 合规扫描，出透明 PNG/成品 PNG/JPG。`python cover.py [配置模块名]`，默认 `cover_config`。配置 `DEPTH` / `GLASS` / `FLOWER` 三段解耦。
- `scripts/embed_cover.sh` — 封面片头拼接 + `attached_pic` 元数据内嵌，自动探测主片参数。
- `references/cover.md` — 封面全流程详解（选帧、云端 matting、token 获取、横竖版构图、验收清单）。
- `references/cover_vertical.example.py` — 竖版 9:16 配置模板（上文下人），复制成 `cover_config_vertical.py` 即用。
- 字体与 BGM：把 `msyh.ttc` / `msyhbd.ttc` 放进工作目录 `fonts/`，把已授权可用的轻氛围垫乐命名为 `bgm.wav` 放在工作目录；封面花字另可备 `Dengb.ttf` / `Dengl.ttf` / `simsun.ttc` / `simkai.ttf`。
