combo-voiceover-fit · writeback-pipeline
combo 跑完,结果不是直接进 Mai 画布的。它先发回调给网关,网关导入产物拿到 Mai file_id,再交给 canvas 服务生成画布卡片。这次我们想多回一张"原视频"卡片、还带条字幕链接——发现得动两个仓库。
runner 不直接写 Mai 的画布表。它发的回调要过两层加工才变成你在 canvas 上看到的卡片:
关键:runner 给的 url 网关其实不直接用——canvas 的 dataURL 是网关 import 后用 mai_file_id 重新拼的(cdn-asia/ultra/<file_id>)。所以"想让某字段出现在画布上",光 runner 发没用,得网关/worker 那两道认它。这就是为什么这次得双边改。
runner 一共发两种回调到同一个 callback_url:
真正的产物在这里,分两批发:
digital_human_uploaded:主播图 + 数字人原片final_artifacts_uploaded:成片 + 音频 + 字幕 +原视频终态,outputs:[] 是空的(产物上面发过了)。只带全局元信息:
summary 人读总结adjustments[] 改了哪些段原视频卡片要进画布,就必须作为一条产物 item 跟着 final_artifacts_uploaded 那批发——和字幕同批,否则下面那个 @ref 解析不到字幕。
runner 用 output_record() 造每条产物,字段是固定的。网关把它映射成 canvas 卡片:
| canvas 卡片字段 | 来自哪 |
|---|---|
id | = mai_file_id(import 后的,缺了才随机) |
dataURL | 网关用 file_id 重拼 ultra/<file_id>,runner 的 url 被忽略 |
name / title / mimeType | 原样来自 item |
created | canvas 服务插入时的时间戳,runner 不给 |
srtURL 新 | canvas_extra 透传 + @ref 解析(见下) |
目标就两件小事:成片回传多一张"原视频"卡片,且这张卡片上挂一个 srtURL 指向本次字幕,给下游做视频/音频合成用。但因为写回要过三道手,落点散在两个仓库:
source_video_output_record():发 out_source_video,回显源视频 mai_file_id不重传,挂 canvas_extra:{srtURL:"@out_subtitle"}final_artifacts_uploaded 同批summary 在有改词时追加"其中 N 段因时长策略已自动改写文案"skill v1 → v2(test only)
canvas_extra 提为一等字段透传out_source_video 加进显示白名单 + 建 @ref 解析器push c5de8d4 → CI 自动部署(test)
为什么不能光 runner 改?因为白名单不认就被丢、canvas_extra 不提就被 normalizer 扔、额外键不 spread 就进不了卡片——这三关都在 Mai 侧。runner 只能"发",能不能"显示"是网关说了算。
你要的 srtURL 是字幕 import 后的 Mai 链接(ultra/<字幕的 mai_file_id>)。但那个 file_id 是网关 import 字幕时才分配的,runner 跑的时候根本不存在。所以没法静态塞。解法是一个通用的引用机制:
flatKey:"@某role" 走同一个解析器,零新 Mai 代码(比如 posterURL:"@out_thumbnail")。id/dataURL/name/...,canvas_extra 不能覆盖关键字段。真 canvas 联调(gw_1bf2ac61)+ 你自己那单(gw_e085fa11)都验过,原视频卡片最终长这样:
6 张卡片全到、canvas_delivered=true、srtURL 只挂在原视频卡片其余没有、保留键护栏没被穿透。顺带这两单都触发了 2 段配音改词自愈——写回链路和自愈是同一条 runner 上的两件事。当前全部在 test,prod 未动。