Comment mettre en pause android.discours.TTS.Synthèse vocale?
je suis en train de jouer de texte avec android TTS - android.speech.tts.TextToSpeech
j'utilise: TextToSpeech.speak
pour parler et .stop
arrêter. Y a-t-il aussi un moyen de mettre le texte en pause?
9 réponses
le SDK TTS n'a pas de fonctionnalité de pause que je connais. Mais vous pourriez utiliser synthesizeToFile()
pour créer un fichier audio qui contient la sortie TTS. Ensuite, vous utiliserez un MediaPlayer objet de lecture, de pause et d'arrêter la lecture du fichier. Selon la longueur de la chaîne de texte, cela pourrait prendre un peu plus de temps pour que l'audio soit produit parce que le synthesizeToFile()
fonction devrait compléter le dossier entier avant que vous puissiez le lire, mais ce retard devrait être acceptable pour la plupart des applications.
j'ai utilisé splitting of string et utilisé playsilence () comme ci-dessous:
public void speakSpeech(String speech) {
HashMap<String, String> myHash = new HashMap<String, String>();
myHash.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "done");
String[] splitspeech = speech.split("\.");
for (int i = 0; i < splitspeech.length; i++) {
if (i == 0) { // Use for the first splited text to flush on audio stream
textToSpeech.speak(splitspeech[i].toString().trim(),TextToSpeech.QUEUE_FLUSH, myHash);
} else { // add the new test on previous then play the TTS
textToSpeech.speak(splitspeech[i].toString().trim(), TextToSpeech.QUEUE_ADD,myHash);
}
textToSpeech.playSilence(750, TextToSpeech.QUEUE_ADD, null);
}
}
Vous pouvez faire la pause TTS entre les phrases, ou n'importe où vous voulez en additionnant jusqu'à trois périodes (".") le tout suivit d'un seul espace " ". L'exemple ci-dessous a une longue pause au début, et de nouveau avant le corps du message. Je ne suis pas sûr que ce soit ce que vous cherchez.
private final BroadcastReceiver SMScatcher = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().equals(
"android.provider.Telephony.SMS_RECEIVED")) {
// if(message starts with SMStretcher recognize BYTE)
StringBuilder sb = new StringBuilder();
/*
* The SMS-Messages are 'hiding' within the extras of the
* Intent.
*/
Bundle bundle = intent.getExtras();
if (bundle != null) {
/* Get all messages contained in the Intent */
Object[] pdusObj = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdusObj.length];
for (int i = 0; i < pdusObj.length; i++) {
messages[i] = SmsMessage
.createFromPdu((byte[]) pdusObj[i]);
}
/* Feed the StringBuilder with all Messages found. */
for (SmsMessage currentMessage : messages) {
// periods are to pause
sb.append("... Message From: ");
/* Sender-Number */
sb.append(currentMessage.getDisplayOriginatingAddress());
sb.append(".. ");
/* Actual Message-Content */
sb.append(currentMessage.getDisplayMessageBody());
}
// Toast.makeText(application, sb.toString(),
// Toast.LENGTH_LONG).show();
if (mTtsReady) {
try {
mTts.speak(sb.toString(), TextToSpeech.QUEUE_ADD,
null);
} catch (Exception e) {
Toast.makeText(application, "TTS Not ready",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}
}
}
};
Si vous omettez l'espace après la dernière période, il (ou peuvent) pas fonctionner comme prévu.
en l'absence d'une option de pause, vous pouvez ajouter le silence pour la durée de quand vous voulez retarder le moteur TTS de parler. Bien sûr, cela devrait être une "pause" prédéterminée et ne contribuerait pas à inclure la fonctionnalité d'un bouton pause, par exemple.
pour API < 21: public int playSilence (long durationInMs, int queueMode, HashMap params)
pour > 21: public int playSilentUtterance (long durationInMs, int queueMode, String utteranceId)
n'oubliez pas d'utiliser synthèse vocale.QUEUE_ADD plutôt que synthèse vocale.QUEUE_FLUSH sinon il va effacer le discours déjà commencé.
Je n'ai pas encore essayé, mais je dois faire la même chose. Je pense d'abord diviser votre texte de discours en plusieurs mots.
puis créer une fonction récursive qui joue le mot suivant après que le mot courant est terminé, tout en gardant un compteur du mot courant.
diviser le messages
en parties et écouter les derniers utterance
en utilisant onutteranceprogress
écouteur
tts.playSilence(1250, TextToSpeech.QUEUE_ADD, null);
Il semble que si vous mettez un point après un mot ET le prochain mot avec une majuscule, tout comme une nouvelle phrase, comme ceci:
après notre retour à la maison. Nous avons mangé le dîner.
les "à la maison. Nous" aurons alors une pause.
- ceci devient une façon grammaticalement étrange de l'écrire.
- jusqu'à présent, je ne l'ai testé que dans ma propre langue, le suédois.
- il pourrait être important que l'espace soit y.
en outre, une citation échappée (\") semble avoir une pause un peu aussi bien - au moins, si vous le mettez autour d'un mot il ajoute de l'espace autour du mot.
Cette solution n'est pas parfaite, mais une alternative à la solution de @Aaron C peut être de créer un texte personnalisé à la classe de la parole comme ci-dessous. Cette solution peut fonctionner assez bien si votre texte est relativement court et les mots parlés par minute sont assez précis pour la langue que vous utilisez.
private class CustomTextToSpeech extends TextToSpeech {
private static final double WORDS_PER_MS = (double)190/60/1000;
long startTimestamp = 0;
long pauseTimestamp = 0;
private Handler handler;
private Runnable speakRunnable;
StringBuilder textToSpeechBuilder;
private boolean isPaused = false;
public CustomTextToSpeech(Context context, OnInitListener initListener){
super(context, initListener);
setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onDone(String arg0) {
Log.d(TAG, "tts done. " + arg0);
startTimestamp = 0;
pauseTimestamp = 0;
handler.postDelayed(speakRunnable, TTS_INTERVAL_MS);
}
@Override
public void onError(String arg0) {
Log.e(TAG, "tts error. " + arg0);
}
@Override
public void onStart(String arg0) {
Log.d(TAG, "tts start. " + arg0);
setStartTimestamp(System.currentTimeMillis());
}
});
handler = new Handler();
speakRunnable = new Runnable() {
@Override
public void run() {
speak();
}
};
textToSpeechBuilder = new StringBuilder(getResources().getString(R.string.talkback_tips));
}
public void setStartTimestamp(long timestamp) {
startTimestamp = timestamp;
}
public void setPauseTimestamp(long timestamp) {
pauseTimestamp = timestamp;
}
public boolean isPaused(){
return (startTimestamp > 0 && pauseTimestamp > 0);
}
public void resume(){
if(handler != null && isPaused){
if(startTimestamp > 0 && pauseTimestamp > 0){
handler.postDelayed(speakRunnable, TTS_SETUP_TIME_MS);
} else {
handler.postDelayed(speakRunnable, TTS_INTERVAL_MS);
}
}
isPaused = false;
}
public void pause(){
isPaused = true;
if (handler != null) {
handler.removeCallbacks(speakRunnable);
handler.removeMessages(1);
}
if(isSpeaking()){
setPauseTimestamp(System.currentTimeMillis());
}
stop();
}
public void utter(){
if(handler != null){
handler.postDelayed(speakRunnable, TTS_INTERVAL_MS);
}
}
public void speak(){
Log.d(TAG, "textToSpeechBuilder: " + textToSpeechBuilder.toString());
if(isPaused()){
String[] words = textToSpeechBuilder.toString().split(" ");
int wordsAlreadySpoken = (int)Math.round((pauseTimestamp - startTimestamp)*WORDS_PER_MS);
words = Arrays.copyOfRange(words, wordsAlreadySpoken-1, words.length);
textToSpeechBuilder = new StringBuilder();
for(String s : words){
textToSpeechBuilder.append(s);
textToSpeechBuilder.append(" ");
}
} else {
textToSpeechBuilder = new StringBuilder(getResources().getString(R.string.talkback_tips));
}
if (tts != null && languageAvailable)
speak(textToSpeechBuilder.toString(), TextToSpeech.QUEUE_FLUSH, new Bundle(), "utter");
}
}