Get available locales for text to speech (TTS)

前端 未结 4 1828
臣服心动
臣服心动 2020-12-04 17:02

I\'m working on a text-to-speech implementation of a flashcard program. Text in different languages should be read out. In order to do this properly the user has to select t

相关标签:
4条回答
  • 2020-12-04 17:36

    Find all available TTS Locale on the device using following function.

    Locale.getAvailableLocales()
    

    Output of: Arrays.toString(Locale.getAvailableLocales())

    [ar, ar_EG, bg, bg_BG, ca, ca_ES, cs, cs_CZ, da, da_DK, de, de_AT, de_BE, de_CH, de_DE, de_LI, de_LU, el, el_CY, el_GR, en, en
    _AU, en_BE, en_BW, en_BZ, en_CA, en_GB, en_HK, en_IE, en_IN, en_JM, en_MH, en_MT, en_NA, en_NZ, en_PH, en_PK, en_RH, en_SG, en_TT, en_US, en_US_POSIX,
     en_VI, en_ZA, en_ZW, es, es_AR, es_BO, es_CL, es_CO, es_CR, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI, es_PA, es_PE, es_PR, es_PY, es_SV, es_US
    , es_UY, es_VE, et, et_EE, eu, eu_ES, fa, fa_IR, fi, fi_FI, fr, fr_BE, fr_CA, fr_CH, fr_FR, fr_LU, fr_MC, gl, gl_ES, hr, hr_HR, hu, hu_HU, in, in_ID,
    is, is_IS, it, it_CH, it_IT, iw, iw_IL, ja, ja_JP, kk, kk_KZ, ko, ko_KR, lt, lt_LT, lv, lv_LV, mk, mk_MK, ms, ms_BN, ms_MY, nl, nl_BE, nl_NL, no, no_N
    O, no_NO_NY, pl, pl_PL, pt, pt_BR, pt_PT, ro, ro_RO, ru, ru_RU, ru_UA, sh, sh_BA, sh_CS, sh_YU, sk, sk_SK, sl, sl_SI, sq, sq_AL, sr, sr_BA, sr_ME, sr_
    RS, sv, sv_FI, sv_SE, th, th_TH, tr, tr_TR, uk, uk_UA, vi, vi_VN, zh, zh_CN, zh_HK, zh_HANS_SG, zh_HANT_MO, zh_MO, zh_TW]
    
    0 讨论(0)
  • 2020-12-04 17:36

    Someone else has done the hard work, at http://kaviddiss.com/2012/08/12/android-text-to-speech-languages/

    To save you time, here's their code extract

    TextToSpeech tts = ...
    // let's assume tts is already inited at this point:
    Locale[] locales = Locale.getAvailableLocales();
    List<Locale> localeList = new ArrayList<Locale>();
    for (Locale locale : locales) {
        int res = tts.isLanguageAvailable(locale);
        if (res == TextToSpeech.LANG_COUNTRY_AVAILABLE) {
            localeList.add(locale);
        }
    }
    // at this point the localeList object will contain
    // all available languages for Text to Speech
    

    The results depend on which TTS engine has been selected. For instance, one of my phones includes both the Pico-TTS and Google-text-to-speech engines.

    Q-Smart (Vietnamese Phone with Google TTS as selected engine)

    D/SpeakRepeatedly( 3979): Engine Google Text-to-speech Engine:com.google.android.tts
    D/SpeakRepeatedly( 3979): Engine Pico TTS:com.svox.pico
    D/SpeakRepeatedly( 3979): German (Germany):German:de_DE
    D/SpeakRepeatedly( 3979): English (United Kingdom):English:en_GB
    D/SpeakRepeatedly( 3979): English (United States):English:en_US
    D/SpeakRepeatedly( 3979): English (United States,Computer):English:en_US_POSIX
    D/SpeakRepeatedly( 3979): Spanish (Spain):Spanish:es_ES
    D/SpeakRepeatedly( 3979): French (France):French:fr_FR
    D/SpeakRepeatedly( 3979): Italian (Italy):Italian:it_IT
    D/SpeakRepeatedly( 3979): Portuguese (Brazil):Portuguese:pt_BR
    D/SpeakRepeatedly( 3979): Portuguese (Portugal):Portuguese:pt_PT
    

    And with Pico selected

    D/SpeakRepeatedly( 4837): Engine Google Text-to-speech Engine:com.google.android.tts
    D/SpeakRepeatedly( 4837): Engine Pico TTS:com.svox.pico
    D/SpeakRepeatedly( 4837): German (Germany):German:de_DE
    D/SpeakRepeatedly( 4837): English (United Kingdom):English:en_GB
    D/SpeakRepeatedly( 4837): English (United States):English:en_US
    D/SpeakRepeatedly( 4837): English (United States,Computer):English:en_US_POSIX
    D/SpeakRepeatedly( 4837): Spanish (Spain):Spanish:es_ES
    D/SpeakRepeatedly( 4837): French (France):French:fr_FR
    D/SpeakRepeatedly( 4837): Italian (Italy):Italian:it_IT
    

    Note: Portuguese isn’t listed in the TTS Settings UI. When I select Portuguese programmatically in my app it speaks with a Portuguese accent! FWIW here's my code to select Portuguese (it accepts both Brazilian and Portuguese locales).

    if (locale.getDisplayName().startsWith("Portuguese")) {
        Log.i(SPEAK_REPEATEDLY, "Setting Locale to: " + locale.toString());
        tts.setLanguage(locale);
        }
    }
    
    0 讨论(0)
  • 2020-12-04 17:41

    Starting from Android 5.0 (API level 21), TextToSpeech.getAvailableLanguages has been added to fetch a set of all locales supported by the TTS engine.

    TextToSpeech tts;              // assume this is initialized
    tts.getAvailableLanguages();   // returns a set of available locales
    

    I have also noticed that the set of locales returned by TextToSpeech.getAvailableLanguages might not be a strict subset of Locale.getAvailableLocales, i.e. there might a locale supported by the TTS engine that isn't supported by the system.

    0 讨论(0)
  • 2020-12-04 17:52

    Since different TTS engines return different results for isLanguageAvailable, I found that the following solution works best on several common TTS engines.

    Please also note that starting with Android Lollipop, there is a simple method in TextToSpeech called getAvailableLanguages that does that easily for you (if the device is running API 21 or later).

    You need to call the following methods in the onInit method of your OnInitListener assigned to the TextToSpeech object.

    ArrayList<Locale> languages;
    TextToSpeech initTTS;
    
    private void initSupportedLanguagesLollipop()
    {
        Set<Locale> availableLocales = initTTS.getAvailableLanguages();
        for (Locale locale : availableLocales)
        {
            languages.add(locale);
        }
    }
    
    private void initSupportedLanguagesLegacy()
    {
        Locale[] allLocales = Locale.getAvailableLocales();
        for (Locale locale : allLocales)
        {
            try
            {
                int res = initTTS.isLanguageAvailable(locale);
                boolean hasVariant = (null != locale.getVariant() && locale.getVariant().length() > 0);
                boolean hasCountry = (null != locale.getCountry() && locale.getCountry().length() > 0);
    
                boolean isLocaleSupported = 
                        false == hasVariant && false == hasCountry && res == TextToSpeech.LANG_AVAILABLE ||
                        false == hasVariant && true == hasCountry && res == TextToSpeech.LANG_COUNTRY_AVAILABLE ||
                        res == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE;
    
                Log.d(TAG, "TextToSpeech Engine isLanguageAvailable " + locale  + " (supported=" + isLocaleSupported + ",res=" + res + ", country=" + locale.getCountry() + ", variant=" + locale.getVariant() + ")");
    
                if (true == isLocaleSupported)
                {
                    languages.add(locale);
                }
            }
            catch (Exception ex)
            {
                Log.e(TAG, "Error checking if language is available for TTS (locale=" + locale +"): " + ex.getClass().getSimpleName() + "-" + ex.getMessage());
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题