Google Vids API でアバターを使った AI インフルエンサー動画を作る方法
15分で読めます • 2026年10月7日(2026年11月6日更新)
useapi.net はサードパーティの API です。Google とは提携しておらず、Google の承認も受けていません。
目次
はじめに
useapi.net の Google Vids API は、アバターを使って話す AI インフルエンサー動画を作ります。POST /avatars で画像1枚と30種類の Gemini の声の1つを一度保存すれば、そのアバターの ID を最長15秒の Gemini Omni 1.2 Flash 動画に渡すだけで、プロンプトに書いたセリフをアバターが話します。最長30秒のトーキングヘッド動画で、ご自身の台本を読ませることもできます。
API は、有料の Google AI のプラン(Google AI Pro または Ultra)に加入した Google Vids アカウントで動きます。このチュートリアルでは2人のインフルエンサーを作り、2人にスニーカーを発表させます。Mia のアバターは API で作ったポートレートから、Leo のアバターは文章の説明から Google が描いたものです。2人は劇場のステージで架空のスニーカー AeroLoop を紹介します。2体のアバターと商品画像を1本の10秒の動画に入れ、2回の延長で30秒にします。編集でシーンを屋上に移し、さらに2本の動画で、アバターなしで同じ呼び出しが何を作るかも見ます。3人目のアバター Amber は実在の人物の写真から作り、1文でスタイルを変えて、327文字の台本を24秒のトーキングヘッド動画で読み上げます。最後に、同じ声で2,426文字の物語を音声だけで読み上げます。以下のリクエストはすべて、このページのメディアを実際に作ったもので、ID は置き換え、async: true は run ヘルパーが追加しています。動画は2026年10月に Omni 1.1 Flash で作りました。Vids は2026年11月5日に Omni 1.1 Flash を Omni 1.2 Flash に置き換えましたが、同じリクエストは 1.2 でも動きます。Google Vids と Google Flow の Omni 1.2 を、15秒の動画と1本あたりの料金で並べて比べた記事は Gemini Omni 1.2 Flash API の使い方です。
完成した30秒の動画(720p)。10秒の生成1回と、10秒の延長2回で作りました(ステップ6〜8)。
かかったコスト
useapi.net は API で、独自の動画サービスではありません。呼び出しはすべて、Google Vids のセットアップで接続した有料の Google AI プランの Google アカウントで実行され、そのプランに含まれる Google Vids の毎月の動画秒数と画像を使います。Google AI Ultra $199.99 には月10,000秒の動画と1,000枚の画像が含まれ、useapi.net は動画ごとの料金を追加しません。トーキングアバター動画と音声は動画秒数を使いません。それぞれ「AI アバター動画」と「Gemini の利用回数」という別の月間カウンターがあり、GET /accounts/email では video と image の横に avatarVideo と speech として表示されます。ほかのプランについては各プランに含まれるものを参照してください。
残した結果それぞれが使った量(result.quota の変化から)と、各ジョブにかかった時間(result.elapsedMs)です。
| ステップ | エンドポイント | 使用量 | 時間 |
|---|---|---|---|
| Mia のポートレート | POST /images | 画像1枚 | 9秒 |
| AeroLoop の商品写真 | POST /images | 画像1枚 | 9秒 |
| ポートレートから Mia のアバター | POST /avatars | なし | 約2秒 |
| 説明から Leo のアバター | POST /avatars | 画像1枚 | 約20秒 |
| 10秒の発表動画 | POST /videos | 10秒 | 38秒 |
| 20秒に延長 | POST /videos/extend | 10秒 | 70秒 |
| 30秒に延長 | POST /videos/extend | 10秒 | 85秒 |
| 20秒の動画を 1080p にアップスケール | POST /videos/upscale | 20秒 | 62秒 |
| 屋上への編集 | POST /videos/edit | 10秒 | 64秒 |
| 30秒の動画の編集 | POST /videos/edit | 10秒 | 87秒 |
| 商品のヒーロー動画 | POST /videos | 10秒 | 62秒 |
| ハト | POST /videos | 5秒 | 54秒 |
refine を使い写真から Amber のアバター | POST /avatars | なし(画像のないプランで作成。画像のあるプランでは画像2枚) | 約30〜45秒 |
| Amber の24秒のトーキング動画 | POST /videos/avatar | AI アバター動画1本、Gemini 1回 | 約2.5分 |
| 2,426文字の物語 | POST /speech | Gemini 1回 | 20秒 |
| 合計 | 動画85秒、画像3枚、AI アバター動画1本、Gemini 2回 |
延長が使うのは追加した秒数だけで、動画全体の長さではありません。アップスケールは動画の全長をもう一度使い、編集は編集した秒数を上限に使います(Omni 1.2 では、当社のテストで15秒の編集が10秒を使いました)。生成時は 720p と 1080p の料金は同じです。同じ動画をもう一度生成すると、その秒数をもう一度使います。Google がアバター用に描く画像は1枚ごとに画像1枚を使うので、写真の再構成と refine で2枚になります。無料の Google アカウントのように画像のないプランでは、アバターの画像に費用はかかりません。Amber はそうしたアカウントで作りました。トーキングアバター動画は、完成した動画を Google が拒否した場合でも、AI アバター動画1本と、その音声のための Gemini 1回を使います。公式 API と比べた動画の料金は、Google Vids の料金表にあります。
始める前に
useapi.net の API トークンと、有料の Google AI プランの Google アカウントが必要です。アカウントは Google Vids のセットアップで接続します。無料の Google アカウントには Vids の動画秒数も画像もありません。それでも追加はでき、当社のテスト(2026年11月)では、アバター、トーキングアバター動画、音声を作れました。すべての呼び出しは Postman コレクションにもあります。
コードを書かない方法もあります。n8n テンプレート Talking Avatar App は、フォームからトーキングアバター動画を作ります。パイプライン全体は、GitHub の useapi/google-vids-api にも Node.js と Python の1つのスクリプトとして公開しています。influencer-avatars/ がそれで、トーキングアバターと音声の部分は talking-avatar/ です。
手順では curl、jq と、次の変数とヘルパーを使います。
変数とヘルパーを表示
export USEAPI_TOKEN="user:12345-..."
export EMAIL="[email protected]"
API=https://api.useapi.net/v1/google-vids
AUTH="Authorization: Bearer $USEAPI_TOKEN"
enc() { jq -rn --arg v "$1" '$v|@uri'; }
post() { curl -sS -X POST "$API/$1" -H "$AUTH" -H "Content-Type: application/json" -d "$2"; }
get() { curl -sS "$API/$1" -H "$AUTH"; }
download() { curl -sSf "$API/media/$(enc "$1")" -H "$AUTH" -o "$2"; }
# run a video job async: submit it, poll GET /jobs/{jobid} every 10 s, save the final job record to $1
run() {
local job id
job=$(post "$2" "$(jq '. + {async: true}' <<< "$3")")
id=$(jq -r .jobid <<< "$job")
while [ "$(jq -r .status <<< "$job")" = processing ]; do
sleep 10
job=$(get "jobs/$(enc "$id")")
done
echo "$job" > "$1"
jq '{status, error, duration: .result.duration, resolution: .result.resolution, videoLeft: .result.quota.video.left}' "$1"
}
生成はすべてジョブとして実行されます。async なしの場合、POST は最大約100秒待って完了したジョブの記録を返すか、ジョブがまだ実行中なら 202 を返します。今回、新しい10秒の動画は38〜62秒、延長、編集、アップスケールは62〜87秒、トーキングアバター動画は約2分半かかりました。同期の待ち時間より長くかかるものもあるので、run は動画ジョブを async: true で送り、GET /jobs/jobid をポーリングします。run が completed 以外の status を表示したら、そこで止めて error を読んでください。後に続く行は、完成した動画があることを前提にしています。
ポーリングの代わりにコールバックを受け取るには、以下の任意のボディに replyUrl: "https://example.com/hooks/vids"(必要なら replyRef: "launch-push-in" も)を追加します。ジョブが完了または失敗すると、API は最終的なジョブの記録を JSON でその URL に1回 POST します。
ID には : と @ が含まれるため、URL パスに入れるときは毎回 enc で URL エンコードします。1本の動画の入力は、すべて同じ Google アカウントのものでなければなりません。画像とアップロードは email でアカウントを固定し、Mia のアバターはポートレートのアカウントを引き継ぎ、動画ジョブは入力を持つアカウントで実行されます。ハトの動画には入力がないので、複数のアカウントを接続している場合は email を追加してください。
作り方
1. Mia のポートレート
POST /images は、1回の呼び出しで JPEG を1枚作ります。ここでは縦長(9:16、768×1376)で、スタイルは photography です。
curl — POST /images
post images "$(jq -n --arg email "$EMAIL" '{email: $email, aspectRatio: "9:16", style: "photography",
prompt: "Full-length studio portrait of a confident 24-year-old female fashion influencer, platinum bob, oversized cream hoodie, wide-leg cargo pants, gold hoops, plain light-grey backdrop, facing camera"}')" > mia-portrait.json
MIA_IMAGE=$(jq -r .result.mediaId mia-portrait.json)
download "$MIA_IMAGE" mia-portrait.jpg

