Horis 2 anos atrás
pai
commit
933bb54603

+ 47 - 7
app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

@@ -15,6 +15,7 @@ import androidx.media3.datasource.cache.CacheDataSink
 import androidx.media3.datasource.cache.CacheDataSource
 import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
 import androidx.media3.datasource.cache.SimpleCache
+import androidx.media3.exoplayer.DefaultLoadControl
 import androidx.media3.exoplayer.ExoPlayer
 import androidx.media3.exoplayer.offline.DefaultDownloaderFactory
 import androidx.media3.exoplayer.offline.DownloadRequest
@@ -47,6 +48,7 @@ import kotlinx.coroutines.Job
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.ensureActive
+import kotlinx.coroutines.isActive
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.sync.Mutex
@@ -66,9 +68,10 @@ import kotlin.coroutines.coroutineContext
 @SuppressLint("UnsafeOptInUsageError")
 class HttpReadAloudService : BaseReadAloudService(),
     Player.Listener {
-
     private val exoPlayer: ExoPlayer by lazy {
-        ExoPlayer.Builder(this).build()
+        ExoPlayer.Builder(this)
+            .setLoadControl(CustomLoadControl())
+            .build()
     }
     private val ttsFolderPath: String by lazy {
         cacheDir.absolutePath + File.separator + "httpTTS" + File.separator
@@ -85,11 +88,7 @@ class HttpReadAloudService : BaseReadAloudService(),
             .setCache(cache)
     }
     private val loadErrorHandlingPolicy by lazy {
-        object : DefaultLoadErrorHandlingPolicy(0) {
-            override fun getRetryDelayMsFor(loadErrorInfo: LoadErrorHandlingPolicy.LoadErrorInfo): Long {
-                return C.TIME_UNSET
-            }
-        }
+        CustomLoadErrorHandlingPolicy()
     }
     private var speechRate: Int = AppConfig.speechRatePlay + 5
     private var downloadTask: Coroutine<*>? = null
@@ -97,10 +96,24 @@ class HttpReadAloudService : BaseReadAloudService(),
     private var downloadErrorNo: Int = 0
     private var playErrorNo = 0
     private val downloadTaskActiveLock = Mutex()
+    private var bufferedPercentage = 0
 
     override fun onCreate() {
         super.onCreate()
         exoPlayer.addListener(this)
+        initBufferedPercentageUpdate()
+    }
+
+    private fun initBufferedPercentageUpdate() {
+        lifecycleScope.launch {
+            while (isActive) {
+                bufferedPercentage = exoPlayer.bufferedPercentage
+                when (exoPlayer.playbackState) {
+                    Player.STATE_BUFFERING -> delay(10)
+                    else -> delay(1000)
+                }
+            }
+        }
     }
 
     override fun onDestroy() {
@@ -575,4 +588,31 @@ class HttpReadAloudService : BaseReadAloudService(),
     override fun aloudServicePendingIntent(actionStr: String): PendingIntent? {
         return servicePendingIntent<HttpReadAloudService>(actionStr)
     }
+
+    inner class CustomLoadErrorHandlingPolicy : DefaultLoadErrorHandlingPolicy(0) {
+        override fun getRetryDelayMsFor(loadErrorInfo: LoadErrorHandlingPolicy.LoadErrorInfo): Long {
+            return C.TIME_UNSET
+        }
+    }
+
+    inner class CustomLoadControl : DefaultLoadControl() {
+        override fun shouldStartPlayback(
+            timeline: Timeline,
+            mediaPeriodId: MediaSource.MediaPeriodId,
+            bufferedDurationUs: Long,
+            playbackSpeed: Float,
+            rebuffering: Boolean,
+            targetLiveOffsetUs: Long
+        ): Boolean {
+            return super.shouldStartPlayback(
+                timeline,
+                mediaPeriodId,
+                bufferedDurationUs,
+                playbackSpeed,
+                rebuffering,
+                targetLiveOffsetUs
+            ) || bufferedPercentage == 100
+        }
+    }
+
 }