提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 效果图
- 一、去讯飞官网注册[讯飞官网](https://www.xfyun.cn/)
- 二、下载jar和so文件[讯飞SDK](https://download.csdn.net/download/Android_Cll/91764299)
- 三、语音合成
- 四、语音识别
- 总结
前言
目前只要是关于小说或者英语相关软件,就会遇到需要朗读文本或者单词,这时就需要涉及到语音合成功能,如果再涉及一些聊天啥的(不一定是即时通讯)就会涉及语音识别,比如简单的聊天问AI,用语音问,这时后台会告诉你AI那边没有语音的,需要把语音转成文字给AI,来吧,看看怎么实现。
效果图
一、去讯飞官网注册讯飞官网
去讯飞官网注册后进行实名认证,然后创建应用就会得到APP_ID。
二、下载jar和so文件讯飞SDK
三、语音合成
1.将jar和so文件放到libs文件下并引用(必须要so文件)
代码如下(语音合成和识别共用):
kotlin
//讯飞
implementation files('libs/Msc.jar')
2.Application中实例化
代码如下(语音合成和识别共用,切记保留appid=,只替换后面YOUR_APP_ID):
kotlin
// 初始化讯飞 SDK(替换 YOUR_APP_ID)
SpeechUtility.createUtility(this, "appid=YOUR_APP_ID")
3.activity中使用
kotlin
//定义变量
private var tts: SpeechSynthesizer? = null
// 初始化语音合成器
tts = SpeechSynthesizer.createSynthesizer(this, null)
//朗读 xiaoyan这里自己去新建应用后找到语音合成,特色发音,新建发音人
private fun startTTS(text: String?) {
// 设置参数
tts!!.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan")
tts!!.setParameter(SpeechConstant.SPEED, "40") // 语速(0~100)
tts!!.setParameter(SpeechConstant.PITCH, "50") // 音调(0~100)
tts!!.setParameter(SpeechConstant.VOLUME, "100") // 音量(0~100)
// 开始合成并播放
tts!!.startSpeaking(text, object : SynthesizerListener {
override fun onSpeakBegin() {
// 开始播放
}
override fun onBufferProgress(percent: Int, beginPos: Int, endPos: Int, info: String?) {
// 缓冲进度
}
override fun onSpeakPaused() {
}
override fun onSpeakResumed() {
}
override fun onSpeakProgress(percent: Int, beginPos: Int, endPos: Int) {
// 播放进度
}
override fun onCompleted(error: SpeechError?) {
if (error != null) {
Log.e("TTS", "Error: " + error.errorCode)
}
}
override fun onEvent(eventType: Int, arg1: Int, arg2: Int, obj: Bundle?) {
// 事件回调(如播放暂停、恢复)
}
})
}
override fun onDestroy() {
super.onDestroy()
// 释放资源
if (tts != null) {
tts!!.stopSpeaking()
tts!!.destroy()
}
}
四、语音识别
1.步骤同上1和2
2.activity中使用
kotlin
//定义变量
private var mIat: SpeechRecognizer? = null // 语音识别对象
// 创建语音识别对象
mIat = SpeechRecognizer.createRecognizer(this, object : InitListener {
override fun onInit(code: Int) {
println("初始化--->$code")
setIatParams() // 设置参数
}
})
// 设置识别参数
private fun setIatParams() {
if (mIat == null) return
// 设置听写参数
mIat!!.setParameter(SpeechConstant.DOMAIN, "iat") // 语音转写
mIat!!.setParameter(SpeechConstant.LANGUAGE, "zh_cn") // 中文
mIat!!.setParameter(SpeechConstant.ACCENT, "mandarin") // 普通话
mIat!!.setParameter(SpeechConstant.VAD_BOS, "4000") // 语音前缀静音超时(毫秒)
mIat!!.setParameter(SpeechConstant.VAD_EOS, "1000") // 语音后缀静音超时(毫秒)
mIat!!.setParameter(SpeechConstant.ASR_PTT, "1") // 标点符号(1有标点,0无标点)
}
//开始录音时调用
if (mIat != null) {
mIat!!.startListening(mRecognizerListener) // 开始录音
}
//结束录音调用
if (mIat != null) {
mIat!!.stopListening() // 停止录音并获取最终结果
}
// 识别监听器
private val mRecognizerListener: RecognizerListener = object : RecognizerListener {
override fun onResult(results: RecognizerResult, isLast: Boolean) {
// 实时返回结果(isLast为true时表示最终结果)
val jsonStr: String? = results.resultString
val text: String? = parseWFromJson(jsonStr)
if (isLast) {
//最终结果
println("文件目录--->$text")
} else {
// tvResult.append("[实时结果] " + text + "\n")
}
}
override fun onError(error: SpeechError) {
println("识别错误:" + error.errorCode + ", " + error.errorDescription)
// 错误处理
// tvResult.setText("错误:" + error.getErrorDescription())
}
override fun onVolumeChanged(p0: Int, p1: ByteArray?) {
// 音量变化(0-30)
println("当前音量:$p0")
}
override fun onBeginOfSpeech() {
// 开始录音
println("开始录音")
// tvResult.setText("正在录音...")
}
override fun onEndOfSpeech() {
// 结束录音(自动触发)
println("录音结束")
}
override fun onEvent(eventType: Int, arg1: Int, arg2: Int, obj: Bundle?) {
// 扩展事件回调
}
}
//语音转文字数据获取格式化
fun parseWFromJson(jsonStr: String?): String {
val result = StringBuilder()
try {
val jsonObject: JSONObject = JSONObject(jsonStr)
val wsArray: JSONArray = jsonObject.getJSONArray("ws") // 获取 ws 数组
// 遍历 ws 数组
for (i in 0 until wsArray.length()) {
val wsItem: JSONObject = wsArray.getJSONObject(i)
val cwArray: JSONArray = wsItem.getJSONArray("cw") // 获取 cw 数组
// 遍历 cw 数组
for (j in 0 until cwArray.length()) {
val cwItem: JSONObject = cwArray.getJSONObject(j)
val w: String? = cwItem.optString("w", "") // 提取 w 字段
result.append(w) // 拼接结果
}
}
} catch (e: JSONException) {
e.printStackTrace()
}
return result.toString()
}
//释放资源
override fun onDestroy() {
super.onDestroy()
// 释放资源
if (mIat != null) {
mIat!!.cancel();
mIat!!.destroy();
}
}
总结
除了添加jar文件外一定要引用so文件,不然会报错,语音合成发音人可新建特色发音,根据自己选择新建,语音识别如果外加录音,就在开始录音时调用,结束录音结束识别即可。