开发者社区 问答 正文

在语音进行过程中突出显示文本

我正在开发一个我的textview由String和两个按钮组成的应用程序。当我单击“语音”按钮时,文本将转换为语音。但是我想在演讲进行时突出显示这个词。

请检查以下链接上的“我的应用”屏幕截图。[1]:https://i.stack.imgur.com/ODB4v.jpg ...

textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {

        @Override
        public void onInit(int status) {

            if (status == TextToSpeech.SUCCESS) {
                result = textToSpeech.setLanguage(Locale.ENGLISH);
                textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                    @Override
                    public void onStart(String utteranceId) {
                        Log.d(utteranceId, "TTS start");}

                    @Override
                    public void onDone(String utteranceId) {
                        Log.d(utteranceId, "TTS done");}

                    @Override
                    public void onError(String utteranceId) {
             });
            } else {
                Toast.makeText(getApplicationContext(), "Feature is not Available", Toast.LENGTH_SHORT).show();
            }
        }
    });

这是我的文本到语音的初始化。

private void speak() {
 if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
        Toast.makeText(getApplicationContext(), "Feature is not Available", Toast.LENGTH_SHORT).show();
    } else {
        textToSpeech.setPitch(1f);
        textToSpeech.setSpeechRate(0.8f);
        HashMap<String, String> params = new HashMap<>();
        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "utteranceId");
        textToSpeech.speak(getString(R.string.storytxt), TextToSpeech.QUEUE_FLUSH, params);

    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (textToSpeech != null) {
        textToSpeech.shutdown();
    }
}

直到这里我都没问题。现在,我要突出显示文本。我不知道该怎么做。我到处搜寻,仍然没有任何线索。

我将字符串存储在String.xml中。

展开
收起
垚tutu 2019-12-26 21:20:28 1199 分享 版权
阿里云 AI 助理回答

要在文本转语音(TTS)进行时突出显示相应的单词,您需要在UtteranceProgressListener中利用onStartonDone方法来控制TextView中的文字高亮。以下是一个简化的示例,说明如何实现这一功能:

首先,确保您的TextView支持spannable文本,这样您可以对其中的特定部分应用样式。

  1. 初始化TextView:

    TextView myTextView = findViewById(R.id.my_text_view);
    SpannableStringBuilder spannableText = new SpannableStringBuilder(getString(R.string.storytxt));
    myTextView.setText(spannableText);
    
  2. 定义一个方法来高亮单词:

    private void highlightWord(String word, int start, int end) {
       ForegroundColorSpan highlightColorSpan = new ForegroundColorSpan(Color.YELLOW); // 或者您选择的高亮颜色
       spannableText.setSpan(highlightColorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
       myTextView.setText(spannableText);
       myTextView.postInvalidate(); // 确保UI更新
    }
    
  3. 修改TTS监听器以同步高亮显示: 为了简化问题,我们假设您能获取到当前要发音的单词及其在字符串中的起始位置。这可能需要您根据TTS引擎的具体实现来调整逻辑,因为标准的TTS API并不直接提供这样的信息。这里仅提供一个概念性的示例:

    textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
       @Override
       public void onStart(String utteranceId) {
           // 假设word是当前要读的单词,start和end是它在文本中的位置
           highlightWord(word, start, end);
           Log.d(utteranceId, "TTS start");
       }
    
       @Override
       public void onDone(String utteranceId) {
           // 在单词读完后移除高亮
           clearHighlight(start, end);
           Log.d(utteranceId, "TTS done");
       }
    
       @Override
       public void onError(String utteranceId) {
           // 错误处理
       }
    
       private void clearHighlight(int start, int end) {
           spannableText.removeSpan(null); // 移除所有span,包括高亮
           myTextView.setText(spannableText);
           myTextView.postInvalidate();
       }
    });
    

请注意,上述代码中的highlightWordclearHighlight方法需要您确切知道每个单词何时开始和结束发音,这在实际应用中可能比较复杂,因为TTS引擎通常不会直接提供这些信息。一种可能的解决方案是将文本分割成单词,并为每个单词设置单独的utterance ID,然后在onStartonDone中使用这个ID来确定哪个单词正在或已经读取。但这种方法可能会增加实现的复杂度,并且依赖于TTS引擎是否能够准确地报告每个utterance的进度。

由于具体实现细节会根据您的需求和所使用的TTS引擎有所不同,您可能需要进一步研究和调试来达到理想的效果。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: