Generate stunning AI videos using OpenAI's Sora 2 API with this Bun-powered CLI tool.
- Bun runtime installed
- OpenAI API key with Sora 2 access
- Set your API key:
export OPENAI_API_KEY=sk-...
# Clone the repository
git clone <repository-url>cd sora2-node
# Install dependencies
bun installbun run create-sora2-video.ts --prompt "your prompt" [options]Start the API server with authentication:
# Set environment variablesexport OPENAI_API_KEY=sk-your-api-key
export AUTH_TOKEN=your-secret-auth-token
export PORT=3000 # optional, defaults to 3000# Start the server
bun run api-server.tsThe server provides RESTful endpoints for video generation with Bearer token authentication.
| Option | Description | Default |
|---|---|---|
--prompt | Text prompt describing the scene (required) | - |
--duration | Video length in seconds: 4, 8, or 12 | 8 |
--orientation | Video orientation: portrait or landscape | landscape |
--image | Path to guide image for style reference | - |
--model | Model version: sora-2 or sora-2-pro | sora-2 |
--outdir | Output directory for generated videos | ./out |
--seed | Random seed for reproducible results | - |
# Simple landscape video
bun run create-sora2-video.ts \
--prompt "A serene mountain lake at dawn with mist rising from the water"# Portrait video for social media
bun run create-sora2-video.ts \
--prompt "Time-lapse of flowers blooming in vibrant colors" \
--orientation portrait# Action sequence
bun run create-sora2-video.ts \
--prompt "A golden retriever surfing at sunset, cinematic lighting, detailed water spray, upbeat indie rock soundtrack" \
--orientation landscape \
--duration 12
# Sci-fi cityscape
bun run create-sora2-video.ts \
--prompt "Futuristic neon-lit city with flying cars, blade runner style, rain reflections, synthwave music" \
--duration 12 \
--model sora-2-pro
# Film noir detective
bun run create-sora2-video.ts \
--prompt "1940s detective in fedora walking through foggy alley, black and white, jazz soundtrack, film noir lighting" \
--duration 8
# Epic fantasy battle
bun run create-sora2-video.ts \
--prompt "Dragon breathing fire over medieval castle at night, epic orchestral music, Game of Thrones style" \
--duration 12# Watercolor animation
bun run create-sora2-video.ts \
--prompt "Watercolor painting coming to life: koi fish swimming in a pond with lotus flowers" \
--orientation portrait \
--duration 8
# Studio Ghibli inspired
bun run create-sora2-video.ts \
--prompt "A cozy cottage in a meadow, Studio Ghibli style, soft clouds drifting by, peaceful piano melody" \
--duration 12
# Oil painting transformation
bun run create-sora2-video.ts \
--prompt "Van Gogh style starry night slowly morphing into dawn, swirling brushstrokes, classical music" \
--duration 8
# Anime action scene
bun run create-sora2-video.ts \
--prompt "Anime character with flowing hair jumping between buildings, sakura petals, dynamic camera angles, j-rock music" \
--orientation portrait \
--duration 4# Wildlife documentary
bun run create-sora2-video.ts \
--prompt "Majestic eagle soaring over snow-capped mountains, documentary style, orchestral score" \
--duration 12
# Underwater scene
bun run create-sora2-video.ts \
--prompt "Coral reef teeming with colorful tropical fish, sunlight filtering through water" \
--duration 8
# Aurora borealis
bun run create-sora2-video.ts \
--prompt "Northern lights dancing across Arctic sky, time-lapse, ethereal ambient music, ultra wide angle" \
--duration 12
# Macro nature
bun run create-sora2-video.ts \
--prompt "Extreme close-up of dewdrops on spider web at sunrise, bokeh background, nature sounds" \
--duration 4# Abstract visuals
bun run create-sora2-video.ts \
--prompt "Flowing liquid metal morphing into geometric shapes, iridescent colors, ambient electronic music" \
--duration 8
# Particle effects
bun run create-sora2-video.ts \
--prompt "Millions of glowing particles forming a phoenix, dramatic orchestral crescendo" \
--duration 12
# Fractal zoom
bun run create-sora2-video.ts \
--prompt "Infinite fractal zoom into Mandelbrot set, psychedelic colors, electronic music" \
--duration 8
# Data visualization
bun run create-sora2-video.ts \
--prompt "3D data points forming constellation patterns, holographic style, tech ambient soundtrack" \
--duration 4# Cooking montage
bun run create-sora2-video.ts \
--prompt "Chocolate lava cake being prepared, macro shots, melting chocolate center reveal, upbeat music" \
--duration 8
# Coffee art
bun run create-sora2-video.ts \
--prompt "Barista creating latte art, steam rising, warm lighting, coffee shop ambiance" \
--orientation portrait \
--duration 4
# Sushi preparation
bun run create-sora2-video.ts \
--prompt "Master sushi chef preparing omakase, precise knife work, minimalist aesthetic, traditional Japanese music" \
--duration 12# Extreme sports
bun run create-sora2-video.ts \
--prompt "Snowboarder doing backflip off mountain cliff, slow motion snow spray, adrenaline rock music" \
--duration 4
# Basketball highlight
bun run create-sora2-video.ts \
--prompt "Basketball player dunking in slow motion, stadium lights, crowd cheering, hip-hop beat" \
--orientation portrait \
--duration 4
# Parkour sequence
bun run create-sora2-video.ts \
--prompt "Parkour athlete running across rooftops at sunset, first person view, electronic music" \
--duration 8# 80s aesthetic
bun run create-sora2-video.ts \
--prompt "Retro wave sunset with palm trees, VHS glitch effects, neon grid floor, synthwave music" \
--duration 8
# Vintage film
bun run create-sora2-video.ts \
--prompt "1920s flapper dancing, sepia tone, film grain, scratches, ragtime piano music" \
--orientation portrait \
--duration 4
# Arcade nostalgia
bun run create-sora2-video.ts \
--prompt "8-bit pixel art world coming to life, retro game sprites, chiptune music, CRT TV effect" \
--duration 8# Fashion runway
bun run create-sora2-video.ts \
--prompt "Model walking runway, flowing fabric, dramatic lighting, fashion show atmosphere, electronic beats" \
--orientation portrait \
--duration 8
# Makeup transformation
bun run create-sora2-video.ts \
--prompt "Time-lapse makeup application, glitter and colors, beauty lighting, pop music" \
--orientation portrait \
--duration 4
# Jewelry showcase
bun run create-sora2-video.ts \
--prompt "Diamond necklace rotating, sparkling under studio lights, luxury presentation, elegant classical music" \
--duration 4# Modern architecture
bun run create-sora2-video.ts \
--prompt "Drone ascending modern glass skyscraper at sunset, reflective surfaces, ambient electronic" \
--duration 12
# Ancient ruins
bun run create-sora2-video.ts \
--prompt "Mayan pyramid emerging from jungle mist at dawn, mystical atmosphere, tribal drums" \
--duration 8
# City time-lapse
bun run create-sora2-video.ts \
--prompt "Tokyo intersection at night, time-lapse of people and traffic, neon signs, city sounds" \
--duration 8# Space exploration
bun run create-sora2-video.ts \
--prompt "Spacecraft approaching Saturn's rings, realistic space physics, epic orchestral score" \
--duration 12
# Microscopic world
bun run create-sora2-video.ts \
--prompt "Journey through human bloodstream, red blood cells flowing, scientific visualization, ambient music" \
--duration 8
# Robot assembly
bun run create-sora2-video.ts \
--prompt "Futuristic robot being assembled, mechanical parts fitting together, industrial sounds" \
--duration 4
# DNA visualization
bun run create-sora2-video.ts \
--prompt "DNA double helix rotating and unzipping, bioluminescent colors, scientific ambient music" \
--orientation portrait \
--duration 4# Magical forest
bun run create-sora2-video.ts \
--prompt "Enchanted forest with glowing mushrooms and fireflies, fairy tale atmosphere, mystical harp music" \
--duration 8
# Wizard spell
bun run create-sora2-video.ts \
--prompt "Wizard casting fire spell, magical particles, ancient library setting, epic fantasy music" \
--duration 4
# Crystal cave
bun run create-sora2-video.ts \
--prompt "Underground crystal cave with rainbow light refractions, ethereal atmosphere, new age music" \
--duration 12# Christmas scene
bun run create-sora2-video.ts \
--prompt "Snow falling on decorated Christmas tree in cozy living room, fireplace crackling, holiday music" \
--duration 8
# Halloween atmosphere
bun run create-sora2-video.ts \
--prompt "Spooky jack-o'-lanterns glowing in foggy graveyard, full moon, eerie ambient sounds" \
--duration 8
# Cherry blossoms
bun run create-sora2-video.ts \
--prompt "Sakura petals falling in slow motion, Japanese garden, traditional koto music" \
--orientation portrait \
--duration 4# Style transfer from image
bun run create-sora2-video.ts \
--prompt "Character walking through enchanted forest" \
--image ./reference-style.jpg \
--duration 8
# Product visualization
bun run create-sora2-video.ts \
--prompt "Luxury watch rotating 360 degrees, studio lighting, elegant presentation" \
--image ./product-photo.jpg \
--duration 4# Use seed for consistent generation
bun run create-sora2-video.ts \
--prompt "Northern lights dancing across starry sky" \
--seed 42 \
--duration 12# Save to specific folder
bun run create-sora2-video.ts \
--prompt "Timelapse of clouds over mountain range" \
--outdir ./videos/timelapse \
--duration 8Be Specific: Include details about lighting, camera angles, and mood
--prompt "Close-up shot of raindrops on a window, bokeh city lights in background, melancholic mood"Include Audio Descriptions: Sora 2 can generate synchronized audio
--prompt "Jazz band performing in smoky club, upbeat swing music, crowd chatter"Specify Art Styles: Reference specific artistic styles or artists
--prompt "Landscape in Van Gogh's style, swirling clouds, vibrant yellows and blues"Camera Movements: Describe how the camera should move
--prompt "Drone shot ascending over foggy forest, revealing mountain peak at sunrise"
- Duration: Shorter videos (4s) generate faster and are good for testing
- Model Selection: Use
sora-2-profor higher quality at increased cost - Image References: Provide high-quality images for better style matching
- Orientation: Choose based on intended platform (landscape for YouTube, portrait for TikTok/Reels)
Generated videos are saved in the output directory with the format:
sora2_<job-id>.mp4
If audio is generated separately, it will be saved as:
sora2_<job-id>.aac
The script includes comprehensive error handling:
- Validates API key presence
- Checks image file existence
- Reports API errors clearly
- Shows generation progress
- Duration options: 4, 8, or 12 seconds
- Resolutions: 1280x720 (landscape) or 720x1280 (portrait)
- Requires valid OpenAI API key with Sora 2 access
- Subject to your OpenAI account rate limits
All API endpoints (except /health) require Bearer token authentication:
-H "Authorization: Bearer your-secret-auth-token"# No authentication required
curl http://localhost:3000/health# Basic video generation
curl -X POST http://localhost:3000/api/videos \
-H "Authorization: Bearer your-secret-auth-token" \
-H "Content-Type: application/json" \
-d '{ "prompt": "A beautiful sunset over the ocean with waves crashing" }'# With all parameters
curl -X POST http://localhost:3000/api/videos \
-H "Authorization: Bearer your-secret-auth-token" \
-H "Content-Type: application/json" \
-d '{ "prompt": "A cyberpunk city at night, neon lights, rain", "duration": 12, "orientation": "landscape", "model": "sora-2-pro", "seed": 42 }'# Response
{
"jobId": "job_1234567890_abc123",
"status": "queued",
"message": "Video generation started"
}# Check job progress
curl http://localhost:3000/api/videos/job_1234567890_abc123 \
-H "Authorization: Bearer your-secret-auth-token"# Response (processing)
{
"id": "job_1234567890_abc123",
"status": "processing",
"progress": 45,
"createdAt": "2025-01-07T12:00:00Z",
"request": {
"prompt": "A beautiful sunset over the ocean with waves crashing"
}
}
# Response (completed)
{
"id": "job_1234567890_abc123",
"status": "completed",
"progress": 100,
"videoUrl": "/videos/job_1234567890_abc123.mp4",
"createdAt": "2025-01-07T12:00:00Z",
"completedAt": "2025-01-07T12:02:30Z",
"request": {
"prompt": "A beautiful sunset over the ocean with waves crashing"
}
}curl http://localhost:3000/api/videos \
-H "Authorization: Bearer your-secret-auth-token"# Response
{
"jobs": [
{
"id": "job_1234567890_abc123",
"status": "completed",
"progress": 100,
"createdAt": "2025-01-07T12:00:00Z",
"completedAt": "2025-01-07T12:02:30Z",
"prompt": "A beautiful sunset over the ocean with waves crashing"
},
{
"id": "job_0987654321_xyz789",
"status": "processing",
"progress": 60,
"createdAt": "2025-01-07T12:05:00Z",
"prompt": "Northern lights dancing across the sky"
}
],
"total": 2
}# Download completed video
curl -O http://localhost:3000/videos/job_1234567890_abc123.mp4 \
-H "Authorization: Bearer your-secret-auth-token"# Or use wget
wget --header="Authorization: Bearer your-secret-auth-token" \
http://localhost:3000/videos/job_1234567890_abc123.mp4curl -X DELETE http://localhost:3000/api/videos/job_1234567890_abc123 \
-H "Authorization: Bearer your-secret-auth-token"# Response
{
"message": "Job deleted successfully"
}| Field | Type | Description | Required | Default |
|---|---|---|---|---|
prompt | string | Text description of the video | Yes | - |
duration | number | Video length: 4, 8, or 12 seconds | No | 8 |
orientation | string | "portrait" or "landscape" | No | "landscape" |
model | string | "sora-2" or "sora-2-pro" | No | "sora-2" |
seed | number | Random seed for reproducibility | No | - |
image | string | Base64 encoded guide image | No | - |
200- Success202- Job accepted and queued400- Bad request (invalid parameters)401- Unauthorized (missing or invalid token)404- Resource not found500- Server error
# 1. Create a video generation job
JOB_ID=$(curl -s -X POST http://localhost:3000/api/videos \ -H "Authorization: Bearer your-secret-auth-token" \ -H "Content-Type: application/json" \ -d '{"prompt": "A serene Japanese garden with koi fish"}' \| jq -r '.jobId')echo"Job created: $JOB_ID"# 2. Poll for completionwhiletrue;do
STATUS=$(curl -s http://localhost:3000/api/videos/$JOB_ID \ -H "Authorization: Bearer your-secret-auth-token" \| jq -r '.status')echo"Status: $STATUS"if [ "$STATUS"="completed" ];thenbreakelif [ "$STATUS"="failed" ];thenecho"Job failed!"exit 1
fi
sleep 5
done# 3. Download the video
curl -O http://localhost:3000/videos/$JOB_ID.mp4 \
-H "Authorization: Bearer your-secret-auth-token"echo"Video downloaded: $JOB_ID.mp4"importrequestsimporttimeimportjson# ConfigurationAPI_URL="http://localhost:3000"AUTH_TOKEN="your-secret-auth-token"headers= {"Authorization": f"Bearer {AUTH_TOKEN}"}
# Create video jobresponse=requests.post(
f"{API_URL}/api/videos",
headers={**headers, "Content-Type": "application/json"},
json={
"prompt": "A futuristic city with flying cars",
"duration": 8,
"orientation": "landscape"
}
)
job_id=response.json()["jobId"]
print(f"Job created: {job_id}")
# Poll for completionwhileTrue:
response=requests.get(f"{API_URL}/api/videos/{job_id}", headers=headers)
data=response.json()
print(f"Status: {data['status']}, Progress: {data.get('progress', 0)}%")
ifdata["status"] =="completed":
video_url=data["videoUrl"]
breakelifdata["status"] =="failed":
print(f"Error: {data.get('error')}")
exit(1)
time.sleep(5)
# Download videoresponse=requests.get(f"{API_URL}{video_url}", headers=headers)
withopen(f"{job_id}.mp4", "wb") asf:
f.write(response.content)
print(f"Video saved as {job_id}.mp4")constAPI_URL='http://localhost:3000';constAUTH_TOKEN='your-secret-auth-token';asyncfunctiongenerateVideo(prompt){// Create jobconstcreateResponse=awaitfetch(`${API_URL}/api/videos`,{method: 'POST',headers: {'Authorization': `Bearer ${AUTH_TOKEN}`,'Content-Type': 'application/json'},body: JSON.stringify({ prompt })});const{ jobId }=awaitcreateResponse.json();console.log(`Job created: ${jobId}`);// Poll for completionwhile(true){conststatusResponse=awaitfetch(`${API_URL}/api/videos/${jobId}`,{headers: {'Authorization': `Bearer ${AUTH_TOKEN}`}});constjob=awaitstatusResponse.json();console.log(`Status: ${job.status}, Progress: ${job.progress||0}%`);if(job.status==='completed'){returnjob.videoUrl;}elseif(job.status==='failed'){thrownewError(job.error);}awaitnewPromise(resolve=>setTimeout(resolve,5000));}}// UsagegenerateVideo('A magical forest at twilight').then(videoUrl=>console.log(`Video ready at: ${videoUrl}`)).catch(error=>console.error('Error:',error));export OPENAI_API_KEY=sk-your-api-key-herechmod +x create-sora2-video.tsInstall Bun from https://bun.sh:
curl -fsSL https://bun.sh/install | bashMIT
Pull requests welcome! Please ensure your code follows the existing style and includes appropriate error handling.
This project was created using bun init in bun v1.2.21. Bun is a fast all-in-one JavaScript runtime.