数字人口播视频 API 实战:Python 跑通模板合成、异步轮询与批量出片

简介: 本文详解如何用销豹AI API实现真人口播视频的自动化剪辑:将素材整理、字幕匹配、模板包装等重复环节封装为API,仅需维护文案、人物视频与模板,程序自动完成任务提交、状态轮询与成片归档。附Python完整示例与工程实践要点。(239字)

对于需要持续更新口播视频的团队,真正耗时的往往不是写文案,而是重复执行素材整理、字幕匹配、模板包装、导出和检查。

把这些重复环节封装成 API 后,内容人员只需要维护文案、人物视频和模板,程序负责提交任务、查询状态和归档成片。一个人管理多条内容生产线,才有了工程上的可行性。

本文以销豹 AI API 开放平台的智能剪辑能力为例,用 Python 跑通下面这条链路:

选择 realMan 模板
    ↓
读取模板详情,确认画布与图层
    ↓
提交已有真人/数字人口播视频
    ↓
realman_broadcast 创建异步合成任务
    ↓
task_query 轮询任务状态
    ↓
获取 video_url,归档成片

先说明一个容易混淆的概念:realman_broadcast 的作用是对已有真人或数字人口播视频进行模板化合成与包装,并不是把一段文案直接变成数字人的单接口。

如果当前只有文案,完整链路应当拆成:

文案 → TTS 语音合成 → 数字人合成 → 智能剪辑包装 → 成片

本文重点演示后半段的智能剪辑接入。接口信息核对日期为 2026 年 11 月 2 日,实际参数与计费请以官方文档和控制台为准。

一、接入前需要准备什么?

开始写代码前,需要准备四项内容:

  1. API Key:在平台控制台创建,只保存在服务端环境变量或密钥管理系统中。
  2. 人物视频地址:公网可访问的 mp4/mov 文件,平台需要读取视频并探测时长。
  3. 模板 ID:通过模板列表接口获取,真人口播场景使用 scene=realMan。
  4. 回调地址:创建任务时需要提交 callback_url;同时建议保留任务轮询作为兜底。

人物视频的主要限制包括:

  • 视频编码支持 H.264、HEVC/H.265;
  • 帧率支持 10~60 fps,官方建议 25 fps;
  • 单边分辨率小于 2000 px;
  • 视频时长小于 5 分钟,文件小于 500 MB;
  • 视频中的音频需要能够进行语音转文本。

建议在上传阶段完成格式、大小和时长校验,不要等到合成任务失败后再排查。

二、第一步:获取真人口播模板

不同剪辑模式对应不同 scene,不能混用:

业务模式 scene 最终合成接口
真人口播 realMan realman_broadcast
素材混剪 oralMixCutting broadcast_mixcut
新闻混剪 newsMixCutting news_mixcut
视频包装 realMan realman_broadcast

获取真人口播模板的请求如下:

curl -X POST "https://xiaoapis.com/api/smartclip/template" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "YOUR_API_KEY",
    "scene": "realMan",
    "pageSize": 10,
    "sortBy": "desc"
  }'

模板列表位于 data.result.data.results,重点字段如下:

{
   
  "id": "6a2668a137004e003477b6ed",
  "name": "双语大橙",
  "coverUrl": "https://example.com/cover.jpg",
  "scene": "realMan",
  "demoUrl": "https://example.com/demo.mp4"
}

其中,id 就是创建合成任务时使用的 styleId。

生产环境中可以缓存模板列表,用户选中某个模板后,再调用模板详情接口读取画布和图层信息,不必每次打开页面都重新请求完整列表。

三、第二步:读取模板详情

curl -X POST "https://xiaoapis.com/api/smartclip/template_detail" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "YOUR_API_KEY",
    "id": "6a2668a137004e003477b6ed"
  }'

模板详情中的 videoStructInfo 描述了画布和图层结构。例如:

