2

我正在尝试做一个应用程序,它可以在谷歌默认的英国男声(en-gb-x-rjs-phone-hmm)和女声(en-gb-x-fis-phone-hmm)之间切换。我正在使用两个 Text-To-Speech 对象,在为每个对象初始化引擎后,我使用 setVoice(voice) 为每个对象分配相应的语音。

 mTTS1 = new TextToSpeech(this, onInitListener, packname);
 mTTS2 = new TextToSpeech(this, onInitListener, packname);

在 onInit() 方法中,当两者都被初始化时:

 mTTS1.setVoice(voice1);
 mTTS2.setVoice(voice2);

'voice1' 和 'voice2' 是通过调用 getVoices() 获得的,当我获得语音名称时,我会获得 'en-gb-x-rjs-phone-hmm' 和 'en-gb-x-fis-phone-嗯'分别,所以这让我觉得声音被正确存储了。

当我显示两个按钮让他们说话时,两种情况下都是女声说话。我认为这是默认语音的事实。将女性声音作为默认声音会发生这种情况。当我将男性声音设置为默认声音时,情况正好相反。

我应该知道我错过了什么......?

谢谢你们,

4

1 回答 1

1

比赛迟到了四年半,但我自己就是这么打的。事实证明,仅仅因为语音出现在 getVoices() 中,没有使用 isNetworkConnectionRequired 标记,并且 TTS isLanguageAvailable() 方法不包括 LANG_MISSING_DATA 或 LANG_NOT_SUPPORTED,并不意味着它已准备好使用。如果您尝试设置尚未准备好的声音,TTS 引擎就会退回到默认值。

我要做的是检查所有这些,但还要确保该声音没有任何缺失的功能(在 Kotlin 中,其中 tts 是我成功初始化后的 TextToSpeech 对象):

var availableVoices = tts.voices
var availableLocales:List<Locale> = Locale.getAvailableLocales().toList()
for (v:Voice in availableVoices){
    if (v.locale.language == Locale.getDefault().language &&
        availableLocales.contains(v.locale) &&
        !v.isNetworkConnectionRequired &&
        tts.isLanguageAvailable(v.locale)!=TextToSpeech.LANG_MISSING_DATA &&
        tts.isLanguageAvailable(v.locale)!=TextToSpeech.LANG_NOT_SUPPORTED &&
        !(v.features.contains(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED))
    ){
        // voice is ready to use
    }
}

只要您确实有网络连接,也许您可​​以摆脱使用非本地语音,但我不觉得尝试指定一个后备是值得的,所以我只是从我的可用列表中删除了它们。

于 2020-01-28T02:29:47.937 回答