提示:
在使用SDK之前,请先确保已阅读了 接口说明文档。
当前最新版本:2.3.16,发布日期:2019年8月4号。
下载安装
SDK下载
C++ SDK 可从CppSdk2.0中下载,压缩文件包含以下几个部分:
- CMakeLists.txt demo工程的CMakeList文件。
- build 编译目录。
- demo 包含demo.cpp,各语音服务配置文件。各文件描述见下表:
文件名 | 描述 |
---|---|
sdkDemo.cpp | windows专用,默认为一句话识别功能demo,如需可自行替换成其它功能(编码格式:UTF-8 代签名) |
speechRecognizerDemo.cpp | 一句话识别demo |
speechSynthesizerDemo.cpp | 语音合成demo |
speechTranscriberDemo.cpp | 实时音频流识别demo |
speechRecognizerSyncDemo.cpp | 一句话同步识别demo |
speechTranscriberSyncDemo.cpp | 实时音频流同步识别demo |
testX.wav | 测试音频 |
- include 包含sdk头文件,以及部分第三方头文件。各文件描述见下表
文件名 | 描述 |
---|---|
openssl | openssl |
pthread | pthread线(windows下使用) |
uuid | uuid(linux下使用) |
opus | opus |
jsoncpp | jsoncpp |
curl | nls SDK并不依赖curl,仅用于demo中,用以获取token) |
nlsCommonSdknls | nls sdk并不依赖nlsCommonSdk,仅用于demo中,用以获取token |
nlsClient.h | SDK实例 |
nlsEvent.h | 回调事件说明 |
speechRecognizerRequest.h | 一句哈识别 |
speechSynthesizerRequest.h | 语音合成 |
speechTranscriberRequest.h | 实时音频流识别 |
speechRecognizerSyncRequest.h | 一句话同步识别 |
speechTranscriberSyncRequest.h | 实时语音同步识别 |
iNlsRequest.h | Request基础 |
- lib 包含sdk,以及第三方依赖库。linux.tar.gz为linux平台lib压缩包。windows.zip为windows平台lib压缩包。其中根据平台不同,可以选择linux版本libnlsCppSdk.so(glibc2.5及以上, Gcc4, Gcc5), windows(x86/x64)版本nlsCppSdk.dll(VS2013、VS2015)。
- readme.txt SDK说明。
- release.log 版本说明。
- version 版本号。
- build.sh demo编译脚本。
依赖库:
SDK 依赖 openssl(l-1.0.2j),opus(1.2.1),jsoncpp(0.10.6),uuid(1.0.3),pthread(2.9.1)。依赖库放置在 path/to/sdk/lib 下。
注意:path/to/sdk/lib/linux/uuid仅在linux下使用。path/to/sdk/lib/windwos/1x.0/pthread仅在windows下使用。
编译运行
运行编译脚本build.sh:
1. 请确认本地系统以安装Cmake,最低版本3.1、Glibc 2.5、Gcc 4.1.2及以上
2. cd NlsSdkCpp2.0/lib
3. tar -zxvpf linux.tar.gz
4. cd NlsSdkCpp2.0
5. 执行./build.sh 编译demo
6. 编译完毕,进入NlsSdkCpp2.0/demo目录。可以看见以生成三个demo可执行程序:srDemo(一句话异步识别)、srSyncDemo(一句话同步识别)、stDemo(实时音频异步识别)、stSyncDemo(实时音频同步识别)、syDemo(语音合成)。
7. 执行[./sydemo <your appkey> <your AccessKey ID> <your AccessKey Secret>]
如果不支持cmake,可尝试手动编译:
1: cd NlsSdkCpp2.0/lib
2: tar -zxvpf linux.tar.gz
3: cd NlsSdkCpp2.0/demo
4: g++ -o srDemo speechRecognizerDemo.cpp -I../include -L../lib/linux -lnlsCppSdk -lnlsCommonSdk -lopus -lcurl -lssl -lcrypto -lpthread -luuid -ljsoncpp -D_GLIBCXX_USE_CXX11_ABI=0
5: g++ -o stDemo speechTranscriberDemo.cpp -I../include -L../lib/linux -lnlsCppSdk -lnlsCommonSdk -lopus -lcurl -lssl -lcrypto -lpthread -luuid -ljsoncpp -D_GLIBCXX_USE_CXX11_ABI=0
6: g++ -o syDemo speechSynthesizerDemo.cpp -I../include -L../lib/linux -lnlsCppSdk -lnlsCommonSdk -lopus -lcurl -lssl -lcrypto -lpthread -luuid -ljsoncpp -D_GLIBCXX_USE_CXX11_ABI=0
7: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../lib/linux
8: ./sydemo <your appkey> <your AccessKey ID> <your AccessKey Secret>
Windows平台需要您自己搭建工程(请将Demo文件修改为含有BOM的UTF-8编码格式)。
Token获取方式可见demo.cpp, 或访问链接:获取访问令牌
注意:
- linux环境下,运行环境最低要求:Glibc 2.5及以上, Gcc4、Gcc5
- windows下,目前支持VS2013,VS2015
关键接口
- NlsClient:语音处理Client,相当于所有语音相关处理类的Factory,全局创建一个实例即可。
- SpeechSynthesizerRequest:语音合成请求对象。
- SpeechSynthesizerCallback:回调事件函数集合的对象,合成结果、异常等回调的统一入口。
- NlsEvent:回调事件对象,您可以从中获取Request状态码、云端返回结果、失败信息等。
更多介绍参见api文档链接:C++ API接口说明
C++ SDK自定义错误码
错误码 | 错误描述 | 解决方案 |
---|---|---|
10000001 | SSL: couldn’t create a ……! | 建议重试 |
10000002 | openssl官方错误描述 | 根据描述提示处理之后,建议重试 |
10000003 | 系统错误描述 | 根据系统错误描述提示处理 |
10000004 | URL: The url is empty. | 检查是否设置 云端URL地址 |
10000005 | URL: Could not parse WebSocket url | 检查是否正确设置 云端URL地址 |
10000006 | MODE: unsupport mode. | 检查时都正确设置了语音功能模式 |
10000007 | JSON: Json parse failed. | 服务端发送错误响应内容,请提供task_id,并反馈给阿里云 |
10000008 | WEBSOCKET: unkown head type. | 服务端发送错误WebSocket类型,请提供task_id,并反馈给阿里云 |
10000009 | HTTP: connect failed. | 与云端连接失败,请检查网络,在重试 |
HTTP协议官方状态码 | HTTP: Got bad status. | 根据HTTP协议官方描述提示处理 |
系统错误码 | IP: ip address is not valid. | 根据系统错误描述提示处理 |
系统错误码 | ENCODE: convert to utf8 error. | 根据系统错误描述提示处理 |
10000010 | please check if the memory is enough | 内存不足. 请检查本地机器内存 |
10000011 | Please check the order of execution | 接口调用顺序错误(接收到Failed/complete事件时,SDK内部会关闭连接。此时在调用send会上报错误。) |
10000012 | StartCommand/StopCommand Send failed | 参数错误. 请检查参数设置是否正确 |
10000013 | The sent data is null or dataSize <= 0. | 发送错误. 请检查发送参数是否正确 |
10000014 | Start invoke failed. | start超时错误. 请调用stop,释放资源,重新开始识别流程. |
10000015 | connect failed等 | connect失败. 释放资源,重新开始识别流程. |
代码示例
说明1:Demo中使用了SDK内置的默认语音合成服务的外网访问URL,如果您使用阿里云上海ECS并想使用内网访问URL,则在创建SpeechSynthesizerRequest的对象中设置内网访问的URL:
request->setUrl("ws://nls-gateway.cn-shanghai-internal.aliyuncs.com/ws/v1");
说明2:Demo中将合成的音频保存在了文件中,如果您需要播放音频且对实时性要求较高,建议使用流式播放,即边接收语音数据边播放,减少延时。
完整示例,详见SDK压缩包中的demo目录。
// 工作线程
void* pthreadFunc(void* arg) {
ParamCallBack cbParam;
SpeechSynthesizerCallback* callback = NULL;
/*
* 0: 从自定义线程参数中获取token, 配置文件等参数.
*/
ParamStruct* tst = (ParamStruct*)arg;
if (tst == NULL) {
cout << "arg is not valid." << endl;
return NULL;
}
// 初始化自定义回调参数
cbParam.binAudioFile = tst->audioFile;
cbParam.audioFile.open(cbParam.binAudioFile.c_str(), ios::binary | ios::out);
/*
* 1: 创建并设置回调函数
*/
callback = new SpeechSynthesizerCallback();
callback->setOnSynthesisStarted(OnSynthesisStarted, &cbParam); // 保留接口,暂不使用
callback->setOnSynthesisCompleted(OnSynthesisCompleted, &cbParam); // 设置音频合成结束回调函数
callback->setOnChannelClosed(OnSynthesisChannelClosed, &cbParam); // 设置音频合成通道关闭回调函数
callback->setOnTaskFailed(OnSynthesisTaskFailed, &cbParam); // 设置异常失败回调函数
callback->setOnBinaryDataReceived(OnBinaryDataRecved, &cbParam); // 设置文本音频数据接收回调函数
/*
* 创建语音识别SpeechSynthesizerRequest对象, 参数为callback对象.
* 目前SynthesizerRequest对象在调用一次start(),发送完一个text文本之后,必须调用stop()并releaseSynthesizerRequest()释放对象
*/
/*
* 2: 创建语音识别SpeechSynthesizerRequest对象
*/
SpeechSynthesizerRequest* request = NlsClient::getInstance()->createSynthesizerRequest(callback);
if (request == NULL) {
cout << "createSynthesizerRequest failed." << endl;
cbParam.audioFile.close();
delete callback;
callback = NULL;
return NULL;
}
request->setAppKey(tst->appkey.c_str()); // 设置AppKey, 必填参数, 请参照官网申请
request->setText(tst->text.c_str()); // 设置待合成文本, 必填参数. 文本内容必须为UTF-8编码。
request->setVoice("xiaoyun"); // 发音人, 包含"xiaoyun", "ruoxi" "xiaogang". 可选参数, 默认是xiaoyun
request->setVolume(50); // 音量, 范围是0~100, 可选参数, 默认50
request->setFormat("wav"); // 音频编码格式, 可选参数, wav. 支持的格式pcm, wav, mp3
request->setSampleRate(SAMPLE_RATE); // 音频采样率, 包含8000, 16000. 可选参数, 默认是16000
request->setSpeechRate(0); // 语速, 范围是-500~500, 可选参数, 默认是0
request->setPitchRate(0); // 语调, 范围是-500~500, 可选参数, 默认是0
request->setMethod(0); // 合成方法, 可选参数, 默认是0. 参数含义0:不带录音的参数合成; 1:带录音的拼接合成; 2:不带录音的拼接合成; 3:带录音的参数合成
request->setToken(tst->token.c_str()); // 设置账号校验token, 必填参数
/*
* 3: start()为阻塞操作, 发送start指令之后, 会等待服务端响应, 或超时之后才返回.
* 调用start()之后, 文本被发送至云端. SDk接到云端返回的合成音频数据,会通过OnBinaryDataRecved回调函数上报至您的进程.
*/
if (request->start() < 0) {
cout << "start() failed." << endl;
NlsClient::getInstance()->releaseSynthesizerRequest(request); // start()失败,释放request对象
cbParam.audioFile.close();
delete callback;
callback = NULL;
return NULL;
}
/*
* 6: start()返回之后,关闭识别连接通道.
* stop()为阻塞操作, 在接受到服务端响应, 或者超时之后, 才会返回.
*
*/
request->stop();
cbParam.audioFile.close();
/*
* 7: 识别结束, 释放request对象
*/
NlsClient::getInstance()->releaseSynthesizerRequest(request);
/*
* 8: 释放callback对象
*/
delete callback;
callback = NULL;
return NULL;
}
/**
* 根据AccessKey ID和AccessKey Secret重新生成一个token,并获取其有效期时间戳
*/
int generateToken(string akId, string akSecret, string* token, long* expireTime) {
NlsToken nlsTokenRequest;
nlsTokenRequest.setAccessKeyId(akId);
nlsTokenRequest.setKeySecret(akSecret);
if (-1 == nlsTokenRequest.applyNlsToken()) {
cout << "Failed: " << nlsTokenRequest.getErrorMsg() << endl; /*获取失败原因*/
return -1;
}
*token = nlsTokenRequest.getToken();
*expireTime = nlsTokenRequest.getExpireTime();
return 0;
}
/**
* 合成单个文本数据
*/
int speechSynthesizerFile(const char* appkey) {
/**
* 获取当前系统时间戳,判断token是否过期
*/
std::time_t curTime = std::time(0);
if (g_expireTime - curTime < 10) {
cout << "the token will be expired, please generate new token by AccessKey-ID and AccessKey-Secret." << endl;
if (-1 == generateToken(g_akId, g_akSecret, &g_token, &g_expireTime)) {
return -1;
}
}
ParamStruct pa;
pa.token = g_token;
pa.appkey = appkey;
// 注意: Windows平台下,合成文本中如果包含中文,请将本CPP文件设置为带签名的UTF-8编码或者GB2312编码
pa.text = "中华人民共和国万岁, 万岁, 万万岁.";
#ifdef _WIN32
pa.text = GBKToUTF8(pa.text); // windows下默认编码是GBK,必须转换成UTF-8编码
#endif
pa.audioFile = "syAudio.wav";
pthread_t pthreadId;
// 启动一个工作线程, 用于识别
pthread_create(&pthreadId, NULL, &pthreadFunc, (void *)&pa);
pthread_join(pthreadId, NULL);
return 0;
}