Skip to content

Huifa Seedance 视频生成 API 调用指南

面向 Huifa 平台调用方。本文档说明如何调用 seedance 系列视频生成模型。 调用方使用 OpenAI 风格的视频协议

基本信息

服务域名https://huifa.one-connect.cn
鉴权Authorization: Bearer <Huifa 令牌 sk-xxx>(在站点「令牌」页面创建)
协议风格OpenAI 视频 API(异步任务:创建 → 轮询)
支持模型doubao-seedance-2-0-260128

令牌 sk-xxx 是你在 Huifa 站点创建的平台令牌。

调用流程

视频生成是异步任务:先创建任务拿到 task_id,再轮询查询直到 status 变为 completed

POST /v1/video/generations      → 返回 task_id (status=queued)
        ↓ 轮询
GET  /v1/video/generations/{id} → status=in_progress ... → completed (metadata.url)

1. 创建视频任务

请求

bash
curl https://huifa.one-connect.cn/v1/video/generations \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-你的Huifa令牌" \
  -d '{
    "model": "doubao-seedance-2-0-260128",
    "prompt": "第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款;全程第一视角构图,背景音乐轻快卡点,女声口播「鲜切现摇」「来一口鲜爽」。",
    "seconds": "11",
    "metadata": {
      "ratio": "16:9",
      "generate_audio": true,
      "watermark": false,
      "content": [
        {
          "type": "image_url",
          "image_url": { "url": "https://你的图床/pic1.jpg" },
          "role": "reference_image"
        },
        {
          "type": "image_url",
          "image_url": { "url": "https://你的图床/pic2.jpg" },
          "role": "reference_image"
        },
        {
          "type": "video_url",
          "video_url": { "url": "https://你的图床/video1.mp4" },
          "role": "reference_video"
        },
        {
          "type": "audio_url",
          "audio_url": { "url": "https://你的图床/audio1.mp3" },
          "role": "reference_audio"
        }
      ]
    }
  }'

请求字段

字段类型必填说明
modelstring模型名,见上方支持列表
promptstring主提示词,自动作为文本内容注入
secondsstring视频时长(秒),对应上游 duration
metadataobject上游特有参数入口,见下

metadata 字段

字段类型说明
ratiostring宽高比:16:9 / 9:16 / 1:1 / 4:3 / 3:4
generate_audiobool是否生成音频(背景音 + 口播)
watermarkbool是否加水印
contentarray参考素材数组,见下

content 数组元素(参考图 / 视频 / 音频)

字段说明
typeimage_url / video_url / audio_url / text
image_url.url / video_url.url / audio_url.url素材公网地址(必须上游可访问,不能是本地文件)
rolereference_image / reference_video / reference_audio

⚠️ 必填项提醒:上游要求 ratiogenerate_audiowatermark 必须传(放在 metadata 里)。若遗漏,会收到错误 调试执行失败: 插件缺少必要输入参数。即使不需要音频/水印,也要显式传 "generate_audio": false"watermark": false

响应

json
{
  "id": "task-xxxxxxxx",
  "task_id": "task-xxxxxxxx",
  "object": "video",
  "model": "doubao-seedance-2-0-260128",
  "status": "queued",
  "created_at": 1751180000
}

记下 task_id 用于轮询。

2. 轮询查询结果

请求

bash
curl https://huifa.one-connect.cn/v1/video/generations/task-xxxxxxxx \
  -H "Authorization: Bearer sk-你的Huifa令牌"

进行中

json
{
  "task_id": "task-xxxxxxxx",
  "status": "IN_PROGRESS",
  "progress": "50%"
}

已完成(实测样例,字段已省略部分)

json
{
  "task_id": "task-xxxxxxxx",
  "status": "SUCCESS",
  "progress": "100%",
  "result_url": "https://ark-acg-cn-beijing.tos-cn-beijing.volces.com/....mp4?X-Tos-...",
  "finish_time": 1782789150
}