{
   
  "videoStructInfo": {
   
    "editInfo": {
   
      "canvas": {
   
        "width": 1080,
        "height": 1920
      }
    }
  }
}

如果只需要使用模板默认效果,可以不修改图层;如果需要调整标题、字幕等图层,再根据模板详情构造 structLayers。

四、第三步:创建异步合成任务

接口地址:

POST https://xiaoapis.com/api/smartclip/realman_broadcast?action=create
Content-Type: application/json

最小请求只需要四个业务字段。使用 POST + JSON 时,key 必须放在 JSON Body 中:

{
   
  "key": "YOUR_API_KEY",
  "styleId": "6a2668a137004e003477b6ed",
  "videoUrl": "https://example.com/presenter.mp4",
  "callback_url": "https://example.com/api/callbacks/smartclip",
  "resolution": "720p"
}

其中,resolution 可选 720p 或 1080p,不传时默认为 720p。

创建成功返回的并不是成片地址,而是任务 ID:

{
   
  "code": 200,
  "msg": "success",
  "data": {
   
    "task_id": "task_6139c79459b9594a32f4737b",
    "status": 1,
    "progress": 0,
    "api_type": "realman_broadcast",
    "power_cost": 150
  }
}

创建接口中的状态值为:1 处理中、2 完成、3 失败。业务代码应先保存 task_id,再进入回调处理或任务查询流程。

五、完整 Python 示例:创建任务并轮询成片

安装依赖:

pip install requests

设置环境变量:

export XIAOAPIS_API_KEY="你的_API_Key"
export XIAOAPIS_STYLE_ID="真实模板_ID"
export XIAOAPIS_VIDEO_URL="https://你的域名/presenter.mp4"
export XIAOAPIS_CALLBACK_URL="https://你的域名/api/callbacks/smartclip"

完整代码:

import os
import time

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry


API_KEY = os.environ["XIAOAPIS_API_KEY"]
STYLE_ID = os.environ["XIAOAPIS_STYLE_ID"]
VIDEO_URL = os.environ["XIAOAPIS_VIDEO_URL"]
CALLBACK_URL = os.environ["XIAOAPIS_CALLBACK_URL"]

CREATE_URL = "https://xiaoapis.com/api/smartclip/realman_broadcast"
QUERY_URL = "https://xiaoapis.com/api/smartclip/task_query"


def build_session() -> requests.Session:
    """只对可重复执行的 GET 查询做自动重试,不自动重试创建任务。"""
    retry = Retry(
        total=3,
        backoff_factor=1,
        status_forcelist=(429, 500, 502, 503, 504),
        allowed_methods=frozenset(["GET"]),
        respect_retry_after_header=True,
    )
    session = requests.Session()
    session.mount("https://", HTTPAdapter(max_retries=retry))
    return session


def parse_response(response: requests.Response) -> dict:
    response.raise_for_status()
    payload = response.json()
    if payload.get("code") != 200:
        raise RuntimeError(
            f"API 业务错误:code={payload.get('code')}, msg={payload.get('msg')}"
        )
    return payload


def create_task(session: requests.Session) -> str:
    payload = {
   
        "key": API_KEY,
        "styleId": STYLE_ID,
        "videoUrl": VIDEO_URL,
        "callback_url": CALLBACK_URL,
        "resolution": "720p",
        "language": "zh-CN",
    }

    # 创建任务不自动重试,避免响应丢失时重复创建任务。
    response = session.post(
        CREATE_URL,
        params={
   "action": "create"},
        json=payload,
        timeout=(10, 60),
    )
    data = parse_response(response)["data"]
    return data["task_id"]


def query_task(session: requests.Session, task_id: str) -> dict:
    response = session.get(
        QUERY_URL,
        params={
   "key": API_KEY, "task_id": task_id},
        timeout=(5, 30),
    )
    return parse_response(response)["data"]


