fade in and out music while speaking a text
Asked Answered
C

3

3

I have an Android application that makes use of TTS (Text to speech) API. Everything is working perfectly, but now i want to fade in/out or even stop music (in case user is playing music with prebuilt Music Player), when application speaks a text. Right now, i think both music and TTS messages are played on the same stream (MUSIC), and it can be difficult to understand the voice messages.

I've tried to play the text on a different stream, like AudioManager.STREAM_NOTIFICATIONS. It does stop the music, but doesn't come back when the text is spoken, so i didn't achieve the goal. Haven't found anything yet, so i hope someone can help here. Thanks!

Could answered 15/6, 2010 at 8:26 Comment(0)
C
5

I finally got something that is working. Not perfect though. A quite dirty trick. Just in case it can help to someone:

This is fixed on API 8 with requestAudioFocus and abandomAudioFocus methods of AudioManager.

But for former versions, you can try this. Play TTS through a different stream channel, let's say STREAM_NOTIFICATIONS. Then you just need to return audio focus to STREAM_MUSIC. How can you achieve that?. Sending a silence string (" ") to TTS but this time through STREAM_MUSIC. The effect will be: music is stopped, your TTS message gets spoken, and finally your music is back after the voice alert. Not nice or something to feel proud of, but... if someone knows of a different way, i will appreciate it

Could answered 30/6, 2010 at 21:23 Comment(2)
New in API 21 is playSilentUtterance developer.android.com/reference/android/speech/tts/…, int, java.lang.String)Synthesize
In my app, When playing music, TTS does not work! Can you help me?Homebody
P
2

Here is a way of doing this in Dec-2021

TexToSpeech needs to be initialized and assigned to tts before calling this method

Method 1 (Recommended):

private void speak(String textToSay) {
    AudioAttributes mPlaybackAttributes = new AudioAttributes.Builder()
          .setUsage(AudioAttributes.USAGE_ASSISTANT)
          .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
          //add this below flag if you need the TTS to speak in a louder volume or TTS volume be heard for sure at any cost
          //.setFlags(FLAG_AUDIBILITY_ENFORCED)
          .build();
    tts.setAudioAttributes(mPlaybackAttributes);
    AudioFocusRequest mFocusRequest =
          new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)
            .setAudioAttributes(mPlaybackAttributes)
            .setAcceptsDelayedFocusGain(false)
            .setWillPauseWhenDucked(false)
            .build();
    AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
    am.requestAudioFocus(mFocusRequest);
    tts.speak(textToSay, TextToSpeech.QUEUE_FLUSH, null, textToSay);
    Handler ttsSpeak = new Handler();
    Runnable checkTTSRunning = new Runnable() {
        @Override
        public void run() {
            if (tts.isSpeaking()) {
                ttsSpeak.postDelayed(this, 1000);
            } else am.abandonAudioFocusRequest(mFocusRequest);
        }
    };
    ttsSpeak.postDelayed(checkTTSRunning, 3000);
}

Method 2: Use this only if you need the TTS to speak in a louder volume and/or TTS volume needs to be heard for sure at any cost

private void speak(String textToSay) {
    AudioAttributes mPlaybackAttributes = new AudioAttributes.Builder()
          .setUsage(AudioAttributes.USAGE_ASSISTANT)
          .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
          .setFlags(FLAG_AUDIBILITY_ENFORCED) //VERY IMPORTANT
          .build();
    tts.setAudioAttributes(mPlaybackAttributes);
    tts.speak(textToSay, TextToSpeech.QUEUE_FLUSH, null, textToSay);
}
Petiolule answered 14/12, 2021 at 23:57 Comment(1)
Android 33 not workingDrumlin
B
0

Could you use the TextToSpeech.OnUtteranceCompletedListener along with AudioManager.setStreamVolume to achieve this?

Barrault answered 30/6, 2010 at 21:36 Comment(2)
Don't think that work, in the case you play your TTS message through STREAM_MUSIC, which is the same as background music. If you play it through another stream, like STREAM_NOTIFICATION, you will still have to deal with focus return. And i've only found one way to fix it, which is the dirty hack explained on my previous postCould
I see. I realize now this was more about returning focus after the "utterance," which you're right - it doesn't look like it was possible without requestAudioFocus.Barrault

© 2022 - 2024 — McMap. All rights reserved.