bestai.codes · Grok 视频生成

用 bestai 的 Grok 生成视频

视频生成是异步的:先提交任务拿到 request_id,再查询任务状态,完成后用返回的地址下载 MP4。下面是完整的接口说明、可直接运行的示例和常见错误的处理办法。

接口地址
https://api.bestai.codes/v1
视频模型
生成 grok-imagine-video-1.5 · 编辑 grok-imagine-video
鉴权
Authorization: Bearer sk-…
API Key 分组
grok

准备 API Key

  • 登录 bestai.codes 控制台,在「API 密钥」里新建一个 Key,分组选择 grok。只有 grok 分组的 Key 能调用视频接口;用其它分组的 Key 会返回 404「Videos API is not supported for this platform」。
  • 每个请求都带上请求头 Authorization: Bearer 你的Key。
  • 接口地址用 https://api.bestai.codes/v1,https://bestai.codes/v1 也可以,两者等价。

下文示例把 Key 放在环境变量 BESTAI_KEY 里,请勿把 Key 写进代码仓库。

调用流程

第 1 步
提交生成任务
POST /v1/videos/generations

立即返回 request_id,不会等待视频生成完。

第 2 步
轮询任务状态
GET /v1/videos/{request_id}

每 5 秒查一次,直到状态变为 done 或 failed。查询不收费。

第 3 步
下载成片
GET video.url

完成后返回 MP4 直链,下载不需要 Key。

线上实测:一个 5~10 秒、720p 的视频通常 30~60 秒生成完,15 秒的视频约 1.5 分钟。

1创建任务

POSThttps://api.bestai.codes/v1/videos/generations

请求体只接受 JSON(Content-Type: application/json)。支持三种模式:文生视频(只给 prompt)、图生视频(给一张首帧图 image)、参考图视频(给若干张参考图 reference_images)。

请求参数

参数类型说明
model必填string固定为 grok-imagine-video-1.5。
promptstring画面描述,中英文都可以。文生视频和参考图视频必填;只传 image 的图生视频可以省略。
durationinteger视频时长,1~15 秒,默认 8。也接受 "8" 这样的整数字符串。
aspect_ratiostring默认 16:9。可选:16:99:161:14:33:43:22:3
绿色为线上已成功生成过的比例。
resolutionstring默认 720p。可选:480p720p1080p
参考图视频最高 720p。1080p 参数可用,但线上还没有成功样本,建议优先用 720p。
imageobject图生视频的首帧图:{"url": "…"}。url 可以是公网 https 图片地址,也可以是 data:image/jpeg;base64,…。
reference_imagesarray参考图视频的参考图列表:[{"url": "…"}, …],建议不超过 7 张。必须同时提供 prompt;不能和 image 同时使用。
不要传未列出的字段。接口会拒绝它不认识的参数,例如 last_frame、output、storage_options,返回 400「视频生成 JSON 请求无效: json: unknown field …」。生成接口也不收 video(返回 400「视频生成不支持 video 输入」);要以一段视频为输入,请用下面的视频编辑接口。

文生视频

curl https://api.bestai.codes/v1/videos/generations \
  -H "Authorization: Bearer $BESTAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-video-1.5",
    "prompt": "一只橘猫缓慢转头看向镜头,固定镜头,午后窗边的自然光",
    "duration": 8,
    "aspect_ratio": "16:9",
    "resolution": "720p"
  }'

图生视频(首帧图)

{
  "model": "grok-imagine-video-1.5",
  "prompt": "镜头缓慢推近,人物抬头微笑,背景保持不动",
  "image": { "url": "https://example.com/first-frame.jpg" },
  "duration": 5,
  "aspect_ratio": "9:16",
  "resolution": "720p"
}

参考图视频

{
  "model": "grok-imagine-video-1.5",
  "prompt": "参考图中的角色在清晨的池塘边散步,镜头平稳跟随",
  "reference_images": [
    { "url": "https://example.com/character-front.png" },
    { "url": "https://example.com/character-side.png" }
  ],
  "duration": 8,
  "resolution": "720p"
}

返回

{ "request_id": "video_cD_859ohP3_-airCdVSx5wYg" }

