Veo 3 を「試してみた」段階から「これでアプリを作りたい」に気持ちが動いたのは、8秒の動画を見た瞬間でした。アニメーションの滑らかさや光の扱いが、1年前の動画AIとは段違いで、「プロダクトに組み込める品質になってきた」と感じたからです。
ここではVeo 3 API を Antigravity で呼び出して動画生成アプリを作る方法を、実装の詳細まで踏み込んで解説します。「Veo 3 とは何か」の説明は既にある記事に譲り、ここでは「どう作るか」に集中します。
作るアプリの全体設計
今回作るのは、テキストプロンプトを入力すると Veo 3 で動画を生成して表示する iOS アプリです。シンプルに見えますが、動画生成APIは「リクエストを投げてすぐ動画が返ってくる」型ではなく、非同期ポーリング型という特性があります。これを理解してから設計しないと、UI が破綻します。
ユーザー → プロンプト入力 → API へリクエスト
↓
ジョブID取得(即時)
↓
ポーリング(5〜30秒)
↓
動画URL取得 → 表示
この非同期フローを Antigravity に伝えると、ステート管理とUI更新のコードをまとめて提案してくれます。
API 呼び出しの実装
Veo 3 API は Gemini API の一部として提供されています。まず Antigravity にプロジェクト構造を作ってもらいます。
Antigravityへの指示:
「Veo 3 APIを呼び出してテキストから動画を生成するiOSアプリを作ります。
SwiftUIを使い、プロンプト入力→生成中表示→動画再生の流れを実装してください。
APIはGoogle AI Studio経由でアクセスします」
Antigravity が生成するコアの API クライアントはこのような形になります。
import Foundation
struct Veo3APIClient {
private let apiKey = "YOUR_API_KEY"
private let baseURL = "https://generativelanguage.googleapis.com/v1beta"
// 動画生成ジョブを開始する
func startVideoGeneration(prompt: String) async throws -> String {
let url = URL(string: "\(baseURL)/models/veo-003:generateVideo?key=\(apiKey)")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body: [String: Any] = [
"contents": [["parts": [["text": prompt]]]],
"generationConfig": [
"durationSeconds": 8,
"aspectRatio": "16:9",
"resolution": "720p"
]
]
request.httpBody = try JSONSerialization.data(withJSONObject: body)
let (data, _) = try await URLSession.shared.data(for: request)
let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
// ジョブIDを返す(完了まで数十秒かかる)
return json["name"] as! String
}
// ジョブのステータスを確認する
func checkJobStatus(jobName: String) async throws -> VideoJobStatus {
let url = URL(string: "\(baseURL)/\(jobName)?key=\(apiKey)")!
let (data, _) = try await URLSession.shared.data(from: url)
let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
let done = json["done"] as? Bool ?? false
if done {
let response = json["response"] as? [String: Any]
let candidates = response?["candidates"] as? [[String: Any]]
let videoUri = candidates?.first?["video"] as? [String: Any]
let uri = videoUri?["uri"] as? String
return .completed(videoURL: uri)
}
return .processing
}
}
enum VideoJobStatus {
case processing
case completed(videoURL: String?)
case failed
}ポーリングループの実装
Antigravity に「非同期ポーリングで完了を待つロジックを作って」と指示すると、次のような ViewModel を提案してくれます。
@MainActor
class VideoGenerationViewModel: ObservableObject {
@Published var status: GenerationStatus = .idle
@Published var videoURL: URL?
@Published var errorMessage: String?
private let client = Veo3APIClient()
func generateVideo(prompt: String) async {
status = .starting
do {
let jobName = try await client.startVideoGeneration(prompt: prompt)
status = .processing(progress: 0)
// ポーリング(最大60秒、5秒間隔)
for attempt in 1...12 {
try await Task.sleep(nanoseconds: 5_000_000_000)
let result = try await client.checkJobStatus(jobName: jobName)
switch result {
case .processing:
let progress = Double(attempt) / 12.0
status = .processing(progress: progress)
case .completed(let urlString):
if let urlString, let url = URL(string: urlString) {
videoURL = url
status = .completed
} else {
status = .failed
errorMessage = "動画URLの取得に失敗しました"
}
return
case .failed:
status = .failed
errorMessage = "動画の生成に失敗しました"
return
}
}
// タイムアウト
status = .failed
errorMessage = "生成がタイムアウトしました。もう一度お試しください"
} catch {
status = .failed
errorMessage = error.localizedDescription
}
}
}
enum GenerationStatus: Equatable {
case idle
case starting
case processing(progress: Double)
case completed
case failed
}UI 設計のポイント
Antigravity に UI を作ってもらうとき、「生成中の体験設計」を明示するとよいです。動画生成には数十秒かかるため、ユーザーが「止まっている」と誤解しないように進捗を可視化する点が肝心です。
Antigravityへの指示:
「生成中は以下を表示してください:
- プログレスバー(ポーリング回数ベース)
- 'Veo 3 が動画を生成中です...' というアニメーション付きテキスト
- キャンセルボタン
生成完了後はアニメーションでビデオプレーヤーが表示されるようにしてください」
課金設計について考えておくこと
Veo 3 API はトークン単位ではなく秒単位の課金になります(2026年5月現在、正確な料金は Google AI Studioで確認してください)。
ユーザー向けアプリに組み込む場合、自分のAPIキーを使うとコストがユーザー数に比例して増大します。実用的な選択肢としては、ユーザーに自分のAPIキーを入力してもらうパターンか、アプリ内課金で生成クレジットを販売するパターンが現実的です。
Antigravity に「アプリ内課金と Veo 3 のクレジット消費を紐付ける設計にして」と指示すると、StoreKit との統合コードも提案してくれます。
実装を始める前の確認事項
Veo 3 API を個人のアプリに組み込む前に、Google の利用規約と生成コンテンツのポリシーを確認してください。特に「生成された動画をApp Storeで配布するアプリで使う場合のライセンス」については、条件が変わることがあるため、公式ドキュメントを常に参照することをおすすめします。
技術的に動くものを作るのに1日もあれば十分です。ただ、ビジネスとして継続できる設計にするには、APIコストとユーザー体験のバランスを最初から考えておく必要があります。そこに時間をかける価値は十分あります。
個人開発12年の現場で実感したこと
線引きするときの3つの判断軸
- 失敗時の影響が金銭やユーザー体験にどれだけ波及するか
- 復旧オペレーションが明文化されているか
- 観測ログから人間が再現できる粒度に整っているか