Vidu S1 是一项流式、实时、双向交互的数字人视频服务。用户通过接口创建直播会话,媒体流经阿里云 RTC 频道传输(不走 HTTP),持久 WebSocket 承载控制信令(开始/挂断)。本技能整理了端到端流程,以及经过实践检验的集成陷阱,其中若干条与公开文档冲突,冲突时以本技能为准(其反映厂商澄清)。
前置准备(属于前提条件,不是代码):
- API Key:从 https://platform.vidu.cn/api-keys 获取。用户可能存为 vda_xxx 或 Token vda_xxx,但每个 Vidu HTTP/WS 请求都必须发送 Authorization: Token vda_xxx。类似 vda_your_api_key_here 的占位值不算已配置密钥。
- 数字人头像图:单人图像,公网 URL 或 base64 data URI。
- 人设文本:自由描述数字人是谁。
- 阿里云 RTC SDK:需单独下载集成;媒体不通过 HTTP 传输。SDK 地址:https://help.aliyun.com/zh/live/introduction-to-real-time-audio-and-video-artc-sdk
- 主机域名:api.vidu.cn(中国)或 api.vidu.com(海外)。文档中的 {host} 是占位符,须替换为真实域名。
六步流程:
- POST /live/v1/lives → 创建会话,获得 live_id 与 RTC 凭证。
- 阿里云 RTC joinChannel → 发布麦克风(视频模式另加摄像头),订阅数字人媒体流。
- WebSocket 连接 + conn_init → 声明“已就绪”。
- 等待 conn_init_ack → success:true 表示数字人已开播(从此开始计费)。
- 交互 → 保持心跳,处理强制挂断。
- 挂断 + leaveChannel → 发送 hangup、关闭 WS、离开 RTC,可选查询账单。
各步骤要点: 步骤一:POST https://{host}/live/v1/lives,携带 avatar 块。返回 live 对象(保存 live.id)与 rtc 对象。会话初始状态为 waiting。 步骤二:使用 rtc.token 和 rtc.user_id 调用 joinChannel。部分阿里云 RTC Web SDK 版本接受单一 token 形式,另一些要求形如 { appId, channelId, userId, token, timestamp } 的 auth-info 对象。加入失败时先检查 SDK 版本的 joinChannel 签名,再改 Vidu 凭证。必须发布麦克风,视频模式发布摄像头,并订阅数字人媒体流,通常为 live-bot-{creatorID}-{liveID},也需将 live-video-push-{creatorID}-{liveID} 视为有效媒体源。角色与 RTC 用户 ID 格式:用户 live-user-{creatorID}-{liveID};数字人 live-bot-{creatorID}-{liveID};视频推流 live-video-push-{creatorID}-{liveID}。 步骤三至四:连接 wss://{host}/live/ws/live/connect?live_id={live_id},携带 Authorization: Token vda_xxx 头;立即发送 conn_init,等待 conn_init_ack。success:true 表示开播,开始计费;success:false 且 error_code 为 NOT_READY 是视频模式预期现象,应关闭 WS、等待后以指数退避(2s→4s→8s)重连重试,并忽略主动关闭的 socket 事件;error_code 为 LIVE_CONN_INIT_FAILED 属致命错误,需回到步骤一新建会话。 步骤五:服务端每 5 秒 ping,客户端须在 15 秒内发送任意消息,否则被判死连接。多数 WS 库会自动回 pong,需确认在上游 Vidu 连接上已启用。浏览器→后端代理→Vidu 架构下,后端 WS 客户端必须回应 Vidu 的 ping。监听 type:6 的挂断消息,并在 WS 异常关闭事件上增加兜底监听。 步骤六:通过 WS 发送 hangup、关闭 WS、调用 RTC SDK 的 leaveChannel()。可选 GET /live/v1/lives/{live_id} 读取账单(billed_seconds、credits_cost)。
实践陷阱(优先于文档):不要假设固定 live_duration,以创建接口返回的正整数为准(实际曾返回 7200)。使用 rtc.token_expire_at,不要假设固定 token 生命周期;token 仅对该直播会话有效,不可跨会话缓存复用,过期需新建会话。WebSocket 鉴权仅用 Authorization 头,不支持查询参数;浏览器原生 WebSocket 无法设置自定义头,且头内含原始 token,故须经自有服务端代理;HTTP 调用同样不得把 vda_xxx 发到不可信客户端。视频模式首次连接必定返回 NOT_READY,属 SIP 预热,须实现断开→退避→重连循环。阿里云 RTC 是独立 SDK 集成而非 HTTP 调用,需预留集成工时。不要将 SDK 自动订阅与重复手动订阅混用;手动选择数字人媒体用户时应关闭默认远端自动订阅,并对进行中/已完成的订阅与视图绑定去重。需防范过期 RTC 与 WS 事件,仅处理属于当前活动会话/套接字的事件。计费从 on_live(conn_init_ack 返回 success:true)开始,而非会话创建时;时长向上取整到偶数秒(11 秒按 12 秒计)。账户需至少约 45 credits(够 30 秒)才能开始会话;会话中持续扣费,余额归零自动断开。当前音频模式与音视频模式定价相同,模式选择是产品决策而非成本手段。GET 会话响应顶层结构稳定为 { "live": { ... } },从该包装解析 live.id、live.status、live.billed_seconds。GET /live/v1/voices 按设计仅返回自定义克隆音色,系统音色列表另见 references/voices.md;空响应不代表错误。音色默认 Tina,可通过 avatar.voice 选择其他;克隆音色接口 POST /live/v1/voices/clone,每用户前 10 个免费,之后每个 899 credits。