iOS Aliyun语音识别&语音合成
Aliyun 语音识别&语音合成
导入 SDK
将ZIP包中的nuisdk.framework添加到工程中,并在工程Build Phases的Link Binary With Libraries中添加nuisdk.framework。请确保在编译配置的General > Frameworks, Libraries, and Embedded Content中配置nuisdk.framework为Embed & Sign。

调用步骤
- 初始化SDK、录音实例。设置代理,初始化录音机
// 初始化语音转文字
instance?.nui_initialize(initParams.utf8String, logLevel: LOG_LEVEL_ERROR, saveLog: true)
instance?.nui_set_params(sttParams.utf8String)
instance?.delegate = self
voiceRecorder = NlsVoiceRecorder()
voiceRecorder?.delegate = self
- 根据业务需求配置参数。初始化参数合成和识别都是一样的。
/// SDK初始化参数
internal var initParams: NSString {
let bundle = Bundle.main.path(forResource: "Resources", ofType: "bundle")!
let bundlePath = Bundle(path: bundle)!.resourcePath
let idString = ASIdentifierManager.shared().advertisingIdentifier.uuidString
voicePath = debugPath()
var dict: [String: String] = [:]
dict["workspace"] = bundlePath // 必填
dict["debug_path"] = voicePath
dict["device_id"] = idString // 必填
dict["save_wav"] = "true"
// 从阿里云获取appkey和token进行语音服务访问
dict["app_key"] = appkey
if token.isEmpty {
HGToast("Need token")
return ""
}
dict["token"] = token
dict["url"] = "wss://nls-gateway.cn-shanghai.aliyuncs.com:443/ws/v1"
// FullMix = 0 // 选用此模式开启本地功能并需要进行鉴权注册
// FullCloud = 1 // 在线实时语音识别可以选这个
// FullLocal = 2 // 选用此模式开启本地功能并需要进行鉴权注册
// AsrMix = 3 // 选用此模式开启本地功能并需要进行鉴权注册
// AsrCloud = 4 // 在线一句话识别可以选这个
// AsrLocal = 5 // 选用此模式开启本地功能并需要进行鉴权注册
dict["service_mode"] = "1" // 必填
var jsonStr = ""
do {
let data = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
jsonStr = String(data: data, encoding: .utf8) ?? ""
} catch {
print("error genInitParams:\(error.localizedDescription)")
}
return jsonStr as NSString
}
- 调用nui_dialog_start开始识别。
instance?.nui_dialog_start(MODE_P2T, dialogParam: NSString(string: "").utf8String)
- 根据音频状态回调audio_state_changed_callback,打开录音机。
func onNuiAudioStateChanged(_ state: NuiAudioState) {
print("onNuiAudioStateChanged state=\(state.rawValue)")
if state == STATE_CLOSE || state == STATE_PAUSE {
voiceRecorder?.stop(true)
} else if state == STATE_OPEN {
recordedVoiceData = NSMutableData()
voiceRecorder?.start()
}
}
- 在user_data_callback回调中提供录音数据。
-(int)onNuiNeedAudioData:(char *)audioData length:(int)len data:(NSMutableData *) recordedVoiceData{
static int emptyCount = 0;
@autoreleasepool {
@synchronized(recordedVoiceData){
if (recordedVoiceData.length > 0) {
int recorder_len = 0;
if (recordedVoiceData.length > len)
recorder_len = len;
else
recorder_len = recordedVoiceData.length;
NSData *tempData = [recordedVoiceData subdataWithRange:NSMakeRange(0, recorder_len)];
[tempData getBytes:audioData length:recorder_len];
tempData = nil;
NSInteger remainLength = recordedVoiceData.length - recorder_len;
NSRange range = NSMakeRange(recorder_len, remainLength);
[recordedVoiceData setData:[recordedVoiceData subdataWithRange:range]];
emptyCount = 0;
return recorder_len;
} else {
if (emptyCount++ >= 50) {
emptyCount = 0;
}
return 0;
}
}
}
return 0;
}
- 在EVENT_ASR_PARTIAL_RESULT和EVENT_SENTENCE_END事件回调中获取识别结果。并将结果转为需要的 String。
func onNuiEventCallback(_ nuiEvent: NuiCallbackEvent, dialog: Int, kwsResult wuw: UnsafePointer<CChar>!, asrResult asr_result: UnsafePointer<CChar>!, ifFinish finish: Bool, retCode code: Int32) {
print("onNuiEventCallback event: \(nuiEvent) finish: \(finish)")
var result = NSString()
if nuiEvent == EVENT_ASR_PARTIAL_RESULT || nuiEvent == EVENT_ASR_RESULT {
result = NSString(utf8String: asr_result) ?? NSString()
print("RESULT: \(result) finish: \(finish)")
if let jsonData = String(result).data(using: .utf8) {
do {
let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
if let jsonDict = jsonObject as? [String: Any] {
if let payload = jsonDict["payload"] as? [String: Any] {
if let res = payload["result"] as? String {
DispatchQueue.main.async {
self.onDone?(res)
}
}
}
}
} catch {
print("Error parsing JSON: \(error.localizedDescription)")
}
}
} else if nuiEvent == EVENT_ASR_ERROR {
print("EVENT_ASR_ERROR error: \(code)")
return
} else if nuiEvent == EVENT_MIC_ERROR {
print("MIC ERROR")
voiceRecorder?.stop(true)
voiceRecorder?.start()
return
}
// finish 为真(可能是发生错误,也可能是完成识别)表示一次任务生命周期结束,可以开始新的识别
if finish {
print("STT result: \(String(result))")
}
}
- 调用nui_dialog_cancel结束识别。
instance?.nui_dialog_cancel(false)
- 结束调用,使用nui_release接口释放SDK资源。
// 释放资源
deinit {
instance?.nui_release()
tts?.nui_tts_release()
}
TTS 步骤与之类似
主要是获取 data 的方法是:
// 需要合成数据
func onNuiTtsUserdataCallback(_ info: UnsafeMutablePointer<CChar>!, infoLen info_len: Int32, buffer: UnsafeMutablePointer<CChar>!, len: Int32, taskId task_id: UnsafeMutablePointer<CChar>!) {
if info_len > 0 {
print("onNuiTtsUserdataCallback info text \(String(describing: info)). index: \(info_len)")
}
if len > 0 {
voicePlayer.write(buffer, length: len)
print("哈哈哈哈哈:\(len)")
}
}
然后通过voicePlayer播放出来
iOS Aliyun语音识别&语音合成的更多相关文章
- IOS开发之语音合成(科大讯飞)详解
1.注册讯飞账号,申请APPID(注意选择IOS平台) 2.加载所需要的类库 3.导入所需要的类库文件头 4.调用申请的APPID以及所需函数,完成语音合成(需要参考官方给出的SDK文件) 详细步 ...
- iOS 10 语音识别Speech Framework详解
最近做了一个项目,涉及到语音识别,使用的是iOS的speech Framework框架,在网上搜了很多资料,也看了很多博客,但介绍的不是很详细,正好项目做完,在这里给大家详解一下speech Fram ...
- iOS中 语音识别功能/语音转文字教程具体解释 韩俊强的博客
原文地址:http://blog.csdn.net/qq_31810357/article/details/51111702 前言:近期研究了一下语音识别,从百度语音识别到讯飞语音识别:首先说一下个人 ...
- 百度AI开放平台,语音识别,语音合成以及短文本相似度
百度AI开放平台:https://ai.baidu.com/ 语音合成 from aip import AipSpeech APP_ID=" #'你的 App ID' API_KEY=&qu ...
- iOS中 语音识别功能/语音转文字教程详解 韩俊强的博客
每日更新关注:http://weibo.com/hanjunqiang 新浪微博 原文地址:http://blog.csdn.net/qq_31810357/article/details/5111 ...
- IOS Google语音识别更新啦!!!
旧版本的API: —Google提供了一个在线语音识别的API接口,通过该API可以进行中文.英文等语言的识别. API地址:http://www.google.com/speech-api ...
- [ios]ios tts的使用
参考:http://www.tekuba.net/program/327/ http://blog.sina.com.cn/s/blog_923fdd9b0101flx3.html iOS平台由于本身 ...
- IOS开发-经常使用站点集合
1. https://developer.apple.com //苹果开发人员站点 2. https://itunesconnect.apple.com //itunes站点 3. ...
- C# 10分钟完成百度语音技术(语音识别与合成)——入门篇
我们已经讲了人脸识别(入门+进阶).图片识别(入门).下面是链接: C# 10分钟完成百度人脸识别——入门篇 C# 30分钟完成百度人脸识别——进阶篇(文末附源码) C# 10分钟完成百度图片提取文字 ...
- python 全栈开发,Day133(玩具与玩具之间的对话,基于jieba gensim pypinyin实现的自然语言处理,打包apk)
先下载github代码,下面的操作,都是基于这个版本来的! https://github.com/987334176/Intelligent_toy/archive/v1.6.zip 注意:由于涉及到 ...
随机推荐
- huge 发在家长群的图片
- 阿里云Centos7修改MariaDB数据库连接时间,解决连接mysql报Too many connection的问题
在测项目的时候突然发现数据库连接不上了,提示Too many connection. 产生问题的原因是MySQL的Sleep进程占用了大量的连接,当时是重启mysql解决的这个问题!后来又配置了连接池 ...
- Android :安卓学习笔记之 Handler机制 的简单理解和使用
目录 Handler机制 1.Handler使用的引出 2.背景和定义 3.作用和意义 4.主要参数 5.工作原理及流程 5.1.对应关系 6.深入分析 Handler机制源码 6.1.Handler ...
- Java日期时间API系列35-----Jdk8中java.time包中的新的日期时间API类应用,微秒和纳秒等更精确的时间格式化和解析。
通过Java日期时间API系列1-----Jdk7及以前的日期时间类中得知,Java8以前除了java.sql.Timestamp扩充纳秒,其他类最大只精确到毫秒:Java8 time包所有相关类都支 ...
- jwt实现登录 和 接口实现动态权限
[Authorize] ==== using Microsoft.AspNetCore.Authorization; 登录的 DTO namespace login; public class ...
- vue打包后,添加入spring boot下,访问不到字体的BUG
主要报错:OTS parsing error: incorrect file size in WOFF header OTS parsing error: incorrect entrySelecto ...
- 神经网络之卷积篇:详解残差网络(ResNets)(Residual Networks (ResNets))
详解残差网络 ResNets是由残差块(Residual block)构建的,首先解释一下什么是残差块. 这是一个两层神经网络,在\(L\)层进行激活,得到\(a^{\left\lbrack l + ...
- 我被 .NET8 JIT 的一个BUG反复折磨了半年之久
很久很久没有写过博客了, 正好最近园子又挣得一线生机, 必须得凑个热闹水一篇. 事情是这样的, 在今年的早些时候, 把公司的一部分api服务器的.net版本从6升级到了8, 毕竟6马上就是EOL了(. ...
- python-requests模拟上传文件-带参数
方法1: 1.安装requests_toolbelt依赖库 #代码实现def upload(self): login_token = self.token.loadTokenList() for to ...
- centos7系统安装部署zabbix5.0
一.简介 zabbix是一个基于[WEB]界面的提供分布式[系统监视]以及网络监视功能的企业级的开源解决方案.zabbix能监视各种网络参数,保证[服务器系统]的安全运营:并提供灵活的通知机制以让[系 ...