AI 视频扩展回调
调用延长 AI 视频时传入
callBackUrl,任务结束后系统会把结果推送到该地址。
回调机制概述
::: note 使用回调无需轮询任务状态,系统会把最终结果主动推送到你的服务器。 :::
- 请求方法:POST
- Content-Type:application/json
- 发送时机:AI 视频延长任务成功或失败时
回调请求格式
回调格式与所有 Market 模型一致。视频地址在 JSON 字符串 data.resultJson 里:JSON.parse(data.resultJson).resultUrls[0]。
成功回调
json
{
"code": 200,
"msg": "Playground task completed successfully.",
"data": {
"taskId": "d6cf9fc7968af5ccd85688083f565757",
"model": "runway/extend-ai-video",
"state": "success",
"param": "{\"input\":\"{\\\"task_id\\\":\\\"94bbfeaa1383c296cd61ba5dfcbfe30e\\\",\\\"prompt\\\":\\\"The cartoon fox steps back and admires the finished rainbow\\\",\\\"quality\\\":\\\"720p\\\"}\",\"callBackUrl\":\"https://your-domain.com/api/callback\",\"model\":\"runway/extend-ai-video\"}",
"resultJson": "{\"resultUrls\":[\"https://tempfile.aiquickdraw.com/p/d6cf9fc7968af5ccd85688083f565757_1_1791218886_3642.mp4\"]}",
"costTime": 85,
"creditsConsumed": 12,
"createTime": 1791218802000,
"completeTime": 1791218887652,
"updateTime": 1791218887652
}
}失败回调
json
{
"code": 501,
"msg": "Playground task failed.",
"data": {
"taskId": "7a3f9c2e5b1d4e6f8a0c2b4d6e8f1a3c",
"model": "runway/extend-ai-video",
"state": "fail",
"param": "{\"input\":\"{\\\"task_id\\\":\\\"94bbfeaa1383c296cd61ba5dfcbfe30e\\\",\\\"prompt\\\":\\\"The cartoon fox steps back and admires the finished rainbow\\\",\\\"quality\\\":\\\"720p\\\"}\",\"callBackUrl\":\"https://your-domain.com/api/callback\",\"model\":\"runway/extend-ai-video\"}",
"failCode": "500",
"failMsg": "internal error, please try again later.",
"costTime": 15,
"creditsConsumed": 0,
"createTime": 1791218802000,
"completeTime": 1791218817000,
"updateTime": 1791218817000
}
}参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
code | integer | 200 成功,501 失败 |
msg | string | 状态消息 |
data.taskId | string | 提交任务时返回的任务 ID |
data.model | string | 任务使用的模型(runway/extend-ai-video) |
data.state | string | success 或 fail |
data.param | string | 创建任务时提交的参数,JSON 字符串 |
data.resultJson | string | 结果,JSON 字符串,如 {"resultUrls":["https://...mp4"]};成功时返回 |
data.failCode | string | 失败码;失败时返回 |
data.failMsg | string | 失败原因;失败时返回 |
data.costTime | integer | 任务耗时(秒) |
data.creditsConsumed | number | 任务消耗的积分 |
data.createTime / data.completeTime / data.updateTime | integer | Unix 毫秒时间戳 |
回调接收示例
Node.js
javascript
const express = require('express');
const app = express();
app.use(express.json());
app.post('/runway-extend-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('收到回调:', { taskId: data.taskId, state: data.state, code, msg });
if (code === 200 && data.state === 'success') {
const videoUrl = JSON.parse(data.resultJson).resultUrls[0];
console.log(`视频地址: ${videoUrl}`);
// 在这里下载并保存视频
} else {
console.log(`任务失败: ${data.failCode} ${data.failMsg}`);
}
// 返回 200 表示已收到回调
res.status(200).json({ status: 'received' });
});
app.listen(3000, () => console.log('回调服务已在 3000 端口启动'));Python
python
import json
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/runway-extend-callback', methods=['POST'])
def handle_callback():
body = request.json
code = body.get('code')
data = body.get('data', {})
print(f"收到回调: taskId={data.get('taskId')}, state={data.get('state')}, code={code}")
if code == 200 and data.get('state') == 'success':
video_url = json.loads(data['resultJson'])['resultUrls'][0]
print(f"视频地址: {video_url}")
# 在这里下载并保存视频
else:
print(f"任务失败: {data.get('failCode')} {data.get('failMsg')}")
# 返回 200 表示已收到回调
return jsonify({'status': 'received'}), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)PHP
php
<?php
header('Content-Type: application/json');
$body = json_decode(file_get_contents('php://input'), true);
$code = $body['code'] ?? null;
$data = $body['data'] ?? [];
error_log("收到回调: taskId={$data['taskId']}, state={$data['state']}, code=$code");
if ($code === 200 && ($data['state'] ?? '') === 'success') {
$result = json_decode($data['resultJson'], true);
$videoUrl = $result['resultUrls'][0];
error_log("视频地址: $videoUrl");
// 在这里下载并保存视频
} else {
error_log("任务失败: " . ($data['failCode'] ?? '') . " " . ($data['failMsg'] ?? ''));
}
// 返回 200 表示已收到回调
http_response_code(200);
echo json_encode(['status' => 'received']);
?>最佳实践
回调地址配置建议
- 回调地址使用 HTTPS。
- 校验回调来源。
- 幂等处理:同一个
taskId可能收到多次回调。 - 快速响应 HTTP 200,耗时的业务逻辑异步处理。
- 及时下载:收到回调后尽快把视频存到自己的存储。
:::caution 重要提醒
- 回调地址必须可从公网访问。
- 服务器须在 15 秒内响应,否则视为超时。
- 连续 3 次重试失败后,系统将停止发送该回调。
:::
故障排查
收不到回调
- 确认回调地址可从公网访问,且未被防火墙拦截。
- 确认服务器在 15 秒内返回 HTTP 200。
- 确认路径与请求方法(POST)正确。
取不到视频地址
data.resultJson是 JSON 字符串,先解析再读取resultUrls[0]。- 失败时(
code501、state为 fail)没有resultJson,请读取data.failMsg。
替代方案
如果无法使用回调,也可以轮询任务状态:
- 获取任务详情 — 用 taskId 查询任务,结果在 resultJson.resultUrls,与回调一致。