基础地址:https://api.douchengjiu.com。所有业务请求携带 Authorization: Bearer YOUR_API_KEY。API Key 放在调用程序的服务端,不嵌入公开网页。
上传参考素材(可选) → 提交生成任务(返回 202) → 每 5–10 秒查询状态 → 完成后凭相同 API Key 下载结果。
| 方法与路径 | 说明 |
|---|---|
| GET /v1/models | 模型和工作流版本 |
| POST /v1/files?filename=reference.png | 上传原始文件字节,返回 file_id。不是 multipart 表单。 |
| POST /v1/images/generations | 千问生图 |
| POST /v1/videos/generations | H3 文生视频 / 多参考视频 / 无缝长视频分段 |
| POST /v1/audio/generations | 固定双音色(真空照1 / 真源空1)的 CPU 按需语音生成 |
| GET /v1/tasks/{id} | 任务状态、实际参数、结果链接 |
| GET /v1/tasks | 当前调用方最近 100 个任务 |
| GET /v1/files/{id}/content | 下载参考文件或生成结果,需要鉴权 |
| POST /v1/tasks/{id}/cancel | 仅取消尚未领取的排队任务 |
| GET /v1/status | 算力机在线状态和全局排队数量 |
{
"model": "qwen-image-2512-bf16",
"prompt": "清晨的竹林,一只白色陶瓷茶杯放在石桌上,写实摄影",
"width": 1024, "height": 1024,
"steps": 50, "cfg": 4, "seed": 12345
}{
"model": "minimax-h3-t2v",
"prompt": "A ceramic cup on a wooden table. Morning light, slow camera move. Gentle birdsong, no dialogue or text.",
"width": 768, "height": 512, "duration": 5,
"steps": 20, "sage_attention": "auto"
}{
"model": "minimax-h3-ref2va-bf16",
"prompt": "The character in <Picture 1> follows the movement in <Video 1>. Natural movement, stable identity, no text.",
"reference_images": ["file_上传图片返回的编号"],
"reference_videos": ["file_上传视频返回的编号"],
"reference_audios": [],
"include_reference_video_audio": false,
"width": 768, "height": 512, "duration": 5,
"steps": 20, "ref_image_size": "max", "sage_attention": "auto"
}最多 9 张图片、3 段参考视频、3 段音频。参考视频为 2–15 秒,自动取 24fps,最大 4K;独立参考音频最多 30 秒。需要参考视频原声时启用 include_reference_video_audio,素材必须含音轨。ref_image_size=max 保留原完整 BF16 工作流设置,速度较慢;match 可减少参考图处理量。T2V 使用现有 INT8 模型及 NVFP4 文本编码器,Ref2VA 使用完整 BF16 主模型和文本编码器。SageAttention 适用于视频接口。
用 minimax-h3-ref2va-slot-bf16 把多段短视频首尾相接成一条长视频,衔接处画面与声音都连续,而不是每段重新起头。它和上面多参考模型的参数完全一致,另加四个:
| 参数 | 说明 |
|---|---|
| clip_index | 本段是第几段,从 1 开始,最大 9999 |
| chain_id | 这条链的名字,字母数字下划线连字符,1–40 字符。不同链、不同调用方互相隔离 |
| prev_task_id | 上一段的任务 id;第 1 段不要传,第 2 段起必填 |
| context_length | 从上一段末尾带入多少帧,默认 22。有效值只有 1/5/22/39,其他会向下吸附 |
一次请求只生成一段,由调用方按顺序逐段提交:第 1 段成功后再提交第 2 段,以此类推。每段返回的 MP4 已经把衔接处重复的头部剪掉,直接按顺序拼接就是成品。
服务端会校验顺序:上一段必须已经 succeeded、必须属于同一个 API Key、clip_index 必须正好接上。跳段、乱序或借用别人的任务都会返回 409 或 400,不会静默生成一条接错的片子。第 1 段请单独起一个 chain_id,同一条链上不要复用旧链的名字。
{
"model": "minimax-h3-ref2va-slot-bf16",
"prompt": "The character in <Picture 1> keeps walking, same direction and speed, no text.",
"reference_images": ["file_上传图片返回的编号"],
"clip_index": 2,
"chain_id": "story-2026-09",
"prev_task_id": "task_上一段返回的编号",
"width": 512, "height": 768, "duration": 5,
"steps": 20, "context_length": 22
}第 1 段把 clip_index 设为 1 并且不要传 prev_task_id。提示词每段都要重述一次人物与动作,续写靠的是画面和声音的衔接,不会自动记住上一段的文字描述。链越长,总耗时约等于段数乘以单段耗时;中途插入其他任务会触发模型卸载重载,建议一条链连着跑完。
import os, time, requests
BASE = "https://api.douchengjiu.com"
headers = {"Authorization": "Bearer " + os.environ["DCJ_API_KEY"]}
r = requests.post(BASE + "/v1/images/generations",
headers={**headers, "Idempotency-Key": "your-unique-request-id"},
json={"prompt": "一只白色陶瓷茶杯,写实摄影"}, timeout=30)
r.raise_for_status()
task_id = r.json()["id"]
while True:
r = requests.get(BASE + "/v1/tasks/" + task_id, headers=headers, timeout=30)
r.raise_for_status()
task = r.json()
if task["status"] in ("succeeded", "failed", "cancelled", "needs_attention"):
break
time.sleep(5)
if task["status"] != "succeeded":
raise RuntimeError(task.get("error") or task["status"])
with requests.get(task["outputs"][0]["download_url"], headers=headers,
stream=True, timeout=120) as result:
result.raise_for_status()
with open("result.png", "wb") as file:
for chunk in result.iter_content(1024 * 1024):
file.write(chunk)
# 参考素材上传:
# with open("reference.png", "rb") as file:
# r = requests.post(BASE + "/v1/files", params={"filename": "reference.png"},
# headers=headers, data=file, timeout=120)
# r.raise_for_status()# file_id = r.json()["id"]
# 无缝长视频:按顺序逐段提交,前一段成功后再提交下一段
def generate_chain(prompt, reference_image, segments=3, chain_id="story-1"):
previous = None
for clip in range(1, segments + 1):
body = {"model": "minimax-h3-ref2va-slot-bf16", "prompt": prompt,
"reference_images": [reference_image],
"clip_index": clip, "chain_id": chain_id,
"width": 512, "height": 768, "duration": 5, "steps": 20}
if previous:
body["prev_task_id"] = previous
r = requests.post(BASE + "/v1/videos/generations", headers=headers, json=body, timeout=30)
r.raise_for_status()
previous = r.json()["id"]
while True:
task = requests.get(BASE + "/v1/tasks/" + previous, headers=headers, timeout=30).json()
if task["status"] in ("succeeded", "failed", "cancelled", "needs_attention"):
break
time.sleep(10)
if task["status"] != "succeeded":
raise RuntimeError("第 %d 段失败:%s" % (clip, task.get("error") or task["status"]))
with requests.get(task["outputs"][0]["download_url"], headers=headers,
stream=True, timeout=120) as result:
with open("clip_%02d.mp4" % clip, "wb") as file:
for chunk in result.iter_content(1024 * 1024):
file.write(chunk)
# 各段已剪掉衔接处的重复头,用同一套编码参数直接拼接即可
# ffmpeg -f concat -safe 0 -i list.txt -c copy long.mp4
{
"model": "cosyvoice-3",
"voice": "真空照1音色",
"input": "你好,这是语音生成测试。",
"speed": 1,
"response_format": "mp3"
}voice 可填 真空照1音色 或 真源空1音色;省略时仍默认原来的真空照1音色。真源空1音色采用 A 版的原始参考片段,不接受调用方指定参考文件。
接口返回 202 异步任务。单次最多 1000 个 Unicode 字符,输出格式仅 mp3 或 wav,语速范围 0.5–2、默认 1。当前不开放任意克隆音频上传和情绪参数。语音任务按需在 CPU 加载模型,空闲时不占用 GPU;H3 换模或 WSL 可用内存低于 15 GiB 时自动等待,必要时中止本次配音计算并重试。首次加载会增加等待时间。
actual_duration,帧率 24fps。短测试和低采样步数只用于连通性检查,不代表正式画质。