本文介绍了如何使用阿里云智能语音服务提供的iOS NUI SDK,包括SDK下载安装、关键接口及代码示例。
前提条件
下载安装
- 说明
下载后请在样例初始化代码中替换您的阿里云账号信息、Appkey和Token才可运行。为方便集成,2.5.14版本后iOS接口使用纯Object-C接口,不再使用C++混合接口。
类别
兼容范围
系统
最低支持iOS9
架构
arm64,x86_64
此SDK还包含如下功能,若未支持您想要的功能,请前往对应文档获取SDK。
功能
是否支持
一句话识别
是
实时语音识别
是
语音合成
是
实时长文本语音合成
是
流式文本语音合成
是
离线语音合成
否
录音文件识别极速版
是
唤醒及命令词
否
听悟实时推流
是
解压ZIP包,将ZIP包中的nuisdk.framework添加到您的工程中,并在工程Build Phases的Link Binary With Libraries中添加nuisdk.framework。请确保在编译配置的General > Frameworks, Libraries, and Embedded Content中配置nuisdk.framework为Embed & Sign。
使用Xcode打开此工程,工程中提供了参考代码以及一些直接可使用的工具类,例如音频播放录制和文件操作,您可以直接复制源码到您的实际工程进行使用。其中语音合成示例代码在TTSViewController类中。
SDK关键接口
tts_initialize:初始化SDK
/** * 初始化SDK,SDK为单例,请先释放后再次进行初始化。请勿在UI线程调用,意外下可能引起阻塞。 * @param parameters: 初始化参数,参见下方说明或接口说明:https://help.aliyun.com/document_detail/173642.html * @param level: log打印级别,值越小打印越多 * @param save_log: 是否保存log为文件,存储目录为parameter中的debug_path字段值。注意,log文件无上限,请注意持续存储导致磁盘存满。 * @return 参考错误码:https://help.aliyun.com/document_detail/459864.html */ -(int) nui_tts_initialize:(const char *)parameters logLevel:(NuiSdkLogLevel)level saveLog:(BOOL)save_log;
nui_tts_play: 开始播放
/** * 开始播放 * @param priority: 任务优先级,请使用"1" * @param taskid: 任务id,可传入32个字节的uuid或者传入空内容由SDK自动生成 * @param text: 要播放的文本内容 * @return 参考错误码:https://help.aliyun.com/document_detail/459864.html */ -(int) nui_tts_play:(const char *)priority taskId:(const char *)taskid text:(const char *)text;
nui_tts_cancel:取消播放
/** * 取消合成任务 * @param taskid: 传入想要停止的任务id,如果为空则取消所有任务 * @return:参见错误码:https://help.aliyun.com/document_detail/459864.html。 */ -(int) nui_tts_cancel:(const char *)taskid;
nui_tts_pause:暂停播放
/** * 暂停 * @return 参考错误码 */ -(int) nui_tts_pause;
nui_tts_resume:恢复播放
/** * 恢复暂停的任务 * @return 参考错误码 */ -(int) nui_tts_resume;
nui_tts_set_param:设置语音合成参数
/** * 以键值对形式设置参数 * @param param: 参数名,参考接口说明 * @param value: 参数值,参考接口说明 * @return 参考错误码 */ -(int) nui_tts_set_param:(const char *)param value:(const char *)value;
nui_tts_get_param:获取参数
/** * 获取参数值 * @param param: 参数名,参考接口说明 * @return 参数值 */ -(const char *) nui_tts_get_param:(const char *)param;
nui_tts_release: 释放SDK资源
/** * 释放SDK * @return 参考错误码 */ -(int) nui_tts_release;
NeoNuiTtsDelegate 事件代理
onNuiTtsUserdataCallback:在回调中提供音频数据。
/** * 当开始识别时,此回调被连续调用,App需要在回调中进行语音数据填充,语音数据来自App的录音 * @param info: 在使用时间戳功能时返回时间戳结果,json格式 * @param info_len: info字段的数据长度 * @param buffer: 合成的语音数据 * @param len: 合成的语音长度 * @param taskid: 本次合成的任务id */ - (void)onNuiTtsUserdataCallback:(char*)info infoLen:(int)info_len buffer:(char*)buffer len:(int)len taskId:(char*)task_id;
onNuiTtsEventCallback: 事件回调。
/** * SDK主要事件回调 * @param event: 回调事件,参考接口说明:https://help.aliyun.com/zh/isi/developer-reference/overview-5 * @param taskid: 本次合成的任务id * @param code: 参考错误码,TTS_EVENT_ERROR时有效 */ - (void)onNuiTtsEventCallback:(NuiSdkTtsEvent)event taskId:(char*)taskid code:(int)code;
NuiSdkTtsEvent事件列表:
名称
说明
TTS_EVENT_START
语音合成开始,准备播放。
TTS_EVENT_END
语音合成结束,合成数据已全部抛出,但并不表示播放结束。
TTS_EVENT_CANCEL
取消语音合成。
TTS_EVENT_PAUSE
语音合成暂停。
TTS_EVENT_RESUME
语音合成恢复。
TTS_EVENT_ERROR
语音合成发生错误。
调用步骤
初始化SDK和播放组件。
根据业务需要设置参数。
调用nui_tts_play进行播放。
在合成数据回调中,将数据写入播放器进行播放,建议使用流式播放。
收到语音合成结束的回调。
代码示例
接口默认采用get_instance方式获得单例,您如果有多例需求,也可以直接alloc对象进行使用。
语音合成初始化
NSString * initParam = [self genInitParams];
[_nui nui_tts_initialize:[initParam UTF8String] logLevel:LOG_LEVEL_VERBOSE saveLog:true];
其中,genInitParams生成为String JSON字符串,包含资源目录和用户信息。其中用户信息包含如下字段。
-(NSString *)genInitParams {
NSString *strResourcesBundle = [[NSBundle mainBundle] pathForResource:@"Resources" ofType:@"bundle"];
NSString *bundlePath = [[NSBundle bundleWithPath:strResourcesBundle] resourcePath];
NSString *debug_path = [_utils createDir];
NSMutableDictionary *ticketJsonDict = [NSMutableDictionary dictionary];
//注意:
// 语音交互服务需要先准备好账号,并开通相关服务。具体步骤请查看:
// https://help.aliyun.com/zh/isi/getting-started/start-here
//
//原始账号:
// 账号(子账号)信息主要包括AccessKey ID(后续简称为ak_id)和AccessKey Secret(后续简称为ak_secret)。
// 此账号信息一定不可存储在app代码中或移动端侧,以防账号信息泄露造成资费损失。
//
//STS临时凭证:
// 由于账号信息下发给客户端存在泄露的可能,阿里云提供的一种临时访问权限管理服务STS(Security Token Service)。
// STS是由账号信息ak_id和ak_secret,通过请求生成临时的sts_ak_id/sts_ak_secret/sts_token
// (为了区别原始账号信息和STS临时凭证, 命名前缀sts_表示STS生成的临时凭证信息)
//什么是STS:https://help.aliyun.com/zh/ram/product-overview/what-is-sts
//STS SDK概览:https://help.aliyun.com/zh/ram/developer-reference/sts-sdk-overview
//STS Python SDK调用示例:https://help.aliyun.com/zh/ram/developer-reference/use-the-sts-openapi-example
//
//账号需求说明:
// 若使用离线功能(离线语音合成、唤醒), 则必须app_key、ak_id和ak_secret,或app_key、sts_ak_id、sts_ak_secret和sts_token
// 若使用在线功能(语音合成、实时转写、一句话识别、录音文件转写等), 则只需app_key和token
[_utils getTicket:ticketJsonDict Type:get_token_from_server_for_online_features];
if ([ticketJsonDict objectForKey:@"token"] != nil) {
NSString *tokenValue = [ticketJsonDict objectForKey:@"token"];
if ([tokenValue length] == 0) {
TLog(@"The 'token' key exists but the value is empty.");
}
} else {
TLog(@"The 'token' key does not exist.");
}
//工作目录路径,SDK从该路径读取配置文件
[ticketJsonDict setObject:bundlePath forKey:@"workspace"]; // 必填, 且需要有读写权限
TLog(@"workspace:%@", bundlePath);
[ticketJsonDict setObject:debug_path forKey:@"debug_path"];
TLog(@"debug_path:%@", debug_path);
[ticketJsonDict setObject:@"wss://nls-gateway.cn-shanghai.aliyuncs.com:443/ws/v1" forKey:@"url"]; // 默认
// 设置成在线语音合成模式, 这个设置很重要, 遗漏会导致无法运行
[ticketJsonDict setObject:@"2" forKey:@"mode_type"]; // 必填
NSString *id_string = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
TLog(@"id: %s", [id_string UTF8String]);
[ticketJsonDict setObject:id_string forKey:@"device_id"]; // 必填, 推荐填入具有唯一性的id, 方便定位问题
NSData *data = [NSJSONSerialization dataWithJSONObject:ticketJsonDict options:NSJSONWritingPrettyPrinted error:nil];
NSString * jsonStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
return jsonStr;
}
根据需求设置参数
//可以设置发音人、语调和语速等参数,参数列表参见接口说明。
[self.nui nui_tts_set_param:"font_name" value:"xiaoyun"];
启动语音合成
//建议同一时间单示例启动一个task进行语音合成,单实例多task易出异常。
[self.nui nui_tts_play:"1" taskId:"" text:[content UTF8String]];
回调处理
onNuiTtsEventCallback:语音合成事件回调,根据语音合成状态控制播放器。
- (void)onNuiTtsEventCallback:(NuiSdkTtsEvent)event taskId:(char*)taskid code:(int)code { TLog(@"onNuiTtsEventCallback event[%d]", event); if (event == TTS_EVENT_START) { TLog(@"onNuiTtsEventCallback TTS_EVENT_START"); loop_in = TTS_EVENT_START; // 旧版本示例工程提供的播放器,仅做参考,可根据自身业务重写播放器。 // [self->_voicePlayer play]; // 新版本示例工程提供了新的播放器,仅做参考,可根据自身业务重写播放器。 [_audioController startPlayer]; } else if (event == TTS_EVENT_END || event == TTS_EVENT_CANCEL || event == TTS_EVENT_ERROR) { loop_in = event; if (event == TTS_EVENT_END) { TLog(@"onNuiTtsEventCallback TTS_EVENT_END"); // 旧版本示例工程提供的播放器,仅做参考,可根据自身业务重写播放器。 // 注意这里的event事件是指语音合成完成,而非播放完成,播放完成需要由voicePlayer对象来进行通知 // [self->_voicePlayer drain]; // 新版本示例工程提供了新的播放器,仅做参考,可根据自身业务重写播放器。 // 注意这里的event事件是指语音合成完成,而非播放完成,播放完成需要由audioController对象来进行通知 [_audioController drain]; } else { // 旧版本示例工程提供的播放器,仅做参考,可根据自身业务重写播放器。 // 取消播报、或者发生异常时终止播放 // [self->_voicePlayer stop]; // 新版本示例工程提供了新的播放器,仅做参考,可根据自身业务重写播放器。 // 取消播报、或者发生异常时终止播放 [_audioController stopPlayer]; } if (event == TTS_EVENT_ERROR) { const char *errmsg = [_nui nui_tts_get_param: "error_msg"]; TLog(@"tts get errmsg:%s", errmsg); } } }
onNuiTtsUserdataCallback:语音合成数据回调,将回调中的合成数据写入播放器进行播放。
- (void)onNuiTtsUserdataCallback:(char*)info infoLen:(int)info_len buffer:(char*)buffer len:(int)len taskId:(char*)task_id { TLog(@"onNuiTtsUserdataCallback info ..."); if (info_len > 0) { TLog(@"onNuiTtsUserdataCallback info text %s. index %d.", info, info_len); } if (len > 0) { // 旧版本示例工程提供的播放器,仅做参考,可根据自身业务重写播放器。 // [_voicePlayer write:(char*)buffer Length:(unsigned int)len]; // 新版本示例工程提供了新的播放器,仅做参考,可根据自身业务重写播放器。 [_audioController write:(char*)buffer Length:(unsigned int)len]; } }
结束语音合成
[self.nui nui_tts_cancel:NULL];