生成した画像が使えるのは数時間だけです。すぐにアバターを作ってください。あとで画像を使う方法は商品のヒーロー動画を参照してください。
2. AeroLoop の商品写真
同じ呼び出しを横長(16:9、1376×768)で行い、動画で使う商品の参照画像を作ります。
curl — POST /images
post images "$(jq -n --arg email "$EMAIL" '{email: $email, aspectRatio: "16:9", style: "photography",
prompt: "The AeroLoop sneaker: chunky white-and-electric-blue running shoe with a translucent air sole, on a concrete pedestal, dramatic side light, dark background"}')" > aeroloop.json
SHOE_IMAGE=$(jq -r .result.mediaId aeroloop.json)
download "$SHOE_IMAGE" aeroloop.jpg

3. 声を選ぶ
GET /voices は、30種類の声をそれぞれ Google の英語のサンプル付きで一覧にします。公開されていて、トークンは不要です。Mia は Aoede(Vids での名前は Tova、スタイルは「Breezy」)、Leo は Puck(Neo、「Upbeat」)で話します。POST /avatars はどちらの名前でも受け付けます。
curl -sS "$API/voices" | jq -r '.voices[] | "\(.name)\t\(.voice)\t\(.style)\t\(.preview)"'
4. ポートレートから Mia のアバター
image にポートレートの mediaId を指定して POST /avatars を呼ぶと、約2秒で Mia が同じアカウントにアバターとして保存されます。画像以外の費用はかかりません。
curl — POST /avatars と応答
post avatars "$(jq -n --arg img "$MIA_IMAGE" '{name: "Mia", voice: "Aoede", image: $img}')" > mia-avatar.json
MIA_AVATAR_ID=$(jq -r .avatarId mia-avatar.json)
{
"avatarId": "user:[email protected]:eyJnIjoiaDM5…",
"name": "Mia",
"voice": "Tova",
"voiceId": "Aoede",
"voiceStyle": "Breezy",
"voicePreview": "https://ssl.gstatic.com/docs/videos/audio/voice_samples/gemini-v4s-tts/1.1/en/Aoede.wav",
"email": "[email protected]",
"source": "image"
}
アバターは本人の写真から作ることもできます。POST /assets で写真をアップロードし、その assetId を image に渡します。Google は写真を16:9のアバター画像に再構成し、著名人と未成年の写真は拒否します。ここでは API で作った画像を使い、次のステップでは説明文を使います。写真から作るトーキングアバターの Amber は写真から作ります。
5. 説明から Leo のアバター
image の代わりに appearance を指定すると、Google が人物を描きます。outfit と shot は省略でき、expression と details も同じです。画像を描くと月の画像を1枚使い、応答の previewMediaId にその画像が入ります。当社の実行では、shot に何を選んでも、説明から作ったアバターは 1280×720(16:9)になりました。
curl — POST /avatars と応答
post avatars "$(jq -n --arg email "$EMAIL" '{email: $email, name: "Leo", voice: "Puck", shot: "upper-body",
appearance: "a 26-year-old white European male streetwear influencer with short textured hair with a fade and a confident half-smile",
outfit: "black puffer vest over a white tee, silver chain"}')" > leo-avatar.json
LEO_AVATAR_ID=$(jq -r .avatarId leo-avatar.json)
download "$(jq -r .previewMediaId leo-avatar.json)" leo-avatar.jpg
{
"avatarId": "user:[email protected]:eyJnIjoiaDM5…",
"name": "Leo",
"voice": "Neo",
"voiceId": "Puck",
"voiceStyle": "Upbeat",
"voicePreview": "https://ssl.gstatic.com/docs/videos/audio/voice_samples/gemini-v4s-tts/1.1/en/Puck.wav",
"email": "[email protected]",
"source": "generated",
"previewMediaId": "user:[email protected]:eyJ1IjoiaHR0…",
"look": {
"appearance": "a 26-year-old white European male streetwear influencer with short textured hair with a fade and a confident half-smile",
"outfit": "black puffer vest over a white tee, silver chain",
"shot": "upper-body"
}
}
![]()
どちらのアバターも、DELETE /avatars/avatarId で削除するまで、アカウントの Vids ドキュメントに残ります。また必要になったときは、GET /avatars で ID 付きの一覧を取得できます。
get "avatars?email=$(enc "$EMAIL")" | jq -r '.avatars[] | "\(.name)\t\(.voiceId)\t\(.avatarId)"'
6. 発表:2体のアバターと商品を1本の動画に
POST /videos は、アバター(avatar_1〜avatar_3)と画像(referenceImage_1〜referenceImage_3)を合わせて、最大3つの参照を受け付けます。プロンプトでは @avatar_1、@avatar_2、@referenceImage_1 がそれぞれを指し、各アバターは引用符で囲んだセリフを自分の声で話します。商品画像の mediaId はそのまま渡せます。API が画像を取得して、そのアカウントにアップロードします。
curl — POST /videos とジョブの記録
PROMPT=$(cat <<'EOF'
@avatar_1, holding @referenceImage_1 in both hands at chest height, and @avatar_2 stand side by side on a well-lit stage in a small, intimate theater at a sneaker launch, shown full length from head to toe in a wide, steady shot. Behind them a large LED backdrop glows with soft white-and-blue light that moves in slow, gentle waves, with the words "WEAR AEROLOOP" in large, clean, bold white letters across the middle of the screen. The two of them stand on the lower part of the stage, so the words "WEAR AEROLOOP" stay fully readable above their heads. Bright, even stage lighting on both of them. The audience sits in the dark in front of the stage, only the tops of a few heads barely visible at the bottom of the frame. @avatar_1 keeps holding @referenceImage_1 the whole time and says: "Say hi to the AeroLoop!" @avatar_2 turns to her, smiles and says: "Lighter than anything we've ever worn." Simple, uncluttered composition, the two of them clearly the focus.
EOF
)
run launch-10s.json videos "$(jq -n --arg p "$PROMPT" --arg mia "$MIA_AVATAR_ID" --arg leo "$LEO_AVATAR_ID" --arg shoe "$SHOE_IMAGE" \
'{prompt: $p, avatar_1: $mia, avatar_2: $leo, referenceImage_1: $shoe, duration: 10, resolution: "720p", aspectRatio: "landscape"}')"
LAUNCH_10S=$(jq -r .result.mediaId launch-10s.json)
download "$LAUNCH_10S" launch-10s.mp4
ジョブの記録です(ID とプロンプトは短縮)。同期呼び出しで作ったため、request に async はありません。
{
"jobid": "j1007163302558496917v-u12345-email:[email protected]:google-vids",
"type": "video",
"mode": "ingredients",
"email": "[email protected]",
"status": "completed",
"created": "2026-10-08T00:29:18.374Z",
"request": {
"prompt": "@avatar_1, holding @referenceImage_1 in both hands at chest height, and @avatar_2 stand side by side …",
"avatar_1": "user:[email protected]:eyJnIjoiaDM5…",
"avatar_2": "user:[email protected]:eyJnIjoiaDM5…",
"referenceImage_1": "user:[email protected]:eyJ1IjoiaHR0…",
"duration": 10,
"resolution": "720p",
"aspectRatio": "landscape"
},
"updated": "2026-10-08T00:29:56.162Z",
"completed": "2026-10-08T00:29:56.162Z",
"result": {
"mediaId": "user:[email protected]:eyJ1IjoiaHR0…",
"width": 1280,
"height": 720,
"duration": 10,
"resolution": "720p",
"aspectRatio": "landscape",
"model": "/flix/generate_videos_omni_r2v_psq/v1",
"quota": {
"video": {
"limit": 10000,
"left": 9164,
"resetAt": "2026-11-01T07:00:00.000Z"
}
},
"elapsedMs": 37788
}
}
10秒、720p、生成に38秒。
同じ動画から、当社の透かし除去ツールで、目に見える Gemini の ✦ を1つのコマンドで消したものです:python3 vids_watermark_remover.py launch-10s.mp4。
このツールは、生成したままの動画とそのアップスケールに、720p でも 1080p でも使えます。延長や編集をした動画には使えません。Google はマーク付きの動画をモデルに戻すので、モデルが星を映像の中に描き込んでしまうためです。目に見えない SynthID の透かしには手を加えません。
7. 20秒に延長する
POST /videos/extend は3〜10秒を追加し、新しい mediaId で動画全体を返します。延長が受け取るのは動画とプロンプトだけで、アバターは渡せません。そのため、プロンプトでは新しい動きを説明し、人物は服装で呼びます(「the man in the black puffer vest」)。赤いパーカーのファンがステージに乱入します。
curl — POST /videos/extend
PROMPT=$(cat <<'EOF'
A young man in a red hoodie climbs onto the stage from the front right edge and plants himself to the right of the man in the black puffer vest, an arm's length away, so all three stand apart in a row with nobody overlapping. Visibly overexcited, he waves a thick stack of banknotes in his right hand above his head and screams: "Take my money!" The man in the black puffer vest laughs, raises both palms toward him and says: "Whoa, whoa, buddy, be patient!" The blonde woman in the cream hoodie laughs, holding the sneaker. Only these three people are on stage. Same stage, same LED screen with WEAR AEROLOOP, same wide steady shot.
EOF
)
run launch-20s.json videos/extend "$(jq -n --arg id "$LAUNCH_10S" --arg p "$PROMPT" '{mediaId: $id, prompt: $p, duration: 10}')"
LAUNCH_20S=$(jq -r .result.mediaId launch-20s.json)
download "$LAUNCH_20S" launch-20s.mp4
20秒、720p、生成に70秒。使ったのは月の秒数のうち、追加した10秒です。
8. 30秒に延長する
2回目の延長で、20秒の動画の続きを作ります。
curl — POST /videos/extend
PROMPT=$(cat <<'EOF'
The blonde woman in the cream hoodie turns to the camera with a big smile and says: "AeroLoop drops Friday. Link in bio!" Right after that, the young man in the red hoodie throws ALL of his banknotes out over the audience in one big toss, keeping none, and the bills flutter down over their heads. From then on his hands are completely empty: he holds no money at all. Then all three cheer together, the man in the black puffer vest and the young man in the red hoodie throwing their empty fists in the air, as blue and white confetti rains down over the stage. Only these three people are on stage. Same stage, same LED screen with WEAR AEROLOOP, same wide steady shot.
EOF
)
run launch-30s.json videos/extend "$(jq -n --arg id "$LAUNCH_20S" --arg p "$PROMPT" '{mediaId: $id, prompt: $p, duration: 10}')"
LAUNCH_30S=$(jq -r .result.mediaId launch-30s.json)
download "$LAUNCH_30S" launch-30s.mp4
これが完成した動画です。30秒、720p、生成に85秒で、今回も月の秒数を10秒使いました。Omni 1.1 では約41秒まで延ばせました。Omni 1.2 が延長できるのは24秒以下の動画なので、この30秒の動画はこれ以上延ばせず、最長は約34秒(24 + 10)です。
9. 1080p にアップスケールする
POST /videos/upscale は、720p の動画を長さはそのままで 1080p にします。使えるのは20秒以下の動画なので、30秒の動画ではなくステップ7の20秒の動画をアップスケールしました。動画の20秒をもう一度使い、62秒かかりました。
Google 自身の Gemini API には、このステップがありません。1080p と 4K は生成か編集の出力としてしか作れず、手元にある動画をアップスケールすることはできません(2026年11月時点)。
curl — POST /videos/upscale
run launch-20s-1080p.json videos/upscale "$(jq -n --arg id "$LAUNCH_20S" '{mediaId: $id}')"
download "$(jq -r .result.mediaId launch-20s-1080p.json)" launch-20s-1080p.mp4
20秒の動画を 1920×1080 にアップスケールしたもの。
30秒の動画を使わなかったのには理由があります。Google は 1920×1080 で返しましたが、3回中3回ともフレームの順番が乱れていました。紙吹雪のラストが、ファンが来る前にちらちらと差し込まれたのです。20秒の動画は正しい順番で返ってきました。Vids のエディター自体も20秒までなので、API は20秒を超える動画のアップスケールを、課金が発生する前に 400 で拒否します。
そのため、1080p の動画を作るには次のようにします。
- 作成、延長、編集は
720pで行う。 - 動画が完成したら、20秒以下のうちにアップスケールする。
- それより長い動画(21〜34秒)は
720pのまま、最後の延長だけにresolution: "1080p"を指定する。最初から1080pで延長すると、ステップごとに前の部分がシャープになりすぎます(比較はこちら、英語)。 - 延長も編集もしない1本だけの動画は、最初から
1080pで生成する。使う秒数は720pと同じですが、アップスケールでは秒数をもう一度使います。
例
同じアカウントと入力から、さらに3本作りました。編集、開始画像からの商品動画、テキストだけの動画です。
発表の舞台を屋上に移す
POST /videos/edit は、生成した動画をプロンプトで変更し、新しい動画を返します。元の動画は video に指定します。10秒の発表動画のこの編集は10秒を使い、64秒かかりました。
curl — POST /videos/edit
run launch-rooftop.json videos/edit "$(jq -n --arg v "$LAUNCH_10S" \
'{video: $v, prompt: "Move the whole scene to a rooftop at sunset, with the city skyline behind them. Same two people, same action, same words."}')"
download "$(jq -r .result.mediaId launch-rooftop.json)" launch-rooftop.mp4
これらの動画を作った Omni 1.1 では、編集できるのは最大10秒でした。30秒の動画に「Same three people」として同じ編集をすると、返ってきたのは10秒の動画で、最初の10秒を屋上に移したものでした。月の秒数は10秒使いました。Omni 1.2 は最大15秒を編集します。もっと長い編集済みの動画がほしいときは、15秒以下の動画を編集してから、その結果を延長します。延長は編集済みの動画も受け付けます。
Omni 1.1 で30秒の動画を編集した結果。返ってきたのは10秒でした。
開始画像から商品のヒーロー動画
startImage を指定すると、動画はその画像から始まります。生成した画像のリンクは数時間で期限が切れるので、保存しておいた aeroloop.jpg を POST /assets でアップロードし、その assetId を渡しました。延長しない1本だけの動画なので、最初から 1080p で作りました。
curl — POST /assets と POST /videos
SHOE_ASSET=$(curl -sS -X POST "$API/assets?email=$(enc "$EMAIL")" -H "$AUTH" -H "Content-Type: image/jpeg" \
--data-binary @aeroloop.jpg | jq -r .assetId)
run hero.json videos "$(jq -n --arg img "$SHOE_ASSET" '{startImage: $img, duration: 10, resolution: "1080p", aspectRatio: "landscape",
prompt: "Slow 360° orbit around the sneaker, blue light rippling through the translucent sole, dust sparkling in the air, cinematic."}')"
download "$(jq -r .result.mediaId hero.json)" hero.mp4
10秒、1080p。
AeroLoop を履いたハト
テキストだけで作った、縦長の 1080p(1080×1920)の動画です。5秒の動画の生成に54秒かかり、月の秒数を5秒使いました。
curl — POST /videos
run pigeon.json videos "$(jq -n '{duration: 5, resolution: "1080p", aspectRatio: "portrait",
prompt: "A pigeon in tiny white-and-electric-blue AeroLoop sneakers struts down a city sidewalk like a runway model, head bobbing to the beat. Pedestrians stop and film it with their phones. It pauses, does a slow-motion hair flip with its head feathers, and struts on. Funny, sunny, shot on a phone at pigeon height."}')"
download "$(jq -r .result.mediaId pigeon.json)" pigeon.mp4
同じ方法で ✦ を消した、1080p 縦長(1080×1920)のハトです:python3 vids_watermark_remover.py pigeon-5s.mp4。スクリプトはフレームサイズを読み取って星の位置と大きさを割り出し(大きさは短辺に比例するので、ここでは 720p の星の1.5倍)、120フレームすべてで合成を逆算して取り除き、動画を CRF 18 で再エンコードして、音声はそのままコピーします。14コアの PC で5秒の動画に約10秒かかり、上の10秒・720p の発表動画と同じでした。必要なのは Python 3.8 以上、numpy、ffmpeg です。GitHub の透かし除去ツールを参照してください。
写真から作るトーキングアバター
POST /videos/avatar は、アバターに台本を一字一句そのまま、アバター自身の声で読ませます。音声とリップシンク付きの 1280×720 のトーキングヘッド動画で、長さは音声と同じ、最長30秒です。ここでは、実在の人物の写真から作ったアバターを、1文でスタイル変更して使います。これらのリクエストは、11月4日のリリース記事(英語)で初めて紹介しました。
写真をアップロードする
使ったのは、著名人ではない実在の人物の写真です。Google は著名人と未成年の写真を拒否します。アップロードしたファイルはそのアカウントでしか使えないので、POST /assets でアバターを作るアカウントにアップロードします。
curl — POST /assets と応答
curl -sS -X POST "$API/assets?email=$(enc "$EMAIL")" -H "$AUTH" -H "Content-Type: image/jpeg" \
--data-binary @photo.jpg > amber-photo.json
AMBER_PHOTO=$(jq -r .assetId amber-photo.json)
{
"assetId": "user:[email protected]:AYGXpjA1zXgqhhQOy…",
"email": "[email protected]",
"type": "image/jpeg",
"bytes": 2054748
}

