VT Lip Sync 口形同期
namifusion/vt-lipsync
VT Lip Sync は、翻訳後の対象動画、翻訳後音声、翻訳後字幕タイミング、および元動画とその元字幕タイミングを使用して、翻訳後動画の口形を同期します。
サンプル
パラメータ
| 名前 | 型 | 既定 | 制約 | 説明 |
|---|---|---|---|---|
| audio_url *翻訳後音声 | audio_upload | — | audio/mpeg,audio/wav,audio/ogg,audio/webm,audio/aac,audio/flac,audio/* | 翻訳後動画に対応する翻訳後音声を指定してください。翻訳後音声は呼び出し側で準備し、サービス側では ASR の区切りが字幕タイミングと対応できることを前提とします。 |
| subs_list *翻訳後字幕セグメント | array<object> | [] | — | 翻訳後動画に対応する文単位の ASR タイミングを指定してください。翻訳後は動画の長さが変わるため、この字幕セグメントは翻訳後動画と一致している必要があります。 |
| ↳start_ms *開始時間 (ms) | number | — | step 1 | セグメントの開始時間(ミリ秒)。 |
| ↳end_ms *終了時間 (ms) | number | — | step 1 | セグメントの終了時間(ミリ秒)。 |
| original_video_url *元動画 | video_upload | — | video/mp4,video/webm,video/quicktime,video/* | ユーザーがアップロードした元動画を指定してください。これは元の口形動作構造を参照するための基準動画です。 |
| original_subs_list *元字幕セグメント | array<object> | [] | — | 元動画に対応する文単位の ASR タイミングを指定してください。元字幕と翻訳後字幕のセグメントは、両方の動画間で対応している必要があります。 |
| ↳start_ms *開始時間 (ms) | number | — | step 1 | セグメントの開始時間(ミリ秒)。 |
| ↳end_ms *終了時間 (ms) | number | — | step 1 | セグメントの終了時間(ミリ秒)。 |
API
統一 REST API でこのモデルを呼び出せます。API Keys ページでキーを取得してください。
cURL
# 1) Submit — returns { "task_uuid": "..." }
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/vt-lipsync" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"audio_url": "https://d5v2vcqcwe9y5.cloudfront.net/algorithm/video_translate/260327/default/qtqfcgymg08o.wav",
"subs_list": [
{
"end_ms": 4178,
"start_ms": 300
}
],
"original_video_url": "https://d5v2vcqcwe9y5.cloudfront.net/video_translate/260327/6964a3741d6212ca41d15d2d/3ftvqu8aewix.mp4",
"original_subs_list": [
{
"end_ms": 3780,
"start_ms": 300
}
]
}
}'
# 2) Poll until status is "completed", then read the output URLs
curl "https://www.namifusion.com/api/v1/marketplace/run/tasks/TASK_UUID" \
-H "Authorization: Bearer YOUR_API_KEY"Python
import time, requests
API_KEY = "YOUR_API_KEY"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 1) Submit
resp = requests.post(
"https://www.namifusion.com/api/v1/marketplace/run/namifusion/vt-lipsync",
headers=HEADERS,
json={
"input": {
"audio_url": "https://d5v2vcqcwe9y5.cloudfront.net/algorithm/video_translate/260327/default/qtqfcgymg08o.wav",
"subs_list": [
{
"end_ms": 4178,
"start_ms": 300
}
],
"original_video_url": "https://d5v2vcqcwe9y5.cloudfront.net/video_translate/260327/6964a3741d6212ca41d15d2d/3ftvqu8aewix.mp4",
"original_subs_list": [
{
"end_ms": 3780,
"start_ms": 300
}
]
}
},
)
resp.raise_for_status() # 401/402/429/5xx stop here instead of polling a bad task
task = resp.json()
# 2) Poll until a terminal state (completed / failed / cancelled).
# This model is allowed up to 1800s server-side.
deadline = time.time() + 1860
while task.get("status") not in ("completed", "failed", "cancelled"):
if time.time() > deadline:
raise TimeoutError(f"still {task.get('status')} — keep the task_uuid and poll later")
time.sleep(3)
poll = requests.get(f"https://www.namifusion.com/api/v1/marketplace/run/tasks/{task['task_uuid']}", headers=HEADERS)
poll.raise_for_status()
task = poll.json()
print(task["status"], task.get("output"))JavaScript
const API_KEY = "YOUR_API_KEY";
const HEADERS = { Authorization: `Bearer ${API_KEY}` };
// 1) Submit
const resp = await fetch("https://www.namifusion.com/api/v1/marketplace/run/namifusion/vt-lipsync", {
method: "POST",
headers: { ...HEADERS, "Content-Type": "application/json" },
body: JSON.stringify({
"input": {
"audio_url": "https://d5v2vcqcwe9y5.cloudfront.net/algorithm/video_translate/260327/default/qtqfcgymg08o.wav",
"subs_list": [
{
"end_ms": 4178,
"start_ms": 300
}
],
"original_video_url": "https://d5v2vcqcwe9y5.cloudfront.net/video_translate/260327/6964a3741d6212ca41d15d2d/3ftvqu8aewix.mp4",
"original_subs_list": [
{
"end_ms": 3780,
"start_ms": 300
}
]
}
}),
});
if (!resp.ok) throw new Error(`submit failed: ${resp.status} ${await resp.text()}`);
let task = await resp.json();
// 2) Poll until a terminal state (completed / failed / cancelled).
// This model is allowed up to 1800s server-side.
const deadline = Date.now() + 1860 * 1000;
while (!["completed", "failed", "cancelled"].includes(task.status)) {
if (Date.now() > deadline) throw new Error(`still ${task.status} — keep the task_uuid and poll later`);
await new Promise((r) => setTimeout(r, 3000));
const poll = await fetch(`https://www.namifusion.com/api/v1/marketplace/run/tasks/${task.task_uuid}`, { headers: HEADERS });
if (!poll.ok) throw new Error(`poll failed: ${poll.status}`);
task = await poll.json();
}
console.log(task.status, task.output);ドキュメント
NamiFusion VT LipSync
翻訳後動画のリップシンク:翻訳後動画、翻訳後音声、および両側の文単位タイムラインを入力し、再同期されたリップシンク動画を出力します。
NamiFusion VT LipSync は、動画翻訳シナリオ向けに設計されたリップシンクサービスです。翻訳後に動画の長さや音声のリズムが変化したケースに適しています。翻訳後の動画、翻訳後の音声、さらに翻訳前後それぞれの文単位で分割されたタイムライン情報を入力することで、ターゲット音声に同期したリップシンク動画を生成します。
主な機能
- 動画翻訳ワークフロー向け: 翻訳後の音声や動画の長さの変化によって生じる口の動きのずれを専門的に処理します。
- 二重タイムライン入力: 翻訳後の文単位タイムラインと原文側の文単位タイムラインを同時に受け取り、文レベルの対応関係を構築します。
- 非同期タスク: 送信後に
task_uuidが返され、ポーリングまたは Webhook で結果を取得できます。 - 結果動画の出力: タスク完了後に、リップシンク済み動画の URL を返します。
技術仕様
| パラメータ | 詳細 |
|---|---|
| モデルID | namifusion/vt-lipsync |
| リクエスト方式 | 非同期POST(タスク送信 + ポーリング/Webhook で結果取得) |
| 入力 | 翻訳後動画URL + 翻訳後音声URL + 両側の文単位タイムライン |
| 出力 | リップシンク済み動画URL |
| 処理時間 | 通常は数十秒から数分。動画の長さと文分割数に依存します |
クイックスタート
APIエンドポイント
| エンドポイント | メソッド | 説明 |
|---|---|---|
/api/v1/marketplace/run/namifusion/vt-lipsync | POST | VT LipSync タスクを送信 |
/api/v1/marketplace/run/tasks/{task_uuid} | GET | タスクのステータスと結果を照会 |
認証
リクエストヘッダーに API Key を含めてください:
X-API-Key: sk-your-api-key
使用例
ステップ1:タスクを送信
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/vt-lipsync" \
-H "X-API-Key: sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"input": {
"video_url": "https://example.com/translated_video.mp4",
"audio_url": "https://example.com/translated_audio.wav",
"subs_list": [
{ "start_ms": 0, "end_ms": 8090 },
{ "start_ms": 8090, "end_ms": 10269 }
],
"original_video_url": "https://example.com/original_video.mp4",
"original_subs_list": [
{ "start_ms": 0, "end_ms": 7840 },
{ "start_ms": 7840, "end_ms": 9820 }
],
}
}'
レスポンス例:
{
"task_uuid": "69b931ac-d2db-d096-fc0a-bed1a2c3d4e5",
"status": "pending",
"cost_credits": 0
}
ステップ2:タスクステータスをポーリング
curl -X GET "https://www.namifusion.com/api/v1/marketplace/run/tasks/69b931ac-d2db-d096-fc0a-bed1a2c3d4e5" \
-H "X-API-Key: sk-your-api-key"
処理中:
{
"task_uuid": "69b931ac-d2db-d096-fc0a-bed1a2c3d4e5",
"status": "processing"
}
完了:
{
"task_uuid": "69af63b1-285a-4ae0-fe92-6cc5a1b2c3d4",
"model_id": "namifusion/vt-lipsync",
"status": "completed",
"output": {
"lipsync_video_url": "https://d5v2vcqcwe9y5.cloudfront.net/algorithm/lipsync/260310/default/tx6hbykt7ntp.mp4",
"lipsync_from": 1
},
"cost_credits": 0,
"created_at": "2026-03-08T00:20:01Z",
"completed_at": "2026-03-08T00:21:31Z"
}
Python 呼び出し例
import requests
import time
API_KEY = "sk-your-api-key"
BASE_URL = "https://www.namifusion.com/api/v1/marketplace/run"
HEADERS = {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
}
payload = {
"input": {
"video_url": "https://example.com/translated_video.mp4",
"audio_url": "https://example.com/translated_audio.wav",
"subs_list": [
{"start_ms": 0, "end_ms": 8090},
{"start_ms": 8090, "end_ms": 10269},
],
"original_video_url": "https://example.com/original_video.mp4",
"original_subs_list": [
{"start_ms": 0, "end_ms": 7840},
{"start_ms": 7840, "end_ms": 9820},
],
}
}
task_resp = requests.post(
f"{BASE_URL}/namifusion/vt-lipsync",
headers=HEADERS,
json=payload,
).json()
task_uuid = task_resp["task_uuid"]
print(f"Task submitted: {task_uuid}")
while True:
status_resp = requests.get(
f"{BASE_URL}/tasks/{task_uuid}",
headers=HEADERS,
).json()
status = status_resp["status"]
print(f"Status: {status}")
if status == "completed":
result = status_resp["output"]
print("Result video:", result["lipsync_video_url"])
print("Source type:", result.get("lipsync_from"))
break
if status == "failed":
print("Failed:", status_resp.get("error_message", "Unknown error"))
break
time.sleep(5)
パラメータと戻り値の詳細
リクエストパラメータ
リクエストボディは JSON 形式で、すべてのパラメータは input オブジェクト内に配置します:
{
"input": {
"video_url": "https://...",
"audio_url": "https://...",
"subs_list": [
{ "start_ms": 6140, "end_ms": 8090 }
],
"original_video_url": "https://...",
"original_subs_list": [
{ "start_ms": 6140, "end_ms": 7840 }
]
}
}
| パラメータ | 型 | 必須 | デフォルト値 | 説明 |
|---|---|---|---|---|
video_url | string | はい | - | 翻訳後動画の URL です。この動画はターゲット言語に合わせて、すでに長さ変更や動的リタイミングが行われています。 |
audio_url | string | はい | - | 翻訳後音声の URL です。サービスはこの音声を基準にリップシンクを行います。 |
subs_list | array | はい | - | 翻訳後音声の ASR 文分割結果です。各要素は 1 文の開始時刻と終了時刻を表します。 |
original_video_url | string | はい | - | ユーザーがアップロードした元動画の URL です。元の口の動きの参照として使用されます。 |
original_subs_list | array | はい | - | 元動画音声の ASR 文分割結果です。各要素は 1 文の開始時刻と終了時刻を表します。 |
文タイムラインオブジェクト
subs_list と original_subs_list の各要素は同じ構造を使用します:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
start_ms | integer | はい | 現在の文の開始時刻。単位はミリ秒です。 |
end_ms | integer | はい | 現在の文の終了時刻。単位はミリ秒です。 |
パラメータ制約と対応関係
| 項目 | 説明 |
|---|---|
subs_list と original_subs_list | それぞれ翻訳後音声と元音声の ASR 文分割結果です。両者の長さは一致する必要はありません。 |
| 時間単位 | すべての時間はミリ秒単位です。 |
| 時間順序 | 各文オブジェクトは start_ms < end_ms を満たす必要があります。 |
| URL の到達可能性 | すべての URL は、サーバーが直接ダウンロードできる公開 URL である必要があります。 |
| 音声と動画の対応関係 | video_url と audio_url は同じ翻訳後コンテンツに属している必要があります。original_video_url と original_subs_list は同じ元コンテンツに属している必要があります。 |
タスクステータス
タスク送信後はポーリングで状態を取得します。ポーリング間隔は 5 秒を推奨します:
| ステータス | 説明 |
|---|---|
pending | タスクは作成済みで、処理待ちです。 |
processing | タスクを処理中です。 |
completed | タスクが完了し、結果は output.lipsync_video_url から取得できます。 |
failed | タスクが失敗しました。理由は error_message を確認してください。 |
戻り値の構造
タスク送信レスポンス
| フィールド | 型 | 説明 |
|---|---|---|
task_uuid | string | 後続の状態照会に使用する一意のタスク識別子。 |
status | string | 初期タスクステータス。通常は pending。 |
cost_credits | number | このタスクで消費されたクレジット。 |
タスク完了レスポンス
| フィールド | 型 | 説明 |
|---|---|---|
task_uuid | string | 一意のタスク識別子。 |
model_id | string | モデルID(namifusion/vt-lipsync)。 |
status | string | タスクステータス。 |
output.lipsync_video_url | string | リップシンク後の動画 URL。 |
output.lipsync_from | integer | 結果ソースを示すマーカーです。現在のサンプルレスポンスでは 1 が返されます。 |
cost_credits | number | 消費されたクレジット。 |
created_at | string | タスク作成時刻(ISO 8601)。 |
completed_at | string | タスク完了時刻(ISO 8601)。 |
error_message | string | エラーメッセージ。failed の場合のみ返されます。 |
内部タスクフィールド対応表
以下の表は、この公開 API と内部タスクドキュメント字段の対応関係を示します:
| 公開リクエストフィールド | 内部タスクドキュメントフィールド |
|---|---|
input.video_url | extra.video_url |
input.audio_url | extra.audio_url |
input.subs_list | extra.subs_list |
input.original_video_url | extra.original_video_url |
input.original_subs_list | extra.original_subs_list |
output.lipsync_video_url | data.lipsync_video_url |
output.lipsync_from | data.lipsync_from |
パラメータが出力結果に与える影響
| パラメータ | 出力への影響 |
|---|---|
video_url | リップシンク整列の基準となる映像と、翻訳後動画のテンポを決定します。 |
audio_url | 結果動画が最終的に合わせるべきターゲット音声内容を決定します。 |
subs_list | 翻訳後音声の ASR 文分割結果です。翻訳後コンテンツの文境界を定義し、文レベルのリップシンク再整列に直接影響します。 |
original_video_url | 元動画の口の動き参照を提供し、元動画の話し方の特徴を保持するために使われます。 |
original_subs_list | 元音声の ASR 文分割結果です。元動画の文単位タイミングを翻訳後バージョンへ対応付けるために使われます。 |
エラーレスポンス
タスクが失敗した場合、ポーリングレスポンスにはエラーメッセージが含まれます:
{
"task_uuid": "69b931ac-d2db-d096-fc0a-bed1a2c3d4e5",
"status": "failed",
"error_message": "Invalid subtitle alignment"
}
一般的なエラー:
| エラーコード | 説明 |
|---|---|
| 400 | 必須フィールド不足やタイムライン形式不正などのパラメータエラー。 |
| 401 | API Key の欠落または無効による認証失敗。 |
| 408 | 動画または音声のダウンロードがタイムアウト。 |
| 422 | 入力メディアにアクセスできない、または文タイムラインと内容が正しく対応していない。 |
| 500 | サービス内部エラー。 |
注意事項
- 翻訳後動画と翻訳後音声の両方を必ず提供してください: このサービスは両方の入力に依存して正しくリップシンクを行います。
- 文タイムラインはそれぞれの音声の ASR 結果から取得してください:
subs_listは翻訳後音声の ASR 文分割結果、original_subs_listは元音声の ASR 文分割結果です。両者の長さは一致する必要はありません。 - 翻訳後動画は長さが変わっていても問題ありません: このサービスは、翻訳後動画の長さが元動画と異なるシナリオ向けに設計されています。
- 安定した文分割を推奨します: 分割が粗すぎたり細かすぎたりすると、同期品質が低下する可能性があります。
- 結果フィールド: 最終的な出力動画 URL は
output.lipsync_video_urlにあります。
関連モデル
Kling Omni Video O3
Kling Omni Video O3は、複数の視点からキャラクター、プロップ、またはシーンの参照を使用して創造的な動画を生成します。対象の特徴を抽出し、フレーム間でアイデンティティの一貫性を維持しながら新しい動画コンテンツを作成します。音声生成をサポート。すぐに使える REST API、最高のパフォーマンス、コールドスタートなし、手頃な価格。
Kling Omni Video O3
Kling Omni Video O3は、複数の視点からキャラクター、プロップ、またはシーンの参照を使用して創造的な動画を生成します。対象の特徴を抽出し、フレーム間でアイデンティティの一貫性を維持しながら新しい動画コンテンツを作成します。音声生成をサポート。すぐに使える REST API、最高のパフォーマンス、コールドスタートなし、手頃な価格。
Kling Omni Video O1 リファレンス動画生成
Kling Omni Video O1 リファレンス動画生成は、複数の視点からのキャラクター、小道具、またはシーンのリファレンスを使用してクリエイティブな動画を生成します。被写体の特徴を抽出し、フレーム間でのアイデンティティの一貫性を維持しながら、新しい動画コンテンツを作成します。すぐに使えるREST API、最高のパフォーマンス、コールドスタートなし、手頃な価格。
Kling Omni Video O1 リファレンス動画生成
Kling Omni Video O1 リファレンス動画生成は、複数の視点からのキャラクター、小道具、またはシーンのリファレンスを使用してクリエイティブな動画を生成します。被写体の特徴を抽出し、フレーム間でのアイデンティティの一貫性を維持しながら、新しい動画コンテンツを作成します。すぐに使えるREST API、最高のパフォーマンス、コールドスタートなし、手頃な価格。
Kling 3.0 Standard モーションコントロール
Kling 3.0 Standard モーションコントロールは、参照動画の動きを静止画像に転送してアニメーション化します。キャラクター画像とモーションクリップ(ダンス、アクション、ジェスチャー)をアップロードすると、モデルが動きを抽出して滑らかでリアルな動画を生成します。すぐに使用可能な REST 推論 API、最高のパフォーマンス、コールドスタートなし、手頃な価格。
seedance-2-0 reference-to-video
Seedance 2.0の「リファレンス動画生成」機能は、ビジュアルの統一性を保つ究極のソリューションです。参考素材からアートスタイル、ライティング、構図の意図を正確に抽出。新しく生成される動画に完璧に融合させ、シリーズ作品を通して一貫した世界観を維持します。
Alibaba WAN 2.6
Alibaba WAN 2.6 Reference-to-Video は、キャラクター、小道具、またはシーンの参照画像(単一または複数視点)から、新しいビデオショットを生成します。アイデンティティ、スタイル、レイアウトを忠実に再現しつつ、滑らかで一貫性のある動きを実現。即利用可能な REST 推理 API は、コールドスタートなしの最高性能を誇り、圧倒的なコストパフォーマンスを提供します。