🔬
android.speech.ttsをJetpack Composeで使ってみた
🎤テキストを読み上げてくれるらしい
普段は、Fltterとたまに、SwiftUIでお仕事をしてます。Flutterで新しいアプリを作ろうとしてたんですけど、Kotlinのバージョン上げろとエラーが出て苦しみました😇
OSに依存したエラー出てくるの辛いな。Kotlinでもあるでしょうけど。オリジナルのAndroidには、tts
が標準機能であった!
やること
- プロジェクトを作る
- サンプルコードを日本語対応にする
- これだけ
example:
package com.junichi.ttsapplication
import android.os.Bundle
import android.speech.tts.TextToSpeech
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.junichi.ttsapplication.ui.theme.TtsApplicationTheme
import java.util.Locale
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TtsApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
TextToSpeechScreen()
}
}
}
}
}
val sentences = listOf(
"おはようございます。",
"こんにちは。",
"こんばんは。",
)
@Composable
fun TextToSpeechScreen() {
var isSpeaking by remember { mutableStateOf(false) }
val tts = rememberTextToSpeech()
Column(modifier = Modifier.padding(24.dp)) {
isSpeaking = false
for (sentence in sentences) {
Button(onClick = {
if (tts.value?.isSpeaking == true) {
tts.value?.stop()
isSpeaking = false
} else {
tts.value?.speak(
sentence, TextToSpeech.QUEUE_FLUSH, null, ""
)
isSpeaking = true
}
}) {
Text(sentence)
} // End Button
} // End for
}
}
@Composable
fun rememberTextToSpeech(): MutableState<TextToSpeech?> {
val context = LocalContext.current
val tts = remember { mutableStateOf<TextToSpeech?>(null) }
DisposableEffect(context) {
val textToSpeech = TextToSpeech(context) { status ->
if (status == TextToSpeech.SUCCESS) {
tts.value?.language = Locale.JAPAN
}
}
tts.value = textToSpeech
onDispose {
textToSpeech.stop()
textToSpeech.shutdown()
}
}
return tts
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
TtsApplicationTheme {
TextToSpeechScreen()
}
}
日本語対応にする
tts.value?.language = Locale.JAPAN
サンプルだと、tts.value?.language = Locale.US
になっています。JAPAN
に修正すると日本語で、音声を読み上げてくれます。
for文で、ダミーのデータをループして渡して、3個ボタンを作ってくれます。ボタンを押すと、日本語の挨拶を読み上げてくれます。
@Composable
fun rememberTextToSpeech(): MutableState<TextToSpeech?> {
val context = LocalContext.current
val tts = remember { mutableStateOf<TextToSpeech?>(null) }
DisposableEffect(context) {
val textToSpeech = TextToSpeech(context) { status ->
if (status == TextToSpeech.SUCCESS) {
tts.value?.language = Locale.JAPAN
}
}
tts.value = textToSpeech
onDispose {
textToSpeech.stop()
textToSpeech.shutdown()
}
}
return tts
}
感想
標準機能で、tts
が使えるのがありがたかったですね。Swiftでも標準機能で使えるみたいです。
Discussion