生成的视频地址在顶层 result_url 字段。它是火山对象存储的签名链接,有效期 24 小时,过期需重新查询任务获取新链接,或提前转存。

注意:返回 JSON 中 result_url 里的 && 的 JSON 转义,程序解析后会自动还原;若手动复制到浏览器,需把 & 替换成 &

失败

json
{
  "task_id": "task-xxxxxxxx",
  "status": "FAILURE",
  "fail_reason": "失败原因"
}

status 取值

status含义
QUEUED排队中
IN_PROGRESS生成中
SUCCESS完成,视频地址在 result_url
FAILURE失败,原因在 fail_reason

建议轮询间隔 5~10 秒,直到 SUCCESSFAILURE

若改用 OpenAI 兼容入口 GET /v1/videos/{task_id}(见第 3 节),返回结构略有不同:status 为小写(completed/failed),视频地址在 metadata.url。两个入口取其一即可。

3. OpenAI 官方兼容入口(可选)

如果你的客户端基于 OpenAI 官方 videos API,可改用以下入口,请求/响应结构一致:

bash
# 创建
curl https://huifa.one-connect.cn/v1/videos \
  -X POST -H "Authorization: Bearer sk-你的Huifa令牌" \
  -H "Content-Type: application/json" \
  -d '{ "model": "doubao-seedance-2-0-260128", "prompt": "...", "seconds": "11" }'

# 查询
curl https://huifa.one-connect.cn/v1/videos/task-xxxxxxxx \
  -H "Authorization: Bearer sk-你的Huifa令牌"

4. 豆包(火山 Ark)原生入口(可选,推荐已有豆包代码的用户)

如果你已经有调用火山引擎 seedance 的代码或 SDK(火山官方 content 数组格式),不想改造成 Huifa 的 prompt/seconds 风格,可以直接用这个入口——请求体与火山官方完全一致,只需把 base_url 指向 https://huifa.one-connect.cn/doubao、把 key 换成 Huifa 令牌即可

端点路径与火山官方一致(/api/v3/contents/generations/tasks),仅多了 /doubao 前缀。仅支持 doubao-seedance-* 系列模型。

bash
# 创建(火山原生 content 数组格式)
curl https://huifa.one-connect.cn/doubao/api/v3/contents/generations/tasks \
  -X POST -H "Authorization: Bearer sk-你的Huifa令牌" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-2-0-260128",
    "content": [
      { "type": "text", "text": "一只猫在跳舞" },
      { "type": "image_url", "image_url": { "url": "https://你的图床/pic1.jpg" }, "role": "reference_image" }
    ],
    "ratio": "16:9",
    "duration": 11,
    "generate_audio": true,
    "watermark": false
  }'

# 查询(task_id 走 URL 路径,同火山官方)
curl https://huifa.one-connect.cn/doubao/api/v3/contents/generations/tasks/task-xxxxxxxx \
  -H "Authorization: Bearer sk-你的Huifa令牌"

请求体:与火山官方 content_generation.tasks.create 的 body 完全一致(model + content[] + ratio/duration/resolution/generate_audio/watermark/seed/camera_fixed 等扁平参数)。提示词放在 content 数组的 type:"text" 项里,时长用 duration(整数)。

⚠️ 与前两个入口不同点:响应仍是 Huifa 的任务格式(不是火山原生响应)。创建返回 {id, task_id, status:"queued", ...};查询返回 {status, result_url, ...},视频地址在顶层 result_url。也就是说"请求体保持豆包原生、响应按 Huifa 格式解析"。

generate_audio/watermark 未显式传时,网关会自动补 false(上游必填),但建议你显式传入。

5. 完整轮询示例

Python

python
import time
import requests

BASE_URL = "https://huifa.one-connect.cn"
API_KEY = "sk-你的Huifa令牌"

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}


