Files
BoosAPI/docs/superpowers/plans/2026-06-18-digital-human-comfy-video-entry.md
T
boos 53f99affec docs: 数字人 Comfy 视频入口实现计划(4 任务三层)
前端视频工作流选择器 → 后端转发 api_video_workflow → Pixelle comfy 注入 audio_path
→ 部署联调。视频入口可选、默认不启用、向后兼容。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 02:54:26 +08:00

10 KiB

数字人接入 Comfy Cloud 视频工作流(完整视频入口)实现计划

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 给 BoosAPI 数字人加「视频工作流」入口,让用户选 comfy/video_digital_ltx2.json 触发「肖像图+旁白音频→LTX2.3 说话视频」,贯穿前端→BoosAPI 后端→Pixelle 三层。

Architecture: 前端 DigitalHuman.tsx 加可选「视频工作流」选择器(列 video_*),提交 api_video_workflow;BoosAPI digital_human.rs 的 pixelle_request_body 透传该字段;Pixelle asset_based.py 对 comfy/ 视频工作流也注入 audio_path。视频入口默认空=不启用,保持现有「图片+HTML 合成」向后兼容。

Tech Stack: React/TS(BoosAPI 前端)、Rust/axum(BoosAPI 后端)、Python(Pixelle,容器内)。

环境: BoosAPI 仓库 /root/metapi,前端 src/web,后端 src/routes。Pixelle 在 Docker 容器 pixelle-video-api,源码 /app/pixelle_video(镜像内置,改后 docker compose restart api,备份到 /opt/Pixelle-Video/patches/)。构建:前端 npm run typecheck:web,后端 cargo build -j 2(-j 2 防 OOM)。分支 feat/comfy-cloud-adapter。

前置(已完成): comfy-cloud 适配器、comfy/video_digital_ltx2.json(probe 通过)、media.py 转发 image_path。


文件结构

  • Modify src/web/pages/DigitalHuman.tsx — 加 apiVideoWorkflow state + 「视频工作流」选择器 + payload 字段 + draft 持久化。
  • Modify src/routes/digital_human.rs — pixelle_request_body 转发 api_video_workflow。
  • Modify(容器内)/app/pixelle_video/pipelines/asset_based.py — comfy 视频工作流注入 audio_path。

Task 1: 前端加「视频工作流」选择器 + 提交字段

Files:

  • Modify: src/web/pages/DigitalHuman.tsx

  • Step 1: DigitalHumanDraft type 加字段(~line 34 附近,imageWorkflow 旁)

找到 imageWorkflow?: string;(约 line 34),其后加一行:

  apiVideoWorkflow?: string;
  • Step 2: 加 state(~line 370,imageWorkflow useState 旁)

找到 const [imageWorkflow, setImageWorkflow] = useState(draftRef.current.imageWorkflow || '');(约 line 370),其后加:

  const [apiVideoWorkflow, setApiVideoWorkflow] = useState(draftRef.current.apiVideoWorkflow || '');
  • Step 3: draft 持久化加字段(~line 462 写入 + ~line 480 依赖数组)

在 writeDigitalHumanDraft({...}) 对象里(约 line 462),imageWorkflow, 后加 apiVideoWorkflow,; 在该 useEffect 的依赖数组里(约 line 480),imageWorkflow, 后同样加 apiVideoWorkflow,。

  • Step 4: 提交 payload 加字段(~line 570 payload 对象)

找到 payload 对象里的 media_workflow: imageWorkflow || undefined,(约 line 575),其后加:

        api_video_workflow: apiVideoWorkflow || undefined,
  • Step 5: 加「视频工作流」选择器 UI(图片工作流 select 之后,~line 1012)

