Horis 2 lat temu
rodzic
commit
ee086c7875

+ 1 - 0
app/src/main/java/io/legado/app/constant/IntentAction.kt

@@ -4,6 +4,7 @@ package io.legado.app.constant
 object IntentAction {
     const val start = "start"
     const val play = "play"
+    const val playNew = "playNew"
     const val stop = "stop"
     const val resume = "resume"
     const val pause = "pause"

+ 8 - 0
app/src/main/java/io/legado/app/data/entities/Book.kt

@@ -288,6 +288,14 @@ data class Book(
         return appDb.bookSourceDao.getBookSource(origin)
     }
 
+    fun getChapter(index: Int): BookChapter? {
+        return appDb.bookChapterDao.getChapter(bookUrl, index)
+    }
+
+    fun getDurChapter(): BookChapter? {
+        return getChapter(durChapterIndex)
+    }
+
     fun isLocalModified(): Boolean {
         return isLocal && LocalBook.getLastModified(this).getOrDefault(0L) > latestChapterTime
     }

+ 4 - 4
app/src/main/java/io/legado/app/data/entities/ReplaceRule.kt

@@ -97,10 +97,10 @@ data class ReplaceRule(
                 AppLog.put("正则语法错误或不支持:${ex.localizedMessage}", ex)
                 return false
             }
-        }
-        // Pattern.compile测试通过,但是部分情况下会替换超时,报错,一般发生在修改表达式时漏删了
-        if (pattern.endsWith('|') and !pattern.endsWith("\\|")) {
-            return false
+            // Pattern.compile测试通过,但是部分情况下会替换超时,报错,一般发生在修改表达式时漏删了
+            if (pattern.endsWith('|') && !pattern.endsWith("\\|")) {
+                return false
+            }
         }
         return true
     }

+ 39 - 4
app/src/main/java/io/legado/app/model/AudioPlay.kt

