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 注意:由于涉及到 ...
随机推荐
- 暑假集训CSP提高模拟 ∫[0,6] (x^2)/6 dx
\[\text{暑假集训CSP提高模拟}\int^{6}_{0}\frac{x^{2}}{6}dx \] 关于这个东西怎么求的良心教程 含义:求出 \(f(x)=\frac{x^{2}}{6}\) 在 ...
- Android Perfetto 系列 3:熟悉 Perfetto View
1. Perfetto View 界面 抓到 Perfetto Trace 之后,一般是在 ui.perfetto.dev 中打开(如果用官方提供的脚本,则会在抓去结束后自动在这个网站上打开,想看看怎 ...
- Csharp的CancellationToken 案例
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Syst ...
- Spark任务OOM问题如何解决?
大家好,我是 V 哥.在实际的业务场景中,Spark任务出现OOM(Out of Memory) 问题通常是由于任务处理的数据量过大.资源分配不合理或者代码存在性能瓶颈等原因造成的.针对不同的业务场景 ...
- 洛谷P1381单词背诵
单词背诵 题目描述 灵梦有 \(n\) 个单词想要背,但她想通过一篇文章中的一段来记住这些单词. 文章由 \(m\) 个单词构成,她想在文章中找出连续的一段,其中包含最多的她想要背的单词(重复的只算一 ...
- 云原生周刊:OpenTofu Registry 获得用户界面和 API|2024.9.9
开源项目推荐 kubectl trace kubectl trace 是一个 kubectl 插件,它允许你在 Kubernetes 集群中调度执行 bpftrace 程序. Kondense Kon ...
- 云原生爱好者周刊:在 PaaS 平台上托管 WebAssembly 应用
云原生一周动态要闻: Knative v1.1 发布 Nocalhost v0.6.12 发布 CircleCI 的企业功能现在免费了 SolarWinds 修复了一个 Serv-U 漏洞 Nvidi ...
- 痞子衡嵌入式:瑞萨RA系列FSP固件库分析之外设驱动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是瑞萨RA系列FSP固件库里的外设驱动. 上一篇文章 <瑞萨RA8系列高性能MCU开发初体验>,痞子衡带大家快速体验了一下瑞萨 ...
- 来看看一台Linux可支持多少个链接 | 漫画
困惑很多人的并发问题 在网络开发中,我发现有很多同学对一个基础问题始终是没有彻底搞明白.那就是一台服务器最大究竟能支持多少个网络连接?我想我有必要单独发一篇文章来好好说一下这个问题. 很多同学看到这个 ...
- CSS:Transform属性
本文将深入探讨css动画中transform属性,这是一种强大的工具,可以实现元素的旋转.缩放.移动和倾斜等效果.本文将通过详细的解释和实际案例,帮助你掌握transform属性的使用方法来增强你的网 ...