def wait_for_result(
    session: requests.Session,
    task_id: str,
    timeout_seconds: int = 900,
) -> str:
    deadline = time.monotonic() + timeout_seconds
    time.sleep(2)

    while time.monotonic() < deadline:
        data = query_task(session, task_id)
        status = data.get("status")
        progress = data.get("progress", 0)
        print(f"task_id={task_id}, status={status}, progress={progress}")

        if status == "completed":
            video_url = data.get("video_url") or (data.get("result") or {
   }).get("video_url")
            if not video_url:
                raise RuntimeError("任务已完成,但响应中没有 video_url")
            return video_url

        if status == "failed":
            reason = data.get("fail_reason") or data.get("error")
            raise RuntimeError(f"合成失败:{reason}")

        if status not in {
   "pending", "processing"}:
            raise RuntimeError(f"未知任务状态:{status}")

        time.sleep(3)

    raise TimeoutError(f"任务在 {timeout_seconds} 秒内未完成:{task_id}")


def main():
    session = build_session()
    task_id = create_task(session)
    print(f"任务已创建:{task_id}")

    video_url = wait_for_result(session, task_id)
    print(f"成片地址:{video_url}")


if __name__ == "__main__":
    main()

这里有两个细节值得注意:

  • 创建与查询的状态格式不同:创建接口返回数字状态 1/2/3,独立任务查询接口返回 pending/processing/completed/failed,不要混用判断逻辑。
  • 查询可以重试,创建不能盲目重试:示例只对 GET 查询配置自动重试。如果创建请求超时,响应中的 task_id 可能已经生成但客户端没有收到,立即重新 POST 可能造成重复任务。

官方建议提交后约 2 秒开始查询,轮询间隔设为 2~5 秒;任务查询不扣费。生产环境还应设置超时、告警和人工复核入口,不能写成无限循环。

六、单条视频成本怎么估算?

根据当前真人口播接口文档,智能剪辑按输出分辨率和输入视频秒数计费:

输出规格 文档列示单价
720p 3 点/输入秒
1080p 4 点/输入秒

计算公式:

智能剪辑消耗点数 = ceil(输入视频秒数) × 对应规格单价

例如,输入视频实际时长为 58.2 秒,按 59 秒计费:

720p:59 × 3 = 177 点
1080p:59 × 4 = 236 点

创建任务后,还应记录响应中的 power_cost,并与控制台账单核对。价格属于动态信息,批量运行前请重新查看接口文档与控制台,不要把文章中的示例单价写成长期报价。

如果从文案开始生产,完整成本还应包含 TTS、数字人合成、素材存储、带宽、失败重试和人工质检。比较人工流程与 API 流程时,建议统一使用下面的口径:

单条有效成片成本 =
(API 成本 + 存储与带宽成本 + 人工成本 + 失败重试成本)
÷ 验收通过的成片数量

相比笼统地宣称“效率提升多少倍”,用小样本记录单条人工分钟数、验收通过率、P50/P95 出片时长和单条有效成片成本,更有助于判断是否适合放量。

七、批量上线前的五个工程检查点

1. 不要把 API Key 放到前端

前端只调用自己的业务后端,由后端保存密钥并调用平台接口。任务查询需要把 key 放在 URL 查询参数中,因此还要检查网关、访问日志和 APM 是否会对敏感参数脱敏。

2. 给每个任务建立完整记录

至少保存:业务视频 ID、task_id、模板 ID、输入视频地址、任务状态、power_cost、失败原因和最终成片地址。日志中不要记录 API Key。

3. 回调与轮询要能做终态对账

收到回调后,可以根据 task_id 再查询一次任务状态,确认终态与成片地址。重复回调或重复查询不应导致业务系统重复发布同一条视频。

4. 在上传阶段校验素材

重点检查视频格式、编码、时长、文件大小和公网可访问性。模板要求的素材格式、数量、尺寸和时长,也应在提交任务前完成校验。

