本文将介绍如何通过实时音视频SDK集成音视频智能体到您的鸿蒙Next应用中。
环境要求
获取 DevEco Studio 5.0.3.900 Release 或以上版本。
获取配套 API Version 12 的 HarmonyOS NEXT SDK 或以上版本。
鸿蒙设备,配套 API Version 12的 HarmonyOS NEXT 5.0.0.102 操作系统或以上版本,且已开启“允许调试”选项。
已注册华为开发者账号并完成实名认证。
业务流程

您的App通过AppServer(你的业务服务器)生成ARTC鉴权Token,便可调用ARTCAICall的callWithConfig(config)方法进入通话,在通话过程中,可以继续调用ARTCAICall的API实现智能体的实时字幕、打断等交互功能。ARTCAICall是ARTC SDK(@aliyun_video_cloud/alivcsdk_artc)提供的基于AI实时互动的API,适用于智能体通话场景。
集成SDK
推荐使用自动集成@aliyun_video_cloud/alivcsdk_artc,在entry下的oh-package.json文件中配置:
"dependencies": {
"@aliyun_video_cloud/alivcsdk_artc":"x.y.z",
}添加配置后,点击当前编辑页面的“Sync Now”按钮进行安装SDK。
@aliyun_video_cloud/alivcsdk_artc 支持手动集成方式,关于支持的最新版本号及手动集成方式,请参考:下载SDK手动集成。
SDK开发指南
步骤一:申请APP音视频权限
在entry模块的module.json配置APP长时间后台模式,添加麦克风、摄像头、长时间后台任务授权。
...
"abilities": [
{
"name": "xxx",
"backgroundModes": [
"audioPlayback",
"audioRecording",
"dataTransfer"
],
...
}
],
"requestPermissions": [
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:module_desc",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "always"
}
},
{
"name": "ohos.permission.CAMERA",
"reason": "$string:reason_camera",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "always"
}
},
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
"reason": "$string:keep_background",
"usedScene": {
"abilities": [],
"when": "always"
}
}
]在发起通话前,检查授权情况,如未授权,则弹框交由用户进行授权,需要您在App上自行实现。
const permissions: Array<Permissions> = ['ohos.permission.MICROPHONE','ohos.permission.CAMERA','ohos.permission.KEEP_BACKGROUND_RUNNING'];
function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
// 授权成功
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}步骤二:导入ARTCAICall相关类
从@aliyun_video_cloud/alivcsdk_artc里按需导入 ARTCAICall 相关的类和接口:
import {
ARTCAICallEngineListener,
ARTCAICallEngineInterface,
ARTCAICallEngineFactory,
ARTCAICallAgentType,
ARTCAICallConfig,
ARTCAICallUtils,
ARTCAICallRTCTokenHelper,
ARTCAICallLog,
ARTCAICallLogType,
ARTCAICallErrorCode,
ARTCAICallConnectionStatus,
ARTCAICallAgentState,
ARTCAICallNetworkQuality,
ARTCAICallAgentSubtitleResult,
ARTCAICallUserSubtitleResult,
ARTCAICallSpeakingInterruptedReason,
RecordValueType,
ARTCAICallAgentVcrResult,
ARTCAICallAudioAccompanyState,
ARTCAICallAudioAccompanyErrorCode,
ARTCAICallViewConfig,
ARTCAICallVideoConfig,
ARTCAICallAgentInfo,
} from '@aliyun_video_cloud/alivcsdk_artc';
步骤三:创建&初始化引擎
创建&初始化ARTCAICallEngine引擎,示例代码如下:
// 定义引擎接口
private aiCallSDK: ARTCAICallEngineInterface | undefined = undefined;
// 创建引擎
this.aiCallSDK = ARTCAICallEngineFactory.createEngine(getContext(this));
步骤四:实现回调方法
按需实现引擎回调方法。引擎回调接口详情参考:API接口详情。
const listener = new ARTCAICallEngineListener();
listener.onErrorOccursCallback = (code: ARTCAICallErrorCode) => {
// 发送了错误
this.handup()
};
listener.onCallBeginCallback = () => {
// 开始通话,这里可以打印智能体实例信息,可以用于排障
const agentInfo = this.aiCallSDK?.agentInfo!;
ARTCAICallLog.writeLog(ARTCAICallLogType.Info, `onCallBeginCallback: AgentInfo {
instanceId: ${ agentInfo.instanceId },
agentId: ${ agentInfo.agentId },
agentType: ${ agentInfo.agentType },
channelId: ${ agentInfo.channelId },
uid: ${ agentInfo.uid },
requestId: ${ agentInfo.requestId },
region:, ${ agentInfo.region }
}`);
};
listener.onCallEndCallback = () => {
// 结束通话
};
listener.onAgentStateChangedCallback = (state: ARTCAICallAgentState) => {
// 智能体状态改变
};
listener.onUserSubtitleNotifyCallback = (data: ARTCAICallUserSubtitleResult) => {
// 用户提问被智能体识别结果的通知
};
listener.onVoiceAgentSubtitleNotifyCallback = (data: ARTCAICallAgentSubtitleResult) => {
// 智能体回答结果通知
};
listener.onVoiceInterruptedCallback = (enable: boolean) => {
// 当前通话的语音打断是否启用
};
...
this.aiCallSDK.listener = listener;步骤五:创建并初始化ARTCAICallConfig
ARTCAICallConfig详情,请参见ARTCAICallConfig。
private agentType: ARTCAICallAgentType = ARTCAICallAgentType.VoiceAgent
const aiCallConfig = new ARTCAICallConfig();
aiCallConfig.agentId = 'xxx'; // 智能体Id
aiCallConfig.agentType = this.agentType; // 智能体类型
aiCallConfig.region = 'xx-xxx'; // 智能体服务所在的区域
aiCallConfig.userId = 'xxx'; // 推荐使用你的App登录后的用户id
aiCallConfig.userJoinToken = 'xxxxxxxxx'; // RTC Token
// 针对视觉理解&视频通话,需要设置视频配置
// 这里frameRate设置为5,需要根据控制台上的智能体的抽帧率(一般为2)进行调整,最大不建议超过15fps
// bitrate: frameRate超过10可以设置为512
if (this.agentType === ARTCAICallAgentType.VisionAgent || this.agentType === ARTCAICallAgentType.VideoAgent) {
const videoConfig = new ARTCAICallVideoConfig();
videoConfig.useFrontCameraDefault = true;
videoConfig.frameRate = 5;
videoConfig.bitrate = 340;
this.aiCallSDK.videoConfig = videoConfig;
}
地域名称 | Region Id |
华东1(杭州) | cn-hangzhou |
华东2(上海) | cn-shanghai |
华北2(北京) | cn-beijing |
华南1(深圳) | cn-shenzhen |
新加坡 | ap-southeast-1 |
步骤六:【可选】创建并初始化渲染视图
如果不是语音通话智能体,那么需要对本地摄像头采集预览或对远端数字人进行渲染。
private localViewConfig = new ARTCAICallViewConfig();
private agentViewConfig = new ARTCAICallViewConfig();
// 对于数字人&视频通话智能体类型,需要在Builder里增加XComponent用于智能体预览
XComponent({
id: 'Agent_XComponent',
type: XComponentType.SURFACE,
controller: this.agentViewConfig.controller
})
// 对于视觉理解&视频通话智能体类型,在Builder里增加XComponent用于本地采集预览
XComponent({
id: 'Local_XComponent',
type: XComponentType.SURFACE,
controller: this.localViewConfig.controller
})
// 对于数字人&视频通话智能体类型,设置数字人视图渲染,需要在XComponent加载完成后调用
if (this.agentType === ARTCAICallAgentType.AvatarAgent || this.agentType === ARTCAICallAgentType.VideoAgent) {
this.aiCallSDK.setAgentViewConfig(this.agentViewConfig);
}
// 对于视觉理解&视频通话智能体类型,设置本地视图渲染,需要在XComponent加载完成后调用
if (this.agentType === ARTCAICallAgentType.VisionAgent || this.agentType === ARTCAICallAgentType.VideoAgent) {
this.aiCallSDK.setLocalViewConfig(this.localViewConfig);
}
步骤七:发起智能体呼叫
调用callWithConfig接口发起智能体呼叫。
const result = this.aiCallSDK.callWithConfig(aiCallConfig);
if (result === true) {
// 成功
}步骤八:通话中的业务实现
在开启通话后,您可以根据您的业务需求处理字幕、打断智能体讲话等。
步骤九:通话结束,挂断智能体通话
调用handup()接口,挂断智能体通话。
handup = () => {
if (this.aiCallSDK === undefined) {
return;
}
this.aiCallSDK.handup(true);
this.aiCallSDK = undefined;
}