接口接收参数:
1.数据体:data = {"xxxx": "xxxx"} or {}
2.分配给外部的密钥:secret = "iamsecret"
3.接口方法路径(不包含host):api_path = "/xxx/xxx?xx=xxx"
计算步骤:
1.将api_path转换为全小写形式:lower_api_path
2.将请求method方法转为小写形式:lower_method(例如:"delete"/"post"/...)
3.将data转换为json的字符串形式:sort_json_str
以python为例:json.dumps(dict(data), sort_keys=True).replace(' ', '')
4.按照如下顺序连接字符串:lower_api_path + lower_method + sort_json_str + secret + X-TIMESTAM
a.X-TIMESTAMP:接口秒级时间戳,距当前时间60s内有效
b.得到sign:/xxx/xxx?xx=xxx{"xxxx": "xxxx"}iamsecret1489133053
5.将sign以utf8编码,计算md5得到X-TOKEN:ddc6457fd0b373475ac65912b797ef05
请求接口时应该加入如下头部信息:
import time
import json
import hashlib
import requests
from urllib.parse import urljoin
def encode_with_md5(s):
m = hashlib.md5()
m.update(s.encode('utf-8'))
return m.hexdigest()
def headers_need_sign(ak, secret, method, url, data):
headers = {}
t = int(time.time())
data = json.dumps(dict(data), sort_keys=True).replace(' ', '')
ori_sign = '{0}{1}{2}{3}{4}'.format(url.lower(), method.lower(), data, secret, t)
sign = encode_with_md5(ori_sign)
headers["X-APP-ID"] = ak
headers["X-TOKEN"] = sign
headers["X-TIMESTAMP"] = str(t)
return headers
if __name__ == '__main__':
ak = '37514ac0-3fce-4f4c-bc3f-86eba37da7dd'
secret = 'bb81b706-ef1f-443e-9e86-9df8399f796b'
method = 'POST'
host = 'https://nebula-agent.xingyun3d.com'
url = '/xxx/xxx?x=xx&z=zz'
req_data = {
"data1": "data1",
"data2": "data2",
}
# 计算获取请求headers
req_headers = headers_need_sign(ak, secret, method, url, req_data)
# 请求接口
req_url = urljoin(host, url)
resp = requests.request(method, req_url, json=req_data, headers=req_headers)
方式1:通过segment发起渲染
host: https://nebula-agent.xingyun3d.com
请求路径:Post: /user/v1/video_synthesis_task/create_render_task
请求参数
参数名 | 类型 | 名称 | 是否必填 | 备注 |
---|---|---|---|---|
video_name | string | 视频名称 | 非必填 |
|
look_name | string | 形象名 | 必填 |
|
tts_vcn_name | string | 音色 | 必填 |
|
studio_name | string | 演播室 | 必填 |
|
sub_title | string | 是否开启字幕 | 非必填 |
|
segment | JSON | SSML脚本 | 非必填 | 数组格式,SSML脚本 或 PPT文件 必填一个 |
if_aigc_mark | bool | 是否AI生成标识 | 非必填 |
|
返回参数:
一级参数名 | 二级参数名 | 类型 | 名称 | 备注 |
---|---|---|---|---|
error_code | int | 错误码 | 0:成功 其他:错误 | |
error_reason | string | 错误原因 | ||
data | dict | |||
task_id | int | 视频任务ID |
方式2:通过PPT发起渲染
先调用 PPT解析接口 再调用 创建渲染任务接口
PPT解析接口:host: https://nebula-agent.xingyun3d.com
请求路径:Post: /user/v1/video_synthesis_task/parse_ppt_file
请求参数
参数名 | 类型 | 名称 | 是否必填 | 备注 |
---|---|---|---|---|
ppt_file | binary | PPT文件 | 必填 | X-TOKEN计算 不需要加入该参数 |
返回参数
一级参数名 | 二级参数名 | 类型 | 名称 | 备注 |
---|---|---|---|---|
error_code | int | 错误码 | 0:成功 其他:错误 | |
error_reason | string | 错误原因 | ||
data | dict | |||
parse_ppt_file_name | string | PPT文件解析名称 |
创建渲染任务接口:
host: https://nebula-agent.xingyun3d.com
请求路径:Post: /user/v1/video_synthesis_task/create_render_task
请求参数
参数名 | 类型 | 名称 | 是否必填 | 备注 |
---|---|---|---|---|
video_name | string | 视频名称 | 非必填 |
|
look_name | string | 形象名 | 必填 |
|
tts_vcn_name | string | 音色 | 必填 |
|
studio_name | string | 演播室 | 必填 |
|
sub_title | string | 是否开启字幕 | 非必填 |
|
parse_ppt_file_name | string | PPT文件解析名称 | 必填 | 通过调用PPT解析接口获取 |
if_aigc_mark | bool | 是否AI生成标识 | 非必填 |
|
返回参数
一级参数名 | 二级参数名 | 类型 | 名称 | 备注 |
---|---|---|---|---|
error_code | int | 错误码 | 0:成功 其他:错误 | |
error_reason | string | 错误原因 | ||
data | dict | |||
task_id | int | 视频任务ID |
host: https://nebula-agent.xingyun3d.com
请求路径:GET: /user/v1/video_synthesis_task/get_render_task
请求参数
参数名 | 类型 | 名称 | 是否必填 | 备注 |
---|---|---|---|---|
task_id | int | 视频任务ID | 必填 |
返回参数
一级参数名 | 二级参数名 | 类型 | 名称 | 备注 |
---|---|---|---|---|
error_code | int | 错误码 | 0:成功 其他:错误 | |
error_reason | string | 错误原因 | ||
data | dict | |||
task_id | int | 视频任务ID | ||
synth_state | string | 任务状态 | not_send:排队中 waiting:处理中 processing:进行中 finished:已完成 error:合成失败 cancel:合成取消 | |
render_image_oss | string | 成片预览图 |
| |
render_video_oss | string | 成片视频 |
| |
synth_start_time | datetime | 成片开始时间 | 视频渲染开始时间 | |
synth_finish_time | datetime | 成片完成时间 |
| |
error_reason | string | 错误日志 |
a. 解析ppt文件报错 b. 创建合成任务报错 c. 检验限流报错 d. 创建有言任务报错 |
host: https://nebula-agent.xingyun3d.com
请求路径:Post: /user/v1/video_synthesis_task/cancel_render_task
请求参数
参数名 | 类型 | 名称 | 是否必填 | 备注 |
---|---|---|---|---|
task_id | int | 视频任务ID | 必填 |
返回参数
一级参数名 | 二级参数名 | 类型 | 名称 | 备注 |
error_code | int | 错误码 | 0:成功 其他:错误 | |
error_reason | string | 错误原因 |
host: https://nebula-agent.xingyun3d.com
请求路径:GET: /user/v1/video_synthesis_task/get_render_task_preview_url
请求参数
参数名 | 类型 | 名称 | 是否必填 | 备注 |
---|---|---|---|---|
task_id | int | 视频任务ID | 必填 |
返回参数
一级参数名 | 二级参数名 | 类型 | 名称 | 备注 |
error_code | int | 错误码 | 0:成功 其他:错误 | |
error_reason | string | 错误原因 | ||
data | dict | |||
preview_url | int | 预览url |
错误码Code | 错误码描述 |
---|---|
20001 | 应用不存在或无法使用 |
30002 | PPT文件不存在 |
30003 | PPT文件解析错误 |
30004 | 视频任务未找到 |
30005 | 创建视频任务错误 |
30006 | 取消视频任务错误 |
Post: /user/v1/video_synthesis_task/create_render_task
Body:
{
"look_name": "AM054_Jap_9021_new",
"tts_vcn_name": "XMOV_HN_TTS__236",
"studio_name": "youling_2d_v",
"segment": [{
"text": "为推动我国制造业数字化转型,促进智能制造技术正确应用,加强企业间友好交流合作,",
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/74275_4b733edeca68484e8940da.png"
},
{
"text": "SIA上海国际工业自动化及机器人展览。整合多年行业资源、汇聚发展优势,将于2024年7月24至26日,在上海国家会展中心隆重举办。",
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/74275_df35e07846584dd98974bf.mp4"
},
{
"text": "同期将举行多场论坛。邀请权威专家。知名企业。和主流厂商。分享智能制造发展的前沿趋势。典型案例。应用热点。以及实施策略。",
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/74275_1ca7a4a5407c43acb0da8b.mp4"
}
], # 可传 segment 或 PPT文件
# PPT文件
"ppt_file": 复古艺术.pptx # binary
}
Response:
{
"error_code": 0,
"error_reason": "",
"data": {
"task_id": 135
}
}
# coding=utf-8
import hashlib
import json
import time
import requests
def generate_x_token(data, secret, api_path, method, timestamp=None):
lower_api_path = api_path.lower()
lower_method = method.lower()
sort_json_str = json.dumps(dict(data), sort_keys=True).replace(' ', '')
x_timestamp = str(int(timestamp or time.time()))
sign_str = f"{lower_api_path}{lower_method}{sort_json_str}{secret}{x_timestamp}"
return hashlib.md5(sign_str.encode('utf-8')).hexdigest()
app_id = 'xxxxx' # 替换成应用的App ID
secret = 'xxxxx' # 替换成应用的App Secret
host = 'https://nebula-agent.xingyun3d.com'
# PPT解析接口
files = [
('ppt_file', ('PPT模板.pptx', open('PPT模板.pptx', 'rb'),
'application/vnd.openxmlformats-officedocument.presentationml.presentation'))
]
data= {}
api_path = '/user/v1/video_synthesis_task/parse_ppt_file'
method = 'POST'
timestamp = int(time.time())
headers = {}
headers["X-APP-ID"] = app_id
headers["X-TOKEN"] = generate_x_token(data, secret, api_path, method, timestamp)
headers["X-TIMESTAMP"] = str(timestamp)
start_time = time.time()
resp = requests.request(method, f'{host}/{api_path}', data=data,
headers=headers, timeout=30, files=files)
res = resp.json()
print(res)
parse_ppt_file_name = res.get('data').get('parse_ppt_file_name')
# 创建渲染任务接口
data = {"look_name": "caihongwei_3663_new", "tts_vcn_name": "XMOV_EN_TTS__13", "if_aigc_mark": True,
"studio_name": "telestudio_simple_red_01", "sub_title": "on", "video_name": "测试调用API生成视频",
"parse_ppt_file_name": parse_ppt_file_name}
api_path = '/user/v1/video_synthesis_task/create_render_task'
method = 'POST'
timestamp = int(time.time())
headers = {"content-type": "application/json"}
headers["X-APP-ID"] = app_id
headers["X-TOKEN"] = generate_x_token(data, secret, api_path, method, timestamp)
headers["X-TIMESTAMP"] = str(timestamp)
resp = requests.request(method, f'{host}/{api_path}', json=data,
headers=headers, timeout=30)
res = resp.json()
print(resp.json())
task_id = res.get('data').get('task_id')
data = {
"task_id": task_id
}
GET: /user/v1/video_synthesis_task/get_render_task
Params: task_id: 135 # 任务id
Response:
{
"error_code": 0,
"error_reason": "",
"data": {
"id": 135,
"error_reason": "合成任务失败,请重新发起或联系客服处理",
"create_time": "2025-07-17T11:30:08.033710+08:00",
"update_time": "2025-07-17T11:30:54.131480+08:00",
"enable": true,
"name": "6b187ef0c68c4ef2b9fda5964a392067",
"video_name": "20250717_11_30_07.833",
"output_resolution": "540P",
"look_name": "AM058_10518_new",
"tts_vcn_name": "XMOV_HN_TTS__6",
"studio_name": "bust_chic_art_museum_01",
"sub_title": "on",
"synth_start_time": null,
"synth_finish_time": null,
"synth_state": "error",
"segment": [
{
"text": "这是一条测试数据。",
"media_id": 123338,
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/171998_b37eb4385ec64bec9fd4be.png"
},
{
"text": "测试数据片段1",
"media_id": 123339,
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/171998_b3195096c8d64cdfaa3b80.png"
},
{
"text": "测试数据片段2",
"media_id": 123340,
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/171998_e30188384695418b831ce6.png"
},
{
"text": "测试数据片段3",
"media_id": 123341,
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/171998_0cef3d5134474e87ad10b1.png"
},
{
"text": "测试数据片段4",
"media_id": 123342,
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/171998_97acf13816a0480f9b76ae.png"
},
{
"text": "测试数据片段5",
"media_id": 123343,
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/171998_5cd15131918e487f8184a2.png"
},
{
"text": "测试数据片段6",
"media_id": 123344,
"media_url": "https://media.xmov.ai/youyan/user_upload_qa/171998_da32d7eece66455182f6ce.png"
}
],
"render_image_oss": null,
"render_video_oss": null
}
}
Post: /user/v1/video_synthesis_task/cancel_render_task
{
task_id: 135 # 任务id
}
Response:
{
"error_code": 0,
"error_reason": ""
}