教程
vidu-q3-ad reference-to-video API:curl、Python 与一次可运行的请求
你将构建什么
在 hiapi 的异步 /v1/tasks API 上发起一次 reference-to-video 调用,把 1–7 张产品静图变成一段带原生音频的短视频广告。vidu-q3-ad/reference-to-video 是 Vidu Q3 面向广告的档位:你上传产品参考图、写一段镜头描述,模型就返回一段 3–15 秒的 MP4,自带智能剪辑、运镜和生成的音效——没有单独的音轨需要你提供。
你只需提交一次 POST,然后轮询(或接收回调)直到任务完成,再下载 MP4。请先从 hiapi 控制台 获取密钥;下面每个请求都使用 Authorization: Bearer sk-...。
需要原样照抄的三项:
- 提交端点:
POST https://api.hiapi.ai/v1/tasks - 轮询端点:
GET https://api.hiapi.ai/v1/tasks/{taskId} - 模型 ID:
vidu-q3-ad/reference-to-video——斜杠和-ad后缀都不可省略;vidu-q3-mix和vidu-q4-preview是不同的端点。
输入 schema(实时探测所得)
| 字段 | 是否必填 | 类型 | 说明 |
|---|---|---|---|
prompt |
是 | string | 镜头描述;用序号指代产品,例如“参考图 1 中的手表” |
reference_image_urls |
是 | array,1–7 | 产品静图的公开 URL(由服务端抓取) |
duration |
是 | integer,3–15 | 秒数;必须是整数(4.5 会被拒绝) |
size |
否 | enum(10 个值) | 同时决定宽高比和 720/1080 档位;默认为 1280*720 |
校验器非常严格——上述列表之外的任何字段都会被直接拒绝。有两类拒绝值得特别指出,因为它们会让所有从其他 hiapi 视频模型迁移过来的人踩坑:
aspect_ratio和resolution都会被拒绝。几乎所有其他 hiapi 视频端点都用这两个字段;q3-ad 不用。尺寸只能通过size控制。reference_audio_urls也会被拒绝。与 Vidu Q4 的 reference-to-video 档位(可接收语音片段)不同,q3-ad 没有音频输入——它的配乐是原生生成的。(我是如何确认这一点的,见下面的验证章节。)
如何选择 size
size 是来自固定集合的 width*height 字符串。可以把它读作五种宽高比 × 两个质量档位的网格:
| 宽高比 | 720 档 | 1080 档 |
|---|---|---|
| 16:9 横屏 | 1280*720 |
1920*1080 |
| 9:16 竖屏 | 720*1280 |
1080*1920 |
| 1:1 方形 | 1280*1280 |
1808*1808 |
| 4:3 | 1280*960 |
1920*1440 |
| 3:4 | 960*1280 |
1440*1920 |
按投放位置选行(Reels 和 TikTok 用竖屏 720*1280 / 1080*1920,YouTube 贴片广告用横屏行),按画质与预算的权衡选列。计费按输出秒数计算,档位决定每秒单价——详见 定价;最低计费为 3 秒片段。
最小请求(curl)
两步:提交,然后轮询。
# 1) 提交——返回一个 taskId
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "vidu-q3-ad/reference-to-video",
"input": {
"prompt": "A product ad of the titanium smartwatch from reference image 1: it rotates slowly on a dark reflective pedestal while a hard strip of light sweeps across the brushed case from left to right, the screen stays dark, the camera holds a low hero angle. Commercial lighting, high contrast, macro detail.",
"reference_image_urls": [
"https://your-cdn.com/watch-front.png",
"https://your-cdn.com/watch-side.png"
],
"duration": 5,
"size": "1280*720"
}
}'
# -> {"data":{"taskId":"..."}}
# 2) 轮询直到 data.status 为 "success" 或 "fail"
curl -s https://api.hiapi.ai/v1/tasks/THE_TASK_ID \
-H "Authorization: Bearer sk-your-key"
# 成功 -> data.status == "success",且 data.output[0].url 就是 MP4
参考图 URL 必须可公开访问——任务会在服务端抓取它们,所以 localhost 或几秒后就过期的签名 URL 都不可用。
Python:提交、轮询、下载
import time
import requests # 或使用 urllib/subprocess 保持零依赖
API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": "Bearer sk-your-key", "Content-Type": "application/json"}
def submit():
payload = {
"model": "vidu-q3-ad/reference-to-video",
"input": {
"prompt": "Ad shot of the sneaker from reference image 1 spinning on a lit turntable, "
"slow push-in, soft rim light, product-hero framing.",
"reference_image_urls": ["https://your-cdn.com/sneaker.png"],
"duration": 5,
"size": "1080*1920", # 竖屏 1080p,用于 Reels / TikTok
},
}
body = requests.post(API, headers=HEADERS, json=payload, timeout=60).json()
task_id = (body.get("data") or {}).get("taskId")
if not task_id:
raise RuntimeError(f"submit rejected: {body}") # 400 会落到这里
return task_id
def wait(task_id, timeout_s=600, interval=5):
deadline = time.time() + timeout_s
while time.time() < deadline:
data = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=30).json().get("data") or {}
status = data.get("status")
if status == "success":
return data["output"][0]["url"]
if status == "fail":
raise RuntimeError(f"task failed: {data.get('error')}")
time.sleep(interval)
raise TimeoutError(task_id)
url = wait(submit())
mp4 = requests.get(url, timeout=120).content # 立即下载——输出 URL 会过期
open("ad.mp4", "wb").write(mp4)
Q3-ad 渲染通常在一两分钟内完成;5 秒的轮询间隔完全够用。输出 URL 是临时的(带有 expireAt),所以任务成功后要立刻下载字节,而不是把它热链接进页面。
生产环境模式
用回调代替轮询。 在服务端场景中,挂一个顶层 callback,这样就不必保持轮询循环:
{
"model": "vidu-q3-ad/reference-to-video",
"input": { "prompt": "...", "reference_image_urls": ["..."], "duration": 5 },
"callback": { "url": "https://your-app.com/hooks/hiapi", "when": "final" }
}
when 仅支持 "final"——任务进入终态时钩子触发一次,其请求体与 GET /v1/tasks/{taskId} 返回的负载相同。钩子可能被重试,所以要按 taskId 去重,并保留一个慢速轮询作为兜底,以防某次投递丢失。
基于响应体分支,而非 HTTP 状态码。 渲染失败仍会返回 HTTP 200;失败信息位于 data.status == "fail",详情在 data.error。只有请求级拒绝(字段错误、缺少密钥、未认证)才使用 4xx,且返回 {"code":400,"error_code":"INVALID_REQUEST","message":"...","data":null}。
幂等性。 每次提交都会创建一个新的计费任务,所以收到 taskId 的瞬间就要保存它,重试时重新轮询该 ID。绝不要因为单次轮询请求超时就重新提交。
我验证了什么
我用非法的值探测了线上端点,这些值会在校验阶段免费被拒绝——不会创建任务,也不计费(非法值会在任何渲染开始前失败,这比漏掉字段更安全)。真实响应就是 schema:
- 近乎空的请求体 →
reference_image_urls: missing required field ...; duration: missing required field ...。因此prompt、reference_image_urls和duration都是必填的。 duration: 99999→maximum: got 99,999, want 15;duration: 1→minimum: got 1, want 3;duration: 4.5→got number, want integer。Duration 是 3–15 的整数。reference_image_urls传入 8 个条目 →maxItems: got 8, want 7。上限为 7。size: "9000p"→value must be one of '1280*720', '1280*960', '1280*1280', '960*1280', '720*1280', '1920*1080', '1920*1440', '1808*1808', '1440*1920', '1080*1920'。aspect_ratio和resolution→ 两者都返回additional properties ... not allowed。它们不是 q3-ad 的字段;请使用size。reference_audio_urls以格式正确的数组传入 →additional properties 'reference_audio_urls' not allowed。(如果以非数组传入,会先触发单独的媒体检查——“must be an array”——这有误导性:该字段确实不在 schema 中。)此档位没有语音参考输入;音频是原生生成的。
这是一份集成参考,因此不包含画质声明——我没有为本文运行付费渲染。关于成功的 output[0].url 是什么样子,下面的模型页面托管了该端点自带的示例:一个真实带音轨的 MP4。
相关指南
- Vidu Q3 Ad reference-to-video 模型页面——规格、示例广告提示词,以及在线试用框。
- Vidu Q4 reference-to-video API 指南——更高档位:最高 4K、1–15 张参考图,以及 q3-ad 没有的
reference_audio_urls语音字段。 - Seedance 2.5 reference-to-video API 指南——另一个 reference-to-video 端点,适合对比模型。
- AI 视频运镜提示词——适合在
prompt字段中使用的镜头语言。 - hiapi 快速入门 与 定价。
常见问题
如何让片段变成竖屏或横屏? 通过 size,而不是 aspect_ratio。竖屏用 720*1280 或 1080*1920,横屏用 1280*720 或 1920*1080。
我可以提供配音或声音参考吗? 此档位不行——reference_audio_urls 会被拒绝。Q3-ad 会自行生成原生音频。如果你需要用参考片段驱动音频,请使用 Vidu Q4 的 reference-to-video 档位。
我可以发送多少张产品图片? 一到七张,放在 reference_image_urls 中,并在提示词里用序号引用(“参考图 2 中的瓶子”)。
我的任务返回了 200 但没有视频——为什么? 看 data.status。"fail" 会返回 HTTP 200,原因在 data.error 中;只有格式错误的请求才会得到 4xx。
费用是多少? 按输出秒数计费,size 档位(720 级 vs 1080 级)决定每秒单价。最低为 3 秒片段。当前费率见 定价。