视频编辑(修改已有视频)

POSThttps://api.bestai.codes/v1/videos/edits

按提示词修改一段已有视频:保留原片的动作、镜头和时长,只改画面内容,例如换衣服、加物件、换风格。它不是「拿视频当动作参考、生成一段新视频」——成片就是原视频改过之后的样子。

提交后同样返回 request_id,之后的查询状态和下载与视频生成完全相同。

请求参数

参数类型说明
model必填string固定为 grok-imagine-video(注意不是 1.5)。传 grok-imagine-video-1.5 会返回 400。
prompt必填string要怎么改,中英文都可以,例如「给猫戴一顶红色毛线帽,其它保持不变」。
video必填object原视频:{"url": "…"}。url 必须是公网 https 的 MP4 直链,打开就能直接下载到视频文件。网盘或中转站的分享页面(例如 gofile 的页面链接)不是直链,不能用。
不支持 duration、aspect_ratio、resolution、image、reference_images:成片的时长、分辨率和画幅都跟原视频一致。

示例

curl https://api.bestai.codes/v1/videos/edits \
  -H "Authorization: Bearer $BESTAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-video",
    "prompt": "给猫戴一顶红色毛线帽,其它保持不变",
    "video": { "url": "https://example.com/source.mp4" }
  }'
  • 线上实测:1 秒、480×480 的原视频,约 20 秒编辑完成,成片同为 1 秒、480×480。
  • grok-imagine-video 只用于编辑;拿它调用 /v1/videos/generations 会返回 400,生成请用 grok-imagine-video-1.5。
  • 视频延长(/v1/videos/extensions)暂未开放,调用返回 404。

2查询任务状态

GEThttps://api.bestai.codes/v1/videos/{request_id}

用同一个 Key 查询。建议每 5 秒查一次。进度按 5% 左右的步长更新,刚开始可能会停在 1% 一段时间,这是正常的。

pending

生成中,progress 为 0~99。

{
  "status": "pending",
  "model": "grok-imagine-video-1.5",
  "progress": 45
}
done

已完成,video.url 是成片地址。

{
  "status": "done",
  "model": "grok-imagine-video-1.5",
  "progress": 100,
  "video": {
    "url": "https://bestai.codes/grok2api/v1/media/videos/vid_…",
    "duration": 15,
    "respect_moderation": true
  }
}
failed

失败。失败的任务不会自动重试,需要重新提交。

{
  "status": "failed",
  "error": {
    "code": "service_unavailable",
    "message": "上游服务暂不可用"
  }
}

respect_moderation 表示成片经过了上游的内容审核,固定为 true,可以忽略。

3下载视频

状态为 done 时,直接下载 video.url:

curl -L -o output.mp4 "https://bestai.codes/grok2api/v1/media/videos/vid_…"
  • 地址是 MP4 直链,不需要带 Key,浏览器和播放器可以直接打开,支持断点续传(Range 请求)。
  • 单个视频通常几 MB(线上平均约 6 MB)。
  • 请在拿到地址后尽快下载并自行保存,不要把这个地址当作长期存储。
  • GET /v1/videos/{request_id}/content 在 bestai 上不可用(返回 404),请一律使用 video.url。

请求体生成器

选好参数,复制生成的命令即可提交任务。命令里的 Key 使用环境变量 $BESTAI_KEY,页面不会接触你的 Key。

模式
宽高比
线上已成功生成过
分辨率
8 秒

提交任务
查询状态(把 request_id 换成上一步返回的值)
curl https://api.bestai.codes/v1/videos/REQUEST_ID \
  -H "Authorization: Bearer $BESTAI_KEY"

完整示例

提交、轮询、下载一条龙。遇到 503(并发已满)会自动等待后重试提交。

需要 requests:pip install requests
import os
import time
import requests

API = "https://api.bestai.codes/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['BESTAI_KEY']}"}


def create_video(payload, retries=5):
    for attempt in range(retries):
        r = requests.post(f"{API}/videos/generations", json=payload, headers=HEADERS, timeout=60)
        if r.status_code == 503:              # 并发已满,稍后重试
            time.sleep(10 * (attempt + 1))
            continue
        r.raise_for_status()
        return r.json()["request_id"]
    raise RuntimeError("提交失败:服务繁忙,请稍后再试")


