【问题标题】:Get available locales for text to speech (TTS)获取文本到语音 (TTS) 的可用区域设置
【发布时间】:2011-06-19 20:26:28
【问题描述】:

我正在开发一个抽认卡程序的文本到语音转换。应读出不同语言的文本。为了正确执行此操作,用户必须选择要阅读的文本语言(将被存储并在以后毫无疑问地使用)。

是否有可能在 Android 系统上获取可用的 TTS 语言?如果没有,是否有可能获取系统上所有可用的语言环境?


我猜,我明白了:getAvailableLocales()tts.isLocaleAvailable(locale)

【问题讨论】:

    标签: android locale text-to-speech


    【解决方案1】:

    其他人已经完成了艰苦的工作,http://kaviddiss.com/2012/08/12/android-text-to-speech-languages/

    为了节省您的时间,这是他们的代码摘录

    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
    

    结果取决于选择的 TTS 引擎。例如,我的一部手机同时包含 Pico-TTS 和 Google-text-to-speech 引擎。

    Q-Smart(以 Google TTS 作为选定引擎的越南手机)

    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
    

    并且选择了 Pico

    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
    

    注意: 葡萄牙语未在 TTS 设置 UI 中列出。当我在我的应用程序中以编程方式选择葡萄牙语时,它会说葡萄牙口音! FWIW 这是我选择葡萄牙语的代码(它同时接受巴西和葡萄牙语区域​​设置)。

    if (locale.getDisplayName().startsWith("Portuguese")) {
        Log.i(SPEAK_REPEATEDLY, "Setting Locale to: " + locale.toString());
        tts.setLanguage(locale);
        }
    }
    

    【讨论】:

    • 注意:这不适用于所有设备和所有 TTS 引擎,因为它与 LANG_COUNTRY_VAR_AVAILABLE 不匹配。你应该使用res &gt;= TextToSpeech.LANG_COUNTRY_AVAILABLE
    【解决方案2】:

    由于不同的 TTS 引擎为 isLanguageAvailable 返回不同的结果,我发现以下解决方案在几种常见的 TTS 引擎上效果最好。

    还请注意,从 Android Lollipop 开始,TextToSpeech 中有一个名为 getAvailableLanguages 的简单方法可以轻松完成(如果设备运行 API 21 或更高版本)。

    您需要在分配给TextToSpeech对象的OnInitListeneronInit方法中调用以下方法。

    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());
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      使用以下函数查找设备上所有可用的 TTS 语言环境。

      Locale.getAvailableLocales()
      

      输出: 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]
      

      【讨论】:

      • 根据文档developer.android.com/reference/java/util/… getAvailableLocales() 是静态的,因此无需创建 Locale 对象。使用“Locale.getAvailableLocales()”是使用此方法的适当方式。
      • tts 是否支持所有可用的语言环境?
      • @Abhinav 当然不是。为什么 OP 接受这个作为答案超出了我的理解。
      • 知道如何强制男声而不是女声吗?使用 URL 参数?
      • getAvailableLocales() 在 Lollipop 之前无法使用。试试isLanguageAvailable()
      【解决方案4】:

      从 Android 5.0(API 级别 21)开始,已添加 TextToSpeech.getAvailableLanguages 以获取 TTS 引擎支持的一组所有语言环境。

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

      我还注意到TextToSpeech.getAvailableLanguages 返回的语言环境集可能不是Locale.getAvailableLocales 的严格子集,即可能存在系统不支持的 TTS 引擎支持的语言环境。

      【讨论】:

      • 如果 tts 引擎支持区域设置但系统不支持它怎么办。 tt.setLanguage() 会工作吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-02
      • 2017-11-20
      • 1970-01-01
      • 2014-01-18
      相关资源
      最近更新 更多