在Android上使用TTS:大声朗读标点符号

时间:2011-12-20 09:09:47

标签: android text-to-speech

背景:我的应用程序正在向用户拥有的任何TTS引擎发送句子。句子是用户生成的,可能包含标点符号。

问题: Some users report that在SVOX,Loquendo和其他人可能会大声朗读标点符号(TTS说“逗号”等)。

问题:

  1. 我应该删除所有标点符号吗?
  2. 我应该使用this kind of API
  3. 转换标点符号
  4. 我应该让TTS引擎处理标点符号吗?
  5. 看到Loquendo问题的同一用户,对于另一个名为FBReader的Android应用程序没有此问题。所以我猜第3个选项不是正确的选择。

2 个答案:

答案 0 :(得分:2)

我的某个应用程序遇到了同样的问题。

输入字符串是:

Next alarm in 10 minutes,it will be 2:45 pm

并且TTS引擎会说:

Next alarm in 10 minutes comma it will be 2:45 pm

只需在逗号之后添加一个空格即可解决问题:

Next alarm in 10 minutes, it will be 2:45 pm

这是一个愚蠢的错误,也许你的问题比这更复杂,但它对我有用。 :)

答案 1 :(得分:2)

因此,您担心用户可能会选择哪种后巷获取的文本语音转换引擎作为默认引擎...大概是因为您不希望应用程序因此而显得糟糕引擎的未知/不良行为。可以理解。

(好的)事实是,除非您决定将引擎嵌入应用本身,否则TTS的行为实际上不是您的责任(难度:难,推荐?否)。

可以并且应该假定引擎遵守here指示的Android规则和行为,并假定可以在Android系统设置(首页\设置\语言和语言环境\ TTS)中提供其自身足够的配置选项集其中可能包含或不包含发音选项。还应该假定用户足够智能,以安装他们满意的发动机。

承担未知和不受欢迎的发动机行为(至少在未经测试的发动机中)的预期和“纠正”工作是一个滑坡。

简单而良好的选择(难度:容易):

  • 在应用中进行设置:“忽略标点符号”。

更好的选择(难度:中):

  • 执行上述操作,但是仅当您在用户设备上检测到的引擎容易出现此问题时,才显示“忽略标点”设置选项。

还有一点要注意的是,引擎之间存在很多很多差异(无论引擎使用嵌入式语音还是在线语音,响应时间,初始化时间,对Android规范的可靠性/坚持性,跨Android API级别的行为,跨引擎的行为)自己的版本历史记录,语音质量,更不用说语言能力了……对于用户而言,差异可能比标点符号是否发音更为重要。

您说“我的应用程序正在向用户拥有的任何TTS引擎发送语句。”好吧……“那是你的问题。”为什么不让用户选择要使用哪种引擎?

并带我们去...

甚至更好的选择(难度:好难![以我的拙见]):

  • 从Google和Samsung开始,确定您的应用将“支持”一些“知名”引擎。我猜想这些天来只有不到5%的设备没有任何引擎。
  • 研究并测试您计划支持的所有Android API级别上的这些引擎,至少要在它们是否标点符号方面进行研究。
  • 随着时间的流逝,如果需要,请测试更多引擎,然后在后续应用更新中将它们添加到支持的引擎中。
  • 在应用启动时运行一种算法,以检测安装了哪些引擎,然后将该信息用于您自己的支持引擎列表:

private ArrayList<String> whatEnginesAreInstalled(Context context) {
    final Intent ttsIntent = new Intent();
    ttsIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
    final PackageManager pm = context.getPackageManager();
    final List<ResolveInfo> list = pm.queryIntentActivities(ttsIntent, PackageManager.GET_META_DATA);
    ArrayList<String> installedEngineNames = new ArrayList<>();
    for (ResolveInfo r : list) {
        String engineName = r.activityInfo.applicationInfo.packageName;
        installedEngineNames.add(engineName);

        // just logging the version number out of interest
        String version = "null";
        try {
            version = pm.getPackageInfo(engineName,
            PackageManager.GET_META_DATA).versionName;
            } catch (Exception e) {
                Log.i("XXX", "try catch error");
            }
        Log.i("XXX", "we found an engine: " + engineName);
        Log.i("XXX", "version: " + version);
    }
    return installedEngineNames;
}

  • 在应用程序的设置中,将您决定支持的所有引擎作为选项显示(即使当前未安装)。这可能是一组简单的RadioButton,其标题对应于不同的引擎名称。如果用户选择了一个未安装的软件,请通知他们,并让他们选择安装它的意图。
  • 在应用程序中需要TTS时,将用户选择的引擎名称(字符串)保存在SharedPreferences中,并将其选择用作TextToSpeech构造函数的最后一个参数。
  • 如果用户安装了一些奇怪的引擎,即使无法识别/不受支持,也请选择该引擎,但要告知他们他们选择了未知/未试用的引擎。
  • 如果用户选择了受支持但已知发音为标点符号(坏)的引擎,则在选择该引擎时,将弹出一个警告对话框,警告用户有关此问题,并说明他们可以关闭此不良行为并已提及“忽略标点”设置。

侧注:

  • 不要让SVOX / PICO(仿真器)引擎让您太担心-它有很多缺陷,甚至没有设计或保证不能在API〜20以上的Android上运行,但仍然包含在仿真器中图像的分辨率最高可达API〜24,导致“无法预测的结果”实际上无法反映现实。我还没有在过去七年左右的时间里在任何实际的硬件设备上看到这种引擎。

  • 由于您说的是“句子是用户生成的”,因此我将更担心解决输入句子将使用哪种语言的问题!我会提一个问题! :)