HARIX RCU v1.2.0
SDK 接入指南

HARIX RCU SDK 提供了 HARIX 全功能集 API,每次设备服务启动时,只需调用 account 模块的激活和登录接口,SDK 会自动建立VBN网络以及与 HARIX 的服务链接,设备只需根据需要控制相应功能模块的开关,并通过 API 进行数据的收发。

1 编译环境准备

SDK 采用跨平台方案,目前已支持 Ubuntu 18.04+(x64,armv8),Ubuntu 16.04+ armv7hf,Windows 10+ x64,Android 7.0+(arm64-v8a, armeabi-v7a)。

针对 Android,推荐集成 Java SDK

1.1 Linux ARM

  1. x86_64的宿主机PC一台,搭载Linux操作系统(armv7hf - Ubuntu 16.04+, armv8 - Ubuntu 18.04+)
  2. cmake工具,版本大于等于3.18.1
  3. 编译器
    • x86
    • arm 交叉编译工具链(与您的 arm 开发板相匹配,通常开发板厂商会提供对应的交叉编译工具,亦可考虑 Linaro 维护的工具链)

      根据arm开发板的架构不同,所使用的交叉编译器也不一样,具体对应方式如下参考:

开发板架构 对应编译器
armv7hf arm-linux-gnueabihf-gcc
armv8 aarch64-linux-gnu-gcc

1.2 Windows

  1. x86_64的宿主机PC一台,搭载 Windows 10 或 Windows 11 操作系统(推荐 Windows 10)
  2. cmake工具,版本大于等于3.18.1
  3. Visual Studio 2019

2 示例代码

2.1 代码结构

目录 说明
include SDK API 头文件
lib SDK 各平台动态库
samples 示例源码
CMakeLists.txt 示例源码的 cmake 规则
*.toolchain.cmake 各平台编译工具链配置

2.2 编译与运行

可以通过 ./build.sh -h./build.bat -h 查看相关平台架构编译指令。

Linux

  • 编译
    # 编译命令:
    # -s <system name> 指定编译目标系统
    # -a <cpu arch abi> 指定编译目标体系结果,x86_64|armv8|armv7hf
    $ ./build.sh -s linux -a x86_64
    # 编译 Linux 支持的所有目标体系
    $ ./build.sh -s linux
  • 运行。vpn 运行需要 root 权限,请确保在 root 权限下运行
    $ sudo LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./mainapp

Window

  • 编译。双击或在命令行中执行 build.bat
  • 运行。双击或在命令行中执行 mainapp.exe
    > ./mainapp.exe

2.3 示例代码说明

Sample 中示例了 SDK 的启动流程,以及主要服务的使能方式。

  1. 新设备需要先进行激活操作,若已进行过激活,则跳过(已激活的设备如需切换账号,需要先进行去激活 HarixRcu_Account_DoDeactivate 以后,再用新账号进行激活);
  2. 登录操作,SDK 会将设备接入 VBN 网络,与 HARIX 建立数据通道,并从云端获取相关服务的配置策略等;
  3. 完成登录后,可调用 SDK API 按需使能或访问服务,例如 听觉 AI(SmartVoice),视觉 AI(SmartVision),语音/视频通话(Call)等。

3 SDK 功能模块

3.1 账号

主要提供设备账号的激活和登录功能,并提供账号信息的查询等。头文件 account.haccount_constant.h

激活和登录是设备访问 HARIX 的第一步。设备在登录前需要首先进行激活(若已激活则直接登录即可),HARIX 提供了两种激活模式:

  1. 账号密码激活,需先联系 HARIX 管理员开设账户,该模式下可定制 AI 特性;
  2. 短信验证码激活,无需提前开户,该模式下为通用 AI 特性。

‍已激活的设备如需切换账号,需要先进行去激活 HarixRcu_Account_DoDeactivate 以后,再用新账号进行激活

代码示例:

