视频生成(wan / happyhorse)
wan / happyhorse 系列视频生成模型均采用异步任务模式:POST /v1/videos/generations 提交任务 → GET /v1/videos/generations/task/{taskId} 轮询结果。
计费:按秒计费的模型在提交时即按请求时长结费;按输出 token 计费的模型在成片时按实际用量结算。按分辨率档计价的模型,成片时会用模型返回的实际档位与时长校核费用,多退少补(同一任务只校核一次)。任务失败时已扣费用自动原路退回。每次费用记入控制台「费用中心」,接口响应本身不返回费用。
异步调用流程
- 提交任务:调用
POST https://test.jw-info.com/v1/videos/generations,传入模型和参数,返回任务 ID(id) - 轮询结果:调用
GET https://test.jw-info.com/v1/videos/generations/task/{taskId}查询状态
| 状态 | 说明 | 操作 |
|---|---|---|
| queued | 排队中 | 继续轮询(建议间隔 5-15 秒) |
| running | 处理中 | 继续轮询(建议间隔 5-15 秒) |
| succeeded | 成功 | 从 content.video_url 获取视频下载地址 |
| failed | 失败 | 查看 error.code 和 error.message 定位原因 |
请求头
| 请求头 | 是否必填 | 说明 |
|---|---|---|
| Content-Type | 是 | 固定为 application/json |
| Authorization | 是 | Bearer {API_KEY},也可用 x-api-key |
提交与轮询都只需以上两个请求头,无需其它自定义头。
错误码
错误响应统一为方舟形状 {"error":{"code","message","param","type"}}(与本平台其它视频接口一致,完整表格见视频生成页):
| HTTP | code | 说明 |
|---|---|---|
| 400 | MissingParameter | 参数错误(如缺 model、缺 input.prompt) |
| 401 | AuthenticationError | 密钥无效 |
| 403 | Insufficient.Balance | 余额不足 |
| 404 | InvalidEndpointOrModel.NotFound | 模型未上架或已停用 |
| 404 | ResourceNotFound | 任务不存在,或查询所用密钥与提交任务的不一致(两者不区分) |
| 429 | RateLimitExceeded | 提交过于频繁,请退避后重试 |
| 5xx | InternalError | 模型服务或平台内部错误,可退避重试 |
任务查不到时返回:
{
"error": {
"code": "ResourceNotFound",
"message": "The specified resource `encrypted-task-id-abc123` is not found. Request id: 1f0c5b8e9a2d4c6f8b0e1a3d5c7f9b2e",
"param": "",
"type": "NotFound"
}
}
任务本身失败时接口仍返回 200(status = failed),失败原因在响应体的 error 字段里;已扣费用自动退回。
接口
提交任务:
POST https://test.jw-info.com/v1/videos/generations
查询结果:
GET https://test.jw-info.com/v1/videos/generations/task/{taskId}
{taskId} 即提交任务返回的 id(代码里常写成 task_id 变量)。
一、文生视频(T2V)
根据文本提示词生成视频。
参数对比
| 参数 | wan2.6-t2v | wan2.7-t2v | happyhorse-1.0-t2v |
|---|---|---|---|
| Prompt 上限 | 1500 字符 | 5000 字符 | 5000 非中文 / 2500 中文 |
| 分辨率指定 | parameters.size | parameters.size | parameters.resolution + parameters.ratio |
| 支持分辨率 | 720P、1080P | 720P、1080P | 720P、1080P |
| 视频时长 | 2-15 秒 | 2-15 秒 | 3-15 秒 |
| negative_prompt | 支持 | 支持 | 不支持 |
| audio_url | 支持 | 支持 | 不支持 |
| prompt_extend | 支持 | 支持 | 不支持 |
| shot_type | 支持 | 不支持 | 不支持 |
| watermark | 支持 | 支持 | 支持 |
| seed | 支持 | 支持 | 支持 |
请求参数(wan2.6-t2v / wan2.7-t2v)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 模型名称 |
| input.prompt | string | 是 | 视频描述文本 |
| input.negative_prompt | string | 否 | 反向提示词,不超过 500 字符 |
| input.audio_url | string | 否 | 音频文件 URL(wav/mp3,3-30s,≤15MB)。不提供则自动生成背景音效 |
| parameters.size | string | 否 | 视频分辨率,默认 1920*1080 |
| parameters.duration | int | 否 | 视频时长(秒),默认 5 |
| parameters.prompt_extend | bool | 否 | 是否开启 Prompt 智能改写,默认 true |
| parameters.shot_type | string | 否 | 镜头类型:single(默认)/ multi。仅 wan2.6 支持 |
| parameters.watermark | bool | 否 | 是否添加水印,默认 false |
| parameters.seed | int | 否 | 随机种子 |
请求参数(happyhorse-1.0-t2v)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 固定为 happyhorse-1.0-t2v |
| input.prompt | string | 是 | 视频描述文本 |
| parameters.resolution | string | 否 | 分辨率档位:720P / 1080P(默认) |
| parameters.ratio | string | 否 | 画面宽高比:16:9(默认)/ 9:16 / 1:1 |
| parameters.duration | int | 否 | 视频时长,3-15 秒,默认 5 |
| parameters.watermark | bool | 否 | 是否添加水印,默认 true |
| parameters.seed | int | 否 | 随机种子 |
支持的视频尺寸
| 分辨率 | 宽高比 | size 值 | resolution + ratio |
|---|---|---|---|
| 720P | 16:9 | 1280*720 | 720P + 16:9 |
| 720P | 9:16 | 720*1280 | 720P + 9:16 |
| 720P | 1:1 | 960*960 | 720P + 1:1 |
| 1080P | 16:9 | 1920*1080 | 1080P + 16:9 |
| 1080P | 9:16 | 1080*1920 | 1080P + 9:16 |
| 1080P | 1:1 | 1440*1440 | 1080P + 1:1 |
分辨率怎么传
parameters.size(如 1280*720)与 parameters.resolution(如 720P)两种写法都收:只传 size 时,接口会按短边自动补出 parameters.resolution 再生成(这批模型只认 resolution,只传 size 会按默认 1080P 出片并按实际档位计费,比预期贵)。因此想明确按某个档位出片时,建议显式传 resolution。成片后接口会按实际档位与时长校核费用,多退少补。
请求示例
wan2.6-t2v / wan2.7-t2v:
{
"model": "wan2.7-t2v",
"input": {
"prompt": "一只白色猫咪在阳光下的书桌上打哈欠,镜头缓慢推进,画面温暖治愈",
"negative_prompt": "低质量,模糊,变形"
},
"parameters": {
"size": "1920*1080",
"duration": 5,
"prompt_extend": true,
"watermark": false,
"seed": 12345
}
}
happyhorse-1.0-t2v:
{
"model": "happyhorse-1.0-t2v",
"input": {
"prompt": "一只白色猫咪在阳光下的书桌上打哈欠,镜头缓慢推进,画面温暖治愈"
},
"parameters": {
"resolution": "1080P",
"ratio": "16:9",
"duration": 5,
"watermark": false,
"seed": 12345
}
}
响应示例
提交任务成功(只回任务 ID):
{
"id": "encrypted-task-id-abc123"
}
轮询参数(路径参数 taskId 为提交时返回的任务 ID):
| 参数 | 类型 | 说明 |
|---|---|---|
| taskId | string | 任务 ID(提交响应里的 id) |
轮询响应字段(与视频生成页一致):
| 参数 | 类型 | 说明 |
|---|---|---|
| id | string | 任务 ID(与提交时一致) |
| model | string | 模型名称 |
| status | string | 任务状态:queued / running / succeeded / failed / cancelled / expired |
| content.video_url | string | 视频下载地址(仅 succeeded 时返回,有时效,请及时转存) |
| duration | int | 视频时长(秒) |
| resolution | string | 实际出片分辨率档位 |
| usage.completion_tokens | int | 输出 Token 数(按 token 计费模型的计费对账依据) |
| usage.total_tokens | int | 总 Token 数 |
| error | object | 失败原因(仅 failed 时返回):error.code / error.message |
轮询结果(成功):
{
"id": "encrypted-task-id-abc123",
"status": "succeeded",
"content": {
"video_url": "https://example.com/video.mp4"
},
"duration": 5
}
轮询结果(处理中):
{
"id": "encrypted-task-id-abc123",
"status": "running"
}
轮询结果(失败):
{
"id": "encrypted-task-id-abc123",
"status": "failed",
"error": {
"code": "InvalidParameter",
"message": "prompt is required"
}
}
二、图生视频 - 首帧(I2V)
基于一张参考图片作为视频首帧,结合文本提示词生成视频。
参数对比
| 参数 | wan2.7-i2v | happyhorse-1.0-i2v |
|---|---|---|
| 输入 | 图片 + prompt | 图片 + prompt |
| 分辨率指定 | parameters.size | parameters.resolution + parameters.ratio |
| 支持分辨率 | 720P、1080P | 720P、1080P |
| 视频时长 | 2-15 秒 | 3-15 秒 |
| negative_prompt | 支持 | 不支持 |
| prompt_extend | 支持 | 不支持 |
| watermark | 支持 | 支持 |
请求参数(wan2.7-i2v)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 固定为 wan2.7-i2v |
| input.prompt | string | 否 | 视频描述文本,不超过 5000 字符 |
| input.first_frame_image | string | 是 | 首帧图片 URL 或 Base64 |
| input.negative_prompt | string | 否 | 反向提示词,不超过 500 字符 |
| parameters.size | string | 否 | 视频分辨率,默认 1920*1080 |
| parameters.duration | int | 否 | 视频时长(秒),默认 5 |
| parameters.prompt_extend | bool | 否 | 是否开启 Prompt 智能改写,默认 true |
| parameters.watermark | bool | 否 | 是否添加水印,默认 false |
| parameters.seed | int | 否 | 随机种子 |
请求参数(happyhorse-1.0-i2v)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 固定为 happyhorse-1.0-i2v |
| input.prompt | string | 是 | 视频描述文本 |
| input.first_frame_image | string | 是 | 首帧图片 URL 或 Base64 |
| parameters.resolution | string | 否 | 分辨率档位:720P / 1080P(默认) |
| parameters.ratio | string | 否 | 画面宽高比:16:9(默认)/ 9:16 / 1:1 |
| parameters.duration | int | 否 | 视频时长,3-15 秒,默认 5 |
| parameters.watermark | bool | 否 | 是否添加水印,默认 true |
| parameters.seed | int | 否 | 随机种子 |
请求示例
wan2.7-i2v:
{
"model": "wan2.7-i2v",
"input": {
"prompt": "画面中的猫咪站起来伸懒腰,然后跳下书桌",
"first_frame_image": "https://example.com/cat.jpg"
},
"parameters": {
"size": "1920*1080",
"duration": 5,
"watermark": false
}
}
happyhorse-1.0-i2v:
{
"model": "happyhorse-1.0-i2v",
"input": {
"prompt": "画面中的猫咪站起来伸懒腰,然后跳下书桌",
"first_frame_image": "https://example.com/cat.jpg"
},
"parameters": {
"resolution": "1080P",
"ratio": "16:9",
"duration": 5
}
}
三、参考生视频(R2V)
基于参考视频的运动风格或参考图片,结合文本提示词生成新视频。
参数对比
| 参数 | wan2.7-r2v | happyhorse-1.0-r2v |
|---|---|---|
| 输入 | 参考视频/图片 + prompt | 参考视频/图片 + prompt |
| 分辨率指定 | parameters.size | parameters.resolution + parameters.ratio |
| 支持分辨率 | 720P、1080P | 720P、1080P |
| 视频时长 | 2-15 秒 | 3-15 秒 |
| negative_prompt | 支持 | 不支持 |
| prompt_extend | 支持 | 不支持 |
| watermark | 支持 | 支持 |
请求参数(wan2.7-r2v)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 固定为 wan2.7-r2v |
| input.prompt | string | 是 | 视频描述文本,不超过 5000 字符 |
| input.reference_video | string | 否 | 参考视频 URL。与 reference_image 二选一或同时提供 |
| input.reference_image | string | 否 | 参考图片 URL。与 reference_video 二选一或同时提供 |
| input.negative_prompt | string | 否 | 反向提示词,不超过 500 字符 |
| parameters.size | string | 否 | 视频分辨率,默认 1920*1080 |
| parameters.duration | int | 否 | 视频时长。有参考视频时 2-10s,无参考视频时 2-15s,默认 5 |
| parameters.prompt_extend | bool | 否 | 是否开启 Prompt 智能改写,默认 true |
| parameters.watermark | bool | 否 | 是否添加水印,默认 false |
| parameters.seed | int | 否 | 随机种子 |
请求参数(happyhorse-1.0-r2v)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 固定为 happyhorse-1.0-r2v |
| input.prompt | string | 是 | 视频描述文本 |
| input.reference_video | string | 否 | 参考视频 URL。与 reference_image 二选一或同时提供 |
| input.reference_image | string | 否 | 参考图片 URL。与 reference_video 二选一或同时提供 |
| parameters.resolution | string | 否 | 分辨率档位:720P / 1080P(默认) |
| parameters.ratio | string | 否 | 画面宽高比:16:9(默认)/ 9:16 / 1:1 |
| parameters.duration | int | 否 | 视频时长,3-15 秒,默认 5 |
| parameters.watermark | bool | 否 | 是否添加水印,默认 true |
| parameters.seed | int | 否 | 随机种子 |
请求示例
wan2.7-r2v(参考视频):
{
"model": "wan2.7-r2v",
"input": {
"prompt": "保持视频中的运镜方式,将场景改为海边日落",
"reference_video": "https://example.com/reference.mp4"
},
"parameters": {
"size": "1920*1080",
"duration": 5,
"watermark": false
}
}
happyhorse-1.0-r2v(参考图片):
{
"model": "happyhorse-1.0-r2v",
"input": {
"prompt": "参考图片中的猫咪动作风格,生成它在花园中奔跑的视频",
"reference_image": "https://example.com/cat.jpg"
},
"parameters": {
"resolution": "1080P",
"ratio": "16:9",
"duration": 5
}
}
四、视频编辑(Video Editing)
对已有视频进行编辑修改,支持风格变换、局部元素替换、画面内容修改等操作。
适用模型
happyhorse-1.0-video-edit
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 固定为 happyhorse-1.0-video-edit |
| input.prompt | string | 是 | 编辑指令,不超过 5000 非中文 / 2500 中文字符 |
| input.media | array | 是 | 媒体素材列表,必须包含 1 个 video 类型元素,可选 0-5 个 reference_image |
| input.media[].type | string | 是 | video(待编辑视频,有且仅有 1 个)/ reference_image(参考图片,最多 5 张) |
| input.media[].url | string | 是 | 视频/图片公网 URL 或 Base64 |
| parameters.resolution | string | 否 | 输出分辨率:720P / 1080P(默认) |
| parameters.watermark | bool | 否 | 是否添加水印,默认 true |
| parameters.audio_setting | string | 否 | 音频控制:auto(默认,模型自主处理)/ origin(保留原始音频) |
请求示例
{
"model": "happyhorse-1.0-video-edit",
"input": {
"prompt": "将视频风格转换为油画风格,色彩更加温暖",
"media": [
{ "type": "video", "url": "https://example.com/input.mp4" },
{ "type": "reference_image", "url": "https://example.com/style.jpg" }
]
},
"parameters": {
"resolution": "1080P",
"watermark": false,
"audio_setting": "origin"
}
}
代码示例
提交任务 + 轮询(cURL)
GATEWAY="https://test.jw-info.com"
API_KEY="sk-你的密钥"
# 提交任务
TASK_ID=$(curl -s -X POST "$GATEWAY/v1/videos/generations" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"model": "wan2.7-t2v",
"input": { "prompt": "一只白色猫咪在阳光下的书桌上打哈欠" },
"parameters": { "size": "1920*1080", "duration": 5 }
}' | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "任务ID: $TASK_ID"
# 轮询结果
while true; do
RESULT=$(curl -s "$GATEWAY/v1/videos/generations/task/$TASK_ID" \
-H "Authorization: Bearer $API_KEY")
STATUS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")
echo "状态: $STATUS"
if [ "$STATUS" = "succeeded" ]; then
VIDEO_URL=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['content']['video_url'])")
echo "视频地址: $VIDEO_URL"
break
elif [ "$STATUS" = "failed" ]; then
echo "任务失败: $RESULT"
break
fi
sleep 10
done
提交任务 + 轮询(Python)
import json
import time
import requests
GATEWAY = "https://test.jw-info.com"
API_KEY = "sk-你的密钥"
HEADERS = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}",
}
def submit_video_task(model, **kwargs):
"""提交视频生成任务"""
url = f"{GATEWAY}/v1/videos/generations"
payload = {"model": model, **kwargs}
response = requests.post(url, json=payload, headers=HEADERS)
result = response.json()
if response.status_code != 200:
print("提交失败:", result.get("error", {}).get("message", result))
return None
task_id = result["id"]
print(f"任务已提交,task_id: {task_id}")
return task_id
def poll_video_task(task_id, poll_interval=10, max_wait=600):
"""轮询视频任务结果"""
url = f"{GATEWAY}/v1/videos/generations/task/{task_id}"
start_time = time.time()
while time.time() - start_time < max_wait:
response = requests.get(url, headers=HEADERS)
result = response.json()
status = result["status"]
print(f"状态: {status}")
if status == "succeeded":
video_url = result["content"]["video_url"]
print(f"视频地址: {video_url}")
return result
elif status == "failed":
print(f"任务失败: code={result['output'].get('code')}, "
f"message={result['output'].get('message')}")
return result
time.sleep(poll_interval)
print("轮询超时")
return None
task_id = submit_video_task(
"wan2.7-t2v",
input={"prompt": "一只白色猫咪在阳光下的书桌上打哈欠"},
parameters={"size": "1920*1080", "duration": 5},
)
if task_id:
poll_video_task(task_id)
提交任务 + 轮询(Java)
import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;
public class VideoGenerationExample {
private static final String GATEWAY = "https://test.jw-info.com";
private static final String API_KEY = "sk-你的密钥";
private static final OkHttpClient CLIENT = new OkHttpClient();
private static final ObjectMapper MAPPER = new ObjectMapper();
public static void main(String[] args) throws Exception {
// 1. 提交任务
String createJson = """
{
"model": "wan2.7-t2v",
"input": { "prompt": "一只白色猫咪在阳光下的书桌上打哈欠" },
"parameters": { "size": "1920*1080", "duration": 5 }
}
""";
Request createRequest = new Request.Builder()
.url(GATEWAY + "/v1/videos/generations")
.addHeader("Authorization", "Bearer " + API_KEY)
.post(RequestBody.create(createJson, MediaType.parse("application/json")))
.build();
String taskId;
try (Response response = CLIENT.newCall(createRequest).execute()) {
var result = MAPPER.readTree(response.body().string());
taskId = result.get("id").asText();
System.out.println("任务ID: " + taskId);
}
// 2. 轮询结果
String queryUrl = GATEWAY + "/v1/videos/generations/task/" + taskId;
for (int i = 0; i < 60; i++) {
Request queryRequest = new Request.Builder()
.url(queryUrl)
.addHeader("Authorization", "Bearer " + API_KEY)
.get()
.build();
try (Response response = CLIENT.newCall(queryRequest).execute()) {
var result = MAPPER.readTree(response.body().string());
String status = result.get("status").asText();
System.out.println("状态: " + status);
if ("succeeded".equals(status)) {
System.out.println("视频地址: "
+ result.get("content").get("video_url").asText());
break;
} else if ("failed".equals(status)) {
System.out.println("任务失败: "
+ result.get("error").get("message").asText());
break;
}
}
Thread.sleep(10000);
}
}
}
可用模型
| 模型 ID | 类型 | 分辨率 | 时长 | 特色 |
|---|---|---|---|---|
| wan2.6-t2v | 文生视频 | 720P/1080P | 2-15s | 多镜头、反向提示词、自定义音频 |
| wan2.7-t2v | 文生视频 | 720P/1080P | 2-15s | wan2.6 升级版,5000 字符 prompt |
| happyhorse-1.0-t2v | 文生视频 | 720P/1080P | 3-15s | 长 prompt 支持 |
| wan2.7-i2v | 图生视频 | 720P/1080P | 2-15s | 首帧图片驱动 |
| happyhorse-1.0-i2v | 图生视频 | 720P/1080P | 3-15s | 首帧图片驱动 |
| wan2.7-r2v | 参考生视频 | 720P/1080P | 2-15s | 参考视频/图片驱动 |
| happyhorse-1.0-r2v | 参考生视频 | 720P/1080P | 3-15s | 参考视频/图片驱动 |
| happyhorse-1.0-video-edit | 视频编辑 | 720P/1080P | 1-5min | 风格变换、元素替换 |
同族还有 wan3.0-video、wan3.0-video-prime、wan2.6-i2v / wan2.6-r2v(含 -flash)、wan2.5-*-preview、wan2.2-*、happyhorse-1.1-* 等型号,请求格式与本页一致;完整清单与各模型价格见模型广场。
注意事项
- 有效期:任务号与视频下载地址有效期为 24 小时,请及时转存。
- 轮询间隔:建议 5–15 秒一次,避免过于频繁。
- 提交频率:创建视频接口默认 QPS 上限 50,超限返回 429(
rate_limit_error),请做好退避重试。 - 提示词上限:各模型不同(1500 字符 / 5000 字符 / 5000 非中文或 2500 中文),见「请求参数」各表。
- 素材地址:首帧图片、参考图/参考视频、编辑素材请使用公网可访问的 URL;图片与首帧也支持 Base64。
- 分辨率与计费:按档计价的模型建议显式传
parameters.resolution,档位越高单价越高;成片后按实际档位与时长校核,多退少补。 - 文件不落盘:接口只返回视频地址,不保存文件,请及时下载。