增加音频播放模式 (#5227)

* Add files via upload

* Update EventBus.kt

* Update strings.xml

* Update activity_audio_play.xml

* Update AudioPlay.kt

* Update AudioPlayActivity.kt
This commit is contained in:
3harmony
2025-07-03 19:14:01 +08:00
committed by GitHub
parent 4ff7a9aacb
commit 72fa5bcc1a
9 changed files with 145 additions and 10 deletions
@@ -32,4 +32,5 @@ object EventBus {
const val READ_ALOUD_PLAY = "readAloudPlay"
const val EXPORT_BOOK = "exportBook"
const val UP_MANGA_CONFIG = "upMangaConfig"
}
const val PLAY_MODE_CHANGED = "playModeChanged"
}
@@ -31,6 +31,25 @@ import splitties.init.appCtx
@SuppressLint("StaticFieldLeak")
@Suppress("unused")
object AudioPlay : CoroutineScope by MainScope() {
/**
* 播放模式枚举
*/
enum class PlayMode(val iconRes: Int) {
LIST_END_STOP(R.drawable.ic_play_mode_list_end_stop),
SINGLE_LOOP(R.drawable.ic_play_mode_single_loop),
RANDOM(R.drawable.ic_play_mode_random),
LIST_LOOP(R.drawable.ic_play_mode_list_loop);
fun next(): PlayMode {
return when (this) {
LIST_END_STOP -> SINGLE_LOOP
SINGLE_LOOP -> RANDOM
RANDOM -> LIST_LOOP
LIST_LOOP -> LIST_END_STOP
}
}
}
var playMode = PlayMode.LIST_END_STOP
var status = Status.STOP
private var activityContext: Context? = null
private var serviceContext: Context? = null
@@ -48,6 +67,11 @@ object AudioPlay : CoroutineScope by MainScope() {
var bookSource: BookSource? = null
val loadingChapters = arrayListOf<Int>()
fun changePlayMode() {
playMode = playMode.next()
postEvent(EventBus.PLAY_MODE_CHANGED, playMode)
}
fun upData(book: Book) {
AudioPlay.book = book
chapterSize = appDb.bookChapterDao.getChapterCount(book.bookUrl)
@@ -259,12 +283,36 @@ object AudioPlay : CoroutineScope by MainScope() {
fun next() {
stopPlay()
if (durChapterIndex + 1 < simulatedChapterSize) {
durChapterIndex += 1
durChapterPos = 0
durPlayUrl = ""
saveRead()
loadPlayUrl()
when (playMode) {
PlayMode.LIST_END_STOP -> {
if (durChapterIndex + 1 < simulatedChapterSize) {
durChapterIndex += 1
durChapterPos = 0
durPlayUrl = ""
saveRead()
loadPlayUrl()
}
}
PlayMode.SINGLE_LOOP -> {
durChapterPos = 0
durPlayUrl = ""
saveRead()
loadPlayUrl()
}
PlayMode.RANDOM -> {
durChapterIndex = (0 until simulatedChapterSize).random()
durChapterPos = 0
durPlayUrl = ""
saveRead()
loadPlayUrl()
}
PlayMode.LIST_LOOP -> {
durChapterIndex = (durChapterIndex + 1) % simulatedChapterSize
durChapterPos = 0
durPlayUrl = ""
saveRead()
loadPlayUrl()
}
}
}
@@ -367,4 +415,4 @@ object AudioPlay : CoroutineScope by MainScope() {
}
}
}
@@ -65,6 +65,7 @@ class AudioPlayActivity :
override val viewModel by viewModels<AudioPlayViewModel>()
private val timerSliderPopup by lazy { TimerSliderPopup(this) }
private var adjustProgress = false
private var playMode = AudioPlay.PlayMode.LIST_END_STOP
private val progressTimeFormat by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@@ -140,6 +141,15 @@ class AudioPlayActivity :
}
private fun initView() {
binding.ivPlayMode.setOnClickListener {
AudioPlay.changePlayMode()
}
observeEventSticky<AudioPlay.PlayMode>(EventBus.PLAY_MODE_CHANGED) {
playMode = it
updatePlayModeIcon()
}
binding.fabPlayStop.setOnClickListener {
playButton()
}
@@ -187,6 +197,10 @@ class AudioPlayActivity :
binding.llPlayMenu.applyNavigationBarPadding()
}
private fun updatePlayModeIcon() {
binding.ivPlayMode.setImageResource(playMode.iconRes)
}
private fun upCover(path: String?) {
BookCover.load(this, path, sourceOrigin = AudioPlay.bookSource?.bookSourceUrl) {
BookCover.loadBlur(this, path, sourceOrigin = AudioPlay.bookSource?.bookSourceUrl)
@@ -303,4 +317,4 @@ class AudioPlayActivity :
}
}
}
}
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3.196,2.147l0.084,0.073l18.5,18.5a0.75,0.75 0,0,1 -0.976,1.133l-0.084,-0.073l-3.509,-3.508q-0.655,0.18 -1.358,0.219l-0.353,0.009H8.564l1.9,1.9l0.066,0.076a0.75,0.75 0,0,1 -1.043,1.056l-0.084,-0.072l-3.182,-3.182l-0.067,-0.077a0.75,0.75 0,0,1 -0.006,-0.899l0.073,-0.085l3.182,-3.182l0.077,-0.067a0.75,0.75 0,0,1 0.899,-0.006l0.084,0.073l0.068,0.077a0.75,0.75 0,0,1 0.005,0.899l-0.073,0.085L8.558,17H15.5q0.213,0 0.422,-0.017L6.4,7.46a5,5 0,0,0 -1.598,7.904a0.75,0.75 0,1,1 -1.11,1.007A6.47,6.47 0,0,1 2,12a6.5,6.5 0,0,1 3.287,-5.652L2.22,3.28a0.75,0.75 0,0,1 0.976,-1.133" />
<path
android:fillColor="#FF000000"
android:pathData="M19.75,7.378c0.22,0 0.416,0.094 0.553,0.244A6.47,6.47 0,0,1 22,12c0,2.057 -0.955,3.89 -2.446,5.081l-1.069,-1.07A5,5 0,0,0 20.5,12c0,-1.306 -0.5,-2.495 -1.32,-3.386a0.75,0.75 0,0,1 0.57,-1.236m-5.217,-4.975l0.077,0.067l3.182,3.182a0.75,0.75 0,0,1 0.067,0.984l-0.067,0.076l-3.182,3.182a0.75,0.75 0,0,1 -1.128,-0.984l0.068,-0.076L15.38,7H9.473l-1.48,-1.48a7,7 0,0,1 0.274,-0.016L8.5,5.5h7.021L13.55,3.53a0.75,0.75 0,0,1 -0.067,-0.984l0.068,-0.076a0.75,0.75 0,0,1 0.983,-0.067" />
</vector>
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="m14.61 2.47l-0.077-0.067a0.75 0.75 0 0 0-0.983 0.067l-0.068 0.078a0.755 0.755 0 0 0 0.068 0.987l1.971 1.977H8.5l-0.233 0.004C4.785 5.639 2 8.51 2 12.036c0 1.69 0.64 3.23 1.692 4.39l0.072 0.069a0.751 0.751 0 0 0 1.08-1.033l-0.2-0.231A5 5 0 0 1 3.5 12.035c0-2.771 2.239-5.018 5-5.018h6.881l-1.832 1.84l-0.067 0.078a0.755 0.755 0 0 0 0.068 0.987a0.75 0.75 0 0 0 1.06 0l3.182-3.193l0.067-0.078a0.755 0.755 0 0 0-0.067-0.987" />
<path
android:fillColor="#FF000000"
android:pathData="M20.23,7.571a0.751,0.751 0 0 0-1.05 1.066a5 5 0 0 1 1.32 3.398c0 2.772-2.239 5.019-5 5.019H8.558l1.905-1.911l0.074-0.086a0.755 0.755 0 0 0-0.007-0.902l-0.067-0.077l-0.084-0.073a0.75 0.75 0 0 0-0.9 0.006l-0.076 0.067l-3.182 3.194l-0.073 0.085a0.755 0.755 0 0 0 0.006 0.902l0.067 0.077l3.182 3.194l0.084 0.072c0.293 0.22 0.71 0.195 0.976-0.073a0.755 0.755 0 0 0 0.068-0.987l-0.068-0.077l-1.899-1.906H15.5l0.233-0.004C19.215 18.432 22 15.56 22 12.035a6.5 6.5 0 0 0-1.697-4.395z"/>
</vector>
@@ -0,0 +1,15 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19.207,4.293a1,1 0,1,0 -1.414,1.414l0.801,0.802c-3.809,0.161 -6.169,2.59 -8.226,4.706l-0.085,0.088C8.057,13.593 6.147,15.5 3,15.5a1,1 0,1,0 0,2c4.05,0 6.503,-2.525 8.632,-4.715l0.085,-0.088c2.124,-2.184 3.96,-4.02 6.857,-4.185l-0.781,0.78a1,1 0,0,0 1.414,1.415l2.5,-2.5a1,1 0,0,0 0,-1.414" />
<path
android:fillColor="#FF000000"
android:pathData="M3,6.5c3.229,0 5.443,1.605 7.287,3.366q-0.295,0.3 -0.574,0.588l-0.147,0.152q-0.349,0.36 -0.68,0.693C7.186,9.68 5.476,8.5 3,8.5a1,1 0,1,1 0,-2" />
<path
android:fillColor="#FF000000"
android:pathData="M18.791,17.584c-3.01,-0.128 -5.115,-1.671 -6.881,-3.357q0.295,-0.3 0.574,-0.589l0.147,-0.151q0.349,-0.36 0.68,-0.693c1.601,1.524 3.21,2.66 5.46,2.787l-0.781,-0.78a1,1 0,0,1 1.414,-1.415l2.5,2.5a1,1 0,0,1 0,1.414l-2.5,2.5a1,1 0,0,1 -1.414,-1.414" />
</vector>
@@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="m14.61 2.47l-0.077-0.067a0.75 0.75 0 0 0-0.983 0.067l-0.068 0.078a0.755 0.755 0 0 0 0.068 0.987l1.971 1.977H8.5l-0.233 0.004C4.785 5.639 2 8.51 2 12.036c0 1.69 0.64 3.23 1.692 4.39l0.072 0.069a0.751 0.751 0 0 0 1.08-1.033l-0.2-0.231A5 5 0 0 1 3.5 12.035c0-2.771 2.239-5.018 5-5.018h6.881l-1.832 1.84l-0.067 0.078a0.755 0.755 0 0 0 0.068 0.987a0.75 0.75 0 0 0 1.06 0l3.182-3.193l0.067-0.078a0.755 0.755 0 0 0-0.067-0.987" />
<path
android:fillColor="#FF000000"
android:pathData="M20.23,7.571a0.751,0.751 0,0,0 -1.05,1.066a5,5 0,0,1 1.31,3.09c0.539,0.28 1.032,0.632 1.47,1.044q0.04,-0.363 0.04,-0.736a6.5,6.5 0,0,0 -1.697,-4.395" />
<path
android:fillColor="#FF000000"
android:pathData="M8.558,17.054h2.457a6.6,6.6 0,0,0 0.07,1.505h-2.52l1.9,1.906l0.066,0.077a0.755,0.755 0,0,1 -0.067,0.987a0.75,0.75 0,0,1 -0.976,0.073l-0.084,-0.073l-3.182,-3.193l-0.067,-0.077a0.755,0.755 0,0,1 -0.006,-0.902l0.073,-0.085l3.182,-3.194l0.077,-0.067a0.75,0.75 0,0,1 0.899,-0.006l0.084,0.073l0.068,0.077a0.755,0.755 0,0,1 0.005,0.902l-0.073,0.085" />
<path
android:fillColor="#FF000000"
android:pathData="M23,17.5a5.5,5.5 0,1,1 -11,0a5.5,5.5 0,0,1 11,0m-4.885,-3.487a0.5,0.5 0,0,0 -0.562,0.263a4.8,4.8 0,0,1 -0.613,0.828c-0.334,0.373 -0.744,0.739 -1.164,0.949a0.5,0.5 0,1,0 0.448,0.894c0.489,-0.244 0.926,-0.616 1.276,-0.977v4.53a0.5,0.5 0,0,0 1,0v-6a0.5,0.5 0,0,0 -0.385,-0.487" />
</vector>
@@ -69,6 +69,20 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar" />
<io.legado.app.ui.widget.image.ImageButton
android:id="@+id/iv_play_mode"
android:layout_width="46dp"
android:layout_height="46dp"
android:background="@drawable/selector_circle_btn_bg"
android:contentDescription="@string/play_mode"
android:padding="5dp"
android:src="@drawable/ic_play_mode_list_end_stop"
android:layout_marginStart="16dp"
app:tint="@color/md_white_1000"
app:layout_constraintBottom_toTopOf="@+id/tv_sub_title"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="ImageContrastCheck" />
<TextView
android:id="@+id/tv_sub_title"
android:layout_width="match_parent"
@@ -250,4 +264,4 @@
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+1
View File
@@ -1227,4 +1227,5 @@
<string name="manga_epaper_value">阈值</string>
<string name="disable_horizontal_animation">禁用水平滚动动画</string>
<string name="enable_manga_gray">开启图片灰色</string>
<string name="play_mode">播放模式</string>
</resources>