void DoLogin()
{
AccountRequestCallBack cb = [](void *context, bool success, int code, const char *error_message) {
if (success)
{
// Step 3: Start service
Start();
}
else
{
LOGE("DoLogin error (%d): %s", code, error_message);
}
};
HarixRcu_Account_DoLogin(NULL, cb, NULL, NULL, NULL);
}
int main()
{
{
DoLogin();
}
else
{
// Demo 账号。切换已激活的账号时,需要先去激活老账号(研发模式下可以清空 app 缓存来模拟),再激活新账号
std::string username = "SH_ZS_CLOUDIA";
std::string password = "123456";
std::string rcu_id = "61bb90c1-c069-4376-9eb1-aa324818ef9a";
std::string robot_id = "61bb90c1-c069-4376-9eb1-aa324818ef9a";
std::string url = "103.235.247.240:30085";
AccountRequestCallBack callback = [](void *context, bool success, int code, const char *error_message) {
if (success)
{
DoLogin();
}
else
{
LOGE("Activate account error (%d): %s", code, error_message);
}
};
username.c_str(), password.c_str(),
rcu_id.c_str(), robot_id.c_str(),
url.c_str(),
callback);
}
}
void HarixRcu_Account_DoActivate(void *context, const char *username, const char *password, const char *rcu_id, const char *robot_id, const char *activation_url, AccountRequestCallBack callback)
用户名密码激活接口
void(* AccountRequestCallBack)(void *context, bool success, int code, const char *error_message)
Account通用回调函数指针,用于激活/登录/取消激活等状态回调。
Definition: account.h:52
void HarixRcu_Account_DoLogin(void *context, AccountRequestCallBack result_cb, const char *robot_id, const char *robot_type, const char *robot_model)
登录接口
bool HarixRcu_Account_IsActivated()
判断是否已经激活
#define LOGE(...)
Definition: logger.h:71

3.2 VBN 网络

HARIX 服务需要设备通过 VBN 安全网络来访问,VBN 会在登录的时候自动连接并维护其持久性。目前 VBN 客户端在 Android 上既可以独立 App,亦可以 aar 集成的方式提供,其他平台则以独立程序的形式提供。

网络模块,主要用于监听获取VBN的相关状态,例如 VBN 的连接状态,网络的时延、抖动、丢包率等,以便业务层进行策略处理,例如弱网切换至离线 TTS。头文件 network.h

// 监听 VBN 接入状态
VpnConnectStatusCallBack onConnectStatus = [](void *context, VpnConnectState status) {
switch (status)
{
LOGD("VBN connect success");
break;
LOGW("VBN connect fail!");
break;
}
};
// 监听 VBN 网络质量信息:丢包率,延时,抖动
VpnQualityInfoCallBack qualityInfoCallback = [](void *context, const char* quality) {
LOGD("VBN quality info: %s", quality);
};
// 监听 VBN 网络质量状态(策略判断网络质量等级)
VpnQualityStatusCallBack qualityStatusCallback = [](void *context, VpnQualityState status) {
switch (status)
{
LOGW("Broken network!");
break;
LOGW("Weak network!");
break;
LOGD("Good network!");
break;
}
};
#define LOGW(...)
Definition: logger.h:70
#define LOGD(...)
Definition: logger.h:51
VpnConnectState
VBN的连接状态
Definition: network.h:39
@ KConnectSuccess
VBN连接成功
Definition: network.h:55
@ KConnectFail
VBN 连接失败
Definition: network.h:47
VpnQualityState
Vpn的网络质量状态,绿灯(网络正常),黄灯(弱网),红灯(断网)
Definition: network.h:68
@ KGreen
网络正常
Definition: network.h:76
@ KRed
断网
Definition: network.h:92
@ KYellow
弱网
Definition: network.h:84
void(* VpnConnectStatusCallBack)(void *context, VpnConnectState status)
Vpn连接状态函数指针
Definition: network.h:108
void(* VpnQualityStatusCallBack)(void *context, VpnQualityState status)
Vpn网络状态(弱网状态)函数指针
Definition: network.h:138
void HarixRcu_Network_SubscribeVpnQualityInfoCallback(void *context, VpnQualityInfoCallBack qualityCallback)
注册监听Vpn网络质量接口
void(* VpnQualityInfoCallBack)(void *context, const char *quality)
Vpn质量信息函数指针
Definition: network.h:123
void HarixRcu_Network_SubscribeVpnConnectStatusCallback(void *context, VpnConnectStatusCallBack vpnConnectStatusCallback)
注册监听Vpn连接状态回调接口
void HarixRcu_Network_SubscribeVpnQualityStatusCallback(void *context, VpnQualityStatusCallBack callback)
注册监听Vpn网络状态(弱网状态)接口,需要配置弱网策略,