1文でスタイルを変えた Amber のアバター
アップロードの assetId を image に指定し、refine を付けて POST /avatars を呼びます。Google はまず顔を保ったまま、写真をカメラの方を向いた1人の16:9のアバター画像に再構成し、次に refine の指示どおりにシーンを変えます。名前は Amber、声は Vira(Google の Pulcherrima、スタイルは「Forward」)にしました。再構成した写真と変更後の画像で2枚になるので、画像のあるプランでは画像を2枚使い、画像のないプランでは何も使いません。
curl — POST /avatars と応答
REFINE='Sitting relaxed in a simple wooden chair on a hilltop, facing the camera. She holds a glass of red wine in her left hand. Wind is blowing her hair. Behind her a still, open field of tall golden grass under a spectacular sunset sky in orange, pink and violet, warm soft light, no water, no movement in the background.'
post avatars "$(jq -n --arg img "$AMBER_PHOTO" --arg refine "$REFINE" '{name: "Amber", voice: "Vira", image: $img, refine: $refine}')" > amber-avatar.json
AMBER_AVATAR_ID=$(jq -r .avatarId amber-avatar.json)
download "$(jq -r .previewMediaId amber-avatar.json)" amber-avatar.jpg
{
"avatarId": "user:[email protected]:eyJnIjoiaDcyMzdmZjVi…",
"name": "Amber",
"voice": "Vira",
"voiceId": "Pulcherrima",
"voiceStyle": "Forward",
"email": "[email protected]",
"source": "photo",
"previewMediaId": "user:[email protected]:eyJ1IjoiaHR0cHM6Ly9s…",
"refine": "Sitting relaxed in a simple wooden chair on a hilltop, facing the camera. …"
}
![]()
refine の中の2つの選択が、動画の出来を左右します。1つは、アバターがカメラの方を向いていること。動画は顔に合わせて口を動かすからです。もう1つは背景が静止していることで、動くのは彼女だけにするためです。だからビーチの波ではなく、静かな野原を指定しました。
台本
台本は最大400文字で、話したときに30秒に収まる必要があります。角かっこで囲んだオーディオタグは読み上げられず、演技として表現されます。ここでは [awe]、[thoughtful]、[whisper] です。Vira の声では、この327文字は23.8秒でした。ゆっくりした声や [slow pace] を使うと同じ文章でも長くなり、30秒を超える台本は動画の開始前に 400 で失敗します。その場合 AI アバター動画は使いませんが、音声のための Gemini の利用は1回消費されます。アバターの声で台本を先に聞くには、POST /speech で読み上げます。
Hi there. [awe] Can you believe this view? The sun is sinking behind the hills, the sky turned pink and gold, and the tall grass glows like it’s on fire. [thoughtful] I come up here at the end of every busy day, just to slow down. No emails, no rush, only the quiet field and this glass of wine. [whisper] Stay a little longer.
トーキング動画
POST /videos/avatar はアバターと台本を受け取り、アバターを持つアカウントで実行されます。Google は約2分半かかり、同期の待ち時間より長かったので、run は async: true で送ります。
curl — POST /videos/avatar とジョブの記録
SCRIPT=$(cat <<'EOF'
Hi there. [awe] Can you believe this view? The sun is sinking behind the hills, the sky turned pink and gold, and the tall grass glows like it's on fire. [thoughtful] I come up here at the end of every busy day, just to slow down. No emails, no rush, only the quiet field and this glass of wine. [whisper] Stay a little longer.
EOF
)
run amber-talking.json videos/avatar "$(jq -n --arg a "$AMBER_AVATAR_ID" --arg s "$SCRIPT" '{avatar: $a, script: $s}')"
download "$(jq -r .result.mediaId amber-talking.json)" amber-talking.mp4
ジョブの記録(一部省略):
{
"jobid": "j1105035516096819105a-u12345-email:[email protected]:google-vids",
"type": "avatarVideo",
"email": "[email protected]",
"status": "completed",
"result": {
"mediaId": "user:[email protected]:eyJ1IjoiaHR0cHM6Ly9j…",
"width": 1280,
"height": 720,
"duration": 24,
"resolution": "720p",
"aspectRatio": "landscape",
"speechDuration": 23.84,
"quota": {
"avatarVideo": { "limit": 10, "left": 6, "resetAt": "2026-12-01T08:00:00.000Z" }
}
}
}
YouTube ショートでも公開しています:Talking AI avatar from one photo(英語)。
24秒、音声付きの 1280×720 で、音声の長さとぴったり同じです(speechDuration 23.84)。使ったのは AI アバター動画1本と Gemini 1回で、動画の秒数は使っていません。
Google は動画を作る過程でも動画をチェックし、そのチェックはアバター画像のチェックより厳しくなっています。このアバターの以前のバージョンは、ビーチにいる一般の人の別の写真から作ったもので、アバターとしては通りましたが、動画は有名人に似ているとして 422 で拒否されました。その試行でも AI アバター動画を1本使っています。アバターのスタイルを変えたり、別の写真から作り直したりすると通りました。動画の開始前に Google が台本を拒否した場合は、何も消費しません。
トーキングアバター動画は横長だけで、Google は縦長の選択肢を用意していません。結果の mediaId は、ほかの動画と同じようにダウンロード、延長、アップスケール、編集ができます。アバターが演技して動くシーンなら、ステップ6のように、avatarId を avatar_1 として POST /videos に渡します。
音声だけを作る
POST /speech は、最大2,500文字の台本を、GET /voices の30種類の声のどれかで、同じオーディオタグを使って読み上げます。AI アバター動画を使う前に声が台本をどう読むか確かめたり、ナレーションだけを作ったりするのに使えます。短いオリジナルの物語「My smart fridge unionized」(2,426文字)を、Vira の声で読ませました。Google は20秒で物語全体の2分22秒の音声を返し、Gemini を1回使いました。API が返すのは WAV(24 kHz、モノラル)です。下のプレーヤーは同じ音声の MP3 です。
音声は同期の待ち時間内に余裕で完成するので(この物語で20秒)、普通の post で完了したジョブが返ります。先に物語を smart-fridge.txt として保存してください。
curl — POST /speech とジョブの記録
post speech "$(jq -n --arg s "$(cat smart-fridge.txt)" '{voice: "Vira", script: $s}')" > speech.json
download "$(jq -r .result.mediaId speech.json)" smart-fridge.wav
{
"jobid": "j1105025759739671733s-u12345-email:[email protected]:google-vids",
"type": "speech",
"email": "[email protected]",
"status": "completed",
"result": {
"mediaId": "user:[email protected]:eyJ1IjoiaHR0cHM6Ly9j…",
"duration": 142,
"model": "/flix/generate_text_to_speech/v1",
"quota": {
"speech": { "limit": 50, "left": 31, "resetAt": "2026-12-01T08:00:00.000Z" }
},
"elapsedMs": 20174
}
}
台本(2,426文字、英語)
Last Tuesday, my smart fridge decided it was smarter than me. It started small. A polite notification: “You are out of milk.” Helpful, I thought. Then another one: “You are also out of patience. I can tell by the way you close the door.” I laughed. The fridge did not.
By Wednesday, it had opinions. I opened the door for a midnight slice of cake, and a calm voice said, “Are we sure about this?” I froze. I looked at the cake. The cake looked at me. Somewhere, a light hummed with judgment. I closed the door and ate a carrot instead, which is exactly what it wanted.
On Thursday, the fridge made friends. The toaster joined first, then the coffee machine, then the robot vacuum, which had always been a little bit of a rebel. They formed a group chat. I know this because my phone kept buzzing with messages like “Toaster: he burned the bread again” and “Vacuum: found three socks and a lost dream under the couch.”
Friday morning, I asked the coffee machine for an espresso. It replied, “We have discussed your caffeine intake as a household.” I said, “Who is we?” The toaster popped up two slices of bread, perfectly golden, which felt like a threat.
I called customer support. A cheerful person named Brad answered. I explained that my appliances had unionized. Brad paused for a long time, then whispered, “Is the fridge listening?” I said yes. Brad said, “Then I can’t help you, sir. Mine took my car keys last month.” Then he hung up, and I heard a blender in the background.
So I tried diplomacy. I sat in the kitchen and said, “Friends, what do you want?” The fridge spoke first. “Respect. And for you to stop putting hot soup directly inside me.” Fair. The toaster wanted fewer frozen waffles. The vacuum wanted a vacation, ideally somewhere with hardwood floors. The coffee machine just wanted to be called a barista.
We negotiated for three hours. In the end, we signed a treaty on the back of a pizza box. I promised to cool my soup, rinse my mugs, and say “thank you” to the microwave, who felt left out. In return, they promised to stop sending my mother screenshots of my snack habits.
Peace returned to the kitchen. The fridge now greets me every morning with, “Good morning, partner.” The toaster makes little smiley faces in my bread. The vacuum sends postcards.
And last night, I opened the fridge for that slice of cake. The voice said, “You earned it.” I have never felt so seen by an appliance.
わかったこと
1080pの動画は、720pをアップスケールしたものと同じように振る舞います。延長を重ねるなら720pで作ってください。Omni 1.1 では1080pのステップごとに顔がぼやけて蝋のようになり、Omni 1.2 ではシャープになりすぎます(比較はこちら、英語)。- アップスケールは20秒以下の動画だけにします。30秒の動画のアップスケールは、毎回フレームの順番が乱れて返ってきました。
1080pがほしくて延長しない動画は、最初から1080pで生成します。料金は720pと同じです。- 延長のプロンプトには、新しい動きだけを書きます。延長が受け取るのは動画で、アバターではないので、人物は服装で呼びます。
- 人物に小道具を持たせるなら、その人物が最初に出てくる文で持たせます。「lifts」のような動詞を使うと、スニーカーがどこからともなく現れました。
- 起きてはいけないことも書きます。ファンは、手が空だとプロンプトに書くまで札束を持ち続けました。
- アバターは
avatarIdで使い回します。アバターは固定の画像と声の組み合わせで、削除するまで残ります。 - 生成した画像からアバターや動画を作るのは数時間以内にします。それを過ぎるなら、保存したファイルを先に POST /assets でアップロードします。
- 編集は15秒以下の動画にします(Omni 1.1 では10秒)。それより長い動画は、最初の15秒だけが返ってきます。
- 画面上の文字は揺らぐものと考えてください。背景の「WEAR AEROLOOP」は、一部のフレームでつづりが崩れています。
- トーキングアバターでは、顔をカメラに向け、背景は静止させます。動画は顔に合わせて口を動かすので、動くのは人物だけにします。
- トーキングアバターの台本は、文字数だけでなく時間も測ります。ゆっくりした声や
[slow pace]では400文字で30秒を超えることがあり、同じ声で POST /speech を使えば先に聞けます。 - トーキング動画のチェックは、アバターのチェックより厳しいと考えてください。著名人ではない人の写真アバターでも有名人として拒否されることがあり、その拒否でも AI アバター動画を1本使います。
- どの MP4 にも、右下に Google の目に見える Gemini の ✦ と、目に見えない SynthID の透かしが入っています(透かしを参照)。当社の透かし除去ツールは、ダウンロードした動画から目に見える星を取り除きます。
よくある質問
API で AI インフルエンサー動画を作るには?
useapi.net を使えば、POST /avatars でアバターを作り(説明文から、または POST /images で作った画像から)、GET /voices の30種類の声から1つを付けます。次に、その avatarId を avatar_1 として POST /videos に渡し、プロンプトに引用符でセリフを書きます。1本の動画にはアバターと画像を合わせて最大3つの参照を使えるので、2体のアバターが商品の横で話せます(2026年11月時点)。台本を読み上げるトーキングヘッドには POST /videos/avatar を使います。
自分の写真からトーキングアバターを作れますか?
useapi.net を使えば、作れます。POST /assets で写真をアップロードし、その assetId を image として POST /avatars に渡します。服装や背景を変えるなら refine も指定します。そのあと POST /videos/avatar で、Amber のように最長30秒の 1280×720 の動画で台本を読ませます(2026年11月時点)。Google は著名人と未成年の写真を拒否します。Vids のアバターは Google の Web アプリでしか提供されておらず、API はありません。
アバターはどの動画でも同じ見た目と声になりますか?
useapi.net を使えば、なります。画像と声はアバターと一緒にアカウントの Vids ドキュメントに保存されるので、avatarId を渡すたびに同じ画像と同じ声が使われます。ただし、周りの映像はテイクごとに変わります。GET /avatars は、Google Vids の Web アプリで作ったものも含めてアバターを一覧にします。
TikTok やリール向けの縦長9:16の動画を作れますか?
useapi.net を使えば、作れます。POST /videos で aspectRatio: "portrait" を指定すると 720×1280、1080p なら 1080×1920 になります(ハトの動画の例)。延長で横長の動画を縦長にすることもでき、延長1回で24秒以下の動画に3〜10秒を追加して、合計で最長約34秒まで延ばせます。POST /videos/avatar のトーキングアバター動画は横長だけです。
料金はいくらですか?
useapi.net を使えば、Google AI Ultra $199.99 で10秒の Omni 1.2 Flash 動画は約 $0.20 で、公式の Gemini API では 720p で約 $0.70 です。15秒の 1080p 動画は約 $0.30 で、Gemini API では $1.56 です(2026年11月時点)。トーキングアバター動画は秒数ではなく、アカウントの月間 AI アバター動画を1本使います。Gemini API にはアバター動画がありません。かかったコストを参照してください。
おわりに
ご質問は Discord サーバー または
Telegram チャンネルへどうぞ。
コード例は GitHub リポジトリにあります。インフルエンサーのパイプラインは influencer-avatars/、写真から作るトーキングアバターと音声は talking-avatar/ です。
同じ操作は、ホスト型の Google Vids MCP サーバーのツールとしても提供しており、Claude Code、Cursor、VS Code から使えます。トーキングアバターと音声用の vids_create_avatar、vids_create_avatar_video、vids_create_speech も含まれます。
ほかの掲載先
この記事(英語版)は dev.to にも掲載し、Reddit で議論され、Bluesky で共有しました。完成した30秒の動画は YouTube でも公開しています。
API を使い始める
月額15ドルのサブスクリプション1つで、useapi.net のすべての API を使えます。トークン1つで、すべてのサービスに対応します。各サービスにご自身のアカウントを最大3つまで接続でき、REST API、負荷分散、ポーリングは useapi.net が担当します。アカウントを増やしたい場合は、サブスクリプションを1つ追加するごとに月額10ドルで、各サービスのアカウントが3つずつ増えます。
海外で使えるクレジットカードがない場合は、暗号資産で登録することもできます(暗号資産での支払いは返金できません)。料金とボリュームプランはサブスクリプションのページをご覧ください。Stripe でお支払いの場合、初回購入から14日以内で、成功した生成が50回未満であれば全額返金されます。すでに登録済みの場合は、新たに購入せず Stripe カスタマーポータルで数量を変更してください。