Jetpark Compose 语音模块
简介
在 Jetpark Compose 中添加语音功能
主体代码
import android.content.Context
import android.speech.tts.TextToSpeech
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import java.util.*
/**
* 用于在 Jetpack Compose 中实现文本转语音功能的可组合函数。
*
* @param textToSpeak 要朗读的文本内容。
* @param autoPlay 是否在初始化完成后自动播放文本,默认为 false。
* @param language 语音的语言设置,默认为设备的默认语言。
* @param onError 当出现错误时调用的回调函数。
*/
@Composable
fun TextToSpeechModule(
textToSpeak: String,
autoPlay: Boolean = false,
language: Locale = Locale.getDefault(),
onError: (String) -> Unit = {}
) {
// 获取当前的上下文
val context = LocalContext.current
// 存储 TextToSpeech 实例
var tts by remember { mutableStateOf<TextToSpeech?>(null) }
// 标记 TTS 是否准备好
var isReady by remember { mutableStateOf(false) }
// TTS 初始化
DisposableEffect(Unit) {
// 创建 TextToSpeech 实例
tts = TextToSpeech(context) { status ->
if (status == TextToSpeech.SUCCESS) {
// 设置语音语言
when (tts?.setLanguage(language)) {
TextToSpeech.LANG_MISSING_DATA ->
// 语言数据缺失时调用错误回调
onError("Missing language data")
TextToSpeech.LANG_NOT_SUPPORTED ->
// 语言不支持时调用错误回调
onError("Language not supported")
else ->
// 其他情况表示准备就绪
isReady = true
}
} else {
// TTS 初始化失败时调用错误回调
onError("TTS initialization failed")
}
}
// 在组件销毁时停止并关闭 TTS
onDispose {
tts?.stop()
tts?.shutdown()
}
}
// 自动播放逻辑
if (autoPlay && isReady) {
// 当 textToSpeak 改变时触发朗读
LaunchedEffect(textToSpeak) {
tts?.speak(textToSpeak, TextToSpeech.QUEUE_FLUSH, null, null)
}
}
}
/**
* 用于控制文本转语音功能的控制器类。
*/
class TtsController {
// 存储 TextToSpeech 实例
var tts: TextToSpeech? = null
/**
* 开始朗读指定的文本。
*
* @param text 要朗读的文本。
*/
fun speak(text: String) {
tts?.speak(text, TextToSpeech.QUEUE_FLUSH, null, null)
}
/**
* 停止当前的朗读。
*/
fun stop() {
tts?.stop()
}
}
/**
* 用于在 Jetpack Compose 中记住并初始化 TtsController 实例的可组合函数。
*
* @param language 语音的语言设置,默认为设备的默认语言。
* @param onError 当出现错误时调用的回调函数。
* @return 返回初始化好的 TtsController 实例。
*/
@Composable
fun rememberTtsController(
language: Locale = Locale.getDefault(),
onError: (String) -> Unit = {}
): TtsController {
// 获取当前的上下文
val context = LocalContext.current
// 创建并记住 TtsController 实例
val controller = remember { TtsController() }
DisposableEffect(Unit) {
// 初始化 TtsController 中的 TextToSpeech 实例
controller.tts = TextToSpeech(context) { status ->
if (status == TextToSpeech.SUCCESS) {
// 设置语音语言
when (controller.tts?.setLanguage(language)) {
TextToSpeech.LANG_MISSING_DATA ->
// 语言数据缺失时调用错误回调
onError("Missing language data")
TextToSpeech.LANG_NOT_SUPPORTED ->
// 语言不支持时调用错误回调
onError("Language not supported")
else ->
Unit
}
} else {
// TTS 初始化失败时调用错误回调
onError("TTS initialization failed")
}
}
// 在组件销毁时停止并关闭 TTS
onDispose {
controller.tts?.stop()
controller.tts?.shutdown()
controller.tts = null
}
}
return controller
}
使用方法
方式一:自动播放(文本变化时触发)
@Composable
fun AutoPlayExample() {
var speechText by remember { mutableStateOf("Initial text") }
TextToSpeechModule(
textToSpeak = speechText,
autoPlay = true,
language = Locale.US,
onError = { error -> Log.e("TTS", error) }
)
Button(onClick = { speechText = "New text to speak" }) {
Text("Update Text")
}
}
方式二:手动控制播放
@Composable
fun ManualControlExample() {
val ttsController = rememberTtsController(
language = Locale.UK,
onError = { error -> Toast.makeText(context, error, Toast.LENGTH_SHORT).show() }
)
var inputText by remember { mutableStateOf("") }
Column {
TextField(
value = inputText,
onValueChange = { inputText = it }
)
Button(onClick = { ttsController.speak(inputText) }) {
Text("Play")
}
Button(onClick = { ttsController.stop() }) {
Text("Stop")
}
}
}
主要特性:
1. 模块化设计:
提供两种使用模式:自动播放和手动控制
封装底层TextToSpeech的生命周期管理
灵活参数:
textToSpeak: String // 需要播报的文本
autoPlay: Boolean // 是否自动播放(默认false)
language: Locale // 语言设置(默认系统语言)
onError: (String) -> Unit // 错误回调
2. 增强功能:
自动处理文本更新(通过LaunchedEffect监听textToSpeak变化)
支持语音队列管理(QUEUE_FLUSH会中断当前播报)
提供停止播放的方法
3. 内存安全:
使用DisposableEffect自动释放资源
防止内存泄漏的销毁逻辑
4. 扩展性:
可轻松添加语速/音调控制:
tts?.setSpeechRate(0.8f) // 语速(0.5-2.0)
tts?.setPitch(1.2f) // 音调(0.5-2.0)
使用建议:
长文本处理:
// 分割长文本避免内存问题
fun speakLongText(controller: TtsController, text: String) {
text.split("\n").forEach {
controller.speak(it, TextToSpeech.QUEUE_ADD, null, null)
}
}
多语言支持:
TextToSpeechModule(
textToSpeak = "こんにちは",
language = Locale.JAPANESE
)
音频焦点管理(可选增强):
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
tts?.setAudioAttributes(audioAttributes)
这个模块化实现可以在多个Composable中复用,同时保持业务逻辑与语音功能的解耦。