找到「图片工作流」那个 <label className="digital-human-field">...select...</label> 块结束处 (约 line 1012,</label> 后),插入新选择器:

          <label className="digital-human-field">
            <span>视频工作流(可选,生成说话视频)</span>
            <select value={apiVideoWorkflow} onChange={(event) => setApiVideoWorkflow(event.target.value)}>
              <option value="">不生成视频(仅图片合成)</option>
              {mediaWorkflows
                .filter((wf) => wf.name.toLowerCase().includes('video'))
                .map((wf) => (
                  <option key={workflowValue(wf)} value={workflowValue(wf)}>{pickItemLabel(wf)}{wf.source ? ` · ${wf.source}` : ''}</option>
                ))}
            </select>
          </label>
  • Step 6: typecheck

Run: cd /root/metapi && npm run typecheck:web 2>&1 | tail -5 Expected: 无 TS 错误。

  • Step 7: Commit
cd /root/metapi && git add src/web/pages/DigitalHuman.tsx
git commit -m "feat(digital-human): 前端加视频工作流选择器(api_video_workflow)

Co-Authored-By: Claude <noreply@anthropic.com>"

Task 2: BoosAPI 后端转发 api_video_workflow 给 Pixelle

Files:

  • Modify: src/routes/digital_human.rs

  • Step 1: 在 pixelle_request_body 加转发(~line 2077,tts_workflow 块之后)

找到 pixelle_request_body 里转发 tts_workflow 的块(约 line 2073-2078):

    if let Some(value) = optional_string(body, &["ttsWorkflow", "tts_workflow"])
        .or_else(|| default_pixelle_tts_workflow(state, backend_provider))
    {
        request_body["tts_workflow"] = json!(value);
    }

在它之后插入:

    if let Some(value) = optional_string(body, &["apiVideoWorkflow", "api_video_workflow"]) {
        request_body["api_video_workflow"] = json!(value);
    }
  • Step 2: 构建确认编译

Run: cd /root/metapi && cargo build -j 2 2>&1 | tail -3 Expected: Finished。

  • Step 3: 确认 optional_string 接受多 key(它已在文件内大量使用,签名兼容)

Run: cd /root/metapi && rtk proxy grep -n "fn optional_string" src/routes/digital_human.rs | head Expected: 找到定义,签名为 (body, keys: &[&str])(与 Step 1 用法一致)。若签名不同,按实际调整调用形式。

  • Step 4: Commit
cd /root/metapi && git add src/routes/digital_human.rs
git commit -m "feat(digital-human): 后端转发 api_video_workflow 给 Pixelle

Co-Authored-By: Claude <noreply@anthropic.com>"

Task 3: Pixelle 给 comfy 视频工作流注入 audio_path

Files:

  • Modify(容器内):/app/pixelle_video/pipelines/asset_based.py

  • Step 1: 定位音频注入块(~line 703)

Run: rtk proxy docker exec pixelle-video-api sh -lc "grep -n 'audio_driven_i2v' /app/pixelle_video/pipelines/asset_based.py" Expected: 命中 if "audio_driven_i2v" in adapter_abilities: 那行(约 703)。

  • Step 2: 在该判断旁加 comfy 前缀分支(用 python 精确改写)
rtk proxy docker exec pixelle-video-api /app/.venv/bin/python -c "
p='/app/pixelle_video/pipelines/asset_based.py'
src=open(p).read()
anchor='                if \"audio_driven_i2v\" in adapter_abilities:\n                    api_video_params[\"audio_path\"] = frame.audio_path'
assert anchor in src, 'anchor not found'
add=anchor + '''
                elif isinstance(api_video_workflow, str) and api_video_workflow.startswith(\"comfy/\"):
                    api_video_params[\"audio_path\"] = frame.audio_path'''
if 'api_video_workflow.startswith(\"comfy/\")' in src:
    print('already patched')
else:
    src=src.replace(anchor, add, 1)
    open(p,'w').write(src)
    print('patched')
"

Expected: patched(或 already patched)。

  • Step 3: 语法校验 + 重启 + 备份
