优化
This commit is contained in:
@@ -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 = dataSpec.length
|
||||||
bytesRemaining = inputStream.available().toLong()
|
|
||||||
if (bytesRemaining == 0L) bytesRemaining = C.LENGTH_UNSET.toLong()
|
|
||||||
} else {
|
|
||||||
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)) {
|
||||||
AppLog.put("Cannot find legal suffix:\n target: $str\n suffix: $suffix")
|
if (default == null) {
|
||||||
|
AppLog.put("Cannot find legal suffix:\n target: $str\n suffix: $suffix")
|
||||||
|
}
|
||||||
default ?: "ext"
|
default ?: "ext"
|
||||||
} else {
|
} else {
|
||||||
suffix
|
suffix
|
||||||
|
|||||||
Reference in New Issue
Block a user