def wait_video(request_id, interval=5, timeout=900):
    deadline = time.time() + timeout
    while time.time() < deadline:
        r = requests.get(f"{API}/videos/{request_id}", headers=HEADERS, timeout=30)
        r.raise_for_status()
        job = r.json()
        if job["status"] == "done":
            return job["video"]["url"]
        if job["status"] == "failed":
            err = job.get("error", {})
            raise RuntimeError(f"生成失败 {err.get('code')}: {err.get('message')}")
        print(f"生成中 {job.get('progress', 0)}%")
        time.sleep(interval)
    raise TimeoutError(f"等待超时:{request_id}")


def download(url, path):
    with requests.get(url, stream=True, timeout=300) as r:
        r.raise_for_status()
        with open(path, "wb") as f:
            for chunk in r.iter_content(1 << 20):
                f.write(chunk)


request_id = create_video({
    "model": "grok-imagine-video-1.5",
    "prompt": "一只橘猫缓慢转头看向镜头,固定镜头,午后窗边的自然光",
    "duration": 8,
    "aspect_ratio": "16:9",
    "resolution": "720p",
})
print("任务已提交:", request_id)
url = wait_video(request_id)
download(url, "output.mp4")
print("已保存 output.mp4")

错误与排查

提交或查询时的 HTTP 错误

状态码典型信息原因与处理
400duration 必须在 1 到 15 秒之间 / aspect_ratio 必须是 … / json: unknown field …参数不合法。按「请求参数」一节检查取值,删掉未列出的字段。
400文本生视频必须提供 prompt / 参考图视频 resolution 最高 720p模式与参数组合不对。文生视频要有 prompt;参考图视频要有 prompt 且分辨率不超过 720p。
401API key is required … / Invalid API key没带 Key 或 Key 无效。检查 Authorization: Bearer 请求头。
403余额或额度不足到控制台充值或调整 Key 的额度。
404Videos API is not supported for this platformKey 不在 grok 分组。新建一个 grok 分组的 Key。
404This endpoint is not supported by grok2api调用了不支持的地址,例如 /v1/videos/{id}/content。下载请用 video.url。
415视频生成仅支持 application/json请求体必须是 JSON,不支持 multipart 上传。图片请传 URL 或 base64。
503upstream_saturated:上游账号当前均达到并发上限站点并发已满。等 10 秒左右重试,重试间隔逐次加长。

任务状态为 failed 时的错误码

error.code含义处理
service_unavailable上游服务暂不可用稍后重新提交。持续出现请联系站点管理员。
invalid_argument模型或参数不被上游接受检查 model 是否为 grok-imagine-video-1.5,以及参数组合。
internal_error其它上游错误,具体原因见 error.message常见原因见下。

internal_error 的常见 message:

  • Failed to read request body: length limit:首帧图或参考图太大,超出了上游的请求大小限制。压缩图片后重试,见下方「使用建议」。
  • invalid-argument:图片格式或内容不被接受,换一张标准的 JPEG 或 PNG 再试。
  • 上游返回 502:上游临时故障,过一会儿重新提交即可。

使用建议

  • 图片尽量用公网 https 地址。用 base64 时,先把图片压缩为 JPEG 或 WebP,长边不超过 2048 像素,体积控制在 2 MB 以内。线上失败的任务里,最常见的原因就是图片过大。
  • 先用 480p、短时长调提示词。效果满意后再换 720p 和目标时长,出片更快。
  • 批量生成要排队提交。整个站点共享有限的生成并发,一次性提交太多任务会收到 503。
  • 轮询间隔 5 秒即可,不要更频繁。客户端等待上限建议设为 15 分钟。
  • 及时保存成片。拿到 video.url 后尽快下载到自己的存储。
  • 费用以控制台的用量记录为准;查询任务状态不收费。
  • Python 用户注意:站点前有 Cloudflare 防护,Python 标准库 urllib 的默认 User-Agent 会被拦截(403)。用 requests,或在 urllib 里自行设置 User-Agent。