视频替换端点
所有 /v1/videos/replacements 端点——上传整个视频,得到它的镜头和其中的人物,把每个人对应到一个角色,拿回替换好的视频。
替换整个视频里的人——有剪辑、多个镜头、多个人物都可以。只需上传一次:找出它的镜头和其中的每个人(每秒视频 $0.01)。然后指定谁变成谁——一个已保存角色、一张图片,或者不替换——以及替换整个人还是只替换头部(脸、头发和头上戴的东西)。每个有被替换人物的镜头都由 MiniMax H3 重新渲染;其余镜头保持原样;最后把镜头按原来的声音拼接回去。
端点位于 https://lovelyrouter.com/v1/videos/replacements。用你的 API 密钥认证:Authorization: Bearer $LOVELY_API_KEY(认证)。模型是 minimax-h3-character-swap 和 minimax-h3-aftermidnight,适用 MiniMax H3 条款:每次上传都要设置 consent: true。不写代码也可以在 Playground 里试用。
工作方式#
- 上传(
POST /v1/videos/replacements):视频(或start到end之间的部分,最长 3 分钟)被切成镜头,其中的每个人被归为一个演员表成员,每人一张脸部图和一张半身图;每个人在每个镜头里都会被跟踪,所以背对镜头或转过身的人也能找到。按分析的秒数每秒 $0.01(至少 5 秒),上传时从余额预扣,ready时扣费;分析失败不收费。状态analyzing→ready。 - 渲染(
POST …/{id}/render):把演员表成员对应到角色。没有被对应人物的镜头保持原样;其余镜头分段重新渲染(rendering),最后拼接回去(stitching→succeeded)。每段都从剪辑点开始、在剪辑点结束,且至少约 5 秒:连续的快切镜头保留剪辑点一起渲染(没有要替换的人的短镜头可能被一并带上——它保持原样,不计费);只有超过 15 秒的镜头才会切成长度相近的几段。 - 下载
…/{id}/content。每段完成后就可以观看(pieces[].url)。
第一个镜头渲染之前,一个视觉模型会查看每个角色的图片,写下图上有什么——头发、头上戴的东西、眼镜,整个人模式下还有衣服——以及没有什么(“没有眼镜、没有耳机”),这样每个镜头都按这个样子来画,不会多加任何东西。它按一次对话调用从你的密钥计费(每个角色约 $0.003)。
每个镜头渲染之前,一个模型会观看并收听这个镜头,记下谁在说话,并为镜头做调度说明:每个被替换的人在画面中的位置、朝向和动作(包括手臂),让新角色保持原来的姿势和动作。镜头描述会点名说话的人,没有说话的被替换者会保持嘴巴不动,而不是对着别人的台词做口型。这次调用按你的密钥计费(每个镜头约 $0.03)。
谁是谁由人脸决定:在每个镜头里,追踪到的人按脸和演员表匹配,所以一个人如果整个镜头都是背影,可能在那个镜头里找不到——那个镜头就保持原样返回,也不收费。
替换对象#
属性
idstringrpl_ 加 24 个字符。
objectstring始终为 video.replacement。
statusstringanalyzing、ready、rendering、stitching、succeeded、failed 或 cancelled。
secondssize` number分析后,处理部分的长度和尺寸。
shotsarray{index, start, end, people}——秒数,以及镜头里从左到右出现的演员表 id。
castarray{id, seconds, shots, appearances, face_url, body_url}——每个找到的人一项(p1、p2……,出镜时间最长的在前)。
modebackground渲染请求的设置。
piecesarray | null渲染开始后:{index, shot, shots, start, seconds, people, status, swapped, missed, last_retry, url}——shot 是该段的第一个镜头,shots 是段内的所有镜头,kept 是一并带上、保持原样的镜头;status 为 pending、rendering、replaced、unchanged(没找到被对应的人)、kept(里面没有被对应的人)、failed 或 retrying。某段完成后,swapped 和 missed 列出其中被对应的人里找到了谁、漏掉了谁——漏掉人的段可以重试(见下文)。
progressinteger | null渲染时为 0–100。
replaced_secondsnumber | null被替换的秒数(渲染时为计划值,完成后为计费值)。
holdcharge` number | nullanalysis_chargenumber——找人花费的金额(再运行一次为 0)预留的金额(美元),以及结算后的收费。
source_urlstring | null你上传的原视频(GET …/{id}/source,用你的密钥),上传后保留 7 天;之后为 null。
urlstring | null完成的 mp4,保留 7 天。
rerun_untilinteger | null在此 Unix 时间之前,可以用 POST …/{id}/rerun 把已结束的替换再跑一次(上传后 2 天);否则为 null。
errorobject | null失败时为 {type, message}。
{
"id": "rpl_5e0c2b9a7f1d4e3b8a6c0d2f",
"object": "video.replacement",
"model": "minimax-h3-character-swap",
"status": "ready",
"seconds": 32.04,
"size": "768x1344",
"shots": [
{ "index": 0, "start": 0, "end": 5.04, "people": ["p1"] },
{ "index": 1, "start": 5.04, "end": 10.04, "people": ["p3", "p2"] }
],
"cast": [
{ "id": "p1", "seconds": 14.2, "shots": [0, 2, 6], "face_url": "https://lovelyrouter.com/v1/videos/replacements/rpl_5e0c…/cast/p1/face", "body_url": "…/cast/p1/body", "appearances": [] },
{ "id": "p2", "seconds": 10, "shots": [1, 4], "face_url": "…/cast/p2/face", "body_url": "…/cast/p2/body", "appearances": [] }
],
"pieces": null,
"url": null,
"error": null,
"powered_by": "MiniMax H3"
}上传视频#
/v1/videos/replacements返回 202 和替换对象,状态为 analyzing。轮询它(?wait=)直到 ready。
请求体参数
modelstring必填minimax-h3-character-swap 或 minimax-h3-aftermidnight。
videofile | stringMP4、MOV 或 WebM,最大 95 MB:multipart 文件,或 http(s) / data: URL。
templatestring一个模板(rvt_…),代替 video:无需上传和分析,免费;替换几秒内就是 ready。
consentboolean必填true 表示接受 MiniMax H3 条款。
startend` number秒:要处理的部分,最长 3 分钟。默认:整个视频(最长 3 分钟)。
waitinteger分析期间保持请求 0–300 秒。
curl https://lovelyrouter.com/v1/videos/replacements \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-F model=minimax-h3-character-swap -F consent=true \
-F video=@party.mp4 -F start=12 -F end=72渲染#
/v1/videos/replacements/{id}/render开始替换一个 ready 的替换任务并返回它,状态为 rendering。发送 JSON,或 multipart(cast 作为 JSON 文本字段,图片作为文件)。
请求体参数
castobject必填演员表 id → {"character_id": "chr_…"}(已保存角色)、{"image": "<http(s) 或 data: URL>"}(一张图片——multipart 中为 "file:<部分名称>"),或 "keep"。未列出的人保持原样。最多 8 人。
modestring默认 personperson:替换整个人——脸、头发、身体、衣服。face:只替换头部——脸、头发和头上戴的东西(眼镜、耳机、帽子);身体和衣服保持不变。
backgroundstring默认 keepkeep:每个镜头保留原来的场景。new(仅 person 模式):每个镜头都在 scene 描述的地方重新生成。
scenestringbackground: "new" 时:发生的地点。最多 2,000 个字符。
promptstring给每个镜头的额外描述。最多 2,000 个字符。
modelstring用另一个替换模型渲染(默认为上传时的模型)。
seedinteger用于可重复的结果。
addedarray分析时漏掉的人(只有背影、太小):[{shot, x, y, time}]——镜头序号、人在画面中的位置(比例)和时间(秒,与 shots 相同的时间轴;默认镜头中间)。按顺序编号为 x1、x2……:像其他人一样在 cast 里对应角色。可在 GET …/{id}/preview 中找到他们。
skipobject按人排除的镜头:{"p1": [3, 7]}——分析把别人当成了这个人的镜头序号(可对照每个人的 appearances)。这些镜头里此人保持原样,也不为此计费。
curl https://lovelyrouter.com/v1/videos/replacements/RPL_ID/render \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/json" \
-d '{
"cast": {"p1": {"character_id": "chr_3b9e1f0c7a2d4e58b6c1a9f2"}, "p2": "keep"},
"mode": "face"
}'重试一个镜头#
/v1/videos/replacements/{id}/pieces/{n}/retry对已完成的替换任务,重新渲染其中一段——用于漏掉了人(pieces[].missed)或替换错了人的段。上传后 2 天内可用(retry_until)。
searchstring,可选 用几个简单的词描述要找的人("man in a black suit",最多 60 个字符),代替“任何人”。仅限整个人模式。pointsarray,可选[{person, x, y, time}]——点击一个被对应的人:x、y为画面中的比例,time为视频中的秒数(默认:该段中间)。点下位置的人会在整段中被追踪。
会预留该段的价格;只有成功替换了人才收费。该段渲染期间视频仍可下载(status 先是 rendering,然后是包含新段的 succeeded)。重试如果没找到人或失败,会保留之前的版本,不收费(pieces[].last_retry.outcome:swapped、none 或 failed)。
curl https://lovelyrouter.com/v1/videos/replacements/RPL_ID/pieces/0/retry \
-H "Authorization: Bearer $LOVELY_API_KEY" -H "Content-Type: application/json" \
-d '{"search": "man in a black suit", "points": [{"person": "p2", "x": 0.18, "y": 0.43, "time": 1.4}]}'再跑一次#
/v1/videos/replacements/{id}/rerun基于一个已结束的替换(succeeded、failed 或 cancelled)新建一个替换:同一段上传、同样的角色对应、图片、模式、背景、场景和提示词,换一个新的 seed——每一段都重新生成。不会重新上传或分析;立即开始渲染,按普通渲染计价、预扣和扣费。首次上传后 2 天内可用(rerun_until)。无需请求体。
返回新的替换对象(status 为 rendering)。原来的任务保持不变。如果分析过的视频已不再保留,返回 410:请重新上传视频。
curl -X POST https://lovelyrouter.com/v1/videos/replacements/RPL_ID/rerun \
-H "Authorization: Bearer $LOVELY_API_KEY"保存为模板#
/v1/videos/replacements/{id}/save把分析过的视频保存为模板,以后可以从它再做替换——换别的人、用别的角色——无需再次上传,也不用再为分析付费。保存会复制它的镜头、演员表和人物跟踪;免费,保留到你删除为止,每个账户最多 20 个。请在上传后 2 天内保存(分析过的视频保留这么久)。请求体:name(可选,最多 80 个字符;默认是文件名)。
返回 202 和模板,status 为 saving,随后变为 ready(几秒到一分钟)。在 POST /v1/videos/replacements 里用 template 使用它。
模板对象
idstringrvt_…。
namestatus` stringstatus:saving、ready 或 failed(带 error.message)。
fromstring它是从哪个替换保存的。
secondswidthcastarray[{id, seconds, shots, face_url, body_url}]——与原替换相同的演员表编号。
GET …/templates——你的模板,最新的在前。GET …/templates/{id}——单个;PATCH加{"name"}改名;DELETE删除(用它做的替换保留各自的副本)。GET …/templates/{id}/cast/{person}/face(或/body)——演员表图片。
curl -X POST https://lovelyrouter.com/v1/videos/replacements/RPL_ID/save \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "Content-Type: application/json" -d '{"name": "Party, take 1"}'
curl https://lovelyrouter.com/v1/videos/replacements \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "minimax-h3-character-swap", "consent": true, "template": "RVT_ID"}'获取、列出和删除#
/v1/videos/replacements/{id}替换对象;?wait=1–300 会一直等到它有变化(进入下一步,或某一段完成)。GET /v1/videos/replacements 列出你的替换任务,最新的在前(?limit=1–100、?after=<id>)。
GET …/{id}/content——完成的 mp4(支持Range请求)。GET …/{id}/pieces/{n}/content——其余部分还在渲染时,某一段已替换的视频。GET …/{id}/source——你上传的原视频(你发送的那一段,保留原文件名),保留 7 天。GET …/{id}/cast/{p}/face和…/body——演员表成员的图片(JPEG)。GET …/{id}/preview——分析部分的小视频(640 px,带声音),与shots相同的时间轴,用于找到分析时漏掉的人;保留 2 天。POST …/{id}/outfit——从分析过的视频中某一帧抠出某个人身上的服装(免费;用于把你的角色画成穿他们的衣服)。请求体{"person": "p3"}(可选"shot":他们出现的某个镜头)或{"added": {"shot", "x", "y", "time"}}→202 {"call", "shot", "shots"}:所用的镜头以及所有拍到他们的镜头,最佳在前(人在不同镜头里可能换衣服)。然后轮询GET …/{id}/outfit/{call}:运行中返回202(约 10 秒;GPU 需要启动时约 40 秒),完成后返回 JPEG——只有这个人(按其自身遮罩),白底,去掉头部(保留帽子)。422:这个镜头里看不清他们,换一个镜头。DELETE …/{id}——渲染前:丢弃(不再收费;已完成的分析照常收费)。渲染中:停止;已经替换的段照常收费。完成后:删除文件。
curl "https://lovelyrouter.com/v1/videos/replacements/RPL_ID?wait=60" \
-H "Authorization: Bearer $LOVELY_API_KEY"
curl https://lovelyrouter.com/v1/videos/replacements/RPL_ID/content \
-H "Authorization: Bearer $LOVELY_API_KEY" -o swapped.mp4获得好效果#
- 人物靠脸来区分:同一个人如果被分成两个演员表成员(一个镜头是侧脸,另一个是正脸),可以把两个都对应到同一个角色。
mode: face时,用角色的头部图片效果最好;mode: person时,用全身图或转身设定图。- 短于 2 秒的镜头也可以(会多渲染一点再裁回原长度)。