Ce tutoriel vous enseignera, à l'aide d'exemples simples, la conversion de texte en parole et de parole en texte. Comment vous pouvez convertir un texte écrit en mots parlés ou des mots parlés en texte écrit de manière programmatique.
Il y a deux exemples jusqu'à présent :
- Exemple 1 Kotlin Speech to Text et Text to Speech
- Exemple 2- Kotlin Speech to Text et Text to Speech
Commençons.
Exemple 1 : Kotlin Android Speech to Text et Text to Speech
Regardons notre exemple. Cet exemple couvre à la fois le Text To Speech et le Speech To Text. Il y a un edittext où vous tapez le texte à convertir.
Voici une démo de ce que nous allons créer :
Etape 1 : Créer le projet
Commencez par créer un projet Android Studio
vide.
Étape 2 : Dépendances
Aucune bibliothèque tierce n'est nécessaire.
Étape 3 : Conception de la mise en page
Nous n'avons qu'un seul layout : le layout de notre MainActivity :
activity_main.xml
Nous allons ajouter TextInputEditText, un FloatingActionButton et un ExtendedFloatingAction comme composants de l'interface utilisateur :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textInputLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edtText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Text" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/fabPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Play"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textInputLayout" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabVoice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/ic_keyboard_voice" />
</androidx.constraintlayout.widget.ConstraintLayout>
Étape 4 : Créer un ViewModel
Nous allons avoir une classe appelée BaseViewModel
qui va étendre la androidx.lifecycle.ViewModel
et être notre classe ViewModel. Ici, nous aurons au moins deux fonctions :
Une fonction pour lancer notre reconnaissance vocale via Intent :
fun displaySpeechRecognizer() {
startForResult.launch(Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
)
putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale("in_ID"))
putExtra(RecognizerIntent.EXTRA_PROMPT, Locale("Bicara sekarang"))
})
}
Et une fonction pour transformer notre texte en parole via le textToSpeechEngine
:
fun speak(text: String) = viewModelScope.launch{
textToSpeechEngine.speak(text, TextToSpeech.QUEUE_FLUSH, null, "")
}
Voici le code complet :
BaseViewModel.kt
import android.content.Intent
import android.speech.RecognizerIntent
import android.speech.tts.TextToSpeech
import androidx.activity.result.ActivityResultLauncher
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import java.util.*
class BaseViewModel : ViewModel() {
private lateinit var textToSpeechEngine: TextToSpeech
private lateinit var startForResult: ActivityResultLauncher<Intent>
fun initial(
engine: TextToSpeech, launcher: ActivityResultLauncher<Intent>
) = viewModelScope.launch {
textToSpeechEngine = engine
startForResult = launcher
}
fun displaySpeechRecognizer() {
startForResult.launch(Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
)
putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale("in_ID"))
putExtra(RecognizerIntent.EXTRA_PROMPT, Locale("Bicara sekarang"))
})
}
fun speak(text: String) = viewModelScope.launch{
textToSpeechEngine.speak(text, TextToSpeech.QUEUE_FLUSH, null, "")
}
}
Étape 5 : Créer notre MainActivity
Enfin, nous aurons notre MainActivity :
MainActivity.kt
import android.os.Bundle
import android.speech.RecognizerIntent
import android.speech.tts.TextToSpeech
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import id.derysudrajat.stttts.databinding.ActivityMainBinding
import java.util.*
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val model: BaseViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
model.initial(textToSpeechEngine, startForResult)
with(binding) {
fabVoice.setOnClickListener { model.displaySpeechRecognizer() }
fabPlay.setOnClickListener {
val text = edtText.text?.trim().toString()
model.speak(if (text.isNotEmpty()) text else "Text tidak boleh kosong")
}
}
}
private val startForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK) {
val spokenText: String? =
result.data?.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
.let { text -> text?.get(0) }
binding.edtText.setText(spokenText)
}
}
private val textToSpeechEngine: TextToSpeech by lazy {
TextToSpeech(this) {
if (it == TextToSpeech.SUCCESS) textToSpeechEngine.language = Locale("in_ID")
}
}
}
Exécuter
Copiez le code ou téléchargez-le dans le lien ci-dessous, construisez et exécutez.
Référence
Voici les liens de référence :
Télécharger Exemple
Exemple 2 : Exemple simple de Text To Speech et Speech to Text
Ceci est un exemple simple de Text To Speech et Speech To Text en Kotlin Android.
Etape 1 : Création du projet
Commencez par créer un projet Android Studio
vide.
Étape 2 : Dépendances
Aucune bibliothèque tierce n'est nécessaire.
Étape 3 : Conception de la mise en page
Ajoutez deux boutons : un pour le TTS et l'autre le STT, ainsi qu'un edittext pour entrer ou afficher le texte.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="24dp"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_stt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Speak" />
<EditText
android:id="@+id/et_text_input"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:layout_weight="1"
android:gravity="center"
android:hint="Text from STT or for TTS goes here." />
<Button
android:id="@+id/btn_tts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Listen" />
</LinearLayout>
Étape 4 : Écrire le code
Voici le code complet :
Activité principale.kt
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.speech.RecognizerIntent
import android.speech.tts.TextToSpeech
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*
class MainActivity : AppCompatActivity() {
companion object {
private const val REQUEST_CODE_STT = 1
}
private val textToSpeechEngine: TextToSpeech by lazy {
TextToSpeech(this,
TextToSpeech.OnInitListener { status ->
if (status == TextToSpeech.SUCCESS) {
textToSpeechEngine.language = Locale.UK
}
})
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_stt.setOnClickListener {
val sttIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
sttIntent.putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
)
sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
sttIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak now!")
try {
startActivityForResult(sttIntent, REQUEST_CODE_STT)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
Toast.makeText(this, "Your device does not support STT.", Toast.LENGTH_LONG).show()
}
}
btn_tts.setOnClickListener {
val text = et_text_input.text.toString().trim()
if (text.isNotEmpty()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
textToSpeechEngine.speak(text, TextToSpeech.QUEUE_FLUSH, null, "tts1")
} else {
textToSpeechEngine.speak(text, TextToSpeech.QUEUE_FLUSH, null)
}
} else {
Toast.makeText(this, "Text cannot be empty", Toast.LENGTH_LONG).show()
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_CODE_STT -> {
if (resultCode == Activity.RESULT_OK && data != null) {
val result = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
result?.let {
val recognizedText = it[0]
et_text_input.setText(recognizedText)
}
}
}
}
}
override fun onPause() {
textToSpeechEngine.stop()
super.onPause()
}
override fun onDestroy() {
textToSpeechEngine.shutdown()
super.onDestroy()
}
}
Exécution
Copiez le code ou téléchargez-le dans le lien ci-dessous, construisez et exécutez.
Référence
Voici les liens de référence :
Télécharger Exemple