Lovely Router文档
获取密钥
API 参考

视频替换端点

所有 /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 里试用。

工作方式#

  1. 上传(POST /v1/videos/replacements):视频(或 start 到 end 之间的部分,最长 3 分钟)被切成镜头,其中的每个人被归为一个演员表成员,每人一张脸部图和一张半身图;每个人在每个镜头里都会被跟踪,所以背对镜头或转过身的人也能找到。按分析的秒数每秒 $0.01(至少 5 秒),上传时从余额预扣,ready 时扣费;分析失败不收费。状态 analyzing → ready。
  2. 渲染(POST …/{id}/render):把演员表成员对应到角色。没有被对应人物的镜头保持原样;其余镜头分段重新渲染(rendering),最后拼接回去(stitching → succeeded)。每段都从剪辑点开始、在剪辑点结束,且至少约 5 秒:连续的快切镜头保留剪辑点一起渲染(没有要替换的人的短镜头可能被一并带上——它保持原样,不计费);只有超过 15 秒的镜头才会切成长度相近的几段。
  3. 下载 …/{id}/content。每段完成后就可以观看(pieces[].url)。

第一个镜头渲染之前,一个视觉模型会查看每个角色的图片,写下图上有什么——头发、头上戴的东西、眼镜,整个人模式下还有衣服——以及没有什么(“没有眼镜、没有耳机”),这样每个镜头都按这个样子来画,不会多加任何东西。它按一次对话调用从你的密钥计费(每个角色约 $0.003)。

每个镜头渲染之前,一个模型会观看并收听这个镜头,记下谁在说话,并为镜头做调度说明:每个被替换的人在画面中的位置、朝向和动作(包括手臂),让新角色保持原来的姿势和动作。镜头描述会点名说话的人,没有说话的被替换者会保持嘴巴不动,而不是对着别人的台词做口型。这次调用按你的密钥计费(每个镜头约 $0.03)。

谁是谁由人脸决定:在每个镜头里,追踪到的人按脸和演员表匹配,所以一个人如果整个镜头都是背影,可能在那个镜头里找不到——那个镜头就保持原样返回,也不收费。

价格#

按被替换的视频秒数计费:真正有人被替换的那些段的秒数——minimax-h3-character-swap 每秒 $0.20,每个被替换的段至少按 5 秒计(它在 FastH3 Omni 上渲染,最短渲染 5 秒);minimax-h3-aftermidnight 每秒 $0.12,每段至少 2 秒——每个视频至少 3 秒。找镜头和人物每秒 $0.01(上传时收一次;再运行一次和模板不会重新分析);保持原样的镜头免费。渲染时预留最多可能花费的金额(所有有被对应人物的段),完成后退还多余部分。

替换对象#

属性

idstring

rpl_ 加 24 个字符。

objectstring

始终为 video.replacement。

statusstring

analyzing、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 | null
analysis_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"
}

上传视频#

POST/v1/videos/replacements

返回 202 和替换对象,状态为 analyzing。轮询它(?wait=)直到 ready。

请求体参数

modelstring必填

minimax-h3-character-swap 或 minimax-h3-aftermidnight。

videofile | string

MP4、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
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

渲染#

POST/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默认 person

person:替换整个人——脸、头发、身体、衣服。face:只替换头部——脸、头发和头上戴的东西(眼镜、耳机、帽子);身体和衣服保持不变。

backgroundstring默认 keep

keep:每个镜头保留原来的场景。new(仅 person 模式):每个镜头都在 scene 描述的地方重新生成。

scenestring

background: "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"
  }'

重试一个镜头#

POST/v1/videos/replacements/{id}/pieces/{n}/retry

对已完成的替换任务,重新渲染其中一段——用于漏掉了人(pieces[].missed)或替换错了人的段。上传后 2 天内可用(retry_until)。

  • search string,可选 用几个简单的词描述要找的人("man in a black suit",最多 60 个字符),代替“任何人”。仅限整个人模式。
  • points array,可选 [{person, x, y, time}]——点击一个被对应的人:x、y 为画面中的比例,time 为视频中的秒数(默认:该段中间)。点下位置的人会在整段中被追踪。

会预留该段的价格;只有成功替换了人才收费。该段渲染期间视频仍可下载(status 先是 rendering,然后是包含新段的 succeeded)。重试如果没找到人或失败,会保留之前的版本,不收费(pieces[].last_retry.outcome:swapped、none 或 failed)。

cURL
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}]}'

再跑一次#

POST/v1/videos/replacements/{id}/rerun

基于一个已结束的替换(succeeded、failed 或 cancelled)新建一个替换:同一段上传、同样的角色对应、图片、模式、背景、场景和提示词,换一个新的 seed——每一段都重新生成。不会重新上传或分析;立即开始渲染,按普通渲染计价、预扣和扣费。首次上传后 2 天内可用(rerun_until)。无需请求体。

返回新的替换对象(status 为 rendering)。原来的任务保持不变。如果分析过的视频已不再保留,返回 410:请重新上传视频。

cURL
curl -X POST https://lovelyrouter.com/v1/videos/replacements/RPL_ID/rerun \
  -H "Authorization: Bearer $LOVELY_API_KEY"

保存为模板#

POST/v1/videos/replacements/{id}/save

把分析过的视频保存为模板,以后可以从它再做替换——换别的人、用别的角色——无需再次上传,也不用再为分析付费。保存会复制它的镜头、演员表和人物跟踪;免费,保留到你删除为止,每个账户最多 20 个。请在上传后 2 天内保存(分析过的视频保留这么久)。请求体:name(可选,最多 80 个字符;默认是文件名)。

返回 202 和模板,status 为 saving,随后变为 ready(几秒到一分钟)。在 POST /v1/videos/replacements 里用 template 使用它。

模板对象

idstring

rvt_…。

namestatus` string

status:saving、ready 或 failed(带 error.message)。

fromstring

它是从哪个替换保存的。

secondswidth
castarray

[{id, seconds, shots, face_url, body_url}]——与原替换相同的演员表编号。

  • GET …/templates——你的模板,最新的在前。
  • GET …/templates/{id}——单个;PATCH 加 {"name"} 改名;DELETE 删除(用它做的替换保留各自的副本)。
  • GET …/templates/{id}/cast/{person}/face(或 /body)——演员表图片。
cURL
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"}'

获取、列出和删除#

GET/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
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 秒的镜头也可以(会多渲染一点再裁回原长度)。