def create_video_task() -> str:
    """创建视频任务,返回 task_id。"""
    payload = {
        "model": "doubao-seedance-2-0-260128",
        "prompt": "第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款。",
        "seconds": "11",
        "metadata": {
            "ratio": "16:9",
            "generate_audio": True,
            "watermark": False,
            "content": [
                {"type": "image_url", "image_url": {"url": "https://你的图床/pic1.jpg"}, "role": "reference_image"},
                {"type": "video_url", "video_url": {"url": "https://你的图床/video1.mp4"}, "role": "reference_video"},
            ],
        },
    }
    resp = requests.post(f"{BASE_URL}/v1/video/generations", headers=HEADERS, json=payload, timeout=30)
    resp.raise_for_status()
    return resp.json()["task_id"]


def poll_video_task(task_id: str, interval: int = 8, max_wait: int = 600) -> dict:
    """轮询任务直到完成或失败。interval 秒/次,max_wait 秒超时。"""
    deadline = time.time() + max_wait
    while time.time() < deadline:
        resp = requests.get(f"{BASE_URL}/v1/video/generations/{task_id}", headers=HEADERS, timeout=30)
        resp.raise_for_status()
        data = resp.json()
        status = data.get("status")
        print(f"status={status} progress={data.get('progress', '0%')}")
        if status == "SUCCESS":
            return data
        if status == "FAILURE":
            raise RuntimeError(f"任务失败: {data.get('fail_reason', '未知原因')}")
        time.sleep(interval)
    raise TimeoutError(f"任务 {task_id} 超过 {max_wait}s 未完成")


if __name__ == "__main__":
    task_id = create_video_task()
    print(f"任务已创建: {task_id}")
    result = poll_video_task(task_id)
    print("视频地址:", result.get("result_url"))

Node.js

javascript
const BASE_URL = 'https://huifa.one-connect.cn'
const API_KEY = 'sk-你的Huifa令牌'

const HEADERS = {
  Authorization: `Bearer ${API_KEY}`,
  'Content-Type': 'application/json',
}

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

async function createVideoTask() {
  const payload = {
    model: 'doubao-seedance-2-0-260128',
    prompt: '第一人称视角果茶宣传广告,seedance牌「苹苹安安」苹果果茶限定款。',
    seconds: '11',
    metadata: {
      ratio: '16:9',
      generate_audio: true,
      watermark: false,
      content: [
        { type: 'image_url', image_url: { url: 'https://你的图床/pic1.jpg' }, role: 'reference_image' },
        { type: 'video_url', video_url: { url: 'https://你的图床/video1.mp4' }, role: 'reference_video' },
      ],
    },
  }
  const resp = await fetch(`${BASE_URL}/v1/video/generations`, {
    method: 'POST',
    headers: HEADERS,
    body: JSON.stringify(payload),
  })
  if (!resp.ok) throw new Error(`创建失败: ${resp.status} ${await resp.text()}`)
  return (await resp.json()).task_id
}

async function pollVideoTask(taskId, { interval = 8000, maxWait = 600000 } = {}) {
  const deadline = Date.now() + maxWait
  while (Date.now() < deadline) {
    const resp = await fetch(`${BASE_URL}/v1/video/generations/${taskId}`, { headers: HEADERS })
    if (!resp.ok) throw new Error(`查询失败: ${resp.status} ${await resp.text()}`)
    const data = await resp.json()
    console.log(`status=${data.status} progress=${data.progress ?? '0%'}`)
    if (data.status === 'SUCCESS') return data
    if (data.status === 'FAILURE') throw new Error(`任务失败: ${data.fail_reason ?? '未知原因'}`)
    await sleep(interval)
  }
  throw new Error(`任务 ${taskId} 超过 ${maxWait}ms 未完成`)
}

;(async () => {
  const taskId = await createVideoTask()
  console.log(`任务已创建: ${taskId}`)
  const result = await pollVideoTask(taskId)
  console.log('视频地址:', result.result_url)
})()

常见问题

Q: 参考素材能传本地文件吗? 不能。url 必须是上游可公网访问的地址(如对象存储 / 图床)。

Q: 计费怎么算? 按生成视频的 token 量计费(分辨率 × 帧率 × 时长相关)。

Huifa API Documentation