2024 年以来,视频生成赛道卷得飞起——Seedance、Kling轮番刷榜,生成质量肉眼可见地在提升。但如果你真正尝试把这些模型落地到产品里,会发现一个共同的天花板:它们都是"离线"的。
行业里当前的"实时数字人"方案,本质是一条拼接链路——ASR 转文字、LLM 生成回复、TTS 合成语音、再驱动口型对齐模型。模块割裂,链路长延迟高,角色的表情动作全靠预设动画库硬凑,谈不上真正的"生成式交互"。
Vidu S1 换了个思路:不做模块拼接,直接让视频生成模型本身具备实时交互能力,让 AI 视频从"离线生成"迈向"实时交互"。
一、核心能力拆解
1. 语音指令实时跟随

传统数字人是"语音驱动口型"——嘴型能对上,但表情、动作靠预设动画库。Vidu S1 做的是"语音控制行为":结合语音内容、情绪和画面状态,实时生成口型、表情、手势和身体姿态,不调动作模板。
过去:语音输入 → 口型同步
现在:语音输入 → 行为理解 → 实时生成表情、动作与反馈
2. 无限时长实时生成

传统模型一次输出一段固定视频,过程中没法改方向。Vidu S1 采用自回归路线,逐帧预测,每一帧都可以接收当前时刻的新指令:
历史画面 + 当前语音/指令 → 生成下一帧 → 更新状态 → 继续
同时维护两级上下文保证稳定性:
-
长期 anchor:锁定角色身份,防止形象漂移
-
短期滑动窗口:保证相邻帧动作连贯
3. 540P + 25FPS 实时输出

模型侧和系统侧同时优化:
-
模型侧:TurboDiffusion(少步生成)+ SageAttention(8-bit 注意力)+ SLA / SpargeAttention(稀疏注意力),消费级显卡可运行
-
系统侧:TurboServe 流式 Serving,播放当前帧时已在算下一帧,新指令可即时注入后续生成
不只是帧率指标——这是进入视频通话、直播、陪伴场景的基础门槛。
4. 一张图即时建角色

