模型能力
视频生成
使用 Grok 视频模型根据文本提示生成视频。API 支持配置时长、宽高比和分辨率,SDK 会自动处理异步轮询。在 grok-imagine-video-1.5 上,文本到视频支持原生 1080p。
快速开始
通过一次 API 调用生成视频:
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
response = client.video.generate(
prompt="A glowing crystal-powered rocket launching from the red dunes of Mars, ancient alien ruins lighting up in the background as it soars into a sky full of unfamiliar constellations",
model="grok-imagine-video-1.5",
duration=10,
aspect_ratio="16:9",
resolution="720p",
)
print(response.url)import os
import time
import requests
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {os.environ['XAI_API_KEY']}",
}
response = requests.post(
"https://api.x.ai/v1/videos/generations",
headers=headers,
json={
"model": "grok-imagine-video-1.5",
"prompt": "A glowing crystal-powered rocket launching from the red dunes of Mars, ancient alien ruins lighting up in the background as it soars into a sky full of unfamiliar constellations",
"duration": 10,
"aspect_ratio": "16:9",
"resolution": "720p",
},
)
request_id = response.json()["request_id"]
# Poll until the video is ready
while True:
result = requests.get(
f"https://api.x.ai/v1/videos/{request_id}",
headers={"Authorization": headers["Authorization"]},
)
data = result.json()
if data["status"] == "done":
print(data["video"]["url"])
break
elif data["status"] == "expired":
print("Request expired")
break
time.sleep(5)import { xai } from "@ai-sdk/xai";
import { experimental_generateVideo as generateVideo } from "ai";
const result = await generateVideo({
model: xai.video("grok-imagine-video-1.5"),
prompt: "A glowing crystal-powered rocket launching from the red dunes of Mars, ancient alien ruins lighting up in the background as it soars into a sky full of unfamiliar constellations",
duration: 10,
aspectRatio: "16:9",
providerOptions: {
xai: { resolution: "720p" },
},
});
const videoUrl = result.providerMetadata?.xai?.videoUrl;
console.log(videoUrl);# Start the video generation request
REQUEST_ID=$(curl -s -X POST https://api.x.ai/v1/videos/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $XAI_API_KEY" \
-d '{
"model": "grok-imagine-video-1.5",
"prompt": "A glowing crystal-powered rocket launching from the red dunes of Mars, ancient alien ruins lighting up in the background as it soars into a sky full of unfamiliar constellations",
"duration": 10,
"aspect_ratio": "16:9",
"resolution": "720p"
}' | jq -r '.request_id')
# Poll until the video is ready
while true; do
RESULT=$(curl -s https://api.x.ai/v1/videos/$REQUEST_ID \
-H "Authorization: Bearer $XAI_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.status')
if [ "$STATUS" = "done" ]; then
echo "$RESULT" | jq -r '.video.url'
break
elif [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ]; then
echo "Request $STATUS"; echo "$RESULT" | jq .
break
fi
sleep 5
done视频生成是一个异步过程,通常需要几分钟才能完成。具体时间取决于:
- 提示复杂度 — 更详细的场景需要额外的处理
- 时长 — 更长的视频需要更多生成时间
- 分辨率 — 更高的分辨率(1080p 对比 480p)会增加处理时间
- 视频编辑 — 与图像转视频或文本转视频相比,编辑现有视频会增加额外开销
视频工作流
使用与您想要创建的视频输出类型相匹配的页面:
工作原理
底层来看,视频生成是一个两步过程:
- 开始 — 提交生成请求并获取一个
request_id - 轮询 — 使用
request_id重复检查状态,直到视频准备就绪
xAI SDK 的 generate() 和 extend() 方法完全抽象了这一过程;它们提交您的请求、轮询结果并返回完成后的视频响应。您无需管理请求 ID 或实现轮询逻辑。对于长时间运行的生成,您可以自定义轮询行为,使用超时和间隔参数,或手动处理轮询以完全控制生成生命周期。
REST API 用户必须手动实现这个两步流程:
步骤 1:开始生成请求
curl -X POST https://api.x.ai/v1/videos/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $XAI_API_KEY" \
-d '{
"model": "grok-imagine-video-1.5",
"prompt": "A glowing crystal-powered rocket launching from Mars"
}'响应:
{"request_id": "d97415a1-5796-b7ec-379f-4e6819e08fdf"}步骤 2:轮询结果
使用 request_id 检查状态。每隔几秒轮询一次,直到视频准备就绪:
curl -X GET "https://api.x.ai/v1/videos/{request_id}" \
-H "Authorization: Bearer $XAI_API_KEY"响应包含一个 status 字段,其值如下之一:
| 状态 | 描述 |
|---|---|
pending | 视频仍在生成中 |
done | 视频已准备就绪 |
expired | 请求已过期 |
failed | 视频生成失败 |
完成时的响应:
{
"status": "done",
"video": {
"url": "https://vidgen.x.ai/.../video.mp4",
"duration": 8,
"respect_moderation": true
},
"model": "grok-imagine-video-1.5"
}视频作为临时 URL 返回。当您需要时直接访问 xAI 托管的 URL,或者如果需要保留副本,请及时下载/处理它。
配置
视频生成 API 让您可以控制生成视频的输出格式。您可以指定时长、宽高比、分辨率以及(在参考转视频中)预设语音,以匹配您的特定用例。
时长
使用 duration 参数控制视频长度。允许的范围是 1-15 秒。
视频编辑不支持自定义 duration。编辑后的视频保留原始时长,上限为 8.7 秒。
宽高比
| 比例 | 用途 |
|---|---|
1:1 | 社交媒体、缩略图 |
16:9 / 9:16 | 宽屏、移动设备、故事(默认:16:9) |
4:3 / 3:4 | 演示文稿、肖像 |
3:2 / 2:3 | 摄影 |
对于图像转视频生成,输出默认为输入图像的宽高比。如果您指定 aspect_ratio 参数,它将覆盖此设置并将图像拉伸到所需的宽高比。
视频编辑不支持自定义 aspect_ratio — 输出与输入视频的宽高比一致。
分辨率
| 分辨率 | 描述 |
|---|---|
1080p | 全高清质量 |
720p | 高清质量 |
480p | 标准清晰度,更快的处理速度(默认) |
注意: 1080p 在 grok-imagine-video-1.5 上支持文本转视频和图像转视频。参考转视频上限为 720p。
视频编辑不支持自定义分辨率。输出分辨率与输入视频的分辨率一致,上限为 720p(例如,1080p 输入将缩小到 720p)。
音频
WARNING
参考音频目前仅在美国对可信合作伙伴可用。。
在 grok-imagine-video-1.5 上,参考转视频 可以通过 reference_audios 携带语音。语音来自内置列表,通过 voice_id 命名;您无法上传自己的音频片段:
| 属性 | 描述 |
|---|---|
| Source | 预设的 voice_id(例如 {"voice_id": "eve"}),与文本转语音来自同一列表。标识符不区分大小写 |
| Limit | 每个请求最多 3 个语音 |
| Prompt | 按索引引用语音:<AUDIO_0>、<AUDIO_1>、<AUDIO_2> |
生成的视频默认包含音轨。
示例
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
response = client.video.generate(
prompt="Timelapse of a flower blooming in a sunlit garden",
model="grok-imagine-video-1.5",
duration=10,
aspect_ratio="16:9",
resolution="720p",
)
print(f"Video URL: {response.url}")
print(f"Duration: {response.duration}s")import os
import time
import requests
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {os.environ['XAI_API_KEY']}",
}
response = requests.post(
"https://api.x.ai/v1/videos/generations",
headers=headers,
json={
"model": "grok-imagine-video-1.5",
"prompt": "Timelapse of a flower blooming in a sunlit garden",
"duration": 10,
"aspect_ratio": "16:9",
"resolution": "720p",
},
)
request_id = response.json()["request_id"]
while True:
result = requests.get(
f"https://api.x.ai/v1/videos/{request_id}",
headers={"Authorization": headers["Authorization"]},
)
data = result.json()
if data["status"] == "done":
print(f"Video URL: {data['video']['url']}")
print(f"Duration: {data['video']['duration']}s")
break
elif data["status"] == "expired":
print("Request expired")
break
time.sleep(5)import { xai } from "@ai-sdk/xai";
import { experimental_generateVideo as generateVideo } from "ai";
const result = await generateVideo({
model: xai.video("grok-imagine-video-1.5"),
prompt: "Timelapse of a flower blooming in a sunlit garden",
duration: 10,
aspectRatio: "16:9",
providerOptions: {
xai: { resolution: "720p" },
},
});
const videoUrl = result.providerMetadata?.xai?.videoUrl;
console.log(videoUrl);# Start the video generation request
REQUEST_ID=$(curl -s -X POST https://api.x.ai/v1/videos/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $XAI_API_KEY" \
-d '{
"model": "grok-imagine-video-1.5",
"prompt": "Timelapse of a flower blooming in a sunlit garden",
"duration": 10,
"aspect_ratio": "16:9",
"resolution": "720p"
}' | jq -r '.request_id')
# Poll until the video is ready
while true; do
RESULT=$(curl -s https://api.x.ai/v1/videos/$REQUEST_ID \
-H "Authorization: Bearer $XAI_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.status')
if [ "$STATUS" = "done" ]; then
echo "$RESULT" | jq -r '.video.url'
break
elif [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ]; then
echo "Request $STATUS"; echo "$RESULT" | jq .
break
fi
sleep 5
done请求模式
视频生成端点支持多种模式,由设置的字段决定。每个请求只能激活一种模式:
| 模式 | REST API 字段 | AI SDK 形状 | 描述 |
|---|---|---|---|
| 文本转视频 | 仅 prompt | prompt: "..." | 仅从文本提示生成视频。 |
| 图像转视频 | prompt + image | prompt: { image, text } | 使用提供的图像作为起始帧生成视频。 |
| 参考转视频 | prompt + reference_images 或 reference_audios | prompt: "..." + providerOptions.xai.{ mode: "reference-to-video", referenceImageUrls } | 由参考图像和/或在 grok-imagine-video-1.5 上的预设语音引导生成视频。 |
| 编辑视频 | /v1/videos/edits + video | prompt: "..." + providerOptions.xai.{ mode: "edit-video", videoUrl } | 根据提示修改现有视频。 |
| 扩展视频 | /v1/videos/extensions + video | prompt: "..." + providerOptions.xai.{ mode: "extend-video", videoUrl } | 从现有视频的最后一帧扩展。 |
以下组合不被允许,将返回 400 Bad Request 错误:
image+reference_images— 使用其中一个- 在 AI SDK 中混合
mode值 — 每个请求只支持"edit-video"、"extend-video"或"reference-to-video"中的一个
当您省略 mode 时,AI SDK 使用标准生成。
自定义轮询行为
使用 SDK 的 generate() 或 extend() 方法时,您可以控制等待时间和检查结果的频率:
| Python SDK | AI SDK (providerOptions.xai) | 描述 | 默认值 |
|---|---|---|---|
timeout | pollTimeoutMs | 等待视频完成的最长时间 | 10 分钟 |
interval | pollIntervalMs | 状态检查之间的时间间隔 | 100 毫秒 |
import os
from datetime import timedelta
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
response = client.video.generate(
prompt="Epic cinematic drone shot flying through mountain peaks",
model="grok-imagine-video-1.5",
duration=15,
timeout=timedelta(minutes=15), # Wait up to 15 minutes
interval=timedelta(seconds=5), # Check every 5 seconds
)
print(response.url)import { xai } from "@ai-sdk/xai";
import { experimental_generateVideo as generateVideo } from "ai";
const result = await generateVideo({
model: xai.video("grok-imagine-video-1.5"),
prompt: "Epic cinematic drone shot flying through mountain peaks",
duration: 15,
providerOptions: {
xai: {
pollTimeoutMs: 15 * 60 * 1000, // Wait up to 15 minutes
pollIntervalMs: 5 * 1000, // Check every 5 seconds
},
},
});
const videoUrl = result.providerMetadata?.xai?.videoUrl;
console.log(videoUrl);如果视频在超时期间内未准备就绪,Python SDK 会引发 TimeoutError,AI SDK 通过其 AbortSignal 中止。为了更精细的控制,请使用手动轮询方法;Python SDK 提供 start() 和 get() 方法,而 AI SDK 支持自定义 abortSignal 以实现取消。
手动处理轮询
为了对生成生命周期进行细粒度控制,使用 start() 或 extend_start() 分别启动生成/扩展请求,使用 get() 检查状态。
get() 方法返回一个包含 status 字段的响应。从 SDK 导入状态枚举:
import os
import time
import xai_sdk
from xai_sdk.proto import deferred_pb2
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
# Start the generation request
start_response = client.video.start(
prompt="A cat lounging in a sunbeam, tail gently swishing",
model="grok-imagine-video-1.5",
duration=5,
)
print(f"Request ID: {start_response.request_id}")
# Poll for results
while True:
result = client.video.get(start_response.request_id)
if result.status == deferred_pb2.DeferredStatus.DONE:
print(f"Video URL: {result.response.video.url}")
break
elif result.status == deferred_pb2.DeferredStatus.EXPIRED:
print("Request expired")
break
elif result.status == deferred_pb2.DeferredStatus.FAILED:
print("Video generation failed")
break
elif result.status == deferred_pb2.DeferredStatus.PENDING:
print("Still processing...")
time.sleep(5)import os
import time
import requests
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {os.environ['XAI_API_KEY']}",
}
# Step 1: Start generation
response = requests.post(
"https://api.x.ai/v1/videos/generations",
headers=headers,
json={
"model": "grok-imagine-video-1.5",
"prompt": "A cat lounging in a sunbeam, tail gently swishing",
"duration": 5,
},
)
request_id = response.json()["request_id"]
print(f"Request ID: {request_id}")
# Step 2: Poll for results
while True:
result = requests.get(
f"https://api.x.ai/v1/videos/{request_id}",
headers={"Authorization": headers["Authorization"]},
)
data = result.json()
if data["status"] == "done":
print(f"Video URL: {data['video']['url']}")
break
elif data["status"] == "expired":
print("Request expired")
break
elif data["status"] == "failed":
print("Video generation failed")
break
else:
print("Still processing...")
time.sleep(5)// Step 1: Start generation
const response = await fetch("https://api.x.ai/v1/videos/generations", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${process.env.XAI_API_KEY}`,
},
body: JSON.stringify({
model: "grok-imagine-video-1.5",
prompt: "A cat lounging in a sunbeam, tail gently swishing",
duration: 5,
}),
});
const { request_id } = await response.json();
console.log(`Request ID: ${request_id}`);
// Step 2: Poll for results
while (true) {
const result = await fetch(`https://api.x.ai/v1/videos/${request_id}`, {
headers: { "Authorization": `Bearer ${process.env.XAI_API_KEY}` },
});
const data = await result.json();
if (data.status === "done") {
console.log(`Video URL: ${data.video.url}`);
break;
} else if (data.status === "expired") {
console.log("Request expired");
break;
} else if (data.status === "failed") {
console.log("Video generation failed");
break;
} else {
console.log("Still processing...");
await new Promise(resolve => setTimeout(resolve, 5000));
}
}# Step 1: Start generation
REQUEST_ID=$(curl -s -X POST https://api.x.ai/v1/videos/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $XAI_API_KEY" \
-d '{
"model": "grok-imagine-video-1.5",
"prompt": "A cat lounging in a sunbeam, tail gently swishing",
"duration": 5
}' | jq -r '.request_id')
echo "Request ID: $REQUEST_ID"
# Step 2: Poll for results
while true; do
RESULT=$(curl -s https://api.x.ai/v1/videos/$REQUEST_ID \
-H "Authorization: Bearer $XAI_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.status')
if [ "$STATUS" = "done" ]; then
echo "$RESULT" | jq -r '.video.url'
break
elif [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ]; then
echo "Request $STATUS"; echo "$RESULT" | jq .
break
fi
echo "Still processing..."
sleep 5
done可用的状态值如下:
| Proto 值 | 描述 |
|---|---|
deferred_pb2.DeferredStatus.PENDING | 视频仍在生成中 |
deferred_pb2.DeferredStatus.DONE | 视频已准备就绪 |
deferred_pb2.DeferredStatus.EXPIRED | 请求已过期 |
deferred_pb2.DeferredStatus.FAILED | 视频生成失败 |
错误处理
使用 SDK 的 generate() 或 extend() 方法时,视频生成失败会引发 VideoGenerationError 异常。此异常包含描述问题的 code 和 message。从 xai_sdk.video 导入它:
import os
import xai_sdk
from xai_sdk.video import VideoGenerationError
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
try:
response = client.video.generate(
prompt="A cat lounging in a sunbeam, tail gently swishing",
model="grok-imagine-video-1.5",
duration=5,
)
print(response.url)
except VideoGenerationError as e:
print(f"Error code: {e.code}")
print(f"Error message: {e.message}")VideoGenerationError 异常具有以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
code | str | 标识失败原因的错误代码 |
message | str | 描述失败的可读消息 |
手动轮询时,失败的生成返回 status: "failed" 和一个 error 对象:
{
"status": "failed",
"error": {
"code": "invalid_argument",
"message": "Prompt cannot be empty. Please provide a prompt."
}
}可能的 error.code 值如下:
| 代码 | 含义 | 如何处理 |
|---|---|---|
invalid_argument | 请求输入无效,例如不支持的时长、无效的图像或视频输入、过长的提示、冲突的请求模式或被内容审核阻止的内容。 | 修复请求参数或输入媒体,然后提交新请求。 |
permission_denied | API 密钥或团队没有请求的视频操作权限。 | 确认 API 密钥属于正确的团队,并且该团队对请求的功能有访问权限。 |
failed_precondition | 请求的操作对所选模型或设置不可用,例如视频编辑、视频扩展或模型无法处理的请求分辨率。 | 更改模型、模式、分辨率或其他请求设置。 |
service_unavailable | 视频生成暂时过载。 | 稍后重试请求。 |
internal_error | 服务因内部故障无法完成生成。 | 重试请求。如果错误持续存在,请使用 request_id 联系 xAI 支持。 |
身份验证错误、缺失的模型和速率限制在创建视频作业之前作为标准 API 错误同步返回,因此它们不会出现在失败视频结果的 error.code 字段中。
您可以将其与 TimeoutError 处理结合使用,以实现全面的错误覆盖:
import os
import xai_sdk
from xai_sdk.video import VideoGenerationError
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
try:
response = client.video.generate(
prompt="A cat lounging in a sunbeam, tail gently swishing",
model="grok-imagine-video-1.5",
duration=5,
)
print(response.url)
except VideoGenerationError as e:
print(f"Generation failed [{e.code}]: {e.message}")
except TimeoutError:
print("Generation timed out — try increasing the timeout or simplifying the prompt")响应详情
SDK 响应包含生成的视频和提供商特定的元数据。在 AI SDK 中,xAI 托管的输出 URL 在 providerMetadata.xai.videoUrl 中可用。
if response.respect_moderation:
print(response.url)
else:
print("Video filtered by moderation")
print(f"Duration: {response.duration} seconds")
print(f"Model: {response.model}")const result = await generateVideo({
model: xai.video("grok-imagine-video-1.5"),
prompt: "A futuristic city skyline at dusk",
duration: 5,
});
console.log(result.providerMetadata?.xai?.videoUrl);并发请求
当您需要生成多个视频时,并发运行请求。这对于比较提示或创建多个变体特别有用。
import os
import asyncio
import xai_sdk
async def generate_concurrently():
client = xai_sdk.AsyncClient(api_key=os.getenv("XAI_API_KEY"))
prompts = [
"A cat sitting on a sunlit windowsill, tail gently swishing.",
"A dog sprinting through a field of tall grass at golden hour.",
"A hummingbird hovering near a red flower in slow motion.",
]
tasks = [
client.video.generate(
prompt=prompt,
model="grok-imagine-video-1.5",
duration=5,
)
for prompt in prompts
]
results = await asyncio.gather(*tasks)
for prompt, result in zip(prompts, results):
print(f"{prompt}: {result.url}")
asyncio.run(generate_concurrently())