contents[].parts[] 的请求结构,将请求转发到可用的 Gemini 上游,并按返回的 usageMetadata 记录用量。
视频理解推荐使用 Gemini 原生接口。OpenAI-compatible
chat/completions 的 video_url 形态可能返回 200,但不保证视频内容会被模型真实读取。接口地址
非流式:POST https://{your-domain}/v1beta/models/{model}:generateContent
POST https://{your-domain}/v1beta/models/{model}:streamGenerateContent?alt=sse
gemini-3.5-flash
鉴权
Gemini 原生接口支持 Google 风格 API Key 请求头:x-goog-api-key: YOUR_API_KEY
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
x-goog-api-key,这样与 Gemini 官方 SDK / REST 示例更一致。
请求结构
contents 是对话内容数组。每条消息包含:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
role | string | 否 | 通常传 user。 |
parts | array | 是 | 文本、视频、图片等内容片段。 |
parts[].text | string | 否 | 给模型的文字指令。 |
parts[].fileData.mimeType | string | 视频必填 | 视频 MIME 类型,例如 video/mp4。 |
parts[].fileData.fileUri | string | 视频必填 | 公网可访问的视频 URL。 |
generationConfig.maxOutputTokens | integer | 否 | 最大输出 token 数。 |
fileUri 必须是模型上游可匿名访问的公网直链。不要传本地文件路径、内网地址、需要登录 Cookie 的链接、过期临时链接或 HTML 播放页地址。非流式视频分析
curl
curl --request POST \
--url 'https://{your-domain}/v1beta/models/gemini-3.5-flash:generateContent' \
--header 'x-goog-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "请分析这个视频的画面内容,用中文输出三句话,说明主体、动作/场景和氛围。"
},
{
"fileData": {
"mimeType": "video/mp4",
"fileUri": "https://vidgen.x.ai/xai-vidgen-bucket/xai-video-9f800388-9bca-9170-bcad-efcfe5bb5c91.mp4"
}
}
]
}
],
"generationConfig": {
"maxOutputTokens": 512
}
}'
请求体
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "请分析这个视频的画面内容,用中文输出三句话,说明主体、动作/场景和氛围。"
},
{
"fileData": {
"mimeType": "video/mp4",
"fileUri": "https://vidgen.x.ai/xai-vidgen-bucket/xai-video-9f800388-9bca-9170-bcad-efcfe5bb5c91.mp4"
}
}
]
}
],
"generationConfig": {
"maxOutputTokens": 512
}
}
响应示例
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"text": "以下是关于视频画面内容的分析:\n\n1. **主体**:视频的主体是一位年轻温婉的母亲和一个活泼可爱的小男孩。\n2. **动作/场景**:他们置身于清澈美丽的溪流边,起初母亲拿着石子与孩子互动,接着两人在水中嬉戏泼水,最后在夕阳西下的河畔石头上温馨地拥抱在一起。\n3. **氛围**:整个画面充满着大自然静谧祥和之美,洋溢着温馨、欢乐且深情的亲子氛围。"
}
]
},
"finishReason": "STOP",
"index": 0,
"safetyRatings": []
}
],
"usageMetadata": {
"promptTokenCount": 935,
"toolUsePromptTokenCount": 0,
"candidatesTokenCount": 572,
"totalTokenCount": 1507,
"thoughtsTokenCount": 0,
"cachedContentTokenCount": 0,
"promptTokensDetails": null,
"toolUsePromptTokensDetails": null,
"candidatesTokensDetails": null
}
}
流式视频分析
流式接口通过 SSE 返回增量片段。URL 末尾必须带?alt=sse。
curl
curl -N --request POST \
--url 'https://{your-domain}/v1beta/models/gemini-3.5-flash:streamGenerateContent?alt=sse' \
--header 'x-goog-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "请流式分析这个视频,用中文输出三句话,说明主体、动作/场景和氛围。"
},
{
"fileData": {
"mimeType": "video/mp4",
"fileUri": "https://vidgen.x.ai/xai-vidgen-bucket/xai-video-9f800388-9bca-9170-bcad-efcfe5bb5c91.mp4"
}
}
]
}
],
"generationConfig": {
"maxOutputTokens": 512
}
}'
请求体
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "请流式分析这个视频,用中文输出三句话,说明主体、动作/场景和氛围。"
},
{
"fileData": {
"mimeType": "video/mp4",
"fileUri": "https://vidgen.x.ai/xai-vidgen-bucket/xai-video-9f800388-9bca-9170-bcad-efcfe5bb5c91.mp4"
}
}
]
}
],
"generationConfig": {
"maxOutputTokens": 512
}
}
响应示例
data: {"candidates":[{"content":{"role":"model","parts":[{"text":"以下"}]},"finishReason":null,"index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":22,"toolUsePromptTokenCount":0,"candidatesTokenCount":0,"totalTokenCount":22,"thoughtsTokenCount":0,"cachedContentTokenCount":0,"promptTokensDetails":null,"toolUsePromptTokensDetails":null,"candidatesTokensDetails":null}}
data: {"candidates":[{"content":{"role":"model","parts":[{"text":"是关于视频内容的流式分析:\n\n1. **主体**:视频的主体是一位年轻温婉的母亲和一个活泼可爱的小男孩。"}]},"finishReason":null,"index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":22,"toolUsePromptTokenCount":0,"candidatesTokenCount":0,"totalTokenCount":22,"thoughtsTokenCount":0,"cachedContentTokenCount":0,"promptTokensDetails":null,"toolUsePromptTokensDetails":null,"candidatesTokensDetails":null}}
data: {"candidates":[{"content":{"role":"model","parts":[{"text":"\n2. **动作/场景**:他们起初在清澈的溪流边观察石子,随后蹲"}]},"finishReason":null,"index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":22,"toolUsePromptTokenCount":0,"candidatesTokenCount":0,"totalTokenCount":22,"thoughtsTokenCount":0,"cachedContentTokenCount":0,"promptTokensDetails":null,"toolUsePromptTokensDetails":null,"candidatesTokensDetails":null}}
data: {"candidates":[{"content":{"role":"model","parts":[{"text":"在水边欢快地嬉戏玩水,最后在夕阳西下的金色余晖中亲密地拥抱在一起。\n3. **氛围**:"}]},"finishReason":null,"index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":22,"toolUsePromptTokenCount":0,"candidatesTokenCount":0,"totalTokenCount":22,"thoughtsTokenCount":0,"cachedContentTokenCount":0,"promptTokensDetails":null,"toolUsePromptTokensDetails":null,"candidatesTokensDetails":null}}
data: {"candidates":[{"content":{"role":"model","parts":[{"text":"整个视频营造出一种温馨、和谐且充满爱意的亲子氛围。"}]},"finishReason":null,"index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":22,"toolUsePromptTokenCount":0,"candidatesTokenCount":0,"totalTokenCount":22,"thoughtsTokenCount":0,"cachedContentTokenCount":0,"promptTokensDetails":null,"toolUsePromptTokensDetails":null,"candidatesTokensDetails":null}}
data: {"candidates":[{"content":{"role":"model","parts":[]},"finishReason":"STOP","index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":22,"toolUsePromptTokenCount":0,"candidatesTokenCount":0,"totalTokenCount":22,"thoughtsTokenCount":0,"cachedContentTokenCount":0,"promptTokensDetails":null,"toolUsePromptTokensDetails":null,"candidatesTokensDetails":null}}
SSE 的每个
data: 片段都可能携带 usageMetadata。对账请以平台最终用量记录为准,不要只取首个片段中的 token 字段。Python 示例
import requests
api_key = "YOUR_API_KEY"
model = "gemini-3.5-flash"
url = f"https://{{your-domain}}/v1beta/models/{model}:generateContent"
payload = {
"contents": [
{
"role": "user",
"parts": [
{"text": "请分析这个视频的画面内容,用中文输出三句话。"},
{
"fileData": {
"mimeType": "video/mp4",
"fileUri": "https://example.com/video.mp4",
}
},
],
}
],
"generationConfig": {"maxOutputTokens": 512},
}
resp = requests.post(
url,
headers={
"x-goog-api-key": api_key,
"Content-Type": "application/json",
},
json=payload,
timeout=180,
)
resp.raise_for_status()
print(resp.json())
JavaScript 示例
const apiKey = "YOUR_API_KEY";
const model = "gemini-3.5-flash";
const response = await fetch(
`https://{your-domain}/v1beta/models/${model}:generateContent`,
{
method: "POST",
headers: {
"x-goog-api-key": apiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
contents: [
{
role: "user",
parts: [
{ text: "请分析这个视频的画面内容,用中文输出三句话。" },
{
fileData: {
mimeType: "video/mp4",
fileUri: "https://example.com/video.mp4",
},
},
],
},
],
generationConfig: {
maxOutputTokens: 512,
},
}),
}
);
if (!response.ok) {
throw new Error(await response.text());
}
console.log(await response.json());
与 OpenAI-compatible 接口的差异
| 能力 | Gemini 原生格式 | OpenAI-compatible chat/completions |
|---|---|---|
| 视频 URL 理解 | 推荐使用,fileData.fileUri 可被模型读取 | 不推荐;video_url 可能被兼容层忽略或不被上游识别 |
| 图片 URL 理解 | 支持,使用 fileData.fileUri | 部分模型/渠道可用,依赖兼容层转换 |
| 流式输出 | :streamGenerateContent?alt=sse | stream: true |
| 鉴权推荐 | x-goog-api-key | Authorization: Bearer |
| usage 字段 | usageMetadata | usage |
常见问题
| 场景 | 表现 | 处理方式 |
|---|---|---|
| 视频 URL 不是直链 | 模型无法读取视频,或返回无法查看视频 | 换成公网可匿名访问的 .mp4 直链。 |
| URL 过期或需要登录 | 上游读取失败或分析内容不准确 | 使用长期有效、无需 Cookie 的链接。 |
| MIME 类型错误 | 上游可能拒绝或忽略视频 | 视频传 video/mp4;图片传 image/jpeg、image/png 等真实类型。 |
使用 OpenAI video_url | 可能 HTTP 200 但模型没有读到视频 | 改用 Gemini 原生 fileData.fileUri。 |
| 流式没有实时输出 | 客户端缓冲或未使用 SSE 读取 | curl 使用 -N;前端使用 EventSource/ReadableStream 处理 data:。 |
返回 model_not_allowed | API Key 未开通该模型 | 检查 API Key 可用模型列表或联系平台开通。 |
返回 model_endpoint_mismatch | 模型未启用 Gemini 原生 endpoint | 使用支持 /v1beta/models/{model}:generateContent 的模型。 |
.png?fit=max&auto=format&n=v_sJS-AFS6goKAv3&q=85&s=e03202fddb83c95be2a503ab9c79163a)