Android TextToSpeech 使用指南 |
您所在的位置:网站首页 › 怎么用小爱同学朗读文章 › Android TextToSpeech 使用指南 |
/** * 文本阅读(TTS) 管理器 * @author lv.qx on 2019/11/25 */class TextToSpeechManager(context: Context) { private var ttsErrorStatus: Int = 0 private var tts: TextToSpeech? = null init { tts = TextToSpeech(context) { status -> ttsErrorStatus = if (status == TextToSpeech.SUCCESS) { TextToSpeech.SUCCESS } else { TextToSpeech.ERROR } } val tts = tts if (ttsErrorStatus == TextToSpeech.SUCCESS && tts != null) { // 默认设定语言为中文,原生的 android 貌似不支持中文。 ttsErrorStatus = when { tts.availableLanguages == null -> TextToSpeech.LANG_NOT_SUPPORTED tts.availableLanguages.contains(Locale.CHINESE) -> tts.setLanguage(Locale.CHINESE) tts.availableLanguages.contains(Locale.SIMPLIFIED_CHINESE) -> tts.setLanguage(Locale.SIMPLIFIED_CHINESE) tts.availableLanguages.contains(Locale.TRADITIONAL_CHINESE) -> tts.setLanguage(Locale.TRADITIONAL_CHINESE) else -> TextToSpeech.LANG_NOT_SUPPORTED } } } /** * 设置音调,值越大声音越尖(女生),值越小则变成男声,默认值为 1.0 */ fun setPitch(pitch: Float) { val tts = tts ?: return tts.setPitch(pitch) } /** * 设置语速,默认值为 1 */ fun setSpeechRate(rate: Float) { val tts = tts ?: return tts.setSpeechRate(rate) } /** * 读文本 * @param content 文本内容 * @param utteranceProgressListener 阅读进度监听 */ fun speak( content: String, utteranceProgressListener: GetLastSegUtteranceProgressListener ) { val tts = tts ?: return tts.setOnUtteranceProgressListener(utteranceProgressListener) when (ttsErrorStatus) { TextToSpeech.LANG_MISSING_DATA -> showToast(R.string.voice_missing_data) TextToSpeech.LANG_NOT_SUPPORTED -> showToast(R.string.voice_lang_not_supported) ANDROID_VERSION_NOT_SUPPORT -> showToast(R.string.voice_android_version_not_supported) else -> { if (tts.isSpeaking) { tts.stop() } else { val textSeg = genSegment(content, 10) utteranceProgressListener.setLastSegId(SEG_PREFIX + (textSeg.size - 1)) for (i in textSeg.indices) { // QUEUE_ADD:播放完之前的语音任务后才播报本次内容,QUEUE_FLUSH:丢弃之前的播报任务,立即播报本次内容 tts.speak(textSeg[i], TextToSpeech.QUEUE_ADD, null, SEG_PREFIX + i) } } } } } /** * 将源文本分段 * * @param segmentLength 每一段的长度,最大设置 3999,大于 3999 将阅读出错 * @param originStr 源文本 * @return 分成的文本段 */ private fun genSegment(originStr: String, segmentLength: Int = 3999): Array { val originLength = originStr.length val arraySize = originLength / segmentLength + 1 val result = arrayOfNulls(arraySize) for (i in 0 until arraySize) { result[i] = originStr.substring(i * segmentLength, min((i + 1) * segmentLength, originLength)) } return result } /** * 取得文本内容大约分钟长度 */ fun getSpeechLength(content: String): Int { val totalSecond = (content.length / 3.7).toInt() return totalSecond / 60 } /** * 扩展 onDone 方法的进度监听 */ @SuppressLint("NewApi") abstract class GetLastSegUtteranceProgressListener : UtteranceProgressListener() { private var lastSegId = "" /** * 设置最后一段的 id */ fun setLastSegId(lastSegId: String) { this.lastSegId = lastSegId } override fun onDone(utteranceId: String?) { onDone(utteranceId, lastSegId == utteranceId) } /** * @param isLastSeg 是否是最后一段 */ abstract fun onDone(utteranceId: String?, isLastSeg: Boolean) } companion object { private const val SEG_PREFIX = "seg" // 段落前缀 private const val ANDROID_VERSION_NOT_SUPPORT = -3 // 版本不支持 }} |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |