Aliyun 语音识别&语音合成

导入 SDK

将ZIP包中的nuisdk.framework添加到工程中,并在工程Build PhasesLink Binary With Libraries中添加nuisdk.framework。请确保在编译配置的General > Frameworks, Libraries, and Embedded Content中配置nuisdk.frameworkEmbed & 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语音识别&语音合成的更多相关文章

  1. IOS开发之语音合成(科大讯飞)详解

    1.注册讯飞账号,申请APPID(注意选择IOS平台) 2.加载所需要的类库 3.导入所需要的类库文件头 4.调用申请的APPID以及所需函数,完成语音合成(需要参考官方给出的SDK文件)   详细步 ...

  2. iOS 10 语音识别Speech Framework详解

    最近做了一个项目,涉及到语音识别,使用的是iOS的speech Framework框架,在网上搜了很多资料,也看了很多博客,但介绍的不是很详细,正好项目做完,在这里给大家详解一下speech Fram ...

  3. iOS中 语音识别功能/语音转文字教程具体解释 韩俊强的博客

    原文地址:http://blog.csdn.net/qq_31810357/article/details/51111702 前言:近期研究了一下语音识别,从百度语音识别到讯飞语音识别:首先说一下个人 ...

  4. 百度AI开放平台,语音识别,语音合成以及短文本相似度

    百度AI开放平台:https://ai.baidu.com/ 语音合成 from aip import AipSpeech APP_ID=" #'你的 App ID' API_KEY=&qu ...

  5. iOS中 语音识别功能/语音转文字教程详解 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 原文地址:http://blog.csdn.net/qq_31810357/article/details/5111 ...

  6. IOS Google语音识别更新啦!!!

      旧版本的API:   —Google提供了一个在线语音识别的API接口,通过该API可以进行中文.英文等语言的识别.  API地址:http://www.google.com/speech-api ...

  7. [ios]ios tts的使用

    参考:http://www.tekuba.net/program/327/ http://blog.sina.com.cn/s/blog_923fdd9b0101flx3.html iOS平台由于本身 ...

  8. IOS开发-经常使用站点集合

    1.    https://developer.apple.com  //苹果开发人员站点 2.    https://itunesconnect.apple.com  //itunes站点 3.   ...

  9. C# 10分钟完成百度语音技术(语音识别与合成)——入门篇

    我们已经讲了人脸识别(入门+进阶).图片识别(入门).下面是链接: C# 10分钟完成百度人脸识别——入门篇 C# 30分钟完成百度人脸识别——进阶篇(文末附源码) C# 10分钟完成百度图片提取文字 ...

  10. python 全栈开发,Day133(玩具与玩具之间的对话,基于jieba gensim pypinyin实现的自然语言处理,打包apk)

    先下载github代码,下面的操作,都是基于这个版本来的! https://github.com/987334176/Intelligent_toy/archive/v1.6.zip 注意:由于涉及到 ...

随机推荐

  1. Vite2 如何设置打包后文件名

    vite.config.js build: { rollupOptions: { output: { entryFileNames: `assets/[name].${timestamp}.js`, ...

  2. Android应用启动全流程分析(源码深度剖析)

    目录 1.前言 2.大纲 3. Input触控事件处理流程 3.1 系统机制分析 3.2 结合Systrace分析 4. 应用进程的创建与启动 4.2 创建应用进程 4.2.1 AMS 发送socke ...

  3. python批量读取并显示图片,处理异常。

    今天写了一个批量读取并显示图片的代码,当做练习,方便以后拿来使用. import imageio import os import matplotlib.pyplot as plt filepath ...

  4. nestjs 和 .net DI 使用并注册的区别

    核心:对象之间的关系 各种 引用  --- 方便使用各种服务 1. .net 注册服务 三种注册方式 build.Service.Addsigtel 单例 瞬时 等 .addSingtel<IU ...

  5. 本地图片上传服务器返回在线地址接口 - file - input -修改头像-带预览功能- 然后使用cropperjs 进行裁剪

    说明:上传的图片是 file 类型 ,核心就是获取图片文件(file类型的) : 实现一:使用 vant2 的图片加载组件 ,选择文件后会触发afterRead方法 ,参数 file 就是文件列表fi ...

  6. kotlin更多语言结构——>注解

    注解声明 注解是将元数据附加到代码的方法.要声明注解,请将 annotation 修饰符放在类的前面 annotation class Fancy 注解的附加属性可以通过用元注解标注注解类来指定 - ...

  7. 云原生周刊:Flux 2.3 发布 | 2024.5.20

    开源项目推荐 kubeinvaders kubeinvaders 专为 Kubernetes 用户设计.它提供了一种有趣而交互式的方式来探索和可视化您的 Kubernetes 集群.通过类似游戏的界面 ...

  8. 云原生周刊:一文读懂 Pod 网络 | 2023.4.10

    文章推荐 一文读懂 Pod 网络 这篇文章旨在帮助读者理解 Pod 网络的概念和原理.Pod 网络是 Kubernetes 中的一个重要概念,它描述了如何在一个集群中部署和运行应用程序. Pod 网络 ...

  9. jmeter测试rpc接口-使用dubbo框架调用

    1.下载用于测试dubbo的spring boot项目 参考文章: http://t.zoukankan.com/111testing-p-11297038.html https://zhuanlan ...

  10. Linux 日志管理基础

    目录 基本介绍 日志的存放 存放目录与存放内容 举例说明 日志管理服务: rsyslogd 功能与配置 检查自启动 配置文件 /etc/rsyslog.conf 修改配置文件 基本介绍 日志文件是重要 ...