rtk proxy docker exec pixelle-video-api /app/.venv/bin/python -c "import ast; ast.parse(open('/app/pixelle_video/pipelines/asset_based.py').read()); print('syntax OK')"
cd /opt/Pixelle-Video && rtk proxy docker compose restart api && sleep 7 && rtk proxy docker ps --filter name=pixelle --format '{{.Names}} {{.Status}}'
mkdir -p /opt/Pixelle-Video/patches && rtk proxy docker cp pixelle-video-api:/app/pixelle_video/pipelines/asset_based.py /opt/Pixelle-Video/patches/asset_based.py.patched

Expected: syntax OK;容器 healthy;备份文件存在。

  • Step 4: 确认改动重启后仍在

Run: rtk proxy docker exec pixelle-video-api sh -lc "grep -c 'api_video_workflow.startswith(\"comfy/\")' /app/pixelle_video/pipelines/asset_based.py" Expected: 1。无 git commit(Pixelle 非本仓库)。

Task 4: 部署 BoosAPI + 端到端联调

Files: 无(部署 + 运行时验证)

  • Step 1: 重新构建并重启 BoosAPI(含前端改动)

前端改了需重新 build 前端资源,后端改了需重新编译。用项目脚本:

cd /root/metapi && ./build-and-run.sh --fast-release 2>&1 | tail -15

若只想快速验证后端逻辑、前端单独 build,可 npm run build:web + ./build-and-run.sh --backend-only。 Expected: 构建成功,BoosAPI 起在 :4000。注意这是动线上服务,确认当前无关键流量再重启。

  • Step 2: 确认数字人 UI 出现「视频工作流」选择器

打开管理控制台数字人页面,确认新增「视频工作流(可选)」下拉,选项含 video_digital_ltx2(comfy)+ video_wan2.1_fusionx(comfy)等 video_* 工作流。

  • Step 3: 发起数字人任务,视频工作流选 comfy/video_digital_ltx2.json

给肖像图 + 文本 + 选 TTS,视频工作流选 comfy/video_digital_ltx2.json,提交。

  • Step 4: 监控流转(BoosAPI 日志 + Comfy Cloud job)
cd /root/metapi && rtk proxy sqlite3 boosapi.db "SELECT id, created_at, client_family, http_status, substr(error_message,1,80) FROM proxy_logs ORDER BY id DESC LIMIT 5;"

Expected: 新日志(id 增长),数字人任务推进;Comfy Cloud 出现 LTX2.3 job;最终出说话视频。

  • Step 5: 出错归因

  • LoadImage 仍用默认图 → 查 media.py image_path 转发(Task 已完成,确认 grep image_path /app/pixelle_video/services/media.py)。

  • LoadAudio 无音频 → 查 Task 3 注入(grep comfy/ /app/pixelle_video/pipelines/asset_based.py)+ workflow 标记 $~audio_path!。

  • api_video_workflow 没传到 → 查 Task 2 后端转发 + Task 1 前端 payload 字段名(api_video_workflow)。

  • 节点/模型错 → 不应发生(probe 已过);若发生看 Comfy Cloud 真实回包。

  • Step 6: 成功标准

数字人任务选 comfy/video_digital_ltx2.json 后,Comfy Cloud 出真实 job,注入了 image_path+audio_path+prompt,返回带音频说话视频,数字人成片。


完成标准

  • 前端:数字人页有「视频工作流」可选下拉,列 video_* 工作流,typecheck 干净。
  • 后端:api_video_workflow 透传给 Pixelle,cargo build -j 2 通过。
  • Pixelle:comfy 视频工作流注入 audio_path,重启生效,备份 patches/。
  • 端到端:选 comfy/video_digital_ltx2.json 出说话视频。
  • 向后兼容:不选视频工作流时,现有「图片+HTML 合成」行为不变。

已知风险 / 备注

  • Pixelle asset_based.py 改动在镜像内置层,重建镜像会丢,已备份 patches/,长期应固化 Dockerfile。
  • Task 4 动线上服务(重启 BoosAPI),确认时机。
  • 单人肖像;多人不在范围。
  • LTX2.3 执行时长/分辨率等真实生成参数,若出片质量/超时问题属调参,非本计划的接线问题。