Текст в речь не воспроизводит звук в первый раз, но играет в следующий раз

Я использую этот тип текста для речи в одном из моих классов в моем приложении (код отредактирован, чтобы показать внешний вид и точное требование.). Я покажу контент на мой взгляд, и если мы нажмем кнопку, я хочу воспроизвести звук, используя этот тексто-речевой движок... Но впервые он не воспроизводит звук. После следующего нажатия, двигатель TEXTTOSPEECH работает хорошо

Хочу узнать, как преодолеть эту проблему....

public class LearnActivity extends Activity implements OnClickListener, OnInitListener {

AudioManager audioManager;
float volume;

TextToSpeech textToSpeech;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_learn);

   textToSpeech = new TextToSpeech(this, this);
    textToSpeech.setLanguage(Locale.US);
    textToSpeech.setSpeechRate(0.95f);

       method();
}
   public void method(){
      bt.setonClickListener(new onClickListener(){
        public void onClick(View v){
                        playSound(datasource.getItemSound);                  
              }

        });

      }
   public void playSound(String sound){
         textToSpeech.speak(sound,TextToSpeech.QUEUE_FLUSH,null);
         }   

@Override
public void onInit(int status) {
    // TODO Auto-generated method stub

}

ПРИМЕЧАНИЕ:- Это также соответствует моему требованию, как воспроизводить звук из движка TEXTTOSPEECH напрямую, без использования onClicks и т. Д.,... потому что я также хочу воспроизводить звук запуска, который тоже только с движком Android Text-To-Speech...

3 ответа

Это потому, что вы нажимаете кнопку до того, как двигатель будет готов.

Вы должны проверить, успешно ли инициализирован двигатель TTS на вашем onInit() метод и включить / отключить кнопку воспроизведения соответственно.

При условии, что bt в твоем коде какая то View который имеет setEnabled(boolean) метод:

@Override
public void onInit(int status) {
    bt.setEnabled(status == TextToSpeech.SUCCESS);
}

Вы всегда должны предполагать, что двигатель не был инициализирован, и, следовательно, по умолчанию кнопка воспроизведения отключена.

Я использовал RXJava, чтобы создать класс, решающий эту проблему. Если ваш движок TTS не готов, когда вы хотите использовать метод Speech, он будет ждать, пока движок подготовится, а затем произносит заданную строку.

import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.util.Pair;
import android.widget.Toast;

import java.util.Locale;

import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;

public class Pronunciation {

    private TextToSpeech textToSpeech;
    private int languageResult;
    private boolean noError;
    private final String errorMessage="Something went wrong with your text to speech engine";
    private PublishSubject<Boolean> engineIsReady=PublishSubject.create();
    private PublishSubject<Pair<String,Integer>> speakObservable=PublishSubject.create();
    private CompositeDisposable compositeDisposable=new CompositeDisposable();

    public Pronunciation(Context context) {
        textToSpeech=new TextToSpeech(context, status -> {

            if (status!=TextToSpeech.ERROR){
               languageResult=  textToSpeech.setLanguage(Locale.ENGLISH);
               engineIsReady.onNext(true);
            } else {
                Toast.makeText(context,errorMessage
                        ,Toast.LENGTH_LONG).show();
            }

        });

        if (languageResult==TextToSpeech.LANG_MISSING_DATA||languageResult== TextToSpeech.LANG_NOT_SUPPORTED){
            noError =false;
            Toast.makeText(context,errorMessage
                    ,Toast.LENGTH_LONG).show();
        }else { noError =true;}


        compositeDisposable.add( Observable.combineLatest(speakObservable, engineIsReady,
                (stringIntegerPair, aBoolean) -> stringIntegerPair)
                .subscribeOn(Schedulers.io())
                .subscribe(pair->{

                    if (noError)
                        textToSpeech.speak( (pair).first
                                ,(pair).second,null,null);
                }));


    }


    public void speak(String text,int queueMode){

        speakObservable.onNext(new Pair<>(text,queueMode));

    }

    public void stop(){
        if (textToSpeech!=null){
            textToSpeech.stop();
            textToSpeech.shutdown();
        }
        compositeDisposable.clear();
    }
}

сначала добавьте зависимость RxJava в свой файл Gradle

implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'

Затем создайте экземпляр этого класса в методе onCreate вашей активности или фрагмента. Теперь вы можете передать строку и режим очереди методу Speak.

pronunciation.speak("Hi", TextToSpeech.QUEUE_FLUSH));

Не забудьте вызвать метод остановки в onDestroy или onDetach, чтобы избежать утечки памяти.

@Override
public void onDetach() {
    super.onDetach();
    pronunciation.stop();
}

Вы должны написать свою программу...

public class MainActivity extends Activity implements TextToSpeech.OnInitListener, OnUtteranceCompletedListener {

  TextToSpeech t1;

  protected void onCreate(Bundle savedInstanceState) {
    t1=new TextToSpeech(MainActivity.this, MainActivity.this);   
  }/////on creat

  protected void onDestroy() {
    if(t1!=null) {
      t1.stop();
      t1.shutdown();
      t1=null;
    }
    super.onDestroy();
  }

  public void onInit(int arg0) {
      t1.setOnUtteranceCompletedListener(this);
  }

}//mainactivity

Добавьте эту команду, когда кнопка нажата или везде, где вы хотите произнести текст.

t1.speak(text, TextToSpeech.QUEUE_FLUSH, null);

Просто установите задержку на 5 секунд, и она работает без нажатия кнопки.

public class Final_Text_To_Speech_Activity extends AppCompatActivity implements TextToSpeech.OnInitListener {

private TextToSpeech tts; // For Text to Speech
CardView ScanProduct, SearchProduct;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tts = new TextToSpeech(this, this);
    init();

    // Just Put Delay For 5 Second And It's Working without any button Click
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        public void run() {

            SpeakOutOnce("Welcome to Text To Speech Application");
        }
    }, 5000);


}


@Override
protected void onResume() {
    super.onResume();


}


public void init() {

    ScanProduct = (CardView) findViewById(R.id.scan_product);
    SearchProduct = (CardView) findViewById(R.id.search_product);


    // Search On Button Click
    ScanProduct.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            speakOut("You have Just pressed Scan  Option");
        }
    });


    SearchProduct.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            speakOut("You have Just pressed Search Option ");
        }
    });


}


@Override
public void onDestroy() {
    if (tts != null) {
        tts.stop();
        tts.shutdown();
    }
    super.onDestroy();
}


@Override
public void onInit(int status) {

    int result = tts.setLanguage(Locale.US);
    if (status == TextToSpeech.SUCCESS) {

        if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
        } else {
            speakOut("");
        }
    } else if (status == TextToSpeech.ERROR) {
        Toast.makeText(this, "Sorry! Text To Speech failed...",
                Toast.LENGTH_LONG).show();
    }
}


private void speakOut(String text) {

    tts.setPitch(1.0f); //Normal Pitch
    tts.setSpeechRate(0.7f); // 1.0 is Normal speech Rate
    tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);

}


private void SpeakOutOnce(String text) {

    if (tts != null) {
        tts.setPitch(1.0f); //Normal Pitch
        tts.setSpeechRate(0.7f); // 1.0 is Normal speech Rate
        tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
    }
}

}

Другие вопросы по тегам