3.3 语音 AI

SDK 提供语音唤醒、语音命令词、语音在线/离线听写,语音合成,语音问答以及文本输入问答等功能。头文件 smart_voice.h

语音识别(ASR)以及自然语言处理(NLP)

语音识别,语音识别中语音的采集是内置在SDK,开发者开启了ASR功能之后SDK中就会进行语音输入的采集。其中语音识别按流式的方式返回识别的结果,同时对识别的文本使用自然语言处理得到匹配的答案并返回该答案;

AsrResultCallback asr_result_callback_ = [](void *context, const char *asrText, const char *questionId, int wakeup_status, int asr_flag) {
LOGI("OnAsr: %s, questionId=%s, wakeup_status=%d, asr_flag_%d", asrText, questionId, wakeup_status, asr_flag);
};
HarixRcu_SVoice_SubscribeAsrResultCallback(nullptr, asr_result_callback_);
QACallback nlp_qa_callback_ = [](void *context, const char *question, const char *answer, const char *intent, const char *source) {
LOGI("onQuestionAnswer question:%s, answer:%s, intent:%s, source:%s", question, answer, intent, source);
};
HarixRcu_SVoice_SubscribeQACallback(nullptr, nlp_qa_callback_);
#define LOGI(...)
Definition: logger.h:69
void(* QACallback)(void *context, const char *question, const char *answer, const char *intent, const char *source)
语音输入或文本输入内容的自然语言处理结果的函数指针
Definition: smart_voice.h:138
void HarixRcu_SVoice_SubscribeAsrResultCallback(void *context, AsrResultCallback streamingRecognizeCallback)
注册ASR识别内容的回调接口
void(* AsrResultCallback)(void *context, const char *asrText, const char *questionId, int wakeup_status, int asr_flag)
语音识别结果的函数指针,对应识别的文本是实时识别之后返回给注册者
Definition: smart_voice.h:53
void HarixRcu_SVoice_SubscribeQACallback(void *context, QACallback callback)
注册Switch QA内容的回调接口

语音合成