@@ -27,9 +27,25 @@ object AudioPlay {
     var inBookshelf = false
     var bookSource: BookSource? = null
     val loadingChapters = arrayListOf<Int>()
+    var durChapterIndex = 0
+
+    fun upData(context: Context, book: Book) {
+        AudioPlay.book = book
+        upDurChapter(book)
+        if (durChapterIndex != book.durChapterIndex) {
+            durChapterIndex = book.durChapterIndex
+            playNew(context)
+        }
+    }
 
-    fun headers(hasLoginHeader: Boolean): Map<String, String>? {
-        return bookSource?.getHeaderMap(hasLoginHeader)
+    fun resetData(context: Context, book: Book) {
+        stop(context)
+        AudioPlay.book = book
+        titleData.postValue(book.name)
+        coverData.postValue(book.getDisplayCover())
+        bookSource = book.getBookSource()
+        durChapterIndex = book.durChapterIndex
+        upDurChapter(book)
     }
 
     /**
@@ -48,11 +64,27 @@ object AudioPlay {
         }
     }
 
+    /**
+     * 从头播放新章节
+     */
+    fun playNew(context: Context) {
+        book?.let {
+            if (durChapter == null) {
+                upDurChapter(it)
+            }
+            durChapter?.let {
+                context.startService<AudioPlayService> {
+                    action = IntentAction.playNew
+                }
+            }
+        }
+    }
+
     /**
      * 更新当前章节
      */
     fun upDurChapter(book: Book) {
-        durChapter = appDb.bookChapterDao.getChapter(book.bookUrl, book.durChapterIndex)
+        durChapter = book.getDurChapter()
         postEvent(EventBus.AUDIO_SUB_TITLE, durChapter?.title ?: "")
         postEvent(EventBus.AUDIO_SIZE, durChapter?.end?.toInt() ?: 0)
         postEvent(EventBus.AUDIO_PROGRESS, book.durChapterPos)
@@ -105,9 +137,10 @@ object AudioPlay {
             book?.let { book ->
                 book.durChapterIndex = index
                 book.durChapterPos = 0
+                durChapterIndex = book.durChapterIndex
                 durChapter = null
                 saveRead()
-                play(context)
+                playNew(context)
             }
         }
     }
@@ -118,6 +151,7 @@ object AudioPlay {
                 if (book.durChapterIndex > 0) {
                     book.durChapterIndex -= 1
                     book.durChapterPos = 0
+                    durChapterIndex = book.durChapterIndex
                     durChapter = null
                     saveRead()
                     play(context)
@@ -133,6 +167,7 @@ object AudioPlay {
             if (book.durChapterIndex + 1 < book.totalChapterNum) {
                 book.durChapterIndex += 1
                 book.durChapterPos = 0
+                durChapterIndex = book.durChapterIndex
                 durChapter = null
                 saveRead()
                 play(context)

+ 10 - 2
app/src/main/java/io/legado/app/service/AudioPlayService.kt

@@ -144,11 +144,20 @@ class AudioPlayService : BaseService(),
             when (action) {
                 IntentAction.play -> {
                     exoPlayer.stop()
+                    upPlayProgressJob?.cancel()
                     pause = false
                     position = AudioPlay.book?.durChapterPos ?: 0
                     loadContent()
                 }
 
+                IntentAction.playNew -> {
+                    exoPlayer.stop()
+                    upPlayProgressJob?.cancel()
+                    pause = false
+                    position = 0
+                    loadContent()
+                }
+
                 IntentAction.pause -> pause()
                 IntentAction.resume -> resume()
                 IntentAction.prev -> AudioPlay.prev(this)
@@ -160,7 +169,7 @@ class AudioPlayService : BaseService(),
                     adjustProgress(intent.getIntExtra("position", position))
                 }
 
-                else -> stopSelf()
+                IntentAction.stop -> stopSelf()
             }
         }
         return super.onStartCommand(intent, flags, startId)
@@ -204,7 +213,6 @@ class AudioPlayService : BaseService(),
                 source = AudioPlay.bookSource,
                 ruleData = AudioPlay.book,
                 chapter = AudioPlay.durChapter,
-                headerMapF = AudioPlay.headers(true),
             )
             exoPlayer.setMediaItem(analyzeUrl.getMediaItem())
             exoPlayer.playWhenReady = true

+ 36 - 42
app/src/main/java/io/legado/app/ui/book/audio/AudioPlayViewModel.kt

@@ -2,6 +2,7 @@ package io.legado.app.ui.book.audio
 
 import android.app.Application
 import android.content.Intent
+import androidx.lifecycle.viewModelScope
 import io.legado.app.R
 import io.legado.app.base.BaseViewModel
 import io.legado.app.constant.BookType
@@ -12,70 +13,63 @@ import io.legado.app.data.entities.BookChapter
 import io.legado.app.data.entities.BookSource
 import io.legado.app.help.book.removeType
 import io.legado.app.model.AudioPlay
+import io.legado.app.model.AudioPlay.durChapter
 import io.legado.app.model.webBook.WebBook
 import io.legado.app.utils.postEvent
 import io.legado.app.utils.toastOnUi
-import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Dispatchers.IO
 
 class AudioPlayViewModel(application: Application) : BaseViewModel(application) {
 
     fun initData(intent: Intent) = AudioPlay.apply {
         execute {
-            val bookUrl = intent.getStringExtra("bookUrl")
-            if (bookUrl != null && bookUrl != book?.bookUrl) {
-                stop(context)
-                inBookshelf = intent.getBooleanExtra("inBookshelf", true)
-                book = appDb.bookDao.getBook(bookUrl)
-                book?.let { book ->
-                    titleData.postValue(book.name)
-                    coverData.postValue(book.getDisplayCover())
-                    durChapter = appDb.bookChapterDao.getChapter(book.bookUrl, book.durChapterIndex)
-                    upDurChapter(book)
-                    bookSource = appDb.bookSourceDao.getBookSource(book.origin)
-                    if (durChapter == null) {
-                        if (book.tocUrl.isEmpty()) {
-                            loadBookInfo(book)
-                        } else {
-                            loadChapterList(book)
-                        }
-                    }
-                }
-            }
+            val bookUrl = intent.getStringExtra("bookUrl") ?: return@execute
+            val book = appDb.bookDao.getBook(bookUrl) ?: return@execute
+            inBookshelf = intent.getBooleanExtra("inBookshelf", true)
+            initBook(book)
+        }.onFinally {
             saveRead()
         }
     }
 
-    private fun loadBookInfo(book: Book) {
-        execute {
-            AudioPlay.bookSource?.let {
-                WebBook.getBookInfo(this, it, book)
-                    .onSuccess {
-                        loadChapterList(book)
-                    }
+    private fun initBook(book: Book) {
+        val isSameBook = AudioPlay.book?.bookUrl == book.bookUrl
+        if (isSameBook) {
+            AudioPlay.upData(context, book)
+        } else {
+            AudioPlay.resetData(context, book)
+        }
+        if (durChapter == null) {
+            if (book.tocUrl.isEmpty()) {
+                loadBookInfo(book)
+            } else {
+                loadChapterList(book)
             }
         }
     }
 
+    private fun loadBookInfo(book: Book) {
+        val bookSource = AudioPlay.bookSource ?: return
+        WebBook.getBookInfo(viewModelScope, bookSource, book).onSuccess(IO) {
+            loadChapterList(book)
+        }
+    }
+
     private fun loadChapterList(book: Book) {
-        execute {
-            AudioPlay.bookSource?.let {
-                WebBook.getChapterList(this, it, book)
-                    .onSuccess(Dispatchers.IO) { cList ->
-                        book.save()
-                        appDb.bookChapterDao.insert(*cList.toTypedArray())
-                        AudioPlay.upDurChapter(book)
-                    }.onError {
-                        context.toastOnUi(R.string.error_load_toc)
-                    }
-            }
+        val bookSource = AudioPlay.bookSource ?: return
+        WebBook.getChapterList(viewModelScope, bookSource, book).onSuccess(IO) { cList ->
+            book.save()
+            appDb.bookChapterDao.insert(*cList.toTypedArray())
+            AudioPlay.upDurChapter(book)
+        }.onError {
+            context.toastOnUi(R.string.error_load_toc)
         }
     }
 
     fun upSource() {
         execute {
-            AudioPlay.book?.let { book ->
-                AudioPlay.bookSource = appDb.bookSourceDao.getBookSource(book.origin)
-            }
+            val book = AudioPlay.book ?: return@execute
+            AudioPlay.bookSource = book.getBookSource()
         }
     }