设置现有语音后,文本到语音将返回不同的不存在的语言环境

时间:2014-01-31 13:53:39

标签: android text-to-speech

原始问题

我有一个标准的texttospeech,android.speech.tts.TextToSpeech

我使用tts.setLanguage(Locale.getDefault())

对其进行初始化并设置语言

默认的Locale是de_DE(对于德国,正确)。 在设置之后,我要求tts给我它的语言tts.getLanguage()

现在它告诉我它设置为" deu_DEU"

没有具有该设置的区域设置。所以我甚至无法检查它是否设置为正确的语言,因为我找不到具有匹配值的Locale对象。

问题可能与Android 4.3有关,但我没有找到任何信息。

背景是,我需要显示具有相同小数符号的值,但是tts需要正确的符号,或者它表示" dot"在德语中根本没有意义。

结论:

Locale是一个容器,其中包含由语言,国家/地区和可选字符串组成的字符串。每个文字转语音引擎都可以返回自定义区域设置,例如" eng_USA_texas"。

此外,tts引擎返回的Locale只能是" close匹配"到想要的Locale。所以" en_US"而不是" en_UK"。

但是,Locale有一个名为getLanguage()的方法,它返回上面提到的字符串的第一部分。 "恩"或" eng"。这些语言代码由ISO管理,人们可以希望每个人都坚持使用它。 (参见接受答案中的链接)

因此,如果满足某种形式的英语语言设置和ISO标准,则应始终检查tts.getLanguage().getLanguage().startsWith("en")

重要的是要提及不应该通过locale_a == locale_b比较区域设置,因为它们可以是不同的对象但具有相同的内容,它们是排序的容器。
始终与locale_a.equals(locale_b)

进行比较

我希望这可以帮助人们解决tts和语言的一些问题

2 个答案:

答案 0 :(得分:2)

你是对的,令人沮丧的是TTS对象使用的语言环境代码与设备语言环境的代码不同。我不明白为什么做出这个决定。

要添加更复杂的内容,请使用TTS引擎can supply all kinds of different locales,例如eng_US_sarah或en-US-female等。这是TTS引擎的存储和显示方式。

我必须编写额外的代码来迭代返回的语言环境,并尝试将它们与系统可以使用的语言环境相匹配,反之亦然。

首先,请查看您安装的引擎are returning their locale information的方式。然后,您可以开始在代码中整理一个列表,将“deu_DEU”与“de_De”相关联。

使用split("_")& startsWith(String),但遗憾的是并非适用于所有区域设置。

这是我用来分析已安装的TTS引擎的语言环境结构的一些基本代码。

private void getEngines() {

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

    final PackageManager pm = getActivity().getPackageManager();

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

    final ArrayList<Intent> intentArray = new ArrayList<Intent>(list.size());

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

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

        getIntent.setPackage(list.get(i).activityInfo.applicationInfo.packageName);
        getIntent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);

        intentArray.add(getIntent);

    }

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

@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {

    try {

        if (data != null) {             
            System.out.print(data.getStringArrayListExtra("availableVoices").toString());
        }

    } catch (NullPointerException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

从上面的ISO-3 codesdevice locale format,您应该可以为您所关注的区域设置提供一些内容。

我一直打算向AOSP提交增强请求一段时间,因为所有TTS引擎都需要使用常量值,并且需要添加性别等extras才能使用TTS引擎能力。

编辑:关于setLanguage()的修改note the wording。单个TTS引擎将尝试匹配尽可能接近请求的区域设置,但是应用的区域设置可能完全错误,具体取决于引擎提供程序in their code and their response的宽松程度。

答案 1 :(得分:0)

创建 TextToSpeech 类的对象后,您应该将其配置(或检查其可用状态/值)到 TextToSpeech.OnInitListeneronInit() 回调中。您将在那里获得有关 TextToSpeech 对象的可靠信息。

在这里查看我的回答: https://stackoverflow.com/a/65620221/7835969