Gemini API로 Veo 3.1 비디오 생성하기
Gemini API로 Veo 3.1 비디오 생성하기
참고: 이 기능은 현재 generateContent API에서만 사용할 수 있어요. 자세한 내용은 이 페이지의 내용을 따르세요. 비디오 이해에 대해 알아보려면 Video understanding 가이드를 참고하세요.
Veo 3.1은 네이티브 생성 오디오를 갖춘 8초 비디오(720p, 1080p, 4k)를 생성하는 모델이에요. Gemini API를 사용해 프로그래밍 방식으로 이 모델에 접근할 수 있어요. 사용 가능한 Veo 모델 변형에 대해 알아보려면 Model Versions 섹션을 참고하세요.
Veo 3.1은 다양한 시각·시네마틱 스타일에 탁월하며 몇 가지 새 기능을 도입해요.
- 세로 비디오(Portrait videos): 가로(
16:9)와 세로(9:16) 비디오 중 선택할 수 있어요. - 비디오 확장(Video extension): 이전에 Veo로 생성한 비디오를 확장할 수 있어요.
- 프레임별 생성(Frame-specific generation): 첫·마지막 프레임을 지정해 비디오를 생성할 수 있어요.
- 이미지 기반 방향(Image-based direction): 최대 3개의 참조 이미지로 생성된 비디오의 콘텐츠를 안내할 수 있어요.
비디오 생성을 위한 효과적인 텍스트 프롬프트 작성에 대해 더 알아보려면 Veo prompt guide를 참고하세요.
출처: 문서
본문
텍스트-투-비디오 생성 (Text to video generation)
다음 예시는 대화, 시네마틱 리얼리즘, 창의적 애니메이션으로 비디오를 생성하는 방법을 보여줘요.
대화 & 음향 효과 (Dialogue & sound effects)
Python
import time
from google import genai
from google.genai import types
client = genai.Client()
prompt = """A close up of two people staring at a cryptic drawing on a wall, torchlight flickering.
A man murmurs, 'This must be it. That's the secret code.' The woman looks at him and whispering excitedly, 'What did you find?'"""
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt,
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the generated video.
generated_video = operation.response.generated_videos[0]
client.files.download(file=generated_video.video, destination="dialogue_example.mp4")
print("Generated video saved to dialogue_example.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = `A close up of two people staring at a cryptic drawing on a wall, torchlight flickering.
A man murmurs, 'This must be it. That's the secret code.' The woman looks at him and whispering excitedly, 'What did you find?'`;
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: prompt,
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...")
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the generated video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "dialogue_example.mp4",
});
console.log(`Generated video saved to dialogue_example.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := `A close up of two people staring at a cryptic drawing on a wall, torchlight flickering.
A man murmurs, 'This must be it. That's the secret code.' The woman looks at him and whispering excitedly, 'What did you find?'`
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
nil,
nil,
)
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the generated video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "dialogue_example.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
Java
import com.google.genai.Client;
import com.google.genai.types.GenerateVideosOperation;
import com.google.genai.types.GeneratedVideo;
Client client = new Client();
String prompt =
"A close up of two people staring at a cryptic drawing on a wall, torchlight flickering.\n"
+ "A man murmurs, 'This must be it. That's the secret code.' The woman looks at him and whispering excitedly, 'What did you find?'";
GenerateVideosOperation operation =
client.models.generateVideos("veo-3.1-generate-preview", prompt, null, null);
// Poll the operation status until the video is ready.
while (!operation.done().orElse(false)) {
System.out.println("Waiting for video generation to complete...");
Thread.sleep(10000);
operation = client.operations.getVideosOperation(operation, null);
}
// Download the generated video.
GeneratedVideo generatedVideo = operation.response().get().generatedVideos().get().get(0);
client.files.download(generatedVideo, "dialogue_example.mp4", null);
System.out.println("Generated video saved to dialogue_example.mp4");
REST
# Note: This script uses jq to parse the JSON response.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "A close up of two people staring at a cryptic drawing on a wall, torchlight flickering. A man murmurs, \"This must be it. That'\''s the secret code.\" The woman looks at him and whispering excitedly, \"What did you find?\""
}
]
}' | jq -r .name)
# Poll the operation status until the video is ready
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Extract the download URI from the final response.
video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')
echo "Downloading video from: ${video_uri}"
# Download the video using the URI and API key and follow redirects.
curl -L -o dialogue_example.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}"
break
fi
# Wait for 5 seconds before checking again.
sleep 10
done
시네마틱 리얼리즘 (Cinematic realism)
Python
import time
from google import genai
from google.genai import types
client = genai.Client()
prompt = """Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below.
The convertible accelerates fast and the engine roars loudly."""
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt,
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the generated video.
generated_video = operation.response.generated_videos[0]
client.files.download(file=generated_video.video, destination="realism_example.mp4")
print("Generated video saved to realism_example.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = `Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below.
The convertible accelerates fast and the engine roars loudly.`;
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: prompt,
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...")
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the generated video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "realism_example.mp4",
});
console.log(`Generated video saved to realism_example.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := `Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below.
The convertible accelerates fast and the engine roars loudly.`
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
nil,
nil,
)
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the generated video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "realism_example.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
Java
import com.google.genai.Client;
import com.google.genai.types.GenerateVideosOperation;
import com.google.genai.types.GeneratedVideo;
Client client = new Client();
String prompt =
"Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below.\n"
+ "The convertible accelerates fast and the engine roars loudly.";
GenerateVideosOperation operation =
client.models.generateVideos("veo-3.1-generate-preview", prompt, null, null);
// Poll the operation status until the video is ready.
while (!operation.done().orElse(false)) {
System.out.println("Waiting for video generation to complete...");
Thread.sleep(10000);
operation = client.operations.getVideosOperation(operation, null);
}
// Download the generated video.
GeneratedVideo generatedVideo = operation.response().get().generatedVideos().get().get(0);
client.files.download(generatedVideo, "realism_example.mp4", null);
System.out.println("Generated video saved to realism_example.mp4");
REST
# Note: This script uses jq to parse the JSON response.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "Drone shot following a classic red convertible driven by a man along a winding coastal road at sunset, waves crashing against the rocks below. The convertible accelerates fast and the engine roars loudly."
}
]
}' | jq -r .name)
# Poll the operation status until the video is ready
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Extract the download URI from the final response.
video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')
echo "Downloading video from: ${video_uri}"
# Download the video using the URI and API key and follow redirects.
curl -L -o realism_example.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}"
break
fi
# Wait for 5 seconds before checking again.
sleep 10
done
창의적 애니메이션 (Creative animation)
Python
import time
from google import genai
client = genai.Client()
prompt = "A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet."
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt,
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the generated video.
generated_video = operation.response.generated_videos[0]
client.files.download(file=generated_video.video, destination="style_example.mp4")
print("Generated video saved to style_example.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = "A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet.";
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: prompt,
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...")
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the generated video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "style_example.mp4",
});
console.log(`Generated video saved to style_example.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := `A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet.`
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
nil,
nil,
)
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the generated video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "style_example.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
Java
import com.google.genai.Client;
import com.google.genai.types.GenerateVideosOperation;
import com.google.genai.types.GeneratedVideo;
Client client = new Client();
String prompt =
"A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet.";
GenerateVideosOperation operation =
client.models.generateVideos("veo-3.1-generate-preview", prompt, null, null);
// Poll the operation status until the video is ready.
while (!operation.done().orElse(false)) {
System.out.println("Waiting for video generation to complete...");
Thread.sleep(10000);
operation = client.operations.getVideosOperation(operation, null);
}
// Download the generated video.
GeneratedVideo generatedVideo = operation.response().get().generatedVideos().get().get(0);
client.files.download(generatedVideo, "style_example.mp4", null);
System.out.println("Generated video saved to style_example.mp4");
REST
# Note: This script uses jq to parse the JSON response.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "A whimsical stop-motion animation of a tiny robot tending to a garden of glowing mushrooms on a miniature planet."
}
]
}' | jq -r .name)
# Poll the operation status until the video is ready
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Extract the download URI from the final response.
video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')
echo "Downloading video from: ${video_uri}"
# Download the video using the URI and API key and follow redirects.
curl -L -o style_example.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}"
break
fi
# Wait for 5 seconds before checking again.
sleep 10
done
종횡비 제어 (Control the aspect ratio)
Veo 3.1은 가로(16:9, 기본 설정) 또는 세로(9:16) 비디오를 만들 수 있어요. aspect_ratio 파라미터로 원하는 것을 모델에 알려줄 수 있어요.
Python
import time
from google import genai
from google.genai import types
client = genai.Client()
prompt = """A montage of pizza making: a chef tossing and flattening the floury dough, ladling rich red tomato sauce in a spiral, sprinkling mozzarella cheese and pepperoni, and a final shot of the bubbling golden-brown pizza, upbeat electronic music with a rhythmical beat is playing, high energy professional video."""
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt,
config=types.GenerateVideosConfig(
aspect_ratio="9:16",
),
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the generated video.
generated_video = operation.response.generated_videos[0]
client.files.download(file=generated_video.video, destination="pizza_making.mp4")
print("Generated video saved to pizza_making.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = `A montage of pizza making: a chef tossing and flattening the floury dough, ladling rich red tomato sauce in a spiral, sprinkling mozzarella cheese and pepperoni, and a final shot of the bubbling golden-brown pizza, upbeat electronic music with a rhythmical beat is playing, high energy professional video.`;
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: prompt,
config: {
aspectRatio: "9:16",
},
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...")
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the generated video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "pizza_making.mp4",
});
console.log(`Generated video saved to pizza_making.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := `A montage of pizza making: a chef tossing and flattening the floury dough, ladling rich red tomato sauce in a spiral, sprinkling mozzarella cheese and pepperoni, and a final shot of the bubbling golden-brown pizza, upbeat electronic music with a rhythmical beat is playing, high energy professional video.`
videoConfig := &genai.GenerateVideosConfig{
AspectRatio: "9:16",
}
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
nil,
videoConfig,
)
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the generated video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "pizza_making.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
REST
# Note: This script uses jq to parse the JSON response.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "A montage of pizza making: a chef tossing and flattening the floury dough, ladling rich red tomato sauce in a spiral, sprinkling mozzarella cheese and pepperoni, and a final shot of the bubbling golden-brown pizza, upbeat electronic music with a rhythmical beat is playing, high energy professional video."
}
],
"parameters": {
"aspectRatio": "9:16"
}
}' | jq -r .name)
# Poll the operation status until the video is ready
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Extract the download URI from the final response.
video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')
echo "Downloading video from: ${video_uri}"
# Download the video using the URI and API key and follow redirects.
curl -L -o pizza_making.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}"
break
fi
# Wait for 5 seconds before checking again.
sleep 10
done
해상도 제어 (Control the resolution)
Veo 3.1은 720p, 1080p 또는 4k 비디오를 직접 생성할 수도 있어요(4k는 Veo 3.1 Lite에서 사용 불가).
해상도가 높을수록 지연 시간도 높아진다는 점에 주의하세요. 4k 비디오는 더 비싸기도 해요(pricing 참고).
비디오 확장도 720p 비디오로 제한돼요.
Python
import time
from google import genai
from google.genai import types
client = genai.Client()
prompt = """A stunning drone view of the Grand Canyon during a flamboyant sunset that highlights the canyon's colors. The drone slowly flies towards the sun then accelerates, dives and flies inside the canyon."""
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt,
config=types.GenerateVideosConfig(
resolution="4k",
),
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the generated video.
generated_video = operation.response.generated_videos[0]
client.files.download(file=generated_video.video, destination="4k_grand_canyon.mp4")
print("Generated video saved to 4k_grand_canyon.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = `A stunning drone view of the Grand Canyon during a flamboyant sunset that highlights the canyon's colors. The drone slowly flies towards the sun then accelerates, dives and flies inside the canyon.`;
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: prompt,
config: {
resolution: "4k",
},
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...")
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the generated video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "4k_grand_canyon.mp4",
});
console.log(`Generated video saved to 4k_grand_canyon.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := `A stunning drone view of the Grand Canyon during a flamboyant sunset that highlights the canyon's colors. The drone slowly flies towards the sun then accelerates, dives and flies inside the canyon.`
videoConfig := &genai.GenerateVideosConfig{
Resolution: "4k",
}
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
nil,
videoConfig,
)
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the generated video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "4k_grand_canyon.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
REST
# Note: This script uses jq to parse the JSON response.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "A stunning drone view of the Grand Canyon during a flamboyant sunset that highlights the canyon'\''s colors. The drone slowly flies towards the sun then accelerates, dives and flies inside the canyon."
}
],
"parameters": {
"resolution": "4k"
}
}' | jq -r .name)
# Poll the operation status until the video is ready
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Extract the download URI from the final response.
video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')
echo "Downloading video from: ${video_uri}"
# Download the video using the URI and API key and follow redirects.
curl -L -o 4k_grand_canyon.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}"
break
fi
# Wait for 5 seconds before checking again.
sleep 10
done
이미지-투-비디오 생성 (Image to video generation)
다음 코드는 Gemini 3.1 Flash Image aka Nano Banana 2로 이미지를 생성한 다음, 그 이미지를 시작 프레임으로 사용해 Veo 3.1로 비디오를 생성하는 방법을 보여줘요.
Python
import time
from google import genai
client = genai.Client()
prompt = "Panning wide shot of a calico kitten sleeping in the sunshine"
# Step 1: Generate an image with Nano Banana 2.
image = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=prompt,
config={"response_modalities":['IMAGE']}
)
# Step 2: Generate video with Veo 3.1 using the image.
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt,
image=image.parts[0].as_image(),
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the video.
video = operation.response.generated_videos[0]
client.files.download(file=video.video, destination="veo3_with_image_input.mp4")
print("Generated video saved to veo3_with_image_input.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = "Panning wide shot of a calico kitten sleeping in the sunshine";
// Step 1: Generate an image with Nano Banana 2.
const imageResponse = await ai.models.generateContent({
model: "gemini-3.1-flash-image-preview",
prompt: prompt,
});
// Step 2: Generate video with Veo 3.1 using the image.
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: prompt,
image: {
imageBytes: imageResponse.generatedImages[0].image.imageBytes,
mimeType: "image/png",
},
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...")
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "veo3_with_image_input.mp4",
});
console.log(`Generated video saved to veo3_with_image_input.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := "Panning wide shot of a calico kitten sleeping in the sunshine"
// Step 1: Generate an image with Nano Banana 2.
imageResponse, err := client.Models.GenerateContent(
ctx,
"gemini-3.1-flash-image-preview",
prompt,
nil, // GenerateImagesConfig
)
if err != nil {
log.Fatal(err)
}
// Step 2: Generate video with Veo 3.1 using the image.
operation, err := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
imageResponse.GeneratedImages[0].Image,
nil, // GenerateVideosConfig
)
if err != nil {
log.Fatal(err)
}
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "veo3_with_image_input.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
Java
import com.google.genai.Client;
import com.google.genai.types.Blob;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.GenerateVideosOperation;
import com.google.genai.types.GeneratedVideo;
import com.google.genai.types.Image;
Client client = new Client();
String prompt = "Panning wide shot of a calico kitten sleeping in the sunshine";
// Step 1: Generate an image with Nano Banana 2.
GenerateContentResponse imageResponse =
client.models.generateContent(
"gemini-3.1-flash-image-preview",
prompt,
GenerateContentConfig.builder().responseModalities("IMAGE").build());
Blob inlineData = imageResponse.parts().get(0).inlineData().get();
Image image =
Image.builder()
.imageBytes(inlineData.data().get())
.mimeType(inlineData.mimeType().orElse("image/png"))
.build();
// Step 2: Generate video with Veo 3.1 using the image.
GenerateVideosOperation operation =
client.models.generateVideos("veo-3.1-generate-preview", prompt, image, null);
// Poll the operation status until the video is ready.
while (!operation.done().orElse(false)) {
System.out.println("Waiting for video generation to complete...");
Thread.sleep(10000);
operation = client.operations.getVideosOperation(operation, null);
}
// Download the video.
GeneratedVideo video = operation.response().get().generatedVideos().get().get(0);
client.files.download(video, "veo3_with_image_input.mp4", null);
System.out.println("Generated video saved to veo3_with_image_input.mp4");
참조 이미지 사용 (Using reference images)
참고: 이 기능은 Veo 3.1 모델에서만 사용할 수 있어요.
Veo 3.1은 이제 생성된 비디오의 콘텐츠를 안내하는 최대 3개의 참조 이미지를 받아들여요. 사람, 캐릭터, 제품의 이미지를 제공해 출력 비디오에서 피사체의 외형을 보존하세요.
예를 들어 Nano Banana로 생성한 이 세 이미지를 잘 작성된 프롬프트와 함께 참조로 사용하면 다음 비디오가 만들어져요.
dress_image |
woman_image |
glasses_image |
|---|
Python
import time
from google import genai
client = genai.Client()
prompt = "The video opens with a medium, eye-level shot of a beautiful woman with dark hair and warm brown eyes. She wears a magnificent, high-fashion flamingo dress with layers of pink and fuchsia feathers, complemented by whimsical pink, heart-shaped sunglasses. She walks with serene confidence through the crystal-clear, shallow turquoise water of a sun-drenched lagoon. The camera slowly pulls back to a medium-wide shot, revealing the breathtaking scene as the dress's long train glides and floats gracefully on the water's surface behind her. The cinematic, dreamlike atmosphere is enhanced by the vibrant colors of the dress against the serene, minimalist landscape, capturing a moment of pure elegance and high-fashion fantasy."
dress_reference = types.VideoGenerationReferenceImage(
image=dress_image, # Generated separately with Nano Banana
reference_type="asset"
)
sunglasses_reference = types.VideoGenerationReferenceImage(
image=glasses_image, # Generated separately with Nano Banana
reference_type="asset"
)
woman_reference = types.VideoGenerationReferenceImage(
image=woman_image, # Generated separately with Nano Banana
reference_type="asset"
)
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt,
config=types.GenerateVideosConfig(
reference_images=[dress_reference, glasses_reference, woman_reference],
),
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the video.
video = operation.response.generated_videos[0]
client.files.download(file=video.video, destination="veo3.1_with_reference_images.mp4")
print("Generated video saved to veo3.1_with_reference_images.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = "The video opens with a medium, eye-level shot of a beautiful woman with dark hair and warm brown eyes. She wears a magnificent, high-fashion flamingo dress with layers of pink and fuchsia feathers, complemented by whimsical pink, heart-shaped sunglasses. She walks with serene confidence through the crystal-clear, shallow turquoise water of a sun-drenched lagoon. The camera slowly pulls back to a medium-wide shot, revealing the breathtaking scene as the dress's long train glides and floats gracefully on the water's surface behind her. The cinematic, dreamlike atmosphere is enhanced by the vibrant colors of the dress against the serene, minimalist landscape, capturing a moment of pure elegance and high-fashion fantasy.";
// dressImage, glassesImage, womanImage generated separately with Nano Banana
// and available as objects like { imageBytes: "...", mimeType: "image/png" }
const dressReference = {
image: dressImage,
referenceType: "asset",
};
const sunglassesReference = {
image: glassesImage,
referenceType: "asset",
};
const womanReference = {
image: womanImage,
referenceType: "asset",
};
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: prompt,
config: {
referenceImages: [
dressReference,
sunglassesReference,
womanReference,
],
},
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...");
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "veo3.1_with_reference_images.mp4",
});
console.log(`Generated video saved to veo3.1_with_reference_images.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := `The video opens with a medium, eye-level shot of a beautiful woman with dark hair and warm brown eyes. She wears a magnificent, high-fashion flamingo dress with layers of pink and fuchsia feathers, complemented by whimsical pink, heart-shaped sunglasses. She walks with serene confidence through the crystal-clear, shallow turquoise water of a sun-drenched lagoon. The camera slowly pulls back to a medium-wide shot, revealing the breathtaking scene as the dress's long train glides and floats gracefully on the water's surface behind her. The cinematic, dreamlike atmosphere is enhanced by the vibrant colors of the dress against the serene, minimalist landscape, capturing a moment of pure elegance and high-fashion fantasy.`
// dressImage, glassesImage, womanImage generated separately with Nano Banana
// and available as *genai.Image objects.
var dressImage, glassesImage, womanImage *genai.Image
dressReference := &genai.VideoGenerationReferenceImage{
Image: dressImage,
ReferenceType: "asset",
}
sunglassesReference := &genai.VideoGenerationReferenceImage{
Image: glassesImage,
ReferenceType: "asset",
}
womanReference := &genai.VideoGenerationReferenceImage{
Image: womanImage,
ReferenceType: "asset",
}
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
nil, // image
&genai.GenerateVideosConfig{
ReferenceImages: []*genai.VideoGenerationReferenceImage{
dressReference,
sunglassesReference,
womanReference,
},
},
)
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "veo3.1_with_reference_images.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
REST
# Note: This script uses jq to parse the JSON response.
# It assumes dress_image_base64, glasses_image_base64, and woman_image_base64
# contain base64-encoded image data.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "The video opens with a medium, eye-level shot of a beautiful woman with dark hair and warm brown eyes. She wears a magnificent, high-fashion flamingo dress with layers of pink and fuchsia feathers, complemented by whimsical pink, heart-shaped sunglasses. She walks with serene confidence through the crystal-clear, shallow turquoise water of a sun-drenched lagoon. The camera slowly pulls back to a medium-wide shot, revealing the breathtaking scene as the dress'\''s long train glides and floats gracefully on the water'\''s surface behind her. The cinematic, dreamlike atmosphere is enhanced by the vibrant colors of the dress against the serene, minimalist landscape, capturing a moment of pure elegance and high-fashion fantasy.",
"referenceImages": [
{
"image": {"inlineData": {"mimeType": "image/png", "data": "'"$dress_image_base64"'"}},
"referenceType": "asset"
},
{
"image": {"inlineData": {"mimeType": "image/png", "data": "'"$glasses_image_base64"'"}},
"referenceType": "asset"
},
{
"image": {"inlineData": {"mimeType": "image/png", "data": "'"$woman_image_base64"'"}},
"referenceType": "asset"
}
]
}],
}' | jq -r .name)
# Poll the operation status until the video is ready
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Extract the download URI from the final response.
video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')
echo "Downloading video from: ${video_uri}"
# Download the video using the URI and API key and follow redirects.
curl -L -o veo3.1_with_reference_images.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}"
break
fi
# Wait for 10 seconds before checking again.
sleep 10
done
첫·마지막 프레임 사용
참고: 이 기능은 Veo 3.1 모델에서만 사용할 수 있어요.
Veo 3.1은 보간을 사용하거나 비디오의 첫·마지막 프레임을 지정해 비디오를 만들 수 있어요.
비디오 생성용 효과적인 텍스트 프롬프트 작성에 대한 정보는 Veo prompt guide를 참고하세요.
Python
import time
from google import genai
client = genai.Client()
prompt = "A cinematic, haunting video. A ghostly woman with long white hair and a flowing dress swings gently on a rope swing beneath a massive, gnarled tree in a foggy, moonlit clearing. The fog thickens and swirls around her, and she slowly fades away, vanishing completely. The empty swing is left swaying rhythmically on its own in the eerie silence."
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=prompt,
image=first_image, # The starting frame is passed as a primary input
config=types.GenerateVideosConfig(
last_frame=last_image # The ending frame is passed as a generation constraint in the config
),
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the video.
video = operation.response.generated_videos[0]
client.files.download(file=video.video, destination="veo3.1_with_interpolation.mp4")
print("Generated video saved to veo3.1_with_interpolation.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = "A cinematic, haunting video. A ghostly woman with long white hair and a flowing dress swings gently on a rope swing beneath a massive, gnarled tree in a foggy, moonlit clearing. The fog thickens and swirls around her, and she slowly fades away, vanishing completely. The empty swing is left swaying rhythmically on its own in the eerie silence.";
// firstImage and lastImage generated separately with Nano Banana
// and available as objects like { imageBytes: "...", mimeType: "image/png" }
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: prompt,
image: firstImage, // The starting frame is passed as a primary input
config: {
lastFrame: lastImage, // The ending frame is passed as a generation constraint in the config
},
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...")
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "veo3.1_with_interpolation.mp4",
});
console.log(`Generated video saved to veo3.1_with_interpolation.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := `A cinematic, haunting video. A ghostly woman with long white hair and a flowing dress swings gently on a rope swing beneath a massive, gnarled tree in a foggy, moonlit clearing. The fog thickens and swirls around her, and she slowly fades away, vanishing completely. The empty swing is left swaying rhythmically on its own in the eerie silence.`
// firstImage and lastImage generated separately with Nano Banana
// and available as *genai.Image objects.
var firstImage, lastImage *genai.Image
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
firstImage, // The starting frame is passed as a primary input
&genai.GenerateVideosConfig{
LastFrame: lastImage, // The ending frame is passed as a generation constraint in the config
},
)
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "veo3.1_with_interpolation.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
REST
# Note: This script uses jq to parse the JSON response.
# It assumes first_image_base64 and last_image_base64
# contain base64-encoded image data.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
# The starting frame is passed as a primary input
# The ending frame is passed as a generation constraint in the config
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "A cinematic, haunting video. A ghostly woman with long white hair and a flowing dress swings gently on a rope swing beneath a massive, gnarled tree in a foggy, moonlit clearing. The fog thickens and swirls around her, and she slowly fades away, vanishing completely. The empty swing is left swaying rhythmically on its own in the eerie silence.",
"image": {"inlineData": {"mimeType": "image/png", "data": "'"$first_image_base64"'"}},
"lastFrame": {"inlineData": {"mimeType": "image/png", "data": "'"$last_image_base64"'"}}
}],
}' | jq -r .name)
# Poll the operation status until the video is ready
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Extract the download URI from the final response.
video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')
echo "Downloading video from: ${video_uri}"
# Download the video using the URI and API key and follow redirects.
curl -L -o veo3.1_with_interpolation.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}"
break
fi
# Wait for 10 seconds before checking again.
sleep 10
done
first_image |
last_image |
veo3.1_with_interpolation.mp4 |
|---|
Veo 비디오 확장 (Extending Veo videos)
참고: 이 기능은 Veo 3.1 & Veo 3.1 Fast 모델에서만 사용할 수 있으며 Veo 3.1 Lite에서는 사용할 수 없어요.
Veo 3.1을 사용해 이전에 Veo로 생성한 비디오를 7초씩 최대 20번까지 확장할 수 있어요.
입력 비디오 제한:
- Veo 생성 비디오만 최대 141초까지 확장 가능.
- Gemini API는 Veo 생성 비디오에 대해서만 비디오 확장을 지원해요.
- 비디오는 이전 생성 결과에서 와야 해요(예:
operation.response.generated_videos[0].video). - 비디오는 2일 동안 저장되지만, 확장에 참조되면 2일 저장 타이머가 재설정돼요.
- 지난 이틀 동안 생성되거나 참조된 비디오만 확장할 수 있어요.
- 입력 비디오는 특정 길이, 종횡비, 치수를 가져야 해요.
- 종횡비: 9:16 또는 16:9
- 해상도: 720p
- 비디오 길이: 141초 이하
확장 출력은 사용자 입력 비디오와 생성된 확장 비디오를 결합한 단일 비디오로 최대 148초의 비디오가 돼요.
이 예시는 원본 프롬프트와 함께 보여주는 Veo 생성 비디오를 video 파라미터와 새 프롬프트로 확장해요.
| 프롬프트 | 출력: butterfly_video |
|---|---|
| An origami butterfly flaps its wings and flies out of the french doors into the garden. |
Python
import time
from google import genai
client = genai.Client()
prompt = "Track the butterfly into the garden as it lands on an orange origami flower. A fluffy white puppy runs up and gently pats the flower."
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
video=operation.response.generated_videos[0].video, # This must be a video from a previous generation
prompt=prompt,
config=types.GenerateVideosConfig(
number_of_videos=1,
resolution="720p"
),
)
# Poll the operation status until the video is ready.
while not operation.done:
print("Waiting for video generation to complete...")
time.sleep(10)
operation = client.operations.get(operation)
# Download the video.
video = operation.response.generated_videos[0]
client.files.download(file=video.video, destination="veo3.1_extension.mp4")
print("Generated video saved to veo3.1_extension.mp4")
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const prompt = "Track the butterfly into the garden as it lands on an orange origami flower. A fluffy white puppy runs up and gently pats the flower.";
// butterflyVideo must be a video from a previous generation
// available as an object like { videoBytes: "...", mimeType: "video/mp4" }
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
video: butterflyVideo,
prompt: prompt,
config: {
numberOfVideos: 1,
resolution: "720p",
},
});
// Poll the operation status until the video is ready.
while (!operation.done) {
console.log("Waiting for video generation to complete...")
await new Promise((resolve) => setTimeout(resolve, 10000));
operation = await ai.operations.getVideosOperation({
operation: operation,
});
}
// Download the video.
ai.files.download({
file: operation.response.generatedVideos[0].video,
downloadPath: "veo3.1_extension.mp4",
});
console.log(`Generated video saved to veo3.1_extension.mp4`);
Go
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
prompt := `Track the butterfly into the garden as it lands on an orange origami flower. A fluffy white puppy runs up and gently pats the flower.`
// butterflyVideo must be a video from a previous generation
// available as a *genai.Video object.
var butterflyVideo *genai.Video
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
prompt,
nil, // image
butterflyVideo,
&genai.GenerateVideosConfig{
NumberOfVideos: 1,
Resolution: "720p",
},
)
// Poll the operation status until the video is ready.
for !operation.Done {
log.Println("Waiting for video generation to complete...")
time.Sleep(10 * time.Second)
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Download the video.
video := operation.Response.GeneratedVideos[0]
client.Files.Download(ctx, video.Video, nil)
fname := "veo3.1_extension.mp4"
_ = os.WriteFile(fname, video.Video.VideoBytes, 0644)
log.Printf("Generated video saved to %s\n", fname)
}
REST
# Note: This script uses jq to parse the JSON response.
# It assumes butterfly_video_base64 contains base64-encoded
# video data from a previous generation.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "Track the butterfly into the garden as it lands on an orange origami flower. A fluffy white puppy runs up and gently pats the flower.",
"video": {"inlineData": {"mimeType": "video/mp4", "data": "'"$butterfly_video_base64"'"}}
}],
"parameters": {
"numberOfVideos": 1,
"resolution": "720p"
}
}' | jq -r .name)
# Poll the operation status until the video is ready
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Extract the download URI from the final response.
video_uri=$(echo "${status_response}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')
echo "Downloading video from: ${video_uri}"
# Download the video using the URI and API key and follow redirects.
curl -L -o veo3.1_extension.mp4 -H "x-goog-api-key: $GEMINI_API_KEY" "${video_uri}"
break
fi
# Wait for 10 seconds before checking again.
sleep 10
done
비디오 생성용 효과적인 텍스트 프롬프트 작성에 대한 정보는 Veo prompt guide를 참고하세요.
비동기 작업 처리 (Handling asynchronous operations)
비디오 생성은 계산 집약적인 작업이에요. API에 요청을 보내면 장기 실행 작업이 시작되고 즉시 operation 객체가 반환돼요. 그런 다음 done 상태가 true가 될 때까지 폴링해 비디오가 준비될 때를 알아야 해요.
이 과정의 핵심은 작업 상태를 주기적으로 확인하는 폴링 루프예요.
Python
import time
from google import genai
from google.genai import types
client = genai.Client()
# After starting the job, you get an operation object.
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt="A cinematic shot of a majestic lion in the savannah.",
)
# Alternatively, you can use operation.name to get the operation.
operation = types.GenerateVideosOperation(name=operation.name)
# This loop checks the job status every 10 seconds.
while not operation.done:
time.sleep(10)
# Refresh the operation object to get the latest status.
operation = client.operations.get(operation)
# Once done, the result is in operation.response.
# ... process and download your video ...
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
// After starting the job, you get an operation object.
let operation = await ai.models.generateVideos({
model: "veo-3.1-generate-preview",
prompt: "A cinematic shot of a majestic lion in the savannah.",
});
// Alternatively, you can use operation.name to get the operation.
// operation = types.GenerateVideosOperation(name=operation.name)
// This loop checks the job status every 10 seconds.
while (!operation.done) {
await new Promise((resolve) => setTimeout(resolve, 1000));
// Refresh the operation object to get the latest status.
operation = await ai.operations.getVideosOperation({ operation });
}
// Once done, the result is in operation.response.
// ... process and download your video ...
Go
package main
import (
"context"
"log"
"time"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
// After starting the job, you get an operation object.
operation, _ := client.Models.GenerateVideos(
ctx,
"veo-3.1-generate-preview",
"A cinematic shot of a majestic lion in the savannah.",
nil,
nil,
)
// This loop checks the job status every 10 seconds.
for !operation.Done {
time.Sleep(10 * time.Second)
// Refresh the operation object to get the latest status.
operation, _ = client.Operations.GetVideosOperation(ctx, operation, nil)
}
// Once done, the result is in operation.Response.
// ... process and download your video ...
}
Java
import com.google.genai.Client;
import com.google.genai.types.GenerateVideosOperation;
Client client = new Client();
// After starting the job, you get an operation object.
GenerateVideosOperation operation =
client.models.generateVideos(
"veo-3.1-generate-preview",
"A cinematic shot of a majestic lion in the savannah.",
null,
null);
// Alternatively, you can use operation.name to construct the operation.
operation = GenerateVideosOperation.builder().name(operation.name().get()).build();
// This loop checks the job status every 10 seconds.
while (!operation.done().orElse(false)) {
Thread.sleep(10000);
// Refresh the operation object to get the latest status.
operation = client.operations.getVideosOperation(operation, null);
}
// Once done, the result is in operation.response().
// ... process and download your video ...
REST
# Note: This script uses jq to parse the JSON response.
# GEMINI API Base URL
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
# Send request to generate video and capture the operation name into a variable.
operation_name=$(curl -s "${BASE_URL}/models/veo-3.1-generate-preview:predictLongRunning" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"instances": [{
"prompt": "A cinematic shot of a majestic lion in the savannah."
}
]
}' | jq -r .name)
# This loop checks the job status every 10 seconds.
while true; do
# Get the full JSON status and store it in a variable.
status_response=$(curl -s -H "x-goog-api-key: $GEMINI_API_KEY" "${BASE_URL}/${operation_name}")
# Check the "done" field from the JSON stored in the variable.
is_done=$(echo "${status_response}" | jq .done)
if [ "${is_done}" = "true" ]; then
# Once done, the result is in status_response.
# ... process and download your video ...
echo "Video generation complete."
break
fi
# Wait for 10 seconds before checking again.
echo "Waiting for video generation to complete..."
sleep 10
done
Veo API 파라미터와 사양 (Veo API parameters and specifications)
다음은 비디오 생성 과정을 제어하기 위해 API 요청에 설정할 수 있는 파라미터예요.
인스턴스(Instances):
prompt: 비디오에 대한 텍스트 설명. 오디오 큐를 지원해요. (Veo 3.1 & Veo 3.1 Fast:string/ Veo 3.1 Lite:string/ Veo 3 & Veo 3 Fast:string)image: 애니메이션할 초기 이미지. (Imageobject)lastFrame: 보간 비디오가 전환할 최종 이미지.image파라미터와 함께 사용해야 해요. (Imageobject)referenceImages: 스타일·콘텐츠 참조로 사용할 최대 3개의 이미지. (Veo 3.1 & Veo 3.1 Fast:VideoGenerationReferenceImageobject / Veo 3.1 Lite: n/a / Veo 3 & Veo 3 Fast: n/a)video: 비디오 확장에 사용할 비디오. (Veo 3.1 & Veo 3.1 Fast: 이전 생성의Videoobject / Veo 3.1 Lite: n/a / Veo 3 & Veo 3 Fast: n/a)
파라미터:
aspectRatio: 비디오의 종횡비."16:9"(기본),"9:16".durationSeconds: 생성된 비디오의 길이."4","6","8". 확장, 참조 이미지를 사용하거나 1080p·4k 해상도일 때는 "8"이어야 해요.personGeneration: 사람 생성 제어. (지역 제한은 Limitations 참고)- Text-to-video & Extension:
"allow_all"만 - Image-to-video, Interpolation, & Reference images:
"allow_adult"만
- Text-to-video & Extension:
- (기타 파라미터는 원문의 파라미터 표를 참고하세요.)
Veo 프롬프트 가이드 (Veo prompt guide)
프롬프트 작성 기초 (Prompt writing basics)
좋은 프롬프트는 다음 요소를 결합하는 경우가 많아요.
- Subject: 무엇이 초점인지(예: 고양이, 로봇, 좋아하는 캐릭터).
- Context: 피사체가 있는 배경이나 환경(예: 아늑한 책방, 빽빽한 도시 거리, 야간 드라이브스루).
- Action: 피사체가 하는 일(예: 걷기, 달리기, 고개 돌리기).
- Style: sci-fi, horror film, film noir 같은 특정 영화 스타일 키워드나 cartoon 같은 애니메이션 스타일로 창의적 방향을 지정.
- Camera positioning and motion: [선택] aerial view, eye-level, top-down shot, dolly shot, worms eye 같은 용어로 카메라 위치·움직임 제어.
- Composition: [선택] wide shot, close-up, single-shot, two-shot 같은 샷 구성.
- Focus and lens effects: [선택] shallow focus, deep focus, soft focus, macro lens, wide-angle lens 같은 용어로 특정 시각 효과 구현.
- Ambiance: [선택] blue tones, night, warm tones 같은 색·빛이 장면에 기여하는 방식.
프롬프트 작성에 대한 추가 팁
- 묘사적 언어 사용: 형용사와 부사를 사용해 Veo에 선명한 그림을 그려 주세요.
- 얼굴 세부 묘사 강화: 프롬프트에 portrait 같은 단어를 사용해 얼굴 세부를 사진의 초점으로 지정하세요.
더 포괄적인 프롬프팅 전략은 Introduction to prompt design을 참고하세요.
오디오 프롬프팅 (Prompting for audio)
Veo에 음향 효과, 주변 소음, 대화에 대한 큐를 제공할 수 있어요. 모델이 이 큐들의 뉘앙스를 포착해 동기화된 사운드트랙을 생성해요.
- 대화(Dialogue): 특정 음성에는 인용 부호를 사용하세요. (예: "This must be the key," he murmured.)
- 음향 효과(SFX): 소리를 명시적으로 설명하세요. (예: tires screeching loudly, engine roaring.)
- 주변 소음(Ambient Noise): 환경의 사운드스케이프를 설명하세요. (예: A faint, eerie hum resonates in the background.)
이 비디오들은 점점 더 많은 세부 묘사로 Veo 3의 오디오 생성을 프롬프팅하는 것을 보여줘요.
| 프롬프트 | 생성된 출력 |
|---|---|
| 더 많은 세부 묘사(대화와 주변 분위기) A wide shot of a misty Pacific Northwest forest. Two exhausted hikers, a man and a woman, push through ferns when the man stops abruptly, staring at a tree. Close-up: Fresh, deep claw marks are gouged into the tree's bark. Man: (Hand on his hunting knife) "That's no ordinary bear." Woman: (Voice tight with fear, scanning the woods) "Then what is it?" A rough bark, snapping twigs, footsteps on the damp earth. A lone bird chirps. | |
| 낮은 세부 묘사(대화) Paper Cut-Out Animation. New Librarian: "Where do you keep the forbidden books?" Old Curator: "We don't. They keep us." |
이 프롬프트들을 직접 시도해 오디오를 들어 보세요! Try Veo
참조 이미지로 프롬프팅 (Prompting with reference images)
Veo의 이미지-투-비디오 기능을 사용해 생성된 비디오를 안내하는 입력으로 하나 이상의 이미지를 사용할 수 있어요. Veo는 입력 이미지를 초기 프레임으로 사용해요. 비디오의 첫 장면으로 상상하는 것에 가장 가까운 이미지를 선택해 일상 객체를 애니메이션하고, 그림과 드로잉에 생명을 불어넣고, 자연 장면에 움직임과 소리를 더하세요.
| 프롬프트 | 생성된 출력 |
|---|---|
| 입력 이미지(Nano Banana로 생성) A hyperrealistic macro photo of tiny, miniature surfers riding ocean waves inside a rustic stone bathroom sink. A vintage brass faucet is running, creating the perpetual surf. Surreal, whimsical, bright natural lighting. | 출력 비디오(Veo 3.1로 생성) A surreal, cinematic macro video. Tiny surfers ride perpetual, rolling waves inside a stone bathroom sink. A running vintage brass faucet generates the endless surf. The camera slowly pans across the whimsical, sunlit scene as the miniature figures expertly carve the turquoise water. |
Veo 3.1은 참조 이미지나 재료를 참조해 생성된 비디오의 콘텐츠를 안내할 수 있어요. 단일 인물, 캐릭터, 제품의 최대 3개 자산 이미지를 제공하세요. Veo가 출력 비디오에서 피사체의 외형을 보존해요.
| 프롬프트 | 생성된 출력 |
|---|---|
| 참조 이미지(Nano Banana로 생성) A deep sea angler fish lurks in the deep dark water, teeth bared and bait glowing. | |
| 참조 이미지(Nano Banana로 생성) A pink child's princess costume complete with a wand and tiara, on a plain product background. | 출력 비디오(Veo 3.1로 생성) Create a silly cartoon version of the fish wearing the costume, swimming and waving the wand around. |
Veo 3.1을 사용하면 비디오의 첫·마지막 프레임을 지정해 비디오를 생성할 수도 있어요.
| 프롬프트 | 생성된 출력 |
|---|---|
| 첫 이미지(Nano Banana로 생성) A high quality photorealistic front image of a ginger cat driving a red convertible racing car on the French riviera coast. | |
| 마지막 이미지(Nano Banana로 생성) Show what happens when the car takes off from a cliff. | 출력 비디오(Veo 3.1로 생성) Optional |
이 기능은 시작·끝 프레임을 정의해 샷 구성을 정밀하게 제어할 수 있게 해줘요. 이전 비디오 생성의 프레임이나 이미지를 업로드해 장면이 상상한 대로 시작·끝나도록 보장하세요.
확장 프롬프팅 (Prompting for extension)
Veo 3.1( Veo 3.1 Lite에서는 사용 불가)로 Veo 생성 비디오를 확장하려면 선택적 텍스트 프롬프트와 함께 비디오를 입력으로 사용하세요. Extend는 비디오의 마지막 1초 또는 24프레임을 확정하고 동작을 계속해요.
음성이 비디오의 마지막 1초에 없다면 효과적으로 확장할 수 없다는 점에 유의하세요.
| 프롬프트 | 생성된 출력 |
|---|---|
| 입력 비디오(Veo 3.1로 생성) The paraglider takes off from the top of the mountain and starts gliding down the mountains overlooking the flower covered valleys below. | |
| 출력 비디오(Veo 3.1로 생성) Extend this video with the paraglider slowly descending. |
예시 프롬프트와 출력 (Example prompts and output)
이 섹션은 각 비디오의 결과를 높이는 데 묘사적 세부 사항이 어떻게 도움이 되는지 강조하는 여러 프롬프트를 제시해요.
고드름 (Icicles)
이 비디오는 프롬프트 작성 기초의 요소를 프롬프트에 어떻게 사용하는지 보여줘요.
| 프롬프트 | 생성된 출력 |
|---|---|
| Close up shot (composition) of melting icicles (subject) on a frozen rock wall (context) with cool blue tones (ambiance), zoomed in (camera motion) maintaining close-up detail of water drips (action). | [이미지: https://storage.googleapis.com/generativeai-downloads/images/Icicles.gif] |
전화하는 남자 (Man on the phone)
이 비디오들은 점점 더 구체적인 세부 사항으로 프롬프트를 수정해 Veo가 출력을 원하는 대로 정제하게 하는 방법을 보여줘요.
| 프롬프트 | 생성된 출력 |
|---|---|
| 낮은 세부 묘사 The camera dollies to show a close up of a desperate man in a green trench coat. He's making a call on a rotary-style wall phone with a green neon light. It looks like a movie scene. | |
| 더 많은 세부 묘사 A close-up cinematic shot follows a desperate man in a weathered green trench coat as he dials a rotary phone mounted on a gritty brick wall, bathed in the eerie glow of a green neon sign. The camera dollies in, revealing the tension in his jaw and the desperation etched on his face as he struggles to make the call. The shallow depth of field focuses on his furrowed brow and the black rotary phone, blurring the background into a sea of neon colors and indistinct shadows, creating a sense of urgency and isolation. |
눈표범 (Snow leopard)
| 프롬프트 | 생성된 출력 |
|---|---|
| 간단한 프롬프트: A cute creature with snow leopard-like fur is walking in winter forest, 3D cartoon style render. | |
| 상세한 프롬프트: Create a short 3D animated scene in a joyful cartoon style. A cute creature with snow leopard-like fur, large expressive eyes, and a friendly, rounded form happily prances through a whimsical winter forest. The scene should feature rounded, snow-covered trees, gentle falling snowflakes, and warm sunlight filtering through the branches. The creature's bouncy movements and wide smile should convey pure delight. Aim for an upbeat, heartwarming tone with bright, cheerful colors and playful animation. |
작성 요소별 예시 (Examples by writing elements)
이 예시들은 각 기본 요소별로 프롬프트를 정제하는 방법을 보여줘요.
피사체와 컨텍스트 (Subject and context)
주요 초점(피사체)과 배경 또는 환경(컨텍스트)을 지정하세요.
| 프롬프트 | 생성된 출력 |
|---|---|
| An architectural rendering of a white concrete apartment building with flowing organic shapes, seamlessly blending with lush greenery and futuristic elements | [이미지: https://storage.googleapis.com/generativeai-downloads/images/architecture.gif] |
| A satellite floating through outer space with the moon and some stars in the background. | [이미지: https://storage.googleapis.com/generativeai-downloads/images/satellite.gif] |
액션 (Action)
피사체가 하는 일을 지정하세요(예: 걷기, 달리기, 고개 돌리기).
| 프롬프트 | 생성된 출력 |
|---|---|
| A wide shot of a woman walking along the beach, looking content and relaxed towards the horizon at sunset. | [이미지: https://storage.googleapis.com/generativeai-downloads/images/sunset.gif] |
스타일 (Style)
특정 미학으로 생성을 유도하는 키워드를 추가하세요(예: surreal, vintage, futuristic, film noir).
| 프롬프트 | 생성된 출력 |
|---|---|
| Film noir style, man and woman walk on the street, mystery, cinematic, black and white. | [이미지: https://storage.googleapis.com/generativeai-downloads/images/noir.gif] |
카메라 움직임과 구성 (Camera motion and composition)
카메라가 어떻게 움직이는지(POV shot, aerial view, tracking drone view)와 샷이 어떻게 구성되는지(wide shot, close-up, low angle) 지정하세요.
| 프롬프트 | 생성된 출력 |
|---|---|
| A POV shot from a vintage car driving in the rain, Canada at night, cinematic. | [이미지: https://storage.googleapis.com/generativeai-downloads/images/car-pov.gif] |
| Extreme close-up of an eye with city reflected in it. | [이미지: https://storage.googleapis.com/generativeai-downloads/images/eye.gif] |
앰비언스 (Ambiance)
색 팔레트와 조명이 분위기에 영향을 줘요. "muted orange warm tones", "natural light", "sunrise", "cool blue tones" 같은 용어를 사용해 보세요.
| 프롬프트 | 생성된 출력 |
|---|---|
| A close-up of a girl holding adorable golden retriever puppy in the park, sunlight. | [이미지: /static/gemini-api/docs/video/images/ambiance_puppy.gif] |
| Cinematic close-up shot of a sad woman riding a bus in the rain, cool blue tones, sad mood. | [이미지: /static/gemini-api/docs/video/images/ambiance_sad.gif] |
종횡비 (Aspect ratios)
Veo는 비디오의 종횡비를 지정할 수 있게 해줘요.
| 프롬프트 | 생성된 출력 |
|---|---|
| 와이드스크린(16:9) Create a video with a tracking drone view of a man driving a red convertible car in Palm Springs, 1970s, warm sunlight, long shadows. | |
| 세로(9:16) Create a video highlighting the smooth motion of a majestic Hawaiian waterfall within a lush rainforest. Focus on realistic water flow, detailed foliage, and natural lighting to convey tranquility. Capture the rushing water, misty atmosphere, and dappled sunlight filtering through the dense canopy. Use smooth, cinematic camera movements to showcase the waterfall and its surroundings. Aim for a peaceful, realistic tone, transporting the viewer to the serene beauty of the Hawaiian rainforest. |
모델 버전 (Model versions)
Veo 모델별 사용 세부 사항은 Pricing 페이지와 Rate limits를 확인하세요.
Veo 3.1 Preview
| 속성 | 설명 |
|---|---|
| 모델 코드 | Gemini API veo-3.1-generate-preview |
| 지원 데이터 유형 | 입력: Text, Image / 출력: Video with audio |
| 한도 | 텍스트 입력: 1,024 토큰 / 출력 비디오: 1 |
| 최신 업데이트 | 2026년 1월 |
Veo 3.1 Fast Preview
| 속성 | 설명 |
|---|---|
| 모델 코드 | Gemini API veo-3.1-fast-generate-preview |
| 지원 데이터 유형 | 입력: Text, Image / 출력: Video with audio |
| 한도 | 텍스트 입력: 1,024 토큰 / 출력 비디오: 1 |
| 최신 업데이트 | 2026년 1월 |
Veo 3.1 Lite Preview
| 속성 | 설명 |
|---|---|
| 모델 코드 | Gemini API veo-3.1-lite-generate-preview |
| 지원 데이터 유형 | 입력: Text, image / 출력: Video with audio |
| 한도 | 텍스트 입력: 1,024 토큰 / 출력 비디오: 1 |
| 최신 업데이트 | 2026년 3월 |
Veo 3 (Deprecated)
| 속성 | 설명 |
|---|---|
| 모델 코드 | Gemini API veo-3.0-generate-001 |
| 지원 데이터 유형 | 입력: Text, Image / 출력: Video with audio |
| 한도 | 텍스트 입력: 1,024 토큰 / 출력 비디오: 1 |
| 최신 업데이트 | 2025년 7월 |
Veo 3 Fast (Deprecated)
| 속성 | 설명 |
|---|---|
| 모델 코드 | Gemini API veo-3.0-fast-generate-001 |
| 지원 데이터 유형 | 입력: Text, Image / 출력: Video with audio |
| 한도 | 텍스트 입력: 1,024 토큰 / 출력 비디오: 1 |
| 최신 업데이트 | 2025년 7월 |
Veo Fast 버전은 높은 품질을 유지하면서 속도와 비즈니스 사용 사례에 최적화해 사운드가 있는 비디오를 만들 수 있게 해줘요. 프로그래밍 방식으로 광고를 생성하는 백엔드 서비스, 창의적 콘셉트의 빠른 A/B 테스트 도구, 또는 소셜 미디어 콘텐츠를 빠르게 제작해야 하는 앱에 이상적이에요.
다음 단계 (What's next)
- Veo Quickstart Colab과 Veo 3.1 applet에서 Veo 3.1 API를 실험해 보세요.
- Introduction to prompt design으로 더 나은 프롬프트 작성법을 배워 보세요.
더 알아보기 (Learn more)
- Pricing 페이지에서 Veo 모델 가격을 확인하세요.
- Image generation 가이드로 Nano Banana로 참조 이미지를 만들어 보세요.
- Video understanding 가이드로 비디오 이해를 배워 보세요.