教程
如何使用 kling-3.0-omni/transformation API:用 curl 和 Python 实现视频重绘
kling-3.0-omni/transformation 是 Kling 3.0 Omni 的视频转视频模型:你提供一段源视频和一个文本提示词,它就会重写该视频的外观——场景、风格、主体——同时保留原始的运动和时序。在 hiapi 上,你通过与其他所有生成模型相同的统一异步端点调用它:POST /v1/tasks。本指南提供经实际验证的参数表、可直接复制粘贴的 curl 请求、一个完整的 Python 客户端(负责轮询并下载结果),以及你在把它接入真实应用之前所需的生产模式(回调、幂等性、错误处理)。
下面每个字段名、枚举值和响应结构都已对照真实 API 核对过。
你将构建的内容 + 前提条件
一个小程序:提交一个重绘任务,等待其完成,然后下载重绘后的 .mp4。你需要两样东西:
- 一个 hiapi API 密钥。 在 hiapi 控制台 创建一个——它的格式类似
sk-...。每个请求都使用Authorization: Bearer sk-<your-key>。 - 一个可公开访问的源视频 URL。 模型会在服务端下载你的视频,因此它必须是一个公开的
http(s)URL(你自己的 CDN、带公开对象的 R2/S3 等),不能是本地文件路径。只允许一个 URL。
模型及其参数
请求外层结构为 {"model": ..., "input": {...}}。input 的 schema 是严格的——只接受以下三个字段,任何多余字段都会被拒绝并返回 400。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
prompt |
string | 是 | 描述目标风格/场景/主体。重绘强度也在这里调节——没有数值型的 strength/fidelity 参数。 |
video_urls |
array | 是 | 恰好一个公开的源视频 URL(minItems 为 1,maxItems 为 1)。 |
resolution |
string 枚举 | 是 | 720p、1080p、4k 之一。 |
几点容易让人出错的地方:
- 没有
duration参数。 输出时长和宽高比跟随源视频(3–15.5 秒),并且按最终输出的时长计费。 - 模型 id 本身带有
-omni:kling-3.0-omni/transformation(其他一些 Omni 端点使用kling-3.0/...)。直接把该 id 作为model的值。 - 重绘强度由提示词驱动。 想要轻微改动,就写“轻微重绘,保留面部特征和光照”;想要大幅改动,就写“完全重新想象为 2D 赛璐璐卡通”。
最小可运行示例(curl)
# 1) 创建重绘任务
curl -s https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-3.0-omni/transformation",
"input": {
"prompt": "将该场景重绘为手绘水彩动画风格,带有柔和的纸张纹理和温暖的黄昏光线;保留原始镜头运动和主体。",
"video_urls": ["https://your-cdn.example.com/source-clip.mp4"],
"resolution": "720p"
}
}'
# -> {"code":200,"data":{"taskId":"tk-hiapi-01..."},"message":"success"}
# 2) 轮询任务直到进入终态
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01... \
-H "Authorization: Bearer sk-<your-key>"
# data.status 依次为:queued -> handling -> archiving -> success
# 成功后,data.output[0].url 即为重绘后的 .mp4
你轮询用的任务 id 来自创建响应中的 data.taskId——不是顶层 id。状态字符串为 queued / handling / archiving / success(终态)或 fail;不要假设是 succeeded/completed。
完整 Python 客户端(创建 → 轮询 → 下载)
import os
import time
import requests
API_KEY = os.environ["HIAPI_KEY"] # 你的 sk-... 密钥
BASE = "https://api.hiapi.ai"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
def create_restyle(source_video_url: str, prompt: str, resolution: str = "720p") -> str:
body = {
"model": "kling-3.0-omni/transformation",
"input": {
"prompt": prompt,
"video_urls": [source_video_url], # 恰好一个公开 URL
"resolution": resolution, # "720p" | "1080p" | "4k"
},
}
r = requests.post(f"{BASE}/v1/tasks", json=body, headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()
if data.get("code") != 200:
raise RuntimeError(f"提交被拒绝:{data}")
return data["data"]["taskId"]
def wait_for_video(task_id: str, poll_s: int = 10, timeout_s: int = 900) -> str:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{BASE}/v1/tasks/{task_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()["data"]
status = data["status"]
if status == "success":
return data["output"][0]["url"]
if status == "fail":
raise RuntimeError(f"任务失败:{data.get('error')}")
time.sleep(poll_s) # queued / handling / archiving
raise TimeoutError(f"{task_id} 未在 {timeout_s} 秒内完成")
if __name__ == "__main__":
task_id = create_restyle(
source_video_url="https://your-cdn.example.com/source-clip.mp4",
prompt=(
"将该场景重绘为手绘水彩动画风格,柔和的纸张纹理,"
"温暖的黄昏光线;保留原始镜头运动和主体。"
),
resolution="720p",
)
print("任务:", task_id)
url = wait_for_video(task_id)
print("视频 URL:", url)
# 输出文件位于 temp.hiapi.ai,会过期(约 7 天)。现在立即下载。
clip = requests.get(url, timeout=120).content
with open("restyled.mp4", "wb") as f:
f.write(clip)
print("已保存 restyled.mp4", len(clip), "字节")
把密钥放入环境变量后运行:
export HIAPI_KEY=sk-<your-key>
python restyle.py
生产模式
用回调代替频繁轮询
对于脚本以外的任何场景,请注册 webhook,以免维持一个轮询循环。callback 是顶层字段——与 model 和 input 同级,绝不能放在 input 内:
{
"model": "kling-3.0-omni/transformation",
"input": {
"prompt": "将该场景重绘为 2D 赛璐璐卡通风格,粗轮廓线;保留原始运动。",
"video_urls": ["https://your-cdn.example.com/source-clip.mp4"],
"resolution": "1080p"
},
"callback": { "url": "https://your-app.example.com/hooks/hiapi", "when": "final" }
}
callback.when只接受final(默认值)。当任务进入终态时,它会被排入队列一次,并且成功和失败都会触发。投递语义为至少一次,因此同一个回调仍可能到达多次(见下文)。- 投递的 POST 请求体与通过
GET /v1/tasks/<id>得到的data对象完全相同——因此你的处理程序无需重新拉取即可读取status、output[].url和error。 - 把
callback放进input会在提交时失败,报错additional properties 'callback' not allowed(每个模型的 input schema 都是严格的)。
幂等性与投递语义
回调是至少一次而非恰好一次——同一个 taskId 可能到达多次。请以 taskId 作为处理程序的键,并让“标记完成 + 存储视频”这一步具备幂等性。hiapi 会按 立即 → +1 分钟 → +5 分钟 → +20 分钟,最多 4 次尝试 的节奏重试非 2xx/超时的回调;你的端点必须返回 HTTP 2xx 才能停止重试。
立即下载输出
data.output[0].url 指向 temp.hiapi.ai,并带有 expireAt(Unix 时间戳,约 7 天 TTL)。过期后对象会被清除,该 URL 返回 404——重新轮询任务会返回同一个 URL,但不会重新生成文件。任务一旦成功,就立刻把字节复制到你自己的存储中。
错误处理
你需要分支处理的三种失败形态:
- 请求错误(HTTP 400)——扁平结构,未创建任务:
{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: resolution: value must be one of '720p', '1080p', '4k'"} - 认证失败(HTTP 401)——嵌套结构:
{"error":{"code":"permission_denied","type":"hiapi_error", ...}} - 任务失败——提交返回
200和一个taskId,但之后的轮询显示data.status == "fail",并带有data.error。失败的任务不收费(任务最终失败时,预扣金额会退还)。源 URL 不可访问或无法下载的情况会在这里体现。
费用
kling-3.0-omni/transformation 按输出秒数计费,费率随你请求的分辨率而变化(720p 每秒 $0.143,1080p 每秒 $0.193,4k 每秒 $0.479,2026 年 10 月 21 日核对)。在批量处理视频之前,请查看实时 hiapi 定价页 获取当前每秒费率——视频任务的费用累积速度远快于图片任务。
相关阅读
- 模型页面与规格:hiapi 上的 kling-3.0-omni/transformation
- 端点参考:创建任务——统一异步 API
- 同一端点上的同系列教程:Python 中的 Kling AI 图生视频 API
常见问题
如何控制重绘强度?
通过提示词,而不是参数。没有 strength、fidelity 或 creativity 字段。轻微编辑可以写成“轻微重绘,保留面部和光照”,大幅编辑可以写成“完全重新想象为