概要
Soraは、テキストプロンプトや画像から高品質な動画を生成できるOpenAIの最新ビデオ生成モデル。3D空間、モーション、シーン連続性を深く理解し、音声付きの詳細で動的なクリップを作成できる。
利用条件(重要)
Sora APIを使用するには以下の条件を満たす必要がある:
- 組織認証が必須: 組織設定ページで"Verify Organization"をクリックして認証を完了させる
- 認証後15分待つ: 認証完了後、アクセス権限の反映に最大15分かかる
- 有料プラン推奨: 無料プランでは使えない可能性が高い
- ベータ版のため: 場合によってはウェイトリスト登録が必要な可能性もある
エラーコード403が出る場合は、上記の組織認証を確認すること。
Video APIの機能
- Create video: プロンプトから新しいレンダリングジョブを開始
- Get video status: レンダリングジョブの進行状況を取得
- Download video: 完成したMP4をダウンロード
- List videos: 動画一覧を取得(ページネーション対応)
- Delete videos: 不要な動画を削除
モデルの種類
Sora 2
- 特徴: スピード重視、柔軟性が高い
- 用途: コンセプト検証、ラピッドプロトタイピング、SNSコンテンツ
- メリット: 高速なフィードバックループ、低コスト
- 適したシーン: トーン確認、構造実験、ラフカット
Sora 2 Pro
- 特徴: 高品質重視、プロダクションレベル
- 用途: シネマティック映像、マーケティング資産、高解像度コンテンツ
- デメリット: レンダリング時間が長い、コストが高い
- 適したシーン: 視覚的精度が求められる本番環境
パラメータ仕様と制約
seconds(動画の長さ)
指定可能な値: "4"
, "8"
, "12"
のみ
それ以外の値を指定するとBadRequestError
が発生する。
size(解像度)
一般的な値の例:
-
"1280x720"
(720p) -
"1920x1080"
(1080p) "1024x576"
"640x480"
解像度はinput_reference
で画像を指定する場合、その画像と一致させる必要がある。
model
-
"sora-2"
: 速度重視 -
"sora-2-pro"
: 品質重視
基本的な使い方
0. APIキーの設定
まずOpenAI Platform(https://platform.openai.com/api-keys)でAPIキーを取得する。
方法A: 環境変数で設定(グローバルデフォルト用)
Linux/Mac(一時的):
export OPENAI_API_KEY='sk-proj-xxxxxxxxxx'
Windows(PowerShell/一時的):
$env:OPENAI_API_KEY='sk-proj-xxxxxxxxxx'
恒久的に設定(ワンライナー):
# bash使いの場合
echo "export OPENAI_API_KEY='sk-proj-xxxxxxxxxx'" >> ~/.bashrc && source ~/.bashrc
# zsh使いの場合
echo "export OPENAI_API_KEY='sk-proj-xxxxxxxxxx'" >> ~/.zshrc && source ~/.zshrc
# fish使いの場合
echo "set -Ux OPENAI_API_KEY 'sk-proj-xxxxxxxxxx'" | fish
Windows(PowerShell/管理者権限):
[Environment]::SetEnvironmentVariable("OPENAI_API_KEY", "sk-proj-xxxxxxxxxx", "User")
方法B: .envファイルで管理(プロジェクトごとのAPIキー管理)
プロジェクトルートに.env
ファイルを作成:
OPENAI_API_KEY=sk-proj-xxxxxxxxxx
Pythonで読み込む:
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv() # カレントディレクトリの.envファイルを読み込み
openai = OpenAI() # 環境変数から自動取得
Node.jsで読み込む:
import OpenAI from 'openai';
import dotenv from 'dotenv';
dotenv.config();
const openai = new OpenAI(); // process.env.OPENAI_API_KEYから取得
複数プロジェクトでのAPIキー使い分け:
プロジェクトごとに異なる.env
ファイルを配置することで、APIキーを使い分けられる。
~/projects/
├─ project-a/
│ ├─ .env # OPENAI_API_KEY=sk-proj-AAA...
│ └─ main.py
├─ project-b/
│ ├─ .env # OPENAI_API_KEY=sk-proj-BBB...
│ └─ main.py
└─ project-c/
├─ .env # OPENAI_API_KEY=sk-proj-CCC...
└─ main.py
重要な挙動:
-
load_dotenv()
はスクリプト実行時のカレントディレクトリから.env
を探す -
~/projects/project-a/
でpython main.py
を実行 →project-a/.env
が読まれる -
~/projects/project-b/
でpython main.py
を実行 →project-b/.env
が読まれる -
.env
の値は環境変数より優先される(上書き)
つまり、~/.bashrc
でグローバルデフォルトを設定しつつ、特定プロジェクトだけ別のAPIキーを使うことが可能。
応用: 明示的なパス指定
カレントディレクトリ以外の.env
を読みたい場合:
from dotenv import load_dotenv
# 絶対パス指定
load_dotenv('/path/to/your/.env')
# 相対パス指定
load_dotenv('../config/.env')
# スクリプトの場所を基準にする
import os
script_dir = os.path.dirname(os.path.abspath(__file__))
load_dotenv(os.path.join(script_dir, '.env'))
注意: .env
ファイルは必ず.gitignore
に追加すること。
# ワンライナーで.gitignoreに追加
echo ".env" >> .gitignore
# 既に.envをコミットしてしまった場合の対処
git rm --cached .env
echo ".env" >> .gitignore
git add .gitignore
git commit -m "Remove .env from git tracking"
方法C: コード内で直接指定(非推奨だが動作確認には便利)
from openai import OpenAI
openai = OpenAI(api_key='sk-proj-xxxxxxxxxx')
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: 'sk-proj-xxxxxxxxxx'
});
デメリット: ハードコードはセキュリティリスクが高い。本番環境では絶対に避けること。
とりあえずサクッと試したい人向け: フル実装サンプル(Python)
以下はAPIキーハードコード版の完全動作サンプル。コピペしてOPENAI_API_KEY
を書き換えれば即実行可能。
from openai import OpenAI
import sys
import time
# APIキーを直接指定(本番では絶対やるな!)
openai = OpenAI(api_key='sk-proj-xxxxxxxxxx') # ← ここを自分のAPIキーに書き換え
# 動画生成開始
print("動画生成を開始します...")
video = openai.videos.create(
model="sora-2",
prompt="夜の街をバイクで走るクールな猫の動画",
size="1280x720",
seconds="8" # 指定可能な値: "4", "8", "12"
)
print(f"ジョブID: {video.id}")
print(f"初期ステータス: {video.status}")
# プログレスバー表示付きポーリング
progress = getattr(video, "progress", 0)
bar_length = 30
while video.status in ("in_progress", "queued"):
# ステータスを再取得
video = openai.videos.retrieve(video.id)
progress = getattr(video, "progress", 0)
# プログレスバー描画
filled_length = int((progress / 100) * bar_length)
bar = "=" * filled_length + "-" * (bar_length - filled_length)
status_text = "待機中" if video.status == "queued" else "生成中"
sys.stdout.write(f"\r{status_text}: [{bar}] {progress:.1f}%")
sys.stdout.flush()
time.sleep(3) # 3秒間隔でポーリング
# 改行
sys.stdout.write("\n")
# 結果確認
if video.status == "failed":
error_msg = getattr(getattr(video, "error", None), "message", "不明なエラー")
print(f"エラー: {error_msg}")
sys.exit(1)
print("動画生成完了!")
print(f"動画ID: {video.id}")
# 動画ダウンロード
print("動画をダウンロード中...")
content = openai.videos.download_content(video.id, variant="video")
content.write_to_file("output_video.mp4")
print("✓ 動画を output_video.mp4 として保存しました")
# サムネイルもダウンロード
print("サムネイルをダウンロード中...")
thumbnail = openai.videos.download_content(video.id, variant="thumbnail")
thumbnail.write_to_file("output_thumbnail.webp")
print("✓ サムネイルを output_thumbnail.webp として保存しました")
print("\n完了!")
実行方法:
pip install openai
python sora_quick_test.py
注意事項:
- このコードは学習・検証用。Gitにコミットするな!
- 実用時は必ず方法AかBで環境変数/
.env
管理に切り替えること - 生成には数分かかる場合がある(モデル・解像度による)
1. 動画生成の開始
動画生成は非同期処理で行われる。
主要パラメータ
-
model:
"sora-2"
または"sora-2-pro"
- prompt: 動画の内容を記述するテキスト
-
size: 解像度(例:
"1280x720"
,"1920x1080"
) -
seconds: 動画の長さ。指定可能な値は
"4"
,"8"
,"12"
のみ
from openai import OpenAI
openai = OpenAI()
video = openai.videos.create(
model="sora-2",
prompt="夜の街をバイクで走るクールな猫の動画",
)
print("動画生成開始:", video)
レスポンス例:
{
"id": "video_68d7512d...",
"object": "video",
"created_at": 1758941485,
"status": "queued",
"model": "sora-2-pro",
"progress": 0,
"seconds": "8",
"size": "1280x720"
}
2. 進行状況の監視
方法A: ポーリング
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI()
async def main():
video = await client.videos.create_and_poll(
model="sora-2",
prompt="バイクに乗った猫の動画",
)
if video.status == "completed":
print("動画生成完了:", video)
else:
print("動画生成失敗。ステータス:", video.status)
asyncio.run(main())
ステータス遷移: queued
→ in_progress
→ completed
/ failed
推奨ポーリング間隔: 10〜20秒(必要に応じて指数バックオフを使用)
方法B: Webhook(推奨)
Webhook設定ページで設定すると、ジョブ完了時に自動通知される。
イベントタイプ:
-
video.completed
: 動画生成完了 -
video.failed
: 動画生成失敗
Webhookペイロード例:
{
"id": "evt_abc123",
"object": "event",
"created_at": 1758941485,
"type": "video.completed",
"data": {
"id": "video_abc123"
}
}
3. 動画のダウンロード
content = openai.videos.download_content(video.id, variant="video")
content.write_to_file("video.mp4")
curl -L "https://api.openai.com/v1/videos/video_abc123/content" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
--output video.mp4
注意: ダウンロードURLは生成後24時間のみ有効。長期保存が必要な場合は独自のストレージに即座に保存すること。
4. サポートアセットのダウンロード
各動画には以下の補助ファイルも生成される:
- thumbnail(サムネイル): WebP形式
- spritesheet(スプライトシート): JPG形式
# サムネイルのダウンロード
curl -L "https://api.openai.com/v1/videos/video_abc123/content?variant=thumbnail" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
--output thumbnail.webp
主な機能
画像参照機能
入力画像を動画の最初のフレームとして使用可能。ブランドアセット、キャラクター、特定の環境を保持したい場合に有効。
curl -X POST "https://api.openai.com/v1/videos" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F prompt="彼女は振り返って微笑み、ゆっくりとフレームから歩き去る。" \
-F model="sora-2-pro" \
-F size="1280x720" \
-F seconds="8" \
-F input_reference="@sample_720p.jpeg;type=image/jpeg"
対応フォーマット: image/jpeg
, image/png
, image/webp
制約: 画像解像度は動画のsize
パラメータと一致する必要がある。
Remix機能(動画の部分編集)
既存の完成動画に対して、ターゲットを絞った調整を加えられる。全体を再生成せずに、元の構造・連続性・構図を保ちながら変更を適用。
curl -X POST "https://api.openai.com/v1/videos/<previous_video_id>/remix" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "カラーパレットをティール、サンド、ラストに変更し、暖かいバックライトを追加。"
}'
ベストプラクティス:
- 1回につき1つの明確な変更に絞ること
- 小さく焦点を絞った編集ほど、元の忠実度が保たれる
- 色調整、オブジェクト追加、モンスターの色変更などに最適
動画ライブラリの管理
一覧取得
curl "https://api.openai.com/v1/videos?limit=20&after=video_123&order=asc" \
-H "Authorization: Bearer $OPENAI_API_KEY"
削除
curl -X DELETE "https://api.openai.com/v1/videos/video_abc123" \
-H "Authorization: Bearer $OPENAI_API_KEY"
コンテンツ制限とガードレール
APIは以下のコンテンツ制限を設けている:
- 18歳未満向けコンテンツのみ(将来的にバイパス設定が追加予定)
- 著作権キャラクター・音楽は拒否される
- 実在の人物(公人含む)は生成不可
- 人間の顔を含む入力画像は現在拒否される
プロンプト、参照画像、トランスクリプトはこれらのルールに従う必要がある。
効果的なプロンプティング
基本構造
ショットタイプ + 被写体 + アクション + 設定 + 照明を含めること。
Good例
- "草原の公園で赤い凧を飛ばす子供のワイドショット、ゴールデンアワーの日光、カメラはゆっくり上方にパンする。"
- "木製テーブルの上の湯気の立つコーヒーカップのクローズアップ、ブラインドからの朝の光、柔らかい被写界深度。"
Bad例
- "猫の動画"(詳細が不足)
- "かっこいいやつ"(曖昧すぎる)
詳細度が高いほど、モデルは不要な詳細を発明せず一貫した結果を生成する。
さらに高度なプロンプティングテクニックについては公式プロンプティングガイドを参照。
応用例
1. ラピッドプロトタイピング
モデル: Sora 2
ユースケース: 広告代理店でのコンセプト提案、複数案の比較検討
フロー: プロンプト → 高速生成 → クライアント確認 → Remix微調整
2. ブランドコンテンツ制作
モデル: Sora 2 Pro
ユースケース: 企業のマーケティング動画、製品デモ
フロー: ブランドロゴ画像 → input_reference
で開始フレーム固定 → 高品質レンダリング
3. SNS用短編動画の量産
モデル: Sora 2
ユースケース: TikTok、Instagram Reels向けコンテンツ
フロー: テンプレートプロンプト作成 → バッチ生成 → サムネイル自動取得
4. 映像制作のプリビズ(プレビジュアライゼーション)
モデル: Sora 2
ユースケース: 映画やCMの絵コンテ動画化
フロー: シーンごとにプロンプト生成 → 連続生成 → 編集ソフトで結合
5. イテレーティブな動画編集
モデル: Sora 2 / Sora 2 Pro
ユースケース: 既存動画の色調整、オブジェクト追加
フロー: ベース動画生成 → Remixで段階的改善 → 最終版をSora 2 Proで再生成
6. A/Bテスト用バリエーション生成
モデル: Sora 2
ユースケース: マーケティングキャンペーンの効果測定
フロー: 同じプロンプトでパラメータ変更 → 複数バージョン生成 → パフォーマンス比較
ベストプラクティスとTips
パフォーマンス最適化
- Webhookを活用: ポーリングよりも効率的でサーバー負荷が低い
- 適切なモデル選択: プロトタイプはSora 2、最終版はSora 2 Pro
- 並列生成: 複数の動画を同時にキューイング可能
コスト最適化
- 段階的アプローチ: Sora 2でコンセプト確認 → Sora 2 Proで仕上げ
- Remixの活用: 全体再生成よりもコスト効率が高い
- 不要な動画の削除: ストレージコストを抑える
エラーハンドリング
try:
video = openai.videos.create(
model="sora-2",
prompt="プロンプト",
)
except OpenAIError as e:
# エラー内容に応じた処理
if "content_policy" in str(e):
# コンテンツポリシー違反
pass
elif "rate_limit" in str(e):
# レート制限
pass
プロンプト改善のイテレーション
- 最初は短いプロンプトで生成
- 結果を見て不足している要素を特定
- ショットタイプ、照明、カメラワークなどを追加
- Remixで微調整を重ねる
ダウンロード管理
- 24時間以内にダウンロードを徹底
- S3やGCSなどのクラウドストレージに自動バックアップ
- サムネイルとスプライトシートも保存してUI表示に活用
まとめ
Sora APIは、テキストや画像から高品質な動画を生成できる強力なツール。非同期処理、Webhook、Remix機能を活用することで、効率的な動画制作ワークフローを構築できる。
キーポイント:
- モデルは用途に応じて使い分け(Sora 2 = 速度、Sora 2 Pro = 品質)
- Webhookによる非同期処理で効率化
- Remixで段階的な改善が可能
- コンテンツ制限に注意してプロンプト設計
- 24時間以内のダウンロード必須
適切な戦略でSora APIを活用すれば、動画制作の可能性が大きく広がる。