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 注意:由于涉及到 ...
随机推荐
- [namespace hdk] Balanced_tree 整合
代码 #include<bits/stdc++.h> using namespace std; namespace hdk{ namespace balanced_tree{ const ...
- MySQL笔记--数据库定时备份与恢复
利用crontab定时.利用mysqldump备份 编写sh启动脚本时记得赋予执行权限(x) 如果没有mysqldump命令执行,基于centos7 yum -y install mysql-clie ...
- Android dtbo(3) 编译和验证
您可以使用设备树编译器 (DTC) 编译设备树源文件.不过,在将叠加层 DT 应用于目标主 DT 之前,您还应该通过模拟 DTO 的行为来验证结果. 1. 通过DTC进行编译 构建主 DT .dts ...
- python 生成requirements 文件
python 要生成 requirements文件 有两种情况 具有独立的虚拟环境 全局环境 具有独立的虚拟环境 pip freeze > requirements.txt 全局环境 安装 pi ...
- ToDesk云电脑开启公测!支持AIGC、高性能渲染等场景,价格低至0.98元
在云计算和人工智能技术飞速发展的今天,云电脑作为一种新型的计算模式,正逐渐改变着传统电脑的使用方式.近日,ToDesk云电脑宣布开启公测,以其支持AIGC(人工智能.大数据.云计算等技术的融合应用). ...
- 一文彻底弄懂MySQL的优化
在企业级 Web 开发中,MySQL 优化是至关重要的,它直接影响系统的响应速度.可扩展性和整体性能.下面从不同角度,列出详细的 MySQL 优化技巧,涵盖查询优化.索引设计.表结构设计.配置调整等方 ...
- 好好的Typora收费了!_2022_01_20
好好的Typora收费了!_2022_01_20 用惯了Typora真的很难再去换别的MarkDown编辑工具了,导出都找不到合适的.1.0以前的不需要验证的版本直接就不能打开了,真是头大. 到处找不 ...
- Promise 简单实例一枚
<script> function t(){ return new Promise((resolve, reject)=>{ setTimeout(()=>{ resolve( ...
- 使用sklearn中的Adaboost分类器来实现ORL人脸分类
使用sklearn中的Adaboost分类器来实现ORL人脸分类 前言:博主上网浏览使用Adaboost实现人脸分类时,发现并没有分类,大部分全都是关于人脸识别检测的,并没有实现对某个人的精准分类(例 ...
- div跟随浏览器大小而改变
<head> <style> .main { position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; ...