Lovely Routerドキュメント
キーを取得
API リファレンス

動画置き換えのエンドポイント

すべての /v1/videos/replacements エンドポイント——動画をまるごとアップロードし、ショットと登場人物を取得し、各人物をキャラクターに割り当てて、入れ替えた動画を受け取ります。

動画の中の人物を入れ替えます——カットがあっても、複数のショットや複数の人物がいても大丈夫です。アップロードは一度だけ:ショットと登場人物を検出します(動画 1 秒あたり $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分)をショットに分け、登場人物をキャストにまとめます。各人物に顔と上半身の画像が付きます。全員をすべてのショットで追跡するので、後ろ姿や横を向いた人物も見つかります。解析した 1 秒あたり $0.01(最低 5 秒)。アップロード時に残高から仮押さえし、ready になったときに請求します。解析が失敗したら無料です。ステータスは analyzing → ready。
  2. レンダリング(POST …/{id}/render):キャストをキャラクターに割り当てます。割り当てた人物がいないショットはそのまま残り、それ以外のショットをピースごとに再レンダリングし、最後につなぎ直します(rendering → stitching → succeeded)。各ピースは必ずカットで始まりカットで終わり、少なくとも約5秒あります。短いカットが続く部分はカット割りを保ったまままとめてレンダリングし(差し替える人のいない短いショットを含めることがあります。そのショットはそのまま残り、課金されません)、15秒を超えるショットだけをほぼ同じ長さに分けます。
  3. ダウンロード …/{id}/content。各パートは完成しだい見られます(pieces[].url)。

最初のショットをレンダリングする前に、ビジョンモデルが各キャラクターの画像を見て、写っているもの——髪、頭に着けているもの、眼鏡、全身モードでは服装——と写っていないもの(「眼鏡なし、ヘッドホンなし」)を書き出します。どのショットもその見た目で描かれ、余計なものは加わりません。あなたのキーでのチャット呼び出しとして課金されます(キャラクター1人あたり約 $0.003)。

各ショットのレンダリング前に、モデルがそのショットを映像と音声で確認し、誰が話しているかを記録したうえで、ショットの演出を書き起こします。置き換える人物それぞれの画面内の位置、向き、腕を含む動きです。これにより新しい人物が元の姿勢と動きを保ちます。ショットの説明には話者が明記され、話していない置き換え対象の人物は、他人のセリフに口を合わせず口を閉じたままになります。この呼び出しはお客様のキーに課金されます(1 ショットあたり約 $0.03)。

誰が誰かは顔で判断します:各ショットで追跡した人物を顔でキャストと照合するため、ショットの間ずっと後ろ姿の人物は見つからないことがあります——そのショットは変更されずに返され、料金もかかりません。

料金#

入れ替えた動画の秒数で課金します:実際に人物が入れ替わったパートの秒数——minimax-h3-character-swap は1秒あたり $0.20、入れ替えた各パートは最低5秒(FastH3 Omni でレンダリングし、最短のレンダリングが5秒のため);minimax-h3-aftermidnight は1秒あたり $0.12、各パート最低2秒——1本あたり最低3秒です。ショットと人物の検出は 1 秒あたり $0.01(アップロード時に 1 回だけ。もう一度実行とテンプレートでは再解析しません)。変更のないショットは無料です。レンダリング時に最大額(割り当てた人物がいるすべてのパート)を確保し、完了後に差額を返金します。

置き換えオブジェクト#

属性

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}——見つかった人物ごとに1つ(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)を返します。ready になるまでポーリングします(?wait=)。

リクエストボディのパラメータ

modelstring必須

minimax-h3-character-swap または minimax-h3-aftermidnight。

videofile | string

MP4・MOV・WebM、最大 95 MB:multipart のファイル、または http(s) / data: URL。

templatestring

video の代わりにテンプレート(rvt_…):アップロードも解析もなく無料。数秒で 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

完了した置き換えの 1 ピースをやり直します。差し替え漏れ(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

解析済みの動画をテンプレートとして保存して、あとから別の人物や別のキャラクターで置き換えを作れます。再アップロードも、解析の再課金もありません。ショット、キャスト、人物の追跡をコピーします。無料で、削除するまで保存され、1 アカウント最大 20 本です。アップロードから 2 日以内に保存してください(解析済みの動画はその間保持されます)。ボディ:name(任意、80 文字まで。省略時はファイル名)。

202 とテンプレートを返します。status は saving、続いて ready(数秒〜1 分)。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}]——保存元と同じキャスト ID。

  • GET …/templates——テンプレート(新しい順)。
  • GET …/templates/{id}——1 本。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——残りのレンダリング中に、入れ替え済みのパートを1つ。
  • GET …/{id}/source——アップロードした元の動画(送信した部分、元のファイル名のまま)。7日間保存。
  • GET …/{id}/cast/{p}/face と …/body——キャストの画像(JPEG)。
  • GET …/{id}/preview——解析した区間の小さな動画(640 px、音声付き)。shots と同じ時間軸で、見つからなかった人物を探すためのもの。2 日間保持。
  • POST …/{id}/outfit——解析した動画の 1 フレームから、ある人物の服装を切り抜きます(無料。キャラクターをその衣装で描くため)。ボディは {"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

よい結果を得るために#

  • 人物は顔で見分けます:同じ人が2つのキャストに分かれた場合(あるショットでは横顔、別のショットでは正面)、両方を同じキャラクターに割り当てられます。
  • mode: face にはキャラクターの頭部の画像、mode: person には全身画像やターンアラウンドシートが最適です。
  • 2秒未満のショットも使えます(少し長くレンダリングしてから元の長さに切り戻します)。