支持在SDK内部对合成的音频进行播放,亦可以将合成的音频提供给外部播放器进行播放,方便开发者根据实际场景进行切换。为了提高合成的效率,合成的音频数据是通过流式的方式返回的,而非一次性返回整个音频数据

  • 使能音频播放器的工作流程(语音合成后自动播放):

    PlayStatusCallback tts_play_status_callback_ = [](void *context, int status, const char *subText, const char *questionId) {
    LOGI("OnTtsPlayStatusChange: status:%d, subText:%s, questionId:%s", status, subText, questionId);
    };
    HarixRcu_SVoice_SubscribePlayerStatusChange(nullptr, tts_play_status_callback_);
    PlayDurationCallback tts_play_duration_callback_ = [](void *context, unsigned long long duration) {
    LOGI("OnTtsPlayDurationChange: duration %lld", duration);
    };
    HarixRcu_SVoice_SubscribePlayerDurationChange(nullptr, tts_play_duration_callback_);
    HarixRcu_SVoice_PlayTts("answer","questionId",true);
    void HarixRcu_SVoice_SubscribePlayerStatusChange(void *context, PlayStatusCallback callback)
    注册音频播放状态的回调接口
    bool HarixRcu_SVoice_PlayTts(const char *text, const char *questionId, bool canInturpeted)
    开始文本播放(其中包括文本转语音,以及对语音的播放)的接口
    void HarixRcu_SVoice_SubscribePlayerDurationChange(void *context, PlayDurationCallback callback)
    注册音频播放时长的回调接口
    void(* PlayStatusCallback)(void *context, int status, const char *subText, const char *questionId)
    TTS音频数据播放的状态的函数指针
    Definition: smart_voice.h:101
    void(* PlayDurationCallback)(void *context, unsigned long long duraion)
    TTS音频数据播放进度的函数指针
    Definition: smart_voice.h:116
  • 关闭音频播放器的工作流程(仅进行语音合成):

    TtsAudioStreamCallback callback = [](void *context, const unsigned char *data, int size, int audioType, const char *text, int index, const char *questionId, const char *ttsVendor, const char *location) {
    LOGI("OnTtsAudioStream");
    // Do audio playing...
    };
    HarixRcu_SVoice_SynthesizeTts("answer","questionId",true);
    bool HarixRcu_SVoice_SynthesizeTts(const char *text, const char *questionId, bool canInturpeted)
    开文本合成音频的接口,合成的音频通过注册的回调返回给调用者
    void HarixRcu_SVoice_SubscribeTtsAudio(void *context, TtsAudioStreamCallback callback)
    注册文本转音频的音频数据回调接口
    void(* TtsAudioStreamCallback)(void *context, const unsigned char *data, int size, int audioType, const char *text, int index, const char *questionId, const char *ttsVendor, const char *location)
    文字转语音的语音数据的函数指针,对应音频数据分多个语音片段返回给注册者
    Definition: smart_voice.h:82

语音唤醒模式


3.4 视觉 AI

SDK 提供人脸检测和人脸识别功能,目前识别频率为 1 秒 1 次。头文件 smart_vision.h

视觉 AI 依赖 Camera 模块,若需要定制 Camera 相关参数,例如 分辨率,采集帧率等,需要调用 camera.h 中 API 进行设置。若使用 Camera 默认参数(640 x 480, 15fps),则无需进行任何操作,使能视觉的流程中会自动开关 Camera。

FaceDetectCallBack face_detect_callback_ = [](void *context, FaceRectInfoList infos) {
if (infos.len > 0)
{
for (int i = 0; i < infos.len; ++i)
{
int x = infos.faceInfos[i].x;
int y = infos.faceInfos[i].y;
int w = infos.faceInfos[i].w;
int h = infos.faceInfos[i].h;
LOGI("OnFaceDetect (id %d / total %d): x %d, y %d, w %d, h %d", i, infos.len, x, y, w, h);
}
}
};
HarixRcu_SVision_SubscribeFaceDetectCallback(nullptr, face_detect_callback_);
FaceRecognizeCallBack face_recognize_callback_ = [](void *context, const char *name, const char *gender, const char *age) {
LOGI("OnFaceRecognize name: %s, gender: %s, age: %s", name, gender, age);
};
HarixRcu_SVision_SubscribeFaceRecognizeCallback(nullptr, face_recognize_callback_);
void HarixRcu_SVision_SubscribeFaceDetectCallback(void *context, FaceDetectCallBack callback)
注册人脸检测信息回调接口。
void(* FaceRecognizeCallBack)(void *context, const char *name, const char *gender, const char *age)
人脸识别信息函数指针。
Definition: smart_vision.h:52
void(* FaceDetectCallBack)(void *context, FaceRectInfoList faceList)
人脸检测信息函数指针。
Definition: smart_vision.h:36
void HarixRcu_SVision_SubscribeFaceRecognizeCallback(void *context, FaceRecognizeCallBack callback)
注册人脸识别信息回调接口。
bool HarixRcu_SVision_EnableFaceDetect()
开启人脸检测。在开启人脸检测的同时,默认也会开启人脸识别(系统会自动将检测到的人脸进行人脸识别操作),亦可通过云端 ROC 关闭人脸识别功能。
人脸信息列表结构体。
Definition: smart_vision_constant.h:66

