优化
This commit is contained in:
@@ -29,6 +29,8 @@ import io.legado.app.ui.book.read.ReadBookActivity
|
||||
import io.legado.app.ui.book.read.page.entities.TextChapter
|
||||
import io.legado.app.utils.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import splitties.init.appCtx
|
||||
import splitties.systemservices.audioManager
|
||||
import splitties.systemservices.powerManager
|
||||
@@ -71,7 +73,7 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
private val mediaSessionCompat: MediaSessionCompat by lazy {
|
||||
MediaSessionCompat(this, "readAloud")
|
||||
}
|
||||
internal val contentList = arrayListOf<String>()
|
||||
internal var contentList = emptyList<String>()
|
||||
internal var nowSpeak: Int = 0
|
||||
internal var readAloudNumber: Int = 0
|
||||
internal var textChapter: TextChapter? = null
|
||||
@@ -132,6 +134,7 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
intent.getIntExtra("pageIndex", ReadBook.durPageIndex),
|
||||
intent.getIntExtra("startPos", 0)
|
||||
)
|
||||
|
||||
IntentAction.pause -> pauseReadAloud()
|
||||
IntentAction.resume -> resumeReadAloud()
|
||||
IntentAction.upTtsSpeechRate -> upSpeechRate(true)
|
||||
@@ -144,20 +147,17 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
private fun newReadAloud(play: Boolean, pageIndex: Int, startPos: Int) {
|
||||
this.pageIndex = pageIndex
|
||||
private fun newReadAloud(play: Boolean, pageIndex: Int, startPos: Int) = launch(IO) {
|
||||
this@BaseReadAloudService.pageIndex = pageIndex
|
||||
textChapter = ReadBook.curTextChapter
|
||||
textChapter?.let { textChapter ->
|
||||
nowSpeak = 0
|
||||
readAloudNumber = textChapter.getReadLength(pageIndex) + startPos
|
||||
contentList.clear()
|
||||
val readAloudByPage = getPrefBoolean(PreferKey.readAloudByPage)
|
||||
textChapter.getNeedReadAloud(pageIndex, readAloudByPage, startPos)
|
||||
.split("\n").forEach { text ->
|
||||
if (text.isNotEmpty()) {
|
||||
contentList.add(text)
|
||||
}
|
||||
}
|
||||
val textChapter = textChapter ?: return@launch
|
||||
nowSpeak = 0
|
||||
readAloudNumber = textChapter.getReadLength(pageIndex) + startPos
|
||||
val readAloudByPage = getPrefBoolean(PreferKey.readAloudByPage)
|
||||
contentList = textChapter.getNeedReadAloud(pageIndex, readAloudByPage, startPos)
|
||||
.split("\n")
|
||||
.filter { it.isNotEmpty() }
|
||||
launch(Main) {
|
||||
if (play) play() else pageChanged = true
|
||||
}
|
||||
}
|
||||
@@ -335,10 +335,12 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
AppLog.put("音频焦点获得")
|
||||
}
|
||||
}
|
||||
|
||||
AudioManager.AUDIOFOCUS_LOSS -> {
|
||||
AppLog.put("音频焦点丢失,暂停朗读")
|
||||
pauseReadAloud()
|
||||
}
|
||||
|
||||
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
|
||||
AppLog.put("音频焦点暂时丢失并会很快再次获得,暂停朗读")
|
||||
if (!pause) {
|
||||
@@ -346,6 +348,7 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
pauseReadAloud(false)
|
||||
}
|
||||
}
|
||||
|
||||
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
|
||||
// 短暂丢失焦点,这种情况是被其他应用申请了短暂的焦点希望其他声音能压低音量(或者关闭声音)凸显这个声音(比如短信提示音),
|
||||
AppLog.put("音频焦点短暂丢失,不做处理")
|
||||
@@ -364,6 +367,7 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
R.string.read_aloud_timer,
|
||||
timeMinute
|
||||
)
|
||||
|
||||
else -> getString(R.string.read_aloud_t)
|
||||
}
|
||||
nTitle += ": ${ReadBook.book?.name}"
|
||||
|
||||
@@ -11,10 +11,12 @@ import io.legado.app.constant.EventBus
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import io.legado.app.help.MediaHelp
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.coroutine.Coroutine
|
||||
import io.legado.app.lib.dialogs.SelectItem
|
||||
import io.legado.app.model.ReadAloud
|
||||
import io.legado.app.model.ReadBook
|
||||
import io.legado.app.utils.*
|
||||
import kotlinx.coroutines.ensureActive
|
||||
|
||||
/**
|
||||
* 本地朗读
|
||||
@@ -24,6 +26,7 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
|
||||
private var textToSpeech: TextToSpeech? = null
|
||||
private var ttsInitFinish = false
|
||||
private val ttsUtteranceListener = TTSUtteranceListener()
|
||||
private var speakJob: Coroutine<*>? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
@@ -74,30 +77,34 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
|
||||
if (contentList.isEmpty()) {
|
||||
AppLog.putDebug("朗读列表为空")
|
||||
ReadBook.readAloud()
|
||||
} else {
|
||||
super.play()
|
||||
kotlin.runCatching {
|
||||
MediaHelp.playSilentSound(this@TTSReadAloudService)
|
||||
val tts = textToSpeech ?: throw NoStackTraceException("tts is null")
|
||||
var result = tts.speak("", TextToSpeech.QUEUE_FLUSH, null, null)
|
||||
if (result == TextToSpeech.ERROR) {
|
||||
clearTTS()
|
||||
initTts()
|
||||
return
|
||||
}
|
||||
for (i in nowSpeak until contentList.size) {
|
||||
val text = contentList[i]
|
||||
if (!text.matches(AppPattern.notReadAloudRegex)) {
|
||||
result = tts.speak(text, TextToSpeech.QUEUE_ADD, null, AppConst.APP_TAG + i)
|
||||
if (result == TextToSpeech.ERROR) {
|
||||
AppLog.put("tts朗读出错:$text")
|
||||
}
|
||||
}
|
||||
}
|
||||
}.onFailure {
|
||||
AppLog.put("tts朗读出错", it)
|
||||
toastOnUi(it.localizedMessage)
|
||||
return
|
||||
}
|
||||
super.play()
|
||||
MediaHelp.playSilentSound(this@TTSReadAloudService)
|
||||
speakJob?.cancel()
|
||||
speakJob = execute {
|
||||
val tts = textToSpeech ?: throw NoStackTraceException("tts is null")
|
||||
var result = tts.speak("", TextToSpeech.QUEUE_FLUSH, null, null)
|
||||
if (result == TextToSpeech.ERROR) {
|
||||
clearTTS()
|
||||
initTts()
|
||||
return@execute
|
||||
}
|
||||
val contentList = contentList
|
||||
for (i in nowSpeak until contentList.size) {
|
||||
ensureActive()
|
||||
val text = contentList[i]
|
||||
if (text.matches(AppPattern.notReadAloudRegex)) {
|
||||
continue
|
||||
}
|
||||
result = tts.speak(text, TextToSpeech.QUEUE_ADD, null, AppConst.APP_TAG + i)
|
||||
if (result == TextToSpeech.ERROR) {
|
||||
AppLog.put("tts朗读出错:$text")
|
||||
}
|
||||
}
|
||||
}.onError {
|
||||
AppLog.put("tts朗读出错", it)
|
||||
toastOnUi(it.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +132,7 @@ class TTSReadAloudService : BaseReadAloudService(), TextToSpeech.OnInitListener
|
||||
*/
|
||||
override fun pauseReadAloud(abandonFocus: Boolean) {
|
||||
super.pauseReadAloud(abandonFocus)
|
||||
speakJob?.cancel()
|
||||
textToSpeech?.stop()
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,21 @@ class SpeakEngineDialog(val callBack: CallBack) : BaseDialogFragment(R.layout.di
|
||||
recyclerView.setEdgeEffectColor(primaryColor)
|
||||
recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
recyclerView.adapter = adapter
|
||||
adapter.addHeaderView {
|
||||
ItemHttpTtsBinding.inflate(layoutInflater, recyclerView, false).apply {
|
||||
sysTtsViews.add(cbName)
|
||||
ivEdit.gone()
|
||||
ivMenuDelete.gone()
|
||||
labelSys.visible()
|
||||
cbName.text = "系统默认"
|
||||
cbName.tag = ""
|
||||
cbName.isChecked = GSON.fromJsonObject<SelectItem<String>>(ttsEngine)
|
||||
.getOrNull()?.value.isNullOrEmpty()
|
||||
cbName.setOnClickListener {
|
||||
upTts(GSON.toJson(SelectItem("系统默认", "")))
|
||||
}
|
||||
}
|
||||
}
|
||||
viewModel.sysEngines.forEach { engine ->
|
||||
adapter.addHeaderView {
|
||||
ItemHttpTtsBinding.inflate(layoutInflater, recyclerView, false).apply {
|
||||
@@ -147,6 +162,7 @@ class SpeakEngineDialog(val callBack: CallBack) : BaseDialogFragment(R.layout.di
|
||||
mode = HandleFileContract.FILE
|
||||
allowExtensions = arrayOf("txt", "json")
|
||||
}
|
||||
|
||||
R.id.menu_import_onLine -> importAlert()
|
||||
R.id.menu_export -> exportDirResult.launch {
|
||||
mode = HandleFileContract.EXPORT
|
||||
|
||||
Reference in New Issue
Block a user