星尘交互数字人iOS SDK标准化文档
星尘交互数字人iOS SDK版本接口文档说明
接入前须知
云端渲染数字人、端测渲染(端到端)数字人的语音交互模式主要有三种模式:push2talk模式、tap2talk模式、duplex双工模式
在push2talk模式下,用户需要像类似钉钉发送语音消息那样,通过发送一段音频,来触发语音交互
在tap2talk模式下,SDK内部的语音服务会实时识别用户的语音输入。但是用户想打断数字人,需要通过额外事件来触发,比如点击屏幕,或者点击某按钮。
在duplex双工模式下,SDK内部的语音服务会实时识别用户的语音输入。数字人在说话状态下,仍可以接受用户的语音打断信号。
在duplex双工模式,容易受到外部环境音的影响导致触发频繁打断,请在相对安静的环境下使用双工模式。
星尘官网上的ApiKey并没有包含前缀Bearer 头,在初始化SDK的时候,请开发者自行添加前缀头,'Bearer ' + ApiKey, 具体可见如下示例项目中的代码或快速集成说明。
接入方法
Xcode framework集成
环境配置
Xcode 14及以上
加载SDK和依赖
在Xcode新建项目,将以下frameworks导入项目工程中 videochat_ios_sdk.framework AliVCSDK_ARTC.framework
alivcffmpeg.framework
权限相关
SDK和数字人交互需要用到录音权限,在Info.plist文件中增加如下代码:
<key>NSMicrophoneUsageDescription</key>
<string>{使用麦克风的原因描述}</string>
云端渲染数字人
示例项目
本示例项目提供了信息录入的界面,包含数字人生成和退出的入口,并且支持push2talk、tap2talk、duplex三种语音交互模式下切换。
下载
从OSS上下载videochat_ios_demo_2biz 项目压缩包,并进行解压。
文件结构
解压后的示例项目文件架构如下:
videochat_ios_demo
├─videochat_ios_demo.xcodeproj
├─videochat_ios_sdk.framework
├─AliVCSDK_ARTC.framework
├─alivcffmpeg.framework
├─SnapKit.framework
├─videochat_ios_demo
| ├─ConfigViewController.swift
| ├─VideoChatViewController.swift
| ├─SceneDelegate.swift
| └ ...
安装依赖并运行示例项目
在解压后的文件夹双击打开videochat_ios_demo.xcodeproj,默认在Xcode中加载。
Xode登录Apple账号,在选择对应的Team,并且勾选Automatically Manage Signing.
设置完成后,点击左上角►运行项目。
在页面上录入对应的信息,然后点击 生成数字人 ,即可看到数字人交互页面。
请注意:云端渲染数字人的数字人资产ID和数字人模型ID请保持一致,均为数字人资产ID
首次启动示例项目并生成数字人后,语音交互模式默认以duplex双工模式的启动。
如果想要切换模式,点击页面顶部进行切换模式。每次切换模式后,都要重新生成数字人。
快速集成
新建云端渲染数字人实例
云端渲染数字人支持三种语音交互模式,分别是duplex双工、tap2talk、push2talk。这三种语音交互模式的取值可以通过SDK中的TYVoiceChatMode枚举值获取。
请注意:云端渲染数字人的数字人资产ID和数字人模型ID请保持一致,均为数字人资产ID
self.avatar =
TYVideoChat(enableVolumeDetection: true,
params: TYRTCAuthParams(type: .Avatar, // 云渲染交互模式
modelId: 'xingchen-plus-v2', //大模型Id,可默认
voiceId: "", // 输入从星尘官网上获取的语音ID
avatarId: "", // 输入从星尘官网上获取的数字人资产I
avatarModelId: "", // 数字人模型ID,云渲染下与avatarId一致
voidePlatform: "nls", // 语音平台,默认为nls,也支持配置为minimax
customVoiceModel: nil, // 语音模型,当使用minimax时,该项为必传
mode: .duplex, // 设置语音交互模式, 可选duplex,tap2talk, push2talk
appId: "", // 预留字段,先临时写死123
characterId: "", // 输入从星尘官网上获取的角色ID
userId: "", //用户Id,建议使用唯一值
keepAlive: false, // 是否做心跳保活,不保活的条件下,超时一分钟不和数字人交互,自动断联
usePlatformChatHistory: false, // usePlatformChatHistory为true时,同一个CharacterId+UserId的组合会记住历史对话上下文,可在此配置
extras: [
// 开发者一般不需要设置此配置,设置后会影响到SDK内部的LLM语音模型
'parameters': [
// LLM语言模型的回复多样性
'topP': 0.1,
// LLM语言模型的回复发散度
'temperature': 1.0,
]
]),
config: TYRequestConfig(headers: [
'Authorization': 'Bearer ' + ApiKey
], url: "https://nlp.aliyuncs.com/"))
自定义鉴权(调用方服务端鉴权)方式
注意点:Headers.Authorization中应包含"Bearer "+ ApiKey,ApiKey可以通过“星尘-我的空间-密钥管理”获取"
/*星尘网关示例 端上sdk可控制的参数*/
"authParams": {
// appId,当前不做校验,鉴权信息放在Header里
"appId": "",
// 数字人Id,必传
"avatarId": "video-chat-tianyou",
// 个性Id,当前不做校验,characterId和content必须传一个
"characterId": "123",
"content": "",
// 通话模式,必传
"mode": "tap2talk",
// LLM大模型ID,必传
"modelId": "xingchen-plus-v2",
// 数字人音频播放采样率
"outboundSampleRate": 48000,
// 是否开启RTC内置的AEC,默认开启
"useRtcAec": true,
// 用户ID,不做权限校验,保证唯一性即可,建议使用UUID传入
"userId": "lxx",
// 音色Id,必传
"voiceId": "longxiaochun",
// 是否开启心跳保活,不开启时,超过一分钟不和数字人交互,会自动断开
"keepAlive": true,
// usePlatformChatHistory为true时,同一个CharacterId+UserId的组合会记住历史对话上下文,可在此配置
"usePlatformChatHistory": false
},
"requestConfig": {
// 自定义Header,预置鉴权信息
"headers": {
// 'Bearer ' + '在此处填入ApiKey'
"Authorization": "鉴权信息,通过“星尘-我的空间-密钥管理”获取",
"x-fag-appcode": "aca",
"x-fag-servicename": "aca-videochat-init"
},
// 自定义鉴权地址,默认为星尘网关地址
"url": "https://nlp.aliyuncs.com/v2/api/videochat/initialize"
// 自定义RequestBody,如果为null,则由SDK内部封装鉴权Body
"body": null
// 自定义RequestBody,如果不为null,则使用用户传入的参数作为鉴权Body
"body": "{
\"request_id\":\"6601fcd0dc6a4c9586acef378056a515\",
\"type\":\"Avatar\",
\"avatar_id\":\"video-chat-tianyou\",
\"voice\":\"longxiaochun\",
\"outbound_sample_rate\":48000,
\"aca\":
{
\"userProfile\":
{
\"userId\":\"843a39e6471f4e29a45dfbf5fd03b488\"
},
\"botProfile\":
{\"characterId\":\"ed187c39234645bf8da9b9d3003ec936\",
\"content\":\"\",
\"appId\":\"\",
\"avatarId\":\"video-chat-tianyou\",
\"avatarModelId\":\"video-chat-tianyou\",
\"voiceId\":\"longxiaochun\",
\"voiceModel\":\"\",
\"voicePlatform\":\"nls\",
\"usePlatformChatHistory\":false
}
}
}"
}
设置RTC视频流容器
在数字人的ViewController里面创建视频流容器,然后在viewDidLoad方法内设置绑定RTC视频流。
let videoView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(videoView)
videoView.frame = view.bounds
// 设置绑定RTC视频流View
self.avatar.setupRTCView(videoView)
}
绑定回调
并不是所有回调都需要绑定,建议开发者根据业务开发需求进行绑定即可。
onFirstFrameReceived
在数字人首页画面出现的时候触发此回调
avatar.onFirstFrameReceived = {
print('数字人渲染完毕')
}
onReadyToSpeech
在数字人可以开始进行语音交互的时候触发此回调
avatar.onReadyToSpeech = {
print('可以进行语音交互了')
}
onErrorReceived
在数字人内部出现错误的时候触发此回调, 更多错误码详情见此教程的错误码列表
avatar.onErrorReceived = { err in
print('数字人内部发生错误:' + err.code + ' ' + err.message)
}
onStateChanged
在数字人内部状态发生变化的时候触发此回调,详情见SDK中的TYVoiceChatState类型声明。
云端数字人拥有三种状态:Listening(倾听)、Thinking(思考中)、Responding(反馈中)
// 数字人状态
avatar.onStateChanged = { tyState in
print('当前数字人状态' + tyState)
}
onVolumeChanged
在数字人或者用户说话音量发生变化的时候触发此回调。回调返回的数据中,source为TYVolumeSourceType.mic的数据表示用户自己说话的音量,source为TYVolumeSourceType.player的数据表示数字人的音量。详情见SDK中的TYVolume和TYVolumeSourceType类型声明。
请注意:SDK已将数字人的音量做了归一化处理,数值大小范围为0~1
avatar.onVolumeChanged = { data in
if(data.source == TYVolumeSourceType.mic) {
print('用户音量:' + data.volume)
} else {
print('数字人音量:' + data.volume)
}
}
onMessageReceived
在识别出数字人对话文本或用户对话文本的时候触发此回调,详情见SDK中的TYVoiceChatMessage和TYVoiceChatMessageType类型声明。
avatar.onMessageReceived = { msg in
if(msg.type == TYVoiceChatMessageType.speaking) {
print("用户的对话文本内容", msg.text)
} else {
print("数字人的反馈文本内容", msg.text)
}
}
初始化
云端渲染数字人底层通过阿里云RTC进行音视频流的传输,所以需要挂载在一个video元素上。
avatar.start()
暂停收音/恢复收音
云端渲染数字人默认会自动开启收音。暂停收音和恢复收音功能均可以在三种语音交互模式下有效,但一般主要用于duplex双工语音交互场景。
在开启双工语音交互模式下,数字人容易受到外界环境音影响,开发者可以通过暂停收音的方法,让数字人免受外界环境音影响。
// true:暂停收音
// false(默认值):恢复收音
avatar.muteLocalMic(mute: Bool)
发送语音和结束语音
发送语音和结束语音主要用于push2talk模式下,用户调用API,告知SDK开始发送语音和结束语音。
// 发送语音
avatar.sendSpeech()
// 结束语音
avatar.stopSpeech()
打断
打断方法常用于push2talk和tap2talk语音交互模式下,而在双工模式下,SDK内部的语音服务本身就能识别用户新的语音输入进行打断。
avatar.interrupt()
指定应答内容
在默认情况下,用户输入的语音如果出现违规的情况下, 数字人是不会做出反馈的。指定应答内容可以让数字人使用传入的文本作为回复。
请注意:如果强制反馈的文本也出现违规的情况,那么数字人同样不会做出反馈。TYRequestToRespondType.prompt表示把文本送到SDK内部的LLM服务进行回答TYRequestToRespondType.transcript表示把文本直接转成语音
avatar.requestToRespond(type: TYRequestToRespondType, text: String)
退出
在离开数字人页面或更换数字人角色的时候,都要调用此方法。否则页面中会存在多个数字人实例,导致互相影响。
avatar.exit()
星尘3.0SDK 合规配置指引(iOS)
说明
根据《个人信息保护法》、《数据安全法》、《网络安全法》等法律法规和监管部门规章要求,App开发运营者(以下简称为“开发者”)在提供网络产品服务时应尊重和保护最终用户的个人信息,不得违法违规收集使用个人信息。为帮助开发者在使用移动统计SDK的过程中更好地落实用户个人信息保护相关要求,避免出现侵害最终用户个人信息权益的情形,特制定本合规使用说明。
一、确保已使用最新版的 VideoChatSDK
最新VideoChatSDK 信息:
version 1.1.0
二、VideoChatSDK权限及调用时机:
个人信息相关权限 | 权限调用时机 | 权限用途 |
NSMicrophoneUsageDescription | 开启录音时 | 获取用户录音输入的数据,通过RTC流传给数字人平台,驱动数字人 |
Network Access | 第一次网络请求时 | 这个权限用于获取网络的使用权限,用于跟服务器建立请求。 |
三、VideoChatSDK功能及相关个人信息
功能 | 采集个人信息字段 | 个人信息采集目的 | 功能配置方案及示例 |
录音 | 通过本地麦克风/耳机/蓝牙耳机采集用户语音 | 获取用户录音输入的数据,通过RTC流传给数字人平台,驱动数字人 | 通过端侧加入RTC通道后,选择开启录音,用户输入的音频数据会上传云端,经过ASR转成文本提问,AI输出答复文本,然后通过RTC返回给端侧播放出来 |
四、VideoChatSDK合规初始化配置方案
您务必严格遵守初始化步骤,确保用户同意《隐私政策》之后,再初始化 SDK。
五、VideoChatSDK隐私政策条款模板:
SDK名称:VideoChatSDK。
使用目的:便于用户通过语音、文本和数字人互动,或者让数字人播放固定语音、动作。
运营方:阿里云计算有限公司。
收集个人信息类型:录音。
附录
错误码
网关服务错误
云端渲染、端测渲染(端到端)数字人错误码
错误码 | 错误名称 | 错误说明 | 解决方案 |
400 | aca.error.invalid.param | 初始化参数错误,参考返回的错误信息 | 重新在星尘官网确认相关参数 |
401 | 用户未认证 | ApiKey错误 | 1、在星尘官网上确认自己的apiKey是否正确 2、确认SDK初始化的ApiKey有没有加'Bearer ' |
465 | aca.error.not.paas.whitelist | 没有开通白名单 | 联系邮箱tongyixingchen@service.aliyun.com |
403 | aca.error.avatar.permission.error | 没有形象的使用权限 | 请确认账号是否拥有形象使用权限 |
403 | aca.error.voice.permission.error | 没有声音的使用权限 | 请确认账号是否拥有声音使用权限 |
422 | aca.error.videochat.initialize.limit | 数字人资源不足 | 请联系产品运营同学进行错误排查 |
431 | aca.error.videochat.quota.exceeded | 超过运行状态数限制 | 同一个账号同时开启的会话有数量限制,需要更多请联系产品运营同学 |
500 | aca.error.internal.exception | 内部服务错误 | 请联系产品运营同学进行错误排查 |
501 | aca.error.gateway.exception | 服务端验证ApiKey失败 | 1、在星尘官网上确认自己的ApiKey是否正确 2、确认SDK初始化的ApiKey有没有加 'Bearer ' |
600 | 获取数字人资产失败 | 请联系产品运营同学进行错误排查 |
RTC错误
错误码 | 错误说明 | 是否断连 | 解决方案 |
1000 | RTC初始化参数错误 | 是 | 检查SDK内部调用星尘initialize初始化的接口返回 |
1001 | RTC鉴权失败 | 是 | 检查SDK内部调用星尘initialize初始化的接口返回 |
1002 | RTC加入频道错误 | 是 | 检查SDK内部调用星尘initialize初始化的接口返回 |
1003 | RTC数据丢包 | 否 | 请联系产品运营同学进行错误排查 |
1004 | RTC 数据通道崩溃 | 是 | 请联系产品运营同学进行错误排查 |
WebSocket错误
错误码 | 错误说明 | 是否断连 | 解决方案 |
400 | 连接初始化参数不对 | 是 | 重新校对单独输出数字人的初始化参数 |
500 | 服务内部错误 | 是 | 数字人执行退出操作,重新初始化数字人实例 |
700 | websocket连接断开 | 是 | 数字人执行退出操作,重新初始化数字人实例 |
语音服务错误
错误码 | 错误说明 | 是否断连 | 解决方案 |
40000000 | 客户端错误 | 是 | 数字人执行退出操作,重新初始化数字人实例 |
40000001 | 参数不合规、检查参数 | ||
40000002 | 指令不支持,如指令名称错误 | ||
40000003 | 指令不合规,如指令格式错误 | ||
40000004 | 连接错误 | ||
40010000 | 拒绝访问 | ||
40010001 | 未授权 | ||
40020000 | 语音输入或输出违规 | 否 | 继续对话 |
40030000 | 对话静默超时 | 是 | 数字人执行退出操作,重新初始化数字人实例 |
50000000 | 服务内部错误 | ||
50000001 | 服务内部错误 | ||
50010000 | 语音识别内部错误 | 否 | 继续对话 |
50020000 | 大模型内部错误 | ||
50030000 | 语音合成内部错误 | ||
50040000 | 数字人内部错误 | 是 | 数字人执行退出操作,重新初始化数字人实例 |
50040001 | 数字人初始化失败 | ||
50040002 | 数字人初始化超时 |
兼容性
支持系统iOS14及以上手机,建议内存至少4GB保证性能,暂不支持模拟器上测试。
云端渲染数字人底层均依赖阿里云RTC的能力。具体兼容性请参考:阿里云ARTC iOS SDK