gpt4 book ai didi

android - 如何在不实例化每个语言并等待初始化的情况下轮询可用的 TTS 引擎以获取可用语言

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:04:32 24 4
gpt4 key购买 nike

我需要实例化一个 TextToSpeech 对象并设置给定的语言(以编程方式设置并且可能会有所不同)。我知道我可以使用 setLanguage() 但只有当语言在特定 TextToSpeech 实例正在使用的 TTS 引擎中可用时才有效。我知道我可以通过 myTTS.isLanguageAvailable() 检查一种语言是否可用,但这只会告诉我该语言在当前引擎上是否可用。

问题是用户可能安装了多个 TTS 引擎,其中一个可能提供了所需的语言,但默认的没有。在那种情况下,我想找到引擎,使用它并设置语言。

所以我需要遍历可用的 TTS 引擎并“询问”每个引擎是否有所需的可用语言。

我试过这个:

mUserLocale=new Locale("it-IT"); //just an example

mTextToSpeech=new TextToSpeech(getApplicationContext(), this);
if (mTextToSpeech.isLanguageAvailable(mUserLocale)<0) {

List<TextToSpeech.EngineInfo> engines=mTextToSpeech.getEngines();
int currentmatchquality=-1;
String defaultTTSEngine=mTextToSpeech.getDefaultEngine();
mTextToSpeech.shutdown();
mTextToSpeech=null;
for (int i=0; i<engines.size(); i++) {
TextToSpeech.EngineInfo engineinfo=engines.get(i);
Log.d("MainActivity", "Examining TTS engine "+engineinfo.name);
if (engineinfo.name.equals(defaultTTSEngine)) {
Log.d("MainActivity", "Skipping default TTS engine "+engineinfo.name);
continue;
}
TextToSpeech candidateTTS=new TextToSpeech(getApplicationContext(),this,engineinfo.name);
int matchquality=candidateTTS.isLanguageAvailable(mUserLocale);
if (matchquality>currentmatchquality) {
Log.d("MainActivity", "Selecting TTS engine "+engineinfo.name);
mTextToSpeech.shutdown();
mTextToSpeech=candidateTTS;
mTTSEngine=engineinfo.name;
currentmatchquality=matchquality;

}
else {
Log.d("MainActivity", " "+mUserLocale.toString()+" not available on this engine: "+matchquality);
}
}
if (mTTSEngine==null) mTTSEngine=defaultTTSEngine;
mTextToSpeech=new TextToSpeech(getApplicationContext(),this,mTTSEngine);
}

if (mTextToSpeech.isLanguageAvailable(mUserLocale)>=0) mTextToSpeech.setLanguage(mUserLocale);

问题是我系统地从 isLanguageAvailable 得到 -2:

D/MainActivity﹕ Examining TTS engine com.google.android.tts
I/TextToSpeech﹕ Sucessfully bound to com.google.android.tts
W/TextToSpeech﹕ isLanguageAvailable failed: not bound to TTS engine
D/MainActivity﹕ it-it not available on this engine: -2

我猜这是因为我需要等待 TTS 的初始化事件,然后才能查询可用语言。

那会很麻烦。有没有一种方法可以循环遍历现有的 TTS 引擎并检查它们中的每一个是否有一种语言可用(或获取每个引擎的所有可用语言的列表)而无需为每个引擎实例化 TextToSpeech 对象并等待它被初始化?

最佳答案

这是我用于调试的设置 - 您可以在生产中使用它的元素:

// Container Class

public class ContainerVoiceEngine {

private String label;
private String packageName;
private ArrayList<String> voices;
private Intent intent;

public ContainerVoiceEngine() {

}

public ContainerVoiceEngine(final String label, final String packageName, final ArrayList<String> voices, final Intent intent) {

this.label = label;
this.packageName = packageName;
this.voices = voices;
this.intent = intent;
}

public Intent getIntent() {
return intent;
}

public void setIntent(final Intent intent) {
this.intent = intent;
}

public String getLabel() {
return label;
}

public void setLabel(final String label) {
this.label = label;
}

public String getPackageName() {
return packageName;
}

public void setPackageName(final String packageName) {
this.packageName = packageName;
}

public ArrayList<String> getVoices() {
return voices;
}

public void setVoices(final ArrayList<String> voices) {
this.voices = voices;
}
}


// Usage within an Activity - Debugging only!

private ArrayList<ContainerVoiceEngine> containerVEArray;
private int requestCount;

private void getEngines() {

requestCount = 0;

final Intent ttsIntent = new Intent();
ttsIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);

final PackageManager pm = getPackageManager();

final List<ResolveInfo> list = pm.queryIntentActivities(ttsIntent, PackageManager.GET_META_DATA);

containerVEArray = new ArrayList<ContainerVoiceEngine>(list.size());

for (int i = 0; i < list.size(); i++) {

final ContainerVoiceEngine cve = new ContainerVoiceEngine();

cve.setLabel(list.get(i).loadLabel(pm).toString());
cve.setPackageName(list.get(i).activityInfo.applicationInfo.packageName);

final Intent getIntent = new Intent();
getIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);

getIntent.setPackage(cve.getPackageName());
getIntent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
getIntent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES);

cve.setIntent(getIntent);

containerVEArray.add(cve);
}

Log.d("TAG", "containerVEArray: " + containerVEArray.size());

for (int i = 0; i < containerVEArray.size(); i++) {
startActivityForResult(containerVEArray.get(i).getIntent(), i);
}

}

@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
Log.i("TAG", "onActivityResult: requestCount: " + " - requestCode: " + requestCode);

requestCount++;

try {

if (data != null) {

final Bundle bundle = data.getExtras();

if (bundle != null) {

Log.d("TAG", containerVEArray.get(requestCode).getLabel() + " - Bundle Data");

final Set<String> keys = bundle.keySet();
final Iterator<String> it = keys.iterator();

while (it.hasNext()) {
final String key = it.next();
Log.d("TAG", "Key: " + key + " = " + bundle.get(key));
}

}

if (data.hasExtra("availableVoices")) {
containerVEArray.get(requestCode).setVoices(data.getStringArrayListExtra("availableVoices"));
} else {
containerVEArray.get(requestCode).setVoices(new ArrayList<String>());
}
}

if (requestCount == containerVEArray.size()) {

for (int i = 0; i < containerVEArray.size(); i++) {

Log.v("TAG", "cve: " + containerVEArray.get(i).getLabel() + " - "
+ containerVEArray.get(i).getVoices().size() + " - " + containerVEArray.get(i).getVoices().toString());
}
}

} catch (final IndexOutOfBoundsException e) {
Log.e("TAG", "IndexOutOfBoundsException");
e.printStackTrace();
} catch (final NullPointerException e) {
Log.e("TAG", "NullPointerException");
e.printStackTrace();
} catch (final Exception e) {
Log.e("TAG", "Exception");
e.printStackTrace();
}
}

希望对您有所帮助。

编辑

根据您的评论,这些“声音”实际上是语言,从某种意义上说,它们在其结构中返回具有代表性的语言环境。但请注意,Locale 与 System Locale 的格式不同,这真的很烦人,需要在未来的 Android 更新中进行排序。

看看my answer here关于使用 tts.setLanguage(Locale) 的陷阱。该问题还涉及创建语言环境 - Locale loc = new Locale(String)。

您可以对可用语言的 ArrayList 使用循环,以尝试为每个引擎从每个语言构建一个 Locale。

希望对您有所帮助。

关于android - 如何在不实例化每个语言并等待初始化的情况下轮询可用的 TTS 引擎以获取可用语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25700155/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com