优化
This commit is contained in:
@@ -17,10 +17,14 @@ class TTS {
|
||||
|
||||
private val clearTtsRunnable = Runnable { clearTts() }
|
||||
|
||||
private var speakStateListener: SpeakStateListener? = null
|
||||
|
||||
private var textToSpeech: TextToSpeech? = null
|
||||
|
||||
private var text: String? = null
|
||||
|
||||
private var onInit = false
|
||||
|
||||
private val initListener by lazy {
|
||||
InitListener()
|
||||
}
|
||||
@@ -29,17 +33,40 @@ class TTS {
|
||||
TTSUtteranceListener()
|
||||
}
|
||||
|
||||
val isSpeaking: Boolean
|
||||
get() {
|
||||
return textToSpeech?.isSpeaking ?: false
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun setSpeakStateListener(speakStateListener: SpeakStateListener) {
|
||||
this.speakStateListener = speakStateListener
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun removeSpeakStateListener() {
|
||||
speakStateListener = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun speak(text: String) {
|
||||
handler.removeCallbacks(clearTtsRunnable)
|
||||
this.text = text
|
||||
if (onInit) {
|
||||
return
|
||||
}
|
||||
if (textToSpeech == null) {
|
||||
onInit = true
|
||||
textToSpeech = TextToSpeech(appCtx, initListener)
|
||||
} else {
|
||||
addTextToSpeakList()
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
textToSpeech?.stop()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun clearTts() {
|
||||
textToSpeech?.let { tts ->
|
||||
@@ -80,6 +107,7 @@ class TTS {
|
||||
} else {
|
||||
appCtx.toastOnUi(R.string.tts_init_failed)
|
||||
}
|
||||
onInit = false
|
||||
}
|
||||
|
||||
}
|
||||
@@ -92,11 +120,13 @@ class TTS {
|
||||
override fun onStart(utteranceId: String?) {
|
||||
//开始朗读取消释放资源任务
|
||||
handler.removeCallbacks(clearTtsRunnable)
|
||||
speakStateListener?.onStart()
|
||||
}
|
||||
|
||||
override fun onDone(utteranceId: String?) {
|
||||
//一分钟没有朗读释放资源
|
||||
handler.postDelayed(clearTtsRunnable, 60000L)
|
||||
speakStateListener?.onDone()
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
@@ -105,4 +135,9 @@ class TTS {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface SpeakStateListener {
|
||||
fun onStart()
|
||||
fun onDone()
|
||||
}
|
||||
}
|
||||
@@ -267,16 +267,15 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
private fun readAloud() {
|
||||
if (viewModel.textToSpeech?.isSpeaking == true) {
|
||||
viewModel.textToSpeech?.stop()
|
||||
if (viewModel.tts?.isSpeaking == true) {
|
||||
viewModel.tts?.stop()
|
||||
upTtsMenu(false)
|
||||
} else {
|
||||
binding.webView.settings.javaScriptEnabled = true
|
||||
binding.webView.evaluateJavascript("document.documentElement.outerHTML") {
|
||||
val html = StringEscapeUtils.unescapeJson(it)
|
||||
.replace("^\"|\"$".toRegex(), "")
|
||||
Jsoup.parse(html).text()
|
||||
viewModel.readAloud(Jsoup.parse(html).textArray())
|
||||
viewModel.readAloud(Jsoup.parse(html).textArray().joinToString("\n"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,18 @@ package io.legado.app.ui.rss.read
|
||||
import android.app.Application
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.speech.tts.TextToSpeech
|
||||
import android.speech.tts.UtteranceProgressListener
|
||||
import android.util.Base64
|
||||
import android.webkit.URLUtil
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseViewModel
|
||||
import io.legado.app.constant.AppConst
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.RssArticle
|
||||
import io.legado.app.data.entities.RssSource
|
||||
import io.legado.app.data.entities.RssStar
|
||||
import io.legado.app.help.TTS
|
||||
import io.legado.app.help.http.newCallResponseBody
|
||||
import io.legado.app.help.http.okHttpClient
|
||||
import io.legado.app.model.analyzeRule.AnalyzeUrl
|
||||
@@ -27,17 +25,14 @@ import java.io.File
|
||||
import java.util.*
|
||||
|
||||
|
||||
class ReadRssViewModel(application: Application) : BaseViewModel(application),
|
||||
TextToSpeech.OnInitListener {
|
||||
class ReadRssViewModel(application: Application) : BaseViewModel(application) {
|
||||
var callBack: CallBack? = null
|
||||
var rssSource: RssSource? = null
|
||||
var rssArticle: RssArticle? = null
|
||||
var tts: TTS? = null
|
||||
val contentLiveData = MutableLiveData<String>()
|
||||
val urlLiveData = MutableLiveData<AnalyzeUrl>()
|
||||
var rssStar: RssStar? = null
|
||||
var textToSpeech: TextToSpeech? = null
|
||||
private var ttsInitFinish = false
|
||||
private var ttsTextList = arrayListOf<String>()
|
||||
|
||||
fun initData(intent: Intent) {
|
||||
execute {
|
||||
@@ -192,59 +187,26 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application),
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onInit(status: Int) {
|
||||
if (status == TextToSpeech.SUCCESS) {
|
||||
textToSpeech?.setOnUtteranceProgressListener(TTSUtteranceListener())
|
||||
ttsInitFinish = true
|
||||
play()
|
||||
} else {
|
||||
context.toastOnUi(R.string.tts_init_failed)
|
||||
}
|
||||
}
|
||||
fun readAloud(text: String) {
|
||||
if (tts == null) {
|
||||
tts = TTS().apply {
|
||||
setSpeakStateListener(object : TTS.SpeakStateListener {
|
||||
override fun onStart() {
|
||||
callBack?.upTtsMenu(true)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun play() {
|
||||
if (!ttsInitFinish) return
|
||||
textToSpeech?.stop()
|
||||
ttsTextList.forEach {
|
||||
textToSpeech?.speak(it, TextToSpeech.QUEUE_ADD, null, "rss")
|
||||
}
|
||||
}
|
||||
|
||||
fun readAloud(textArray: Array<String>) {
|
||||
ttsTextList.clear()
|
||||
ttsTextList.addAll(textArray)
|
||||
textToSpeech?.let {
|
||||
play()
|
||||
} ?: let {
|
||||
textToSpeech = TextToSpeech(context, this)
|
||||
override fun onDone() {
|
||||
callBack?.upTtsMenu(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
tts?.speak(text)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
textToSpeech?.stop()
|
||||
textToSpeech?.shutdown()
|
||||
}
|
||||
|
||||
/**
|
||||
* 朗读监听
|
||||
*/
|
||||
private inner class TTSUtteranceListener : UtteranceProgressListener() {
|
||||
|
||||
override fun onStart(s: String) {
|
||||
callBack?.upTtsMenu(true)
|
||||
}
|
||||
|
||||
override fun onDone(s: String) {
|
||||
callBack?.upTtsMenu(false)
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onError(s: String) {
|
||||
|
||||
}
|
||||
|
||||
tts?.clearTts()
|
||||
}
|
||||
|
||||
interface CallBack {
|
||||
|
||||
Reference in New Issue
Block a user