Android之讯飞语音合成和语音识别

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

目前只要是关于小说或者英语相关软件,就会遇到需要朗读文本或者单词,这时就需要涉及到语音合成功能,如果再涉及一些聊天啥的(不一定是即时通讯)就会涉及语音识别,比如简单的聊天问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文件,不然会报错,语音合成发音人可新建特色发音,根据自己选择新建,语音识别如果外加录音,就在开始录音时调用,结束录音结束识别即可。