Horis il y a 3 ans
Parent
commit
4344959853
1 fichiers modifiés avec 32 ajouts et 41 suppressions
  1. 32 41
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

+ 32 - 41
app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

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