[Feat]新增支持多语言的TTS
[Feat]新增支持多语言的TTS
This commit is contained in:
4
app/proguard-rules.pro
vendored
4
app/proguard-rules.pro
vendored
@@ -426,6 +426,6 @@
|
||||
-keep class com.squareup.haha.guava.collect.*{*;}
|
||||
-keep class **.zego.**{*;}
|
||||
|
||||
|
||||
|
||||
#-----科大讯飞语音合成-----
|
||||
-keep class com.iflytek.**{*;}
|
||||
|
||||
|
||||
@@ -142,6 +142,7 @@ ext {
|
||||
ttszhi : "com.mogo.tts:tts-zhi:${TTS_ZHI_VERSION}",
|
||||
ttspad : "com.mogo.tts:tts-pad:${TTS_ZHI_VERSION}",
|
||||
ttsnoop : "com.mogo.tts:tts-noop:${TTS_NOOP_VERSION}",
|
||||
ttsiflytek : "com.mogo.tts:tts-iflytek :${TTS_IFLYTEK_VERSION}",
|
||||
|
||||
//========================= 网约车 Maven 版本管理 =========================
|
||||
mogooch : "com.mogo.och:och:${MOGO_OCH_VERSION}",
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.tts.base.IMogoTTS;
|
||||
import com.mogo.tts.base.IMogoTTSCallback;
|
||||
import com.mogo.tts.base.MultiLangTtsEntity;
|
||||
import com.mogo.tts.base.PreemptType;
|
||||
|
||||
/**
|
||||
@@ -52,7 +53,9 @@ public class AIAssist {
|
||||
private AIAssist(Context context) {
|
||||
try {
|
||||
// 暂时换成反射,解决死锁问题
|
||||
// TODO:("支持切换思必驰和科大讯飞")
|
||||
Class<?> clazz = Class.forName("com.mogo.tts.pad.PadTTS");
|
||||
// Class<?> clazz = Class.forName("com.mogo.tts.iflytek.IFlyTekTts");
|
||||
mTTS = (IMogoTTS) clazz.getConstructor().newInstance();
|
||||
mTTS.init(context);
|
||||
// mTTS = (IMogoTTS) ARouter.getInstance().build(MogoTTSConstants.API_PATH).navigation(context.getApplicationContext());
|
||||
@@ -122,6 +125,18 @@ public class AIAssist {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持多语言的Tts
|
||||
* @param ttsEntity: 多语言Entity
|
||||
* @param level: 等级由低到高为0、1、2、3,分别对应p3、p2、p1、p0
|
||||
* @param callback
|
||||
*/
|
||||
public void speakMultiLangTTSWithLevel(MultiLangTtsEntity ttsEntity, int level, IMogoTTSCallback callback) {
|
||||
if (mTTS != null) {
|
||||
mTTS.speakMultiLangTTSWithLevel(ttsEntity, level, callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 语音播报
|
||||
*
|
||||
|
||||
@@ -123,6 +123,7 @@ TTS_DI_VERSION=2.1.16.10
|
||||
TTS_ZHI_VERSION=2.1.16.10
|
||||
TTS_PAD_VERSION=2.1.16.10
|
||||
TTS_NOOP_VERSION=2.1.16.10
|
||||
TTS_IFLYTEK_VERSION=2.1.16.10
|
||||
# 自研地图
|
||||
MAP_CUSTOM_VERSION=2.1.16.10
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ include ':libraries:mogo-obu'
|
||||
// 语音
|
||||
include ':tts:tts-base'
|
||||
include ':tts:tts-pad'
|
||||
include ':tts:tts-iflytek'
|
||||
|
||||
// 测试DEBUG
|
||||
include ':test:crashreport'
|
||||
|
||||
@@ -64,6 +64,12 @@ interface IMogoTTS extends IProvider {
|
||||
*/
|
||||
void speakTTSVoice( String tts, PreemptType type, IMogoTTSCallback callback );
|
||||
|
||||
void speakMultiLangTTSWithLevel(
|
||||
MultiLangTtsEntity ttsEntity,
|
||||
int level,
|
||||
IMogoTTSCallback callback
|
||||
);
|
||||
|
||||
void stopSpeakTts(String text);
|
||||
|
||||
void stopTts();
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.mogo.tts.base
|
||||
|
||||
enum class LanguageType(val langName: String) {
|
||||
CHINESE("chinese"),
|
||||
ENGLISH("english"),
|
||||
KOREAN("korean")
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.mogo.tts.base
|
||||
|
||||
data class MultiLangTtsEntity(
|
||||
private var ttsList: List<LangTtsEntity>
|
||||
) {
|
||||
private val stringBuffer by lazy {
|
||||
StringBuffer()
|
||||
}
|
||||
|
||||
private var ttsIndex = 0
|
||||
|
||||
fun ttsNext(): LangTtsEntity? {
|
||||
return if (ttsIndex in ttsList.indices) {
|
||||
ttsList[ttsIndex++]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return stringBuffer.let {
|
||||
it.setLength(0)
|
||||
ttsList.forEachIndexed { index, langTtsEntity ->
|
||||
if (index != ttsList.size - 1) {
|
||||
it.append("${langTtsEntity};")
|
||||
} else {
|
||||
it.append(langTtsEntity)
|
||||
}
|
||||
}
|
||||
it.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class LangTtsEntity(
|
||||
var ttsContent: String,
|
||||
var language: LanguageType
|
||||
) {
|
||||
override fun toString(): String {
|
||||
return "ttsContent is:$ttsContent,language is:${language.langName}"
|
||||
}
|
||||
}
|
||||
1
tts/tts-iflytek/.gitignore
vendored
Normal file
1
tts/tts-iflytek/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
62
tts/tts-iflytek/build.gradle
Normal file
62
tts/tts-iflytek/build.gradle
Normal file
@@ -0,0 +1,62 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'kotlin-android'
|
||||
id 'kotlin-android-extensions'
|
||||
id 'kotlin-kapt'
|
||||
id 'com.alibaba.arouter'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
// buildToolsVersion rootProject.ext.android.buildToolsVersion
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode Integer.valueOf(VERSION_CODE)
|
||||
versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION")
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles "consumer-rules.pro"
|
||||
|
||||
//ARouter apt 参数
|
||||
kapt {
|
||||
useBuildCache = false
|
||||
arguments {
|
||||
arg("AROUTER_MODULE_NAME", project.getName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation rootProject.ext.dependencies.androidxappcompat
|
||||
|
||||
implementation rootProject.ext.dependencies.arouter
|
||||
kapt rootProject.ext.dependencies.aroutercompiler
|
||||
|
||||
api rootProject.ext.dependencies.aiassist
|
||||
api rootProject.ext.dependencies.aiassistReplace
|
||||
|
||||
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
|
||||
implementation rootProject.ext.dependencies.ttsbase
|
||||
implementation rootProject.ext.dependencies.mogo_core_utils
|
||||
} else {
|
||||
implementation project(":tts:tts-base")
|
||||
implementation project(':core:mogo-core-utils')
|
||||
}
|
||||
}
|
||||
|
||||
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()
|
||||
0
tts/tts-iflytek/consumer-rules.pro
Normal file
0
tts/tts-iflytek/consumer-rules.pro
Normal file
3
tts/tts-iflytek/gradle.properties
Normal file
3
tts/tts-iflytek/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
GROUP=com.mogo.tts
|
||||
POM_ARTIFACT_ID=tts-iflytek
|
||||
VERSION_CODE=1
|
||||
BIN
tts/tts-iflytek/libs/Msc.jar
Normal file
BIN
tts/tts-iflytek/libs/Msc.jar
Normal file
Binary file not shown.
21
tts/tts-iflytek/proguard-rules.pro
vendored
Normal file
21
tts/tts-iflytek/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
4
tts/tts-iflytek/src/main/AndroidManifest.xml
Normal file
4
tts/tts-iflytek/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.mogo.tts.iflytek">
|
||||
|
||||
</manifest>
|
||||
375
tts/tts-iflytek/src/main/java/com/mogo/tts/iflytek/IFlyTekTts.kt
Normal file
375
tts/tts-iflytek/src/main/java/com/mogo/tts/iflytek/IFlyTekTts.kt
Normal file
@@ -0,0 +1,375 @@
|
||||
package com.mogo.tts.iflytek
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.os.Looper
|
||||
import android.util.Pair
|
||||
import androidx.annotation.Keep
|
||||
import com.iflytek.cloud.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
|
||||
import com.mogo.tts.base.*
|
||||
import java.util.*
|
||||
|
||||
@Keep
|
||||
class IFlyTekTts : IMogoTTS, InitListener {
|
||||
companion object {
|
||||
const val TAG = "IFlyTekTts"
|
||||
}
|
||||
|
||||
private var context: Context? = null
|
||||
|
||||
private var ttsEngine: SpeechSynthesizer? = null
|
||||
private var engineType = SpeechConstant.TYPE_CLOUD
|
||||
|
||||
private var voicer: String = "xiaoyan"
|
||||
private var voicerEntries: Array<String>? = null
|
||||
|
||||
// 等级由低到高为0、1、2、3,默认为-1表示没有正在tts的
|
||||
private var curTtsLevel = -1
|
||||
|
||||
// 由于主动打断不会有回调事件,所以主动打断时清掉map中被打断的text和callback
|
||||
private var curTtsContent = ""
|
||||
private var curTtsEntity: MultiLangTtsEntity? = null
|
||||
private val linkedList = LinkedList<Pair<MultiLangTtsEntity, Int>>()
|
||||
|
||||
// 上一次语音合成的语言
|
||||
private var lastLang = LanguageType.CHINESE
|
||||
|
||||
private val speakVoiceMap by lazy {
|
||||
HashMap<String, IMogoTTSCallback>()
|
||||
}
|
||||
|
||||
override fun init(context: Context) {
|
||||
this.context = context
|
||||
|
||||
// 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史intent进入Activity造成SpeechUtility对象为null
|
||||
// 如在Application中调用初始化,需要在Mainifest中注册该Applicaiton
|
||||
// 注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请增加参数:SpeechConstant.FORCE_LOGIN+"=true"
|
||||
// 参数间使用半角“,”分隔。
|
||||
// 设置你申请的应用appid,请勿在'='与appid之间添加空格及空转义符
|
||||
// 注意: appid 必须和下载的SDK保持一致,否则会出现10407错误
|
||||
SpeechUtility.createUtility(context, "appid=0c498b42")
|
||||
ttsEngine = SpeechSynthesizer.createSynthesizer(context, this)
|
||||
voicerEntries = context.resources?.getStringArray(R.array.voicer_cloud_values)
|
||||
}
|
||||
|
||||
override fun initTts(sn: String?) {}
|
||||
|
||||
override fun onInit(code: Int) {
|
||||
if (code != ErrorCode.SUCCESS) {
|
||||
CallerLogger.e(
|
||||
TAG,
|
||||
"初始化失败,错误码为:$code,请点击网址https://www.xfyun.cn/document/error-code查询解决方案"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
ttsEngine?.stopSpeaking()
|
||||
ttsEngine?.destroy()
|
||||
}
|
||||
|
||||
override fun flush() {
|
||||
}
|
||||
|
||||
override fun speakTTSVoice(tts: String?) {
|
||||
|
||||
}
|
||||
|
||||
override fun speakTTSVoice(tts: String?, callback: IMogoTTSCallback?) {
|
||||
}
|
||||
|
||||
override fun speakTTSVoice(tts: String?, type: PreemptType?, callback: IMogoTTSCallback?) {
|
||||
}
|
||||
|
||||
override fun speakTTSVoiceWithLevel(tts: String?, level: Int) {
|
||||
}
|
||||
|
||||
override fun speakTTSVoiceWithLevel(tts: String?, level: Int, callBack: IMogoTTSCallback?) {
|
||||
}
|
||||
|
||||
override fun speakMultiLangTTSWithLevel(
|
||||
ttsEntity: MultiLangTtsEntity,
|
||||
level: Int,
|
||||
callBack: IMogoTTSCallback?
|
||||
) {
|
||||
if (callBack != null) {
|
||||
speakVoiceMap[ttsEntity.toString()] = callBack
|
||||
}
|
||||
speakMultiLangTTSWithLevel(ttsEntity, level)
|
||||
}
|
||||
|
||||
override fun stopSpeakTts(text: String?) {
|
||||
stopTts()
|
||||
}
|
||||
|
||||
override fun stopTts() {
|
||||
curTtsEntity?.let {
|
||||
val string = it.toString()
|
||||
if (speakVoiceMap.containsKey(string)) {
|
||||
speakVoiceMap.remove(string)
|
||||
}
|
||||
curTtsEntity = null
|
||||
}
|
||||
curTtsContent = ""
|
||||
curTtsLevel = -1
|
||||
ttsEngine?.stopSpeaking()
|
||||
}
|
||||
|
||||
override fun speakQAndACmd(tts: String?, callback: IMogoTTSCallback?) {
|
||||
}
|
||||
|
||||
override fun speakQAndACmd(
|
||||
tts: String?,
|
||||
okWords: Array<out String>?,
|
||||
cancelWords: Array<out String>?,
|
||||
callback: IMogoTTSCallback?
|
||||
) {
|
||||
}
|
||||
|
||||
override fun registerUnWakeupCommand(
|
||||
cmd: String?,
|
||||
cmdWords: Array<out String>?,
|
||||
callback: IMogoTTSCallback?
|
||||
) {
|
||||
}
|
||||
|
||||
override fun unregisterUnWakeupCommand(cmd: String?) {
|
||||
}
|
||||
|
||||
override fun unregisterUnWakeupCommand(cmd: String?, callback: IMogoTTSCallback?) {
|
||||
}
|
||||
|
||||
override fun startAIAssist(context: Context?) {
|
||||
}
|
||||
|
||||
override fun startAIAssist(context: Context?, status: Int) {
|
||||
}
|
||||
|
||||
override fun breakOffSpeak() {
|
||||
}
|
||||
|
||||
// 降序插入Tts(目前Level0、1可排队)
|
||||
private fun insertTts(ttsEntity: MultiLangTtsEntity, level: Int) {
|
||||
var index = -1
|
||||
for (i in linkedList.indices.reversed()) {
|
||||
val nodeLevel = linkedList[i].second
|
||||
// 只有高优先级才插入到前面,等于的情况下是插到后面
|
||||
if (level > nodeLevel) {
|
||||
index = i
|
||||
}
|
||||
}
|
||||
if (index >= 0) {
|
||||
linkedList.add(index, Pair(ttsEntity, level))
|
||||
} else {
|
||||
linkedList.addLast(Pair(ttsEntity, level))
|
||||
}
|
||||
for (ttsPair in linkedList) {
|
||||
d(TAG, "tts文本为:" + ttsPair.first + ",level为:" + ttsPair.second)
|
||||
}
|
||||
d(TAG, "===================")
|
||||
}
|
||||
|
||||
private fun speakMultiLangTTSWithLevel(ttsEntity: MultiLangTtsEntity, ttsLevel: Int) {
|
||||
ttsEngine?.let {
|
||||
if (ttsLevel == curTtsLevel) {
|
||||
// 对应p3、p2级别的排队
|
||||
if (ttsLevel == 0 || ttsLevel == 1) {
|
||||
d(TAG, "===================")
|
||||
d(TAG, "插入消息:$ttsEntity,level为:$ttsLevel")
|
||||
insertTts(ttsEntity, ttsLevel)
|
||||
return
|
||||
} else {
|
||||
// 打断并合成新的
|
||||
stopTts()
|
||||
d(TAG, "非Level1同级别打断!")
|
||||
}
|
||||
} else {
|
||||
// 将要TTS的比现在正在TTS的优先级高
|
||||
if (ttsLevel > curTtsLevel) {
|
||||
if (curTtsLevel >= 0) {
|
||||
// 打断并合成高优先级的
|
||||
stopTts()
|
||||
}
|
||||
d(TAG, "高优先级打断低级别的!")
|
||||
} else {
|
||||
if (ttsLevel == 0 || ttsLevel == 1) {
|
||||
d(TAG, "===================")
|
||||
d(TAG, "插入消息:$ttsEntity,level为:$ttsLevel")
|
||||
insertTts(ttsEntity, ttsLevel)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
curTtsLevel = ttsLevel
|
||||
curTtsEntity = ttsEntity
|
||||
// 合成并播放
|
||||
d(TAG, "tts准备合成:$ttsEntity,curTtsLevel为:$curTtsLevel")
|
||||
startSpeak(ttsEntity.ttsNext())
|
||||
}
|
||||
}
|
||||
|
||||
private fun startSpeak(langTtsEntity: LangTtsEntity?) {
|
||||
langTtsEntity?.let {
|
||||
if (it.language != lastLang) {
|
||||
updateVoicer(it.language)
|
||||
updateTtsParam()
|
||||
lastLang = it.language
|
||||
}
|
||||
ttsEngine?.startSpeaking(it.ttsContent, ttsListener)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleCompleteEvent() {
|
||||
curTtsLevel = -1
|
||||
if (curTtsEntity != null) {// 多语言
|
||||
val langTtsEntity = curTtsEntity!!.ttsNext()
|
||||
if (langTtsEntity != null) {
|
||||
speakVoiceMap[curTtsEntity.toString()]?.onSpeakEnd(curTtsEntity.toString())
|
||||
ttsNextLanguage(langTtsEntity)
|
||||
} else {
|
||||
speakVoiceMap.remove(curTtsEntity.toString())?.onSpeakEnd(curTtsEntity.toString())
|
||||
curTtsEntity = null
|
||||
ttsNextMultiLangEntity()
|
||||
}
|
||||
} else {// 单语言
|
||||
speakVoiceMap.remove(curTtsContent)?.onSpeakEnd(curTtsContent)
|
||||
curTtsContent = ""
|
||||
ttsNextMultiLangEntity()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleErrorEvent(error: SpeechError) {
|
||||
curTtsLevel = -1
|
||||
if (curTtsEntity != null) {
|
||||
speakVoiceMap.remove(curTtsEntity.toString())
|
||||
?.onSpeakError(curTtsEntity.toString(), error.message)
|
||||
} else {
|
||||
speakVoiceMap.remove(curTtsContent)?.onSpeakError(curTtsContent, error.message)
|
||||
}
|
||||
curTtsEntity = null
|
||||
curTtsContent = ""
|
||||
}
|
||||
|
||||
private val ttsListener = object : SynthesizerListener {
|
||||
override fun onSpeakBegin() {
|
||||
|
||||
}
|
||||
|
||||
override fun onBufferProgress(p0: Int, p1: Int, p2: Int, p3: String?) {
|
||||
}
|
||||
|
||||
override fun onSpeakPaused() {
|
||||
}
|
||||
|
||||
override fun onSpeakResumed() {
|
||||
}
|
||||
|
||||
override fun onSpeakProgress(p0: Int, p1: Int, p2: Int) {
|
||||
}
|
||||
|
||||
override fun onEvent(p0: Int, p1: Int, p2: Int, p3: Bundle?) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* error - 错误信息,若为null,则没有出现错误。
|
||||
* 在音频播放完成,或会话出现错误时,将回调此函数。
|
||||
* 若应用主动调用SpeechSynthesizer.stopSpeaking()停止会话,则不会回调此函数。
|
||||
*/
|
||||
override fun onCompleted(error: SpeechError?) {
|
||||
if (Thread.currentThread() == Looper.getMainLooper().thread) {
|
||||
if (error == null) {// 播放完成
|
||||
handleCompleteEvent()
|
||||
} else {// 播放出错
|
||||
handleErrorEvent(error)
|
||||
}
|
||||
} else {
|
||||
UiThreadHandler.post {
|
||||
if (error == null) {
|
||||
handleCompleteEvent()
|
||||
} else {
|
||||
handleErrorEvent(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 语音合成下一个MultiLangTtsEntity
|
||||
*/
|
||||
private fun ttsNextMultiLangEntity() {
|
||||
if (!linkedList.isEmpty()) {
|
||||
val ttsPair = linkedList.removeFirst()
|
||||
i(TAG, "排队播放的下一条文本为:" + ttsPair.first + ",级别为:" + ttsPair.second)
|
||||
curTtsLevel = ttsPair.second
|
||||
startSpeak(ttsPair.first.ttsNext())
|
||||
} else {
|
||||
i(TAG, "队列为空")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 语音合成下一个MultiLangTtsEntity中的语言
|
||||
*/
|
||||
private fun ttsNextLanguage(langTtsEntity: LangTtsEntity) {
|
||||
startSpeak(langTtsEntity)
|
||||
}
|
||||
|
||||
private fun updateVoicer(language: LanguageType) {
|
||||
voicerEntries?.let {
|
||||
voicer = when (language) {
|
||||
LanguageType.ENGLISH -> it[5]
|
||||
LanguageType.KOREAN -> it[6]
|
||||
else -> it[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTtsParam() {
|
||||
// 清空参数
|
||||
ttsEngine?.setParameter(SpeechConstant.PARAMS, null)
|
||||
// 根据合成引擎设置相应参数
|
||||
if (engineType == SpeechConstant.TYPE_CLOUD) {
|
||||
ttsEngine?.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD)
|
||||
// 支持实时音频返回,仅在 synthesizeToUri 条件下支持
|
||||
ttsEngine?.setParameter(SpeechConstant.TTS_DATA_NOTIFY, "1")
|
||||
// ttsEngine?.setParameter(SpeechConstant.TTS_BUFFER_TIME,"1");
|
||||
// 设置在线合成发音人
|
||||
ttsEngine?.setParameter(SpeechConstant.VOICE_NAME, voicer)
|
||||
//设置合成语速
|
||||
ttsEngine?.setParameter(
|
||||
SpeechConstant.SPEED, "50"
|
||||
)
|
||||
//设置合成音调
|
||||
ttsEngine?.setParameter(
|
||||
SpeechConstant.PITCH, "50"
|
||||
)
|
||||
//设置合成音量
|
||||
ttsEngine?.setParameter(
|
||||
SpeechConstant.VOLUME, "50"
|
||||
)
|
||||
} else {
|
||||
ttsEngine?.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL)
|
||||
ttsEngine?.setParameter(SpeechConstant.VOICE_NAME, "")
|
||||
}
|
||||
|
||||
//设置播放器音频流类型
|
||||
ttsEngine?.setParameter(
|
||||
SpeechConstant.STREAM_TYPE, "3"
|
||||
)
|
||||
// 设置播放合成音频打断音乐播放,默认为true
|
||||
ttsEngine?.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "false")
|
||||
|
||||
// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
|
||||
ttsEngine?.setParameter(SpeechConstant.AUDIO_FORMAT, "pcm")
|
||||
ttsEngine?.setParameter(
|
||||
SpeechConstant.TTS_AUDIO_PATH,
|
||||
context?.getExternalFilesDir("msc")?.absolutePath + "/tts.pcm"
|
||||
)
|
||||
}
|
||||
}
|
||||
BIN
tts/tts-iflytek/src/main/jniLibs/arm64-v8a/libmsc.so
Normal file
BIN
tts/tts-iflytek/src/main/jniLibs/arm64-v8a/libmsc.so
Normal file
Binary file not shown.
17
tts/tts-iflytek/src/main/res/values/strings.xml
Normal file
17
tts/tts-iflytek/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="voicer_cloud_values">
|
||||
<!-- 汉语发音人 -->
|
||||
<item>xiaoyan</item>
|
||||
<item>aisjiuxu</item>
|
||||
<item>aisxping</item>
|
||||
<item>aisjinger</item>
|
||||
<item>aisbabyxu</item>
|
||||
|
||||
<!-- 英语发音人 -->
|
||||
<item>x2_enus_catherine</item>
|
||||
|
||||
<!-- 韩语发音人 -->
|
||||
<item>zhimin</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -29,6 +29,7 @@ import com.mogo.eagle.core.utilcode.util.ThreadUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.tts.base.IMogoTTS;
|
||||
import com.mogo.tts.base.IMogoTTSCallback;
|
||||
import com.mogo.tts.base.MultiLangTtsEntity;
|
||||
import com.mogo.tts.base.PreemptType;
|
||||
import com.zhidao.auto.platform.voice.VoiceClient;
|
||||
import com.zhidao.voicesdk.MogoVoiceManager;
|
||||
@@ -505,6 +506,11 @@ public class PadTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsList
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void speakMultiLangTTSWithLevel(MultiLangTtsEntity ttsEntity, int level, IMogoTTSCallback callback) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 问答类型语音注册:默认确认和取消
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user