comic-explainer

漫画转动态漫视频(comic-explainer 下游管线)

产物:1080p/30fps MP4(分镜逐格运镜 + 中文配音 + 黄字大字幕 + BGM)+ 发布包(封面/章节轴/双平台文案)。工作目录建议 video_<主题>/{slides,pngs,aud,seg,subs}

流水线(顺序执行)

  1. 配音剧本 script.json{"<页码>": [["角色","台词"],…]}。每页 1~3 条、单条 ≤90 字(约 20s 内)。风格三选一:标准播报 / 评书腔(结论先行+自问自答+职场隐喻+口头禅)/ 分角色。时长硬规则(火宝短剧那套 4.5 字/秒、500 字/分钟是它自家口径,别照搬:本机 edge-tts 云健 +12% 实测 5.05 字/秒 = 303 字/分钟,套 500 字/分钟会把目标时长算短一半、套 4.5 字/秒会让每页都误报「台词不够」)。正确算法:先估 成片时长 ≈ 总字数 ÷ 5.05 + Σ每页(0.5 前置 + 0.8 尾 + 0.45×(句数-1)),再据此定写词字数(10 页 × 每页 2 条约 = 500 字 ≈ 138s);超了砍台词不砍画面。注意音轨长度本来就是 TTS 实测出来的,「台词下限」只在画面时长要独立于配音设定(如给 AI 生视频定 8-15s 段)时才是硬约束;分格必须落在【开场】【触发】【高潮】【收尾】节拍边界,同一因果链不许切散;口播稿禁抽象形容词(”很伤心”“紧张”),一律转可见描写(”低下头、攥紧杯沿”)——评书腔同理。
  2. 拆页截图:从漫画 HTML 正则提取 <header class="cover"> 与各 <section class="panel">,逐页包进 1920×1080 舞台(.stage{width:860px;transform:translate(-50%,-50%) scale(2.02)},px 定位的气泡会随 SVG 等比缩放,勿改布局)。Chrome 无头截图:--headless --window-size=1920,1080 --hide-scrollbars --screenshot
  3. TTS:首选 edge-tts(微软神经音色,比 macOS say 自然一个次元):python -m edge_tts --voice zh-CN-YunjianNeural --rate=+12% --proxy socks5h://127.0.0.1:7890 --text ... --write-media x.mp3,国内直连报 NoAudioReceived 必须走代理;mp3→ffmpeg -ar 44100 -ac 2 转 wav。定版音色:云健 zh-CN-YunjianNeural rate+12%(评书腔,用户拍板),edge-tts 音量偏轻,成片混音时人声轨加 volume=2.2 再限幅。备选 say -v <音色> -r 235~255say 音色必须用完整显示名(见坑①)。每句生成后断言时长 >1s,防整段静音。可仿口吻,不克隆真人声音(声纹授权红线,平台判违规)。
  4. 每页音轨:0.5s 前置 + 句间 0.45s + 尾 0.8s 静音拼接;评书腔/大嗓门加 volume=1.75,alimiter=limit=0.92
  5. 字幕:按 [,。!?;:] 切 ≤20 字条,句内按字数比例分摊实测时长。渲染成透明底 PNG(HTML + Chrome --default-background-color=00000000),样式:PingFang 52px 900 #ffd94a + 四向 text-shadow 描边。横屏 bottom 必须 ≤30px 且把舞台 scale 降到 1.86、top 改 47%:scale 2.02 时面板几乎铺满 1080 高,漫画自带的那条黑底白字旁白条正好压在 y≈890-990,字幕放 bottom:168 会和它叠成一片糊字(实测踩过,见坑⑨);缩小上移后底部才腾出一条米色净空带。竖屏 bottom:420px 本来就落在面板下方的空白区,不受影响。
  6. 分段渲染:每段 = PNG + 音轨,zoompan 缓推缓拉交替(输入先 scale=3840:2160 减抖,d=时长×30)。可选黑底大字开场/收场卡(同 Chrome 截图,配静默音轨)。
  7. 合成一条命令:N 段 + M 张字幕 PNG + BGM 全部作输入 → concat=n=N:v=1:a=1(滤镜!见坑③)→ 逐条 overlay=enable='between(t,a,b)'amix BGM(volume≈0.32)→ alimiter + 尾部 afade
  8. BGM:先试 qwenwork_music_generate(见坑④,常失败);兜底本地合成:Python wave 写五声音阶八分拨弦(指数衰减正弦+泛音)+ 每拍贝斯 + 反拍噪声沙锤,73s 循环,峰值归一 ~0.22。
  9. 验收(必做)ffprobe 视频流与音频流时长差 <0.5s(坑③同类漂移);抽 2 帧看字幕对齐与遮挡;volumedetect mean ≈ -19~-22dB。
  10. 发布包:封面 = 大字 HTML → Chrome 截图 1920×1080 PNG + sips -Z 1280 出 YouTube jpg;章节轴 = 逐段实测时长累加;文案包 = B站(分区/标题/简介/标签)+ YouTube(双语 description/章节/Category),必含 AI 语音申报提醒;仿写口吻注明”与任何创作者无关”。

竖屏 9:16 版(抖音/快手/视频号必做)

不是加黑边,是重排版式:1080×1920 舞台,顶部常驻系列徽章+大标题(70~330px 区),中段漫画格 .stage{left:40px;top:640px;width:860px;transform-origin:top left} 缩放 1.1628(左右各留 40px 安全边距),底部字幕区。运镜改纵向缓推缓拉:输入 scale=2160:3840zoompan z=1.06(>1.1 会裁掉格内边缘文字!实测 1.16 切掉”第二站”标题),y 在 0..(ih-ih/zoom) 逐帧线性移动、奇偶页换方向;字幕 PNG 重出 1080×1920 版,bottom:420px。音轨与横屏共用,事件时间轴不变。

重配音(换嗓子不动画)

面板 PNG、字幕 PNG 全部复用:①新音色重跑逐句 TTS;②重拼每页音轨;③重算字幕事件时间轴(断言切条数不变,变了才需重截字幕 PNG);④分段重渲染(时长变了);⑤若只是响度不够,跳过 ①-④,仅在最终混音给 [ca]volume=2.2 重跑合成。视频号已发布视频换不了视频文件,只能重发新帖+引导用户手机长按删旧。

坑录(全部实测踩过)

交付

成片与封面、文案包复制到 outputs 并 present_files;若仓库化发布,视频放 videos/(<100MB 免 LFS),push 前先 git pull --rebase(多会话并发仓库)。