This commit is contained in:
Horis
2025-04-01 17:31:23 +08:00
parent 3ad189b9ef
commit 5654a2e56d
6 changed files with 21 additions and 12 deletions
@@ -27,12 +27,7 @@ class InputStreamDataSource(private val supplier: () -> InputStream) : BaseDataS
inputStream.skip(dataSpec.position) inputStream.skip(dataSpec.position)
if (dataSpec.length == C.LENGTH_UNSET.toLong()) {
bytesRemaining = inputStream.available().toLong()
if (bytesRemaining == 0L) bytesRemaining = C.LENGTH_UNSET.toLong()
} else {
bytesRemaining = dataSpec.length bytesRemaining = dataSpec.length
}
opened = true opened = true
transferStarted(dataSpec) transferStarted(dataSpec)
@@ -550,6 +550,7 @@ class HttpReadAloudService : BaseReadAloudService(),
override fun onPlayerError(error: PlaybackException) { override fun onPlayerError(error: PlaybackException) {
super.onPlayerError(error) super.onPlayerError(error)
AppLog.put("朗读错误\n${contentList[nowSpeak]}", error) AppLog.put("朗读错误\n${contentList[nowSpeak]}", error)
deleteCurrentSpeakFile()
playErrorNo++ playErrorNo++
if (playErrorNo >= 5) { if (playErrorNo >= 5) {
toastOnUi("朗读连续5次错误, 最后一次错误代码(${error.localizedMessage})") toastOnUi("朗读连续5次错误, 最后一次错误代码(${error.localizedMessage})")
@@ -558,7 +559,6 @@ class HttpReadAloudService : BaseReadAloudService(),
} else { } else {
if (exoPlayer.hasNextMediaItem()) { if (exoPlayer.hasNextMediaItem()) {
exoPlayer.seekToNextMediaItem() exoPlayer.seekToNextMediaItem()
exoPlayer.playWhenReady = true
exoPlayer.prepare() exoPlayer.prepare()
} else { } else {
exoPlayer.clearMediaItems() exoPlayer.clearMediaItems()
@@ -567,6 +567,15 @@ class HttpReadAloudService : BaseReadAloudService(),
} }
} }
private fun deleteCurrentSpeakFile() {
if (AppConfig.streamReadAloudAudio) {
return
}
val mediaItem = exoPlayer.currentMediaItem ?: return
val filePath = mediaItem.localConfiguration!!.uri.path!!
File(filePath).delete()
}
override fun aloudServicePendingIntent(actionStr: String): PendingIntent? { override fun aloudServicePendingIntent(actionStr: String): PendingIntent? {
return servicePendingIntent<HttpReadAloudService>(actionStr) return servicePendingIntent<HttpReadAloudService>(actionStr)
} }
@@ -253,7 +253,6 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_
delay(500) delay(500)
} }
} }
} }
lifecycleScope.launch { lifecycleScope.launch {
@@ -25,6 +25,7 @@ import io.legado.app.help.config.SourceConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.internString import io.legado.app.utils.internString
import io.legado.app.utils.mapParallel
import io.legado.app.utils.mapParallelSafe import io.legado.app.utils.mapParallelSafe
import io.legado.app.utils.onEachIndexed import io.legado.app.utils.onEachIndexed
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
@@ -35,6 +36,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -231,11 +233,13 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
} }
}.onStart { }.onStart {
searchStateData.postValue(true) searchStateData.postValue(true)
}.mapParallelSafe(threadCount) { }.mapParallel(threadCount) {
runCatching { try {
withTimeout(60000L) { withTimeout(60000L) {
search(it) search(it)
} }
} catch (_: Throwable) {
currentCoroutineContext().ensureActive()
} }
it it
}.onEachIndexed { index, value -> }.onEachIndexed { index, value ->
@@ -64,7 +64,7 @@ inline fun <T, R> Flow<T>.mapParallelSafe(
flow { flow {
try { try {
emit(transform(value)) emit(transform(value))
} catch (e: Throwable) { } catch (_: Throwable) {
coroutineContext.ensureActive() coroutineContext.ensureActive()
} }
} }
@@ -159,7 +159,9 @@ object UrlUtil {
.substringAfterLast(".", "") .substringAfterLast(".", "")
//检查截取的后缀字符是否合法 [a-zA-Z0-9] //检查截取的后缀字符是否合法 [a-zA-Z0-9]
return if (suffix.length > 5 || !suffix.matches(fileSuffixRegex)) { return if (suffix.length > 5 || !suffix.matches(fileSuffixRegex)) {
if (default == null) {
AppLog.put("Cannot find legal suffix:\n target: $str\n suffix: $suffix") AppLog.put("Cannot find legal suffix:\n target: $str\n suffix: $suffix")
}
default ?: "ext" default ?: "ext"
} else { } else {
suffix suffix