云渲染推流接口
接口说明
接口调用域名:https://open.xiling.baidu.com
使用直播 API 可以开启云端数字人渲染推流,和云渲染交互 SDK 的区别是,交互 SDK 主要用于客户端集成面向C端用户进行数字人交互的场景,而直播 API 主要用于后端对接,驱动数字人并获取数字人视频流后推送到第三方直播平台的场景。
注意:这里的直播指的是数字人应用场景,我们并不提供直播分发能力,需要接入方获取数字人视频流后使用其他直播平台完成向用户的分发。
调用本接口需要在平台购买直播组件商品并绑定到应用,操作说明参考:平台操作指引
接口调用流程
- 通过 HTTP 请求开启、关闭直播间,查看直播间信息
- 直播间开启后通过 Websocket 接口发送驱动数字人的指令,注意直播间开启后尽快建立 Websocket 连接,否则直播间会在开启 1 分钟后关闭。
- client具体是客户侧的哪一个端,可以由客户选择
- 客户可自行从media_server处进行音视频流拉取
直播间状态流转
- NULL -> OPENED: 打开一个新的直播间
- OPENED -> OPENED: 打开一个正在打开的直播间是有效的,会根据新的OPEN参数重新打开直播间
- OPENED -> CLOSED: 主动关闭一个直播间或者不活跃一段时间,都会让直播间进入关闭状态
- CLOSED -> OPENED: 可以打开一个已经关闭的直播间,重新开始直播
接口列表
HTTP API
接口鉴权和通用字段说明请查阅:接口通用说明
打开直播间
request
POST /api/digitalhuman/open/v1/liveRooms HTTP/1.1
Content-Type: application/json
{
"liveRoom": "live room", // 直播间名称,长度小于 50,同一 app 下唯一
"resolution": { // 画面输出分辨,比例需要和人像一致,否则会出现人像比例异常
"width": 1080,
"height": 1920
},
"elements": [ // IMAGE 和 DIGITAL_HUMAN 两个 element 的顺序固定不可调整
{
"type": "IMAGE", // 背景图
"image": {
"location": { // 背景图位置和尺寸
"top": 0, // 固定填 0
"left": 0, // 固定填 0
"width": 1080, // 需要和画面宽度(resolution.width)保持一致
"height": 1920 // 需要和画面高度(resolution.height)保持一致
},
"url": "http://image url" // 图片地址,推荐使用 BOS(百度对象存储服务)地址,其他地址可能会因为网络原因加载图片失败导致会话打开失败
},
},
{
"type": "DIGITAL_HUMAN",
"digitalhuman": {
"figureId": "figure id" // 数字人形象id,只支持 2D 小样本人像,可以使用系统公共人像[2D小样本数字人](AI_DH/数字人形象使用/公共形象库/2D小样本数字人.md)或定制人像[2D小样本数字人形象定制接口](AI_DH/定制服务/2D小样本数字人形象定制接口.md)
}
}
],
"output": {
"mode": "BRTC", // 视频流输出模式:RTMP - 延迟较高,更适合直播场景; BRTC - 延迟较低,更适合交互场景
"rtmp": { // mode 为 "RTMP" 时需要填写,BRTC 无需填写
"pushUrl": "rtmp push url" // 可选,指定数字人 RTMP 推流地址,示例值:rtmp://show-pu.kaywang.cn/{app}/{steam},如果不填写会返回平台提供的 RTMP 地址
}
},
"audioFormat": {
"sampleRate": 16000 // 可选,会话输入音频采样率,默认16000。TEXT_REDNER或AUDIO_RENDER对应的音频采样率和该值不一致,则不会进行播报,并返回event为ERROR的消息;AUDIO_STREAM上的采样率如果和该值不一致,会进行播报,但播报声音会有问题
}
}
response
HTTP/1.1 200 OK
{
"code": 0,
"message": "error message",
"result": {
"liveRoom": "live room",
"status": "OPEN",
"output": {
"rtmp": {
"pullUrl": "rtmp pull url" // output mode 为 RTMP 且请求没有提供 RTMP 推流地址(pushUrl),系统返回内置的 RTMP 地址供调用方进行拉流
},
"brtc": { // output mode 为 BRTC 时返回,参数使用参考文档直播流获取章节
"appId": "app id", // BRTC 侧 appId,非数字人开放平台应用 ID
"roomName": "room name", // BRTC 侧 roomName,非数字人直播间 name
"userId": "user id", // 拉流需使用的 user id
"userToken": "user token", // 拉流需填写的鉴权 token
"feedId": "feed id", // 数字人推流侧的 user id
"previewBrowseUrl": "preview url" // BRTC 模式下预览音视频 demo 网页链接
}
},
"createTime": "2023-08-14 00:00:00",
"updateTime": "2023-08-14 00:00:00"
}
}
错误码
code | 说明 |
---|---|
10006 | 参数校验不通过,根据 message 排查请求参数 |
22001 | figure id 不存在 |
22002 | figure id 查询失败 |
22003 | figure id 无权限 |
60100 | 会话开启失败,联系平台排查解决 |
60101 | app 渲染并发路数已达上限 |
60102 | 渲染资源不足 |
60200 | 直播服务异常,联系平台排查解决 |
60000 | 直播通用异常,联系平台排查解决 |
10004 | 未识别通用异常,联系平台排查解决 |
关闭直播间
request
DELETE /api/digitalhuman/open/v1/liveRooms?liveRoom=${liveRoom} HTTP/1.1
response
HTTP/1.1 200 OK
{
"code": 0,
"message": "error message",
"result": {
"liveRoom": "live room",
"status": "CLOSE",
"output": {
"rtmp": {
"pullUrl": "rtmp pull url"
}
},
"createTime": "2023-08-14 00:00:00",
"updateTime": "2023-08-14 00:00:00"
}
}
查询直播间
request
GET /api/digitalhuman/open/v1/liveRooms?liveRoom=${liveRoom} HTTP/1.1
response
{
"code": 0,
"message": null,
"requestId": "cd46a9e2-8bc5-490b-9c76-d5122ddf2b7b",
"result": {
"liveRoom": "test",
"sessionId": "sl-piehqauahma2vcfzp",
"status": "CLOSED",
"createTime": "2023-09-04T19:43:58Z",
"updateTime": "2023-09-05T07:00:26Z"
}
}
WebSocket API
WebSocket 地址
wss://open.xiling.baidu.com/live/2d/ws?appId=${app_id}&token=${app_token}&expire=${expire}&liveRoom=${live_room}
- app_token 和 expire 参数分别对应接口通用说明 中的 Signature 和 ExpireTime。
Ping/Pong机制
百度服务端会定时向客户端发送Ping消息,客户端收到后将payload原封不动放在Pong消息里返回给百度服务端。如果服务端发现长时间没有收到Pong消息,会主动将WebSocket连接断开。
重连说明
- 在会话关闭前,ws可以重复连接,但同时只能有一条相同直播间的ws链接存在
- 重新连接ws后,会默认展示最后一次OPEN的画面
- ws断开超过一定时间(60秒),系统会自动将会话关闭,此时ws重连会失败,可通过调用打开接口重新打开后进行重连
- 在ws断开过程中产生的事件会丢失,无法发送到客户端,但调用方可通过Ready消息内容来做一些业务判断
通用业务消息格式
- 上行代表调用方发送给百度服务器,下行代表百度服务器发送给调用方
- 下行的消息的id和上行的id进行对应,方便客户端进行判断处理,注意:上行消息 id 需为大于 0 的整数,递增且全局不重复。
- 上下行消息的body为json string格式,后续各类型的消息结构就是body的json格式
up
{
"id": 1, // 大于 0 的整数,递增不能重复
"type": "msg type",
"body": "msg body in json"
}
down
{
"id": 1, // 大于0的整数
"type": "msg type",
"code": 0, // 0 - 成功;非0 - 失败
"message": "error msg" // 异常信息
"body": "msg body in json"
}
服务端主动断开异常码
code | 说明 |
---|---|
4000 | 直播房间不存在 |
4001 | 直播房间未打开 |
4100 | 渲染流打开超时 |
4101 | 渲染流打开被打断 |
4102 | 渲染流打开异常 |
4103 | 渲染流异常 |
4104 | 渲染流关闭 |
4105 | 渲染流重复 |
4200 | ping/pong超时 |
4300 | 用户输入异常 |
Ready
type = READY
ws连接成功后,由后端返回的状态信息,收到该消息表明整个链路完全建立,可以开始发送驱动指令
down
{
"status": "IDLE", // 后端状态:IDLE - 空闲;SPEAKING - 播报中
"id": 1 // 最近一个正在播报(SPEAKING)或已经播报完(IDLE)的RENDER指令的 id
}
- Ready消息外层的 id 为 0
- 如果status为SPEAKING,但是在Ready之前有event为COMPLETE的消息返回,那么SPEAKING消息无意义,此时调用方可根据COMPLETE消息进行业务判断
TextRender
type = TEXT_RENDER
文本驱动
up
{
"textId": "text id", // 自定义id,便于问题排查
"text": "text", // 播报文本,长度不能超过 1000
"tts": {
"per": "5116", // 音色id,公共音色列表参考:[公共音色库](AI_DH/数字人形象使用/公共音色库.md),定制音色参考:[音色克隆和查询接口](AI_DH/定制服务/音色克隆和查询接口.md)
"spd": "5", // 语速:5是正常值,0-15的取值范围。越大语速越快,默认值5 (字面量需要是整数)
"vol": "5", // 音量:5是正常值,0-15的取值范围,越大音量越大,默认值5 (字面量需要是整数)
"pit": "5" // 语调:5是正常值,0-15的取值范围,越大声音越尖,默认值5 (字面量需要是整数)
},
"insert": false, // 为 true 则插入到当前播报中 TEXT_RENDER 的未播报文本最近的一个标点符号后播报或当前播报中 AUDIO_RENDER 的音频后播报,默认 false,多个 TEXT_RENDER 消息排队播报
"delayed": true // insert 为 false 时生效,为 true 则会在播报前延迟约 1 秒再播报,模拟真人播报的停顿
}
down
{
"event": "START" // START, COMPLETE, ERROR, INTERRUPTED
}
AudioRender
type = AUDIO_RENDER
单个音频文件驱动
up
{
"audioId": "audio id", // 自定义id,便于问题排查
"url": "audio url", // 音频需要满足:WAV格式,16k 采样率,通道数 1,位深 16 bit,WAV header 44 字节,推荐使用 BOS(百度对象存储服务)地址,其他地址可能会因为网络原因加载失败导致驱动失败
"insert": false, // 为 true 则插入到当前播报中 TEXT_RENDER 的未播报文本最近的一个标点符号后播报或当前播报中 AUDIO_RENDER 的音频后播报,默认 false,多个 AUDIO_RENDER 消息排队播报
"delayed": true // insert 为 false 时生效,为 true 则会在播报前延迟约 1 秒再播报,模拟真人播报的停顿
}
可以使用我们提供的素材库接口上传音频,进行转码,获取URL(即将上线)
down
{
"event": "START" // START, COMPLETE, ERROR, INTERRUPTED
}
AudioStream
type = AUDIO_STREAM
音频流驱动,音频需要保证PCM格式,通道数1,位深16bit。默认采样率16000,如果是其他采样率,需要在上行START消息中指定。
客户端先发上行START消息,待收到服务端下发的event为READY的消息后代表可以开始发送音频数据。
之后客户端可以通过websocket上行的二进制数据通道发送音频数据,当音频发送结束时,客户端发送上行COMPLETE事件。
在一对START和COMPLETE之间,除了INTERRUPT之外的其他文本类型的ws消息都会被认为是异常请求。
up
{
"streamId": "stream id", // 自定义id,便于问题排查
"event": "START", // START, COMPLETE
"sampleRate": 16000 // 默认 16000
}
- 如果想要确保插入在当前播报的一句话之后,请在这句话播报结束前3秒之前发送插入指令
down
{
"streamId": "stream id", // stream id
"event": "START" // READY, START, COMPLETE, ERROR, INTERRUPTED
}
up binary
调用方在收到下行成功的START后,可以通过ws的binary数据通道发送流式音频,该音频会用于实时驱动数字人:
- 调用方需要确保发送速率,避免卡顿
- 单次上行binary数据最大不超过256KB
Interrupt
type = INTERRUPT
打断播报,包括清空buffer中还没有播报的内容:
- INTERRUPT会有一个对应id和类型的下行消息,代表INTERRUPT被处理了
- 被打断的播报内容会触发event为INTERRUPTED的下行事件消息,对应的外层id为触发播报内容的驱动指令外层id
直播流获取
RTMP
打开房间请求体中 output.mode == RTMP
可直接通过响应中的RTMP链接获取直播流。RTMP 流存在秒级的延迟,如果业务上需要准确对齐视频内容建议使用 BRTC 流。
BRTC
打开房间请求体中 output.mode == BRTC
输出采用BRTC的方式,时延较低,在这种模式下,获取输出流需要接入百度RTC的SDK,请参考 实时音视频介绍