优化
This commit is contained in:
@@ -26,13 +26,14 @@ import io.legado.app.utils.printOnDebug
|
|||||||
import io.legado.app.utils.servicePendingIntent
|
import io.legado.app.utils.servicePendingIntent
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.mozilla.javascript.WrappedException
|
import org.mozilla.javascript.WrappedException
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -68,32 +69,22 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
downloadTask?.cancel()
|
downloadTask?.cancel()
|
||||||
exoPlayer.release()
|
exoPlayer.release()
|
||||||
|
Coroutine.async {
|
||||||
|
removeCacheFile()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun play() {
|
override fun play() {
|
||||||
pageChanged = false
|
pageChanged = false
|
||||||
exoPlayer.stop()
|
exoPlayer.stop()
|
||||||
|
exoPlayer.clearMediaItems()
|
||||||
|
if (!requestFocus()) return
|
||||||
if (contentList.isEmpty()) {
|
if (contentList.isEmpty()) {
|
||||||
AppLog.putDebug("朗读列表为空")
|
AppLog.putDebug("朗读列表为空")
|
||||||
ReadBook.readAloud()
|
ReadBook.readAloud()
|
||||||
} else {
|
} else {
|
||||||
super.play()
|
super.play()
|
||||||
kotlin.runCatching {
|
downloadAndPlayAudios()
|
||||||
if (nowSpeak == 0) {
|
|
||||||
downloadAudio()
|
|
||||||
} else {
|
|
||||||
val fileName = md5SpeakFileName(contentList[nowSpeak])
|
|
||||||
val file = getSpeakFileAsMd5(fileName)
|
|
||||||
if (file.exists()) {
|
|
||||||
playAudio(file)
|
|
||||||
} else if (!downloadTaskActiveLock.isLocked) {
|
|
||||||
downloadAudio()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.onFailure {
|
|
||||||
toastOnUi("朗读出错:${it.localizedMessage}")
|
|
||||||
AppLog.put("朗读出错:${it.localizedMessage}", it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,21 +96,20 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
readAloudNumber += contentList[nowSpeak].length + 1
|
readAloudNumber += contentList[nowSpeak].length + 1
|
||||||
if (nowSpeak < contentList.lastIndex) {
|
if (nowSpeak < contentList.lastIndex) {
|
||||||
nowSpeak++
|
nowSpeak++
|
||||||
play()
|
|
||||||
} else {
|
} else {
|
||||||
nextChapter()
|
nextChapter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun downloadAudio() {
|
private fun downloadAndPlayAudios() {
|
||||||
downloadTask?.cancel()
|
downloadTask?.cancel()
|
||||||
downloadTask = execute {
|
downloadTask = execute {
|
||||||
downloadTaskActiveLock.withLock {
|
downloadTaskActiveLock.withLock {
|
||||||
ensureActive()
|
ensureActive()
|
||||||
removeCacheFile()
|
|
||||||
val httpTts = ReadAloud.httpTTS ?: throw NoStackTraceException("tts is null")
|
val httpTts = ReadAloud.httpTTS ?: throw NoStackTraceException("tts is null")
|
||||||
contentList.forEachIndexed { index, content ->
|
contentList.forEachIndexed { index, content ->
|
||||||
ensureActive()
|
ensureActive()
|
||||||
|
if (index < nowSpeak) return@forEachIndexed
|
||||||
val fileName = md5SpeakFileName(content)
|
val fileName = md5SpeakFileName(content)
|
||||||
val speakText = content.replace(AppPattern.notReadAloudRegex, "")
|
val speakText = content.replace(AppPattern.notReadAloudRegex, "")
|
||||||
if (speakText.isEmpty()) {
|
if (speakText.isEmpty()) {
|
||||||
@@ -141,13 +131,19 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
return@execute
|
return@execute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index == nowSpeak) {
|
|
||||||
val file = getSpeakFileAsMd5(fileName)
|
val file = getSpeakFileAsMd5(fileName)
|
||||||
playAudio(file)
|
val mediaItem = MediaItem.fromUri(Uri.fromFile(file))
|
||||||
|
launch(Main) {
|
||||||
|
exoPlayer.addMediaItem(mediaItem)
|
||||||
|
if (!exoPlayer.isPlaying && nowSpeak == index) {
|
||||||
|
exoPlayer.playWhenReady = true
|
||||||
|
exoPlayer.prepare()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.onError(IO) {
|
}
|
||||||
|
}.onError {
|
||||||
|
toastOnUi("朗读出错:${it.localizedMessage}")
|
||||||
AppLog.put("朗读下载出错\n${it.localizedMessage}", it)
|
AppLog.put("朗读下载出错\n${it.localizedMessage}", it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,6 +189,7 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
e.printOnDebug()
|
e.printOnDebug()
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
|
|
||||||
is SocketTimeoutException, is ConnectException -> {
|
is SocketTimeoutException, is ConnectException -> {
|
||||||
downloadErrorNo++
|
downloadErrorNo++
|
||||||
if (downloadErrorNo > 5) {
|
if (downloadErrorNo > 5) {
|
||||||
@@ -202,6 +199,7 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
downloadErrorNo++
|
downloadErrorNo++
|
||||||
val msg = "tts下载错误\n${e.localizedMessage}"
|
val msg = "tts下载错误\n${e.localizedMessage}"
|
||||||
@@ -223,22 +221,6 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
private fun playAudio(file: File) {
|
|
||||||
if (requestFocus()) {
|
|
||||||
launch {
|
|
||||||
kotlin.runCatching {
|
|
||||||
val mediaItem = MediaItem.fromUri(Uri.fromFile(file))
|
|
||||||
exoPlayer.setMediaItem(mediaItem)
|
|
||||||
exoPlayer.playWhenReady = true
|
|
||||||
exoPlayer.prepare()
|
|
||||||
}.onFailure {
|
|
||||||
it.printOnDebug()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun md5SpeakFileName(content: String): String {
|
private fun md5SpeakFileName(content: String): String {
|
||||||
return MD5Utils.md5Encode16(textChapter?.title ?: "") + "_" +
|
return MD5Utils.md5Encode16(textChapter?.title ?: "") + "_" +
|
||||||
MD5Utils.md5Encode16("${ReadAloud.httpTTS?.url}-|-$speechRate-|-$content")
|
MD5Utils.md5Encode16("${ReadAloud.httpTTS?.url}-|-$speechRate-|-$content")
|
||||||
@@ -338,7 +320,7 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
downloadTask?.cancel()
|
downloadTask?.cancel()
|
||||||
exoPlayer.stop()
|
exoPlayer.stop()
|
||||||
speechRate = AppConfig.speechRatePlay + 5
|
speechRate = AppConfig.speechRatePlay + 5
|
||||||
downloadAudio()
|
downloadAndPlayAudios()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPlaybackStateChanged(playbackState: Int) {
|
override fun onPlaybackStateChanged(playbackState: Int) {
|
||||||
@@ -347,15 +329,18 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
Player.STATE_IDLE -> {
|
Player.STATE_IDLE -> {
|
||||||
// 空闲
|
// 空闲
|
||||||
}
|
}
|
||||||
|
|
||||||
Player.STATE_BUFFERING -> {
|
Player.STATE_BUFFERING -> {
|
||||||
// 缓冲中
|
// 缓冲中
|
||||||
}
|
}
|
||||||
|
|
||||||
Player.STATE_READY -> {
|
Player.STATE_READY -> {
|
||||||
// 准备好
|
// 准备好
|
||||||
if (pause) return
|
if (pause) return
|
||||||
exoPlayer.play()
|
exoPlayer.play()
|
||||||
upPlayPos()
|
upPlayPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
Player.STATE_ENDED -> {
|
Player.STATE_ENDED -> {
|
||||||
// 结束
|
// 结束
|
||||||
playErrorNo = 0
|
playErrorNo = 0
|
||||||
@@ -364,6 +349,12 @@ class HttpReadAloudService : BaseReadAloudService(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||||
|
if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED) return
|
||||||
|
upPlayPos()
|
||||||
|
playNext()
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user