不需要多图建模、绑定、训练。上传一张首帧图,模型即时理解角色外观和风格,直接开始交互。支持真人、动漫、萌宠,支持音色克隆。
过去:上传素材 → 等待训练 → 开始使用 现在:上传首帧 → 即时交互
二、使用场景与最佳案例
AI 陪伴、虚拟 IP、互动游戏、AI 客服、电商直播——所有需要"角色实时在线"的场景。
1. AI陪伴
ViduS1-AI陪伴
2. 电商直播
ViduS1-AI电商
三、API 接入实战:6 步搞定
好了,说完原理,来点实在的。Vidu S1 已经开放了 API,接入流程其实挺清晰的。
你需要准备什么
-
一个 API Key(格式:
Token vda_xxx,可以这里获取) -
麦克风(必须),摄像头(video 模式需要)
-
一张数字人形象图(URL 或 Base64)
-
一段人设描述文字
-
接入阿里云 RTC SDK(音视频传输用)
完整接入流程
第1步:调接口创建数字人会话 → 拿到"房间号"和"入场券"
第2步:用"入场券"接入阿里云 RTC 视频频道
第3步:建立 WebSocket 连接,发"我准备好了"的信号
第4步:收到"数字人准备好了"的回复,开始互动
第5步:互动中保持心跳,处理被强制断开的情况
第6步:通话结束,发挂断信号,查账单
接口总览
| 方法 | 路径 | 用途 |
|---|---|---|
| POST |
| 创建数字人会话 |
| GET |
| 查询会话状态和账单 |
| WebSocket |
| 控制信令(开始/挂断) |
| POST |
| 创建新音色 |
| GET |
| 查询音色列表(系统音色 + 自定义音色) |
Step 1:创建数字人会话
调这个接口,相当于"开一个房间"。
注意:
{host}使用真实域名,文档里是占位符
国内域名:api.vidu.cn
海外域名:api.vidu.com
请求:
POST https://{host}/live/v1/lives
Authorization: Token vda_xxx
Content-Type: application/json
{
"call_mode": "video",
"avatar": {
"persona": "你是一个友好的客服,请自然地与用户实时互动",
"image_uri": "https://你的数字人图片地址.png",
"name": "小美",
"voice": ""
}
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
|
| String | 是 | 交互方式,目前提供2种交互方式,可以根据需求自由选择,枚举值如下:
|
|
| String | 是 | 数字人的人设,不限字符数,具体见“推荐的人设模板”章节 |
|
| String | 是 | 数字人形象图片地址,支持图片URL和base64
|
|
| String | 否 | 数字人名字,建议20字符内 |
|
| String | 否 | 音色,不填用默认,Vidu支持音色克隆,具体见:【音色克隆接口】 默认值:Tina |
你会收到:
{
"live": {
"id": "123456789",
"status": "waiting",
"live_duration": 600,
"call_mode": "video"
},
"rtc": {
"app_id": "xxxx",
"channel_id": "live-user-123456789",
"user_id": "live-user-1001-123456789",
"token": "base64-token...",
"token_expire_at": "1750003600"
}
}
关键字段说明:
| 字段 | 字段类型 | 说明 |
|---|---|---|
|
| String | 房间ID,后面所有步骤都要用这个,务必保存 |
|
| String | 此时是 |
|
| Int | 本次会话最大时长(秒),超时自动断开,最大600秒 |
|
| String | 进视频房间的凭证,默认1小时有效 |
|
| String | 你在RTC频道里的用户名 |
|
| String | token过期时间(Unix时间戳),过期需重新创建会话 |
⚠️ 此时数字人状态是
waiting,房间建好了但还没人进去,继续下一步。
Step 2:接入 RTC(进入视频通话房间)
数字人的视频和声音不是通过 HTTP 传的,是通过实时音视频通道传的,所以必须先接入这个频道才能看到/听到数字人。
阿里云 RTC SDK 下载地址:
https://help.aliyun.com/zh/live/introduction-to-real-time-audio-and-video-artc-sdk
用第一步拿到的信息加入频道:
// 加入频道(用第一步拿到的 rtc.token 和 rtc.user_id)
await aliRtc.joinChannel(rtc.token, rtc.user_id);
// 推送你自己的麦克风声音(必须推,否则数字人听不到你说话)
await aliRtc.publishLocalAudioStream(true);
// 推送你自己的摄像头画面(只有 video 模式才需要)
await aliRtc.publishLocalVideoStream(true);
// 订阅数字人的音视频(这样才能看到/听到数字人)
// 数字人在频道里的用户ID固定格式是:live-bot-{creatorID}-{liveID}
aliRtc.on('videoSubscribeStateChanged', (uid, newState) => {
if (newState === 'subscribed') {
// 把视频流渲染到你的页面上
}
});
RTC频道里各角色的用户ID格式:
| 角色 | 用户ID格式 |
|---|---|
| 你(用户) |
|
| 数字人 |
|
| 视频推流 |
|
⚠️ 进了视频房间,但数字人还没"开机",继续下一步发信号。
如果是 App:
### audio 模式
join channel: live-audio-{liveID}
my uid: live-user-{creatorID}-{liveID}
publish:
- 麦克风音频 -> live-user-{creatorID}-{liveID}
subscribe:
- 数字人音频 -> live-bot-{creatorID}-{liveID}
### video 模式
join channel: live-user-{liveID}
my uid: live-user-{creatorID}-{liveID}
publish:
- 麦克风音频 -> live-user-{creatorID}-{liveID}
- 摄像头视频 -> live-user-{creatorID}-{liveID}
subscribe:
- 数字人视频 -> live-video-push-{creatorID}-{liveID}
Step 3:建立 WebSocket 连接并发"开始"信号
WebSocket 是一条持续保持的"控制通道",用来告诉服务器你准备好了,以及后续的挂断操作。
注意:
{host}使用真实域名,文档里是占位符
国内域名:api.vidu.cn
海外域名:api.vidu.com
连接地址:
wss://{host}/live/ws/live/connect?live_id={live_id}
Authorization: Token vda_xxx
Content-Type: application/json
连接建立后,立刻发这条消息:
{
"type": 1,
"live_id": "123456789",
"seq_id": 1,
"payload": {
"conn_init": { "version": 1 } // version固定 1
}
}
Step 4:等待数字人准备好
发完上一步的消息后,等待服务器回复。
情况一:数字人准备好了 ✅
{
"type": 2,
"payload": {
"conn_init_ack": { "success": true } // success:true/false
}
}
→ 收到这个,数字人正式上线,可以开始说话了!
情况二:数字人还没准备好(video模式常见)⏳
{
"type": 2,
"payload": {
"conn_init_ack": {
"success": false,
"error_code": "NOT_READY"
}
}
}
→ 收到这个,按以下步骤重试:
-
关闭当前 WebSocket 连接
-
等待 2-3 秒
-
重新建立 WebSocket 连接(回到第三步)
-
重复直到收到
success: true,建议使用指数退避(2s → 4s → 8s)
情况三:初始化彻底失败 ❌
{
"type": 2,
"payload": {
"conn_init_ack": {
"success": false,
"error_code": "LIVE_CONN_INIT_FAILED"
}
}
}
→ 这个不是临时错误,需要回到第一步重新创建会话。
Step 5:互动进行中
保持心跳
服务端每 5 秒发一次 ping,你的客户端必须在 15 秒内有任何消息,否则被服务器判定为死连接强制断开。大多数 WebSocket 库会自动处理 ping/pong,但一定要确认你的库开启了自动回复。
通过文字聊天
-
音视频模式和音频模式都支持通过文字对话聊天
{
"type": 99,
"payload": {
"text_msg": {
"content": "你好"
}
}
}
处理被强制断开(必须处理!)
服务器可能随时踢你下线,收到这条消息就是被强制断开:
{
"type": 6,
"payload": {
"hangup": {
"hangup_reason": "xxxx"
}
}
}
根据 hangup_reason 处理:
| hangup_reason | 触发场景 |
|---|---|
|
| 用户主动断开 |
|
| 会话超时 |
|
| 会话触发风控断开 |
|
| 积分不足 |
|
| SIP/provider 侧关闭 |
|
| provider 主动 close |
|
| SIP 断连后超过重连宽限仍未恢复 |
|
| App 客户端断线后超过重连宽限仍未恢复 |
|
| video live 还在 prepared、App 从未 ready/未开播时 SIP 断开,直接结束 |
|
| SIP 断连期间 owner 被其他节点接管,本地 session 自关;通常更多是内部关闭原因 |
|
| owner 续租失败/丢失,本地 session 自关;通常更多是内部关闭原因 |
|
| AI 输出通道关闭导致 session 关闭;通常更多是内部关闭原因 |
|
| Redis live:close,广播关闭 |
⚠️ 除了监听
type: 6,还要监听 WebSocket 的异常关闭事件做兜底处理。
Step 6:结束通话
主动挂断
通话结束时,通过 WebSocket 发这条消息:
{
"type": 5,
"live_id": "123456789",
"seq_id": 2,
"payload": {
"hangup": { "hangup_reason": "user_end" }
}
}
发完之后:
-
关闭 WebSocket 连接
-
调用阿里云 RTC SDK 的
leaveChannel()离开视频频道
查询本次通话账单(可选)
注意:
{host}使用真实域名,文档里是占位符
国内域名:api.vidu.cn
海外域名:api.vidu.com
GET https://{host}/live/v1/lives/{live_id}
Authorization: Token vda_xxx
返回:
{
"live": {
"id": "969824102288199680",
"stream_url": "",
"live_duration": 600,
"status": "on_live",
"call_mode": "video",
"character_id": "1",
"avatar": {
"persona": "你是甜甜 Tina,我的声音像温热的奶茶,甜甜的、暖暖的,但解决问题可一点都不含糊哦!",
"image_uri": "https://prod-maas-vidu.s3.ap-southeast-1.amazonaws.com/live/avatar/969824102288199680/avatar.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Checksum-Mode=ENABLED&X-Amz-Credential=AKIAZVXP2QJE7YFNWAHM%2F20260701%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Date=20260701T084708Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&response-cache-control=max-age%3D86400&response-content-disposition=attachment&x-id=GetObject&X-Amz-Signature=4bc80c384970532cee3ecabdd420441257da79eb0cb00185f838dc0fbc6808e7",
"name": "甜甜 Tina",
"voice": "Tina",
"live_prompt": ""
},
"created_at": "1782895599",
"start_time": "0",
"end_time": "0",
"trace_id": "2a41b767baddff1f54bf5d859d371083",
"infer_task_id": "969824126237679616",
"billed_seconds": 18,
"credits_cost": 27
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
|
| String |
|
|
| String | 计费时长(秒),从数字人准备好开始算 |
|
| String | 开始计费时间(Unix时间戳) |
|
| String | 结束时间(Unix时间戳) |
会话状态流转
waiting → on_live → ending → ended
(创建后) (双端就绪) (结束中) (已结束)
四、踩坑提醒
几个容易卡住的地方:
| 错误 | 原因 | 处理方式 |
|---|---|---|
| HTTP 401 | API Key 错误或缺失 | 检查 Authorization Header |
| HTTP 403 | 不是这个会话的创建者 | 确认用的是创建这个会话的 API Key |
| HTTP 404 | 会话不存在或已过期 | 重新创建会话 |
| WS | 数字人SIP还没准备好 | 断开重连,指数退避重试 |
| WS | 初始化彻底失败 | 重新创建会话 |
五、写在最后
从开发者角度看,Vidu S1 的接入体验比我预期的顺畅。API 设计清晰,WebSocket + RTC 的架构虽然比普通 HTTP 接口多了几步,但换来的是真正的实时双向交互——这在之前的视频生成产品里是做不到的。
未来,Vidu API开放平台将持续分享:
AI 视频创作教程、最佳实践案例、行业解决方案及最新能力解析......
欢迎关注我们,与更多开发者和创作者共同探索 AI 视频的无限可能!
31



被折叠的 条评论
为什么被折叠?