3.5 音视频通话

音视频通话,提供设备与客服坐席之间的双向音视频通话、双向音频通话、双向音频单向上行视频通话、单向音视频监控。头文件 call.hcall_constant.h

  1. 通话依赖音频采集和播报模块,目前是自动调用 SDK 内部功能模块,无需设置。
  2. 视频通话依赖 Camera 模块,若需要定制 Camera 相关参数,例如 分辨率,采集帧率等,需要调用 camera.h 中 API 进行设置。若使用 Camera 默认参数(640 x 480, 15fps),则无需进行任何操作,视频通话的流程中会自动开关 Camera。

呼叫示例:

// 监听通话状态事件
CallEventCallback call_event_callback_ = [](void *context, CallEventType eventType) {
LOGI("OnCallEvent: %d", eventType);
};
HarixRcu_Call_SubscribeCallEventCallback(nullptr, call_event_callback_);
// 订阅收到的对端视频画面数据
CallVideoDataCallback call_recv_video_callback_ = [](void *context, unsigned char *data, int size, int width, int height) {
((CallService *)context)->OnRecvVideoData(data, size, width, height);
};
HarixRcu_Call_SubscribeCallVideoDataCallback(this, call_recv_video_callback_);
// 发起双向视频通话
// 主动挂断通话
void(* CallEventCallback)(void *context, CallEventType callEvent)
通话事件函数指针
Definition: call.h:40
void HarixRcu_Call_SubscribeCallEventCallback(void *context, CallEventCallback callback)
注册接收通话事件回调接口
void HarixRcu_Call_SubscribeCallVideoDataCallback(void *context, CallVideoDataCallback callback)
注册接收远端视频数据回调接口
void HarixRcu_Call_StartTalk(bool isOnlyAudio, bool isTwoWayVideo)
机器人发起呼叫
void HarixRcu_Call_StopTalk()
机器人挂断通话
void(* CallVideoDataCallback)(void *context, unsigned char *data, int size, int width, int height)
远端视频数据回调函数指针
Definition: call.h:61
CallEventType
通话事件类型定义.
Definition: call_constant.h:26

3.6 日志

SDK 提供日志控制台和文件的输出 API,调用者可以使用该套日志功能;亦可由外部注入日志输出 API,让SDK 内部日志使用调用者的日志模块,还可配合 ROC 远程获取设备日志。头文件 logger.h

// 初始化配置日志文件输出目录,大小限制
HarixRcu_InitConfig_ConfigLogger(".", 20 * 1024 * 1024, 210 * 1024 * 1024);
// 注册外部日志输出
logprint_func_ = [](void *context, int loglevel, const char *tag, const char *msg)
{
printf("[%s]: %s\n", tag, msg);
};
// 设置当前文件日志 Tag
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "HarixRcuDemo"
// 通过宏 NDEBUG 控制 LOGV 和 LOGD 是否输出
LOGV("test!!! ");
LOGD("test!!! ");
LOGI("test!!! ");
LOGW("test!!! ");
LOGE("test!!! ");
bool HarixRcu_InitConfig_ConfigLogger(const char *logPath, int maxFileSize, int maxSize)
设置日志配置接口,这个接口需要第一个被调用,否则会导致日志路径不能变更。路径不仅指日志,如果debug开启,SmartVoice和SmartVision数据也会保存到此路径。必须在调用第一个打印日志之前...
void HarixRcu_Logger_RegisterLogPrintFunction(void *context, LogPrintFunction func)
注册日志回调接口
#define LOGV(...)
Definition: logger.h:50