灵眸数字人开放平台推出的适用于iOS数字人流媒体服务SDK。当您调用服务端OpenAPI CreateChatSession - 创建实时数字人会话接口获取RTC入会信息后,可以在iOS搭建App,实现数字人拉流和实时对话。VideoChatiOSSdk通过SDK下载/集成(AliRTC)提供视频流的订阅,并通过RTC内置的消息通道进行信令传输
接入前须知
SDK不包含操作服务端实例的接口(如数字人初始化),如有需要请参考OpenAPI文档;
Demo 需要依赖配合后端应用才能体验,请先确认建立好可以调用OpenAPI的后端应用。
使用限制:
系统版本:支持iOS 14及以上版本
其他限制,可参考SDK下载/集成
云端渲染数字人的语音交互模式主要有两种模式:tap2talk模式、duplex双工模式
在tap2talk模式下,SDK内部的语音服务会实时识别用户的语音输入。但是用户想打断数字人,需要通过额外事件来触发,比如点击屏幕,或者点击某按钮。
在duplex双工模式下,SDK内部的语音服务会实时识别用户的语音输入。数字人在说话状态下,仍可以接受用户的语音打断信号。
在duplex双工模式,容易受到外部环境音的影响导致触发频繁打断,请在相对安静的环境下使用双工模式。
若使用本文档提供的SDK,用于对公众提供人工智能生成合成服务,作为服务提供者需遵守《互联网信息服务深度合成管理规定》《人工智能生成合成内容标识办法》以及相关标准要求,履行人工智能生成合成内容标识的义务。
接入方法
下载示例工程及SDK Framework
从OSS上下载VideoChatSdkDemo压缩包,并进行解压
环境配置
Xcode 14及以上
加载SDK和依赖
xcode中导入如下的framework,可从示例工程中获取
videochat_ios_sdk.framework
AliVCSDK_ARTC.framework
alivcffmpeg.framework
权限相关
SDK和数字人交互需要用到录音权限,在Info.plist文件中增加如下代码:
<key>NSMicrophoneUsageDescription</key> <string>{使用麦克风的原因描述}</string>
接口列表
API | 功能描述 |
init | 初始化方法,主要用来配置参数 |
start | 初始化成功后,启动对话流程 |
interrupt | 打断数字人说话 |
muteLocalMic | 是否关闭本地麦克风采集 |
exit | 退出 |
扩展接口 | SDK针对音频采集和播放提供了一些自定义配置 |
接口详情
初始化SDK
init
/**
* 初始化方法,主要用来配置参数,用于云渲染
* @param license 扩展字段,云渲染暂未用到
* @param avatarInitData 用户从平台拿到的数字人和资产信息
* @param dialogConfig 业务层对话配置,如Tap2Talk/PushTalk/Duplex等
*/
init(license: String, avatarInitData: TYAvatarInitData, dialogConfig: TYDialogConfig)
参数说明
参数名称 | 类型 | 是否必传 | 描述 |
license | String | 否 | 扩展字段,云渲染暂未用到 |
avatarInitData | TYAvatarInitData | 是 | 数字人初始化数据 |
dialogConfig | TYDialogConfig | 是 | 数字人对话模式配置 |
其中TYAvatarInitData为数字人初始化数据,主要包括RTC入会信息和资产信息
TYAvatarInitData数据可通过调用服务端OpenAPI CreateChatSession - 创建实时数字人会话接口获取,请务必在使用前验证服务端OpenAPI接口是否能正常调用
获取成功后,将Data字段对应的JsonObject传入SDK即可
"data": {
"sessionId": "9827f4bd-5008-4d34-98fb-62598f3ad3b5",
"rtcParams": {
"appId": "xxx",
"avatarUserId": "xxx",
"channel": "channel_info",
"clientUserId": "xxx",
"gslb": "https://gw.rtn.aliyuncs.com",
"nonce": "f8b0ef02c5da778f4488e2470c",
"serverUserId": "xxx",
"timestamp": 1560588594,
"token": "xxx"
},
"avatarAssets": {
"url": "xxx",
"md5": "xxx",
"secret": "xxx"
"type": "xxx",
"minRequiredVersion": "0.0.1"
}
}
参数名称 | 类型 | 是否必传 | 描述 |
rtcParams | TYAvatarInitConfig | 是 | RTC入会信息 |
avatarAssets | TYAvatarAssetConfig | 否 | 资产信息,云渲染暂不需要 |
sessionId | String? | 否 | 本轮对话的全局sessionId |
TYAvatarInitConfig为RTC入会信息
参数名称 | 类型 | 是否必传 | 描述 |
appId | String | 是 | RTC应用id |
channel | String | 是 | RTC通道信息 |
gslb | String | 是 | RTC负载均衡地址 |
timestamp | long | 是 | RTC鉴权有效的时间戳 |
token | String | 是 | RTC鉴权相关的token |
clientUserId | String | 是 | 客户端入会的id |
serverUserId | String | 是 | 服务端入会的id |
avatarUserId | String | 是 | 数字人入会的id |
nonce | String | 否 | 鉴权标识 |
sessionId | String | 是 | 数字人对话的全局sessionId |
TYAvatarAssetConfig为数字人资产信息,为扩展结构,暂未开放
TYDialogConfig为对话属性配置信息
参数名称 | 类型 | 是否必传 | 描述 |
renderType | TYAvatarRenderType | 是 | 渲染类型,当前仅支持云端渲染 |
mode | TYVoiceChatMode | 是 | 对话模式,当前仅支持Tap2Talk |
keepAlive | Boolean | 否 | 是否开启心跳保活,默认开启 |
keepAlivePeriod | Int | 否 | 心跳保活间隔,默认10s |
outboundSampleRate | Int | 否 | TTS音频播放采样率,默认48000 |
开启对话
start
初始化完成后,启动对话流程
/**
* 启动对话流程
*
* @param chatCallback 主回调,SDK运行过程中的所有信息,都会从这里透出给上层
*/
func start(completion: @escaping (Bool, TYError?) -> Void)
参数名称 | 类型 | 是否必传 | 描述 |
completion | @escaping (Bool, TYError?) | 是 | 启动对话的回调 |
TYError的格式为
参数名称 | 类型 | 是否必传 | 描述 |
key | Int | 是 | 错误信息Key |
message | String | 否 | 错误信息Message |
绑定回调
并不是所有回调都需要绑定,建议开发者根据业务开发需求进行绑定即可。
onReadyToSpeech: 对话准备完成,三端(客户端/VoiceChat/Avatar)均加入通道后,会回调该消息,此时才能调用业务接口
/** * 对话准备完成,三端(客户端/VoiceChat/Avatar)均加入通道后,会回调该消息,此时才能调用业务接口 */ public var onReadyToSpeech: (() -> Void)?
onFirstFrameReceived: 收到第一帧视频帧
/** * RTC收到第一帧视频 */ public var onFirstFrameReceived: (() -> Void)?
onStateChanged: 数字人状态切换
/** * 状态切换 */ public var onStateChanged: ((TYVoiceChatState) -> Void)?
TYVoiceChatState为数字人状态,详细信息如下
/// VoiceChat对话状态,和服务端状态一一对应 public enum TYVoiceChatState: String { case idle = "Idle" // 空置状态,未连接/连接断开对应的状态 case listening = "Listening" // 听 case responding = "Responding" // 说 case thinking = "Thinking" // 思考 }
onVolumeChanged: 音频强度回调
/** * 音量强度回调 * @param audioType 音频类型参考 * @param audioLevel 音频强度,归一到【0,1】区间 */ public var onVolumeChanged: ((Float, TYVolumeSourceType) -> Void)?
TYVolumeSourceType为音频类型,详细信息如下
/** * 语音类型,分为本地采集和远端TTS两种 */ public enum TYVolumeSourceType: Int { case mic case player }
onMessageReceived: 对话过程中的文本详情回调
/** * 对话的文本详情回调 * @param chatMessage */ public var onMessageReceived: ((TYVoiceChatMessage) -> Void)?
TYVoiceChatMessage为文本详情封装类,详细信息如下
参数名称
类型
是否必传
描述
chatMessageType
TYVoiceChatMessageType
是
消息类型
chatMessageText
String
是
消息文本
isFinish
Boolean
是
是否结束,用户说/AI说每次会返回当前已识别到的全部内容,说完后,该标志位为true
llmRequestId
String
否
对话过程中的LLM请求ID,可以此定位LLM的问题
TYVoiceChatMessageType为消息类型的枚举,详细信息如下
/// voice chat消息类型 public enum TYVoiceChatMessageType: Int { case speaking // 输入消息 case responding // 输出消息 }
onPerformanceInfoTrack:对话过程中的性能监测
/** * 对话过程中的性能监测 * @param type 信息类型 * @param performanceInfo 信息详情 */ public var onPerformaceInfoTrack: ((_ type:TYPerformanceInfotype,_ performanceInfo:String) -> Void)?
type为信息类型的枚举,当前仅支持耗时统计,详细信息如下
/** * Performance信息类型 */ public enum TYPerformanceInfotype : String { // 链路耗时统计 case TIMESTAMP_STATISTICS }
onErrorReceived: 对话过程中的异常回调
/** * 对话过程中的异常信息 * @param errorInfo 异常信息 */ public var onErrorReceived: ((TYError) -> Void)?
打断
interrupt
打断数字人说话,异步方法,打断结果会通过回调返回
/**
* 打断数字人说话
*/
func interrupt()
暂停收音/恢复收音
muteLocalMic
是否关闭本地麦克风采集
/**
* 是否关闭本地麦克风采集
*/
func muteLocalMic(mute: Bool)
文本问答
requestToRespond
请求服务端回答指定内容,或者播报指定内容
/**
* 请求服务端回答指定问题or做TTS播放出来
* @param type: transcript 表示直接把文本转语音,prompt 表示把文本送大模型回答
* @param text:对应的文本
*/
fun requestToRespond(type: String, text: String)
退出
exit
退出SDK,退出页面时必须调用该方法,否则会导致实例未释放,功能会出现异常
/**
* 销毁实例
*/
fun exit()
扩展接口
用户在一些场景下,需要对音频采集和播放做一些自定义配置,此处开放一些配置参数,通过调用getRtcConfig()获取TYRtcConfig对象,当前支持的配置参数如下。注意:该接口需要在SDK start接口前调用生效
参数名称 | 类型 | 默认值 | 描述 |
playOutAudioVolume | Integer | 100 | TTS音频增益,值域为[0, 400],大于100标识增大音量,小于100标识降低音量 |
recordAudioVolumeBeforeVAD | Integer | 100 | VAD唤起前采集音量大小,值域为[0, 400],大于100标识增大音量,小于100标识降低音量。双工对话模式建议设置为40,其他对话模式建议设置为100 |
recordAudioVolumeAfterVAD | Integer | 100 | VAD唤起后采集音量大小,值域为[0, 400],大于100标识增大音量,小于100标识降低音量 |
renderMode | AliRtcEngine.AliRtcRenderMode | AliRtcRenderMode.AliRtcRenderModeAuto | 视频流渲染的填充模式,AliRtcRenderModeAuto(0):自动模式 AliRtcRenderModeStretch(1):拉伸平铺模式 AliRtcRenderModeFill(2):填充黑边模式 AliRtcRenderModeClip(3):裁剪模式 |
错误码
应用内部错误
错误码 | 错误说明 | 解决方案 |
1120 | RTC参数过期 场景1)生成RTC的json信息存在有效期限制,拿到信息后超出5min未入会; 场景2)同样的RTC参数重复入会 | 刷新RTC入会参数 |
RTC错误
错误码 | 错误说明 | 解决方案 |
1000 | RTC初始化参数错误 | 检查RTC入会信息 |
1001 | RTC鉴权失败 | 检查RTC入会信息 |
1002 | RTC加入频道错误 | 检查网络或者RTC入会信息 |
1003 | RTC数据丢包 | 请联系产品运营同学进行错误排查 |
1004 | RTC 数据通道崩溃 | 请联系产品运营同学进行错误排查 |
1005 | RTC房间被销毁 | RTC房间被服务端主动销毁 |
1006 | 用户被踢出RTC房间 | 服务端将用户主动踢出房间 |
1007 | 端渲染模式下语音LAG | 请联系产品运营同学进行错误排查 |
服务端错误
参考服务端错误码