5. 把肖像、声音与素材授权纳入流程

数字人形象、真人视频、克隆音色、音乐和图片都可能涉及授权。批量生成之前,应确认使用权和内容合规要求,并为生成内容保留必要的审核环节。

八、常见问题

Q1:只有文案,可以直接调用 realman_broadcast 吗?

不能直接这样理解。该接口需要传入已有的 videoUrl。只有文案时,应先完成 TTS 和数字人合成,再把生成的人物视频交给智能剪辑接口包装。

Q2:配置了 callback_url,还需要轮询吗?

建议保留轮询作为补偿机制。回调用于及时接收终态,轮询用于处理回调未到达、业务服务重启等情况,两者都应以 task_id 关联同一条任务记录。

Q3:创建任务超时后,应该立即重试吗?

不建议直接重试。网络超时不等于任务未创建,盲目重试可能产生重复任务和重复计费。应先记录异常并进入人工或自动对账流程;对于已经拿到 task_id 的任务,查询接口可以安全重试。

Q4:如何评估是否真的降本提效?

先选一批相同时长、相同模板和相同分辨率的内容试跑,对比人工流程与 API 流程的单条人工分钟数、验收通过率、出片时长和有效成片成本,再决定是否扩大批量。

结语

数字人口播 API 的价值,不是把内容生产简化成一个“生成”按钮,而是把人物素材、模板、任务状态、计费和质检连接成可观测的生产流水线。

对开发者而言,最小可行路径也很清晰:先跑通一种 realMan 模板,再接入任务查询和业务对账,最后扩展批量队列。 相比一开始同时接入多种剪辑模式,这条路径更容易定位参数问题,也更容易核算真实成本。

相关文章
|
4天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
|
云安全 安全 网络安全
|
18天前
|
JSON 程序员 数据格式
最新版Notepad++下载、安装、配置保姆级教程(附官网安装包)
Notepad++ 是一款免费开源、轻量快速的 Windows 文本编辑器,支持多标签、语法高亮、代码折叠与宏录制,体积小、启动快、资源占用低,兼容 x64/x32/ARM 架构,是程序员和文字工作者的高效利器。
4333 2
|
17天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
2886 49
|
11天前
|
JavaScript 安全 前端开发
Nodejs Brotli decoder 代码执行漏洞 (CVE-2026-111497)10629
Node.js发布安全更新修复Brotli解码器高危RCE漏洞(CVE-2026-111497),建议受影响版本用户立即升级。
2094 2
|
9天前
|
人工智能 JSON Linux
【保姆级】ComfyUI部署教程(下载+安装+配置+工作流,2026最新)
ComfyUI 是一款开源节点式AI生成工具,支持图像、视频、音频及3D内容创作。通过拖拽连线组合模型加载、提示词、采样等节点,构建可复用、易修改的工作流,兼容SD1.5、SDXL、Flux、Qwen Image等主流模型。
|
14天前
|
Web App开发 人工智能 前端开发
2026 年 AI 浏览器怎么选?Ego Lite、Tabbit、Chrome DevTools MCP 深度对比,开发者到底该用哪个?
2026年AI浏览器选型指南:Ego Lite专注多Agent协同(Mac优先),Tabbit国产首选,原生支持Windows与Codex控制;Chrome DevTools MCP非浏览器而是开发者利器,深度集成Console/Network/Performance调试能力,让AI真正“看懂并验证”前端代码。
1550 3
|
11天前
|
开发者 索引
DeepSeekHarness大肥鱼自带插件市场了?加个地址就能用
Open Plugin Market 是一个开放插件索引平台,收录800+优质DSH插件,支持分类浏览、智能推荐与随机发现。无需安装市场,粘贴索引地址即可一键接入,网页版直访 dshopen.org,助力小开发者被看见。(239字)
2206 1
DeepSeekHarness大肥鱼自带插件市场了?加个地址就能用

热门文章

最新文章