Skip to content

Commit 2ea3254

Browse files
dev: refactor playbackmode
1 parent 679caa2 commit 2ea3254

8 files changed

Lines changed: 29 additions & 58 deletions

File tree

android/src/main/kotlin/project/pipepipe/app/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ class MainActivity : ComponentActivity() {
511511
when (minimizeSetting) {
512512
"minimize_on_exit_background_key" -> {
513513
// Minimize to background player
514-
SharedContext.platformMediaController?.setPlaybackMode(PlaybackMode.AUDIO_ONLY)
514+
SharedContext.updatePlaybackMode(PlaybackMode.AUDIO_ONLY)
515515
}
516516

517517
"minimize_on_exit_popup_key" -> {

android/src/main/kotlin/project/pipepipe/app/platform/AndroidActions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class AndroidActions(
7070
MainScope().launch {
7171
SharedContext.sharedVideoDetailViewModel.loadVideoDetails(streamInfo.url, streamInfo.serviceId)
7272
SharedContext.enterPipmode()
73-
SharedContext.platformMediaController?.setPlaybackMode(PlaybackMode.VIDEO_AUDIO)
73+
SharedContext.updatePlaybackMode(PlaybackMode.VIDEO_AUDIO)
7474
SharedContext.platformMediaController?.playFromStreamInfo(streamInfo)
7575
SharedContext.sharedVideoDetailViewModel.showAsFullscreenPlayer()
7676
activity.enterPipMode(streamInfo.isPortrait)

android/src/main/kotlin/project/pipepipe/app/platform/AndroidMediaController.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,16 @@ class AndroidMediaController(
285285

286286
// ===== Business Operations =====
287287

288-
override fun setPlaybackMode(mode: PlaybackMode) {
289-
mediaController.sendCustomCommand(
290-
PlaybackService.CustomCommands.buildSetPlaybackModeCommand(mode),
291-
Bundle.EMPTY
292-
)
288+
override fun applyPlaybackMode(mode: PlaybackMode) {
289+
val disableVideo = (mode == PlaybackMode.AUDIO_ONLY)
290+
val params = mediaController.trackSelectionParameters
291+
.buildUpon()
292+
.setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, disableVideo)
293+
.build()
294+
mediaController.trackSelectionParameters = params
295+
if (!disableVideo && mediaController.currentMediaItem != null && mediaController.isPlaying) {
296+
mediaController.seekTo(mediaController.currentMediaItemIndex, mediaController.currentPosition)
297+
}
293298
}
294299

295300
override fun setPlaybackParameters(speed: Float, pitch: Float) {

android/src/main/kotlin/project/pipepipe/app/service/PlaybackService.kt

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,11 @@ class PlaybackService : MediaLibraryService() {
125125
}
126126

127127
object CustomCommands {
128-
const val ACTION_SET_PLAYBACK_MODE = "project.pipepipe.app.action.SET_PLAYBACK_MODE"
129128
const val ARG_MODE = "mode"
130-
131129
const val ACTION_STOP_SERVICE = "project.pipepipe.app.action.STOP_SERVICE"
132130
val STOP_SERVICE_COMMAND = SessionCommand(ACTION_STOP_SERVICE, Bundle.EMPTY)
133131
const val ACTION_CHANGE_REPEAT_MODE = "project.pipepipe.app.action.CHANGE_REPEAT_MODE"
134132
val CHANGE_REPEAT_MODE_COMMAND = SessionCommand(ACTION_CHANGE_REPEAT_MODE, Bundle.EMPTY)
135-
136-
fun buildSetPlaybackModeCommand(mode: PlaybackMode): SessionCommand {
137-
val args = Bundle().apply { putString(ARG_MODE, mode.name) }
138-
return SessionCommand(ACTION_SET_PLAYBACK_MODE, args)
139-
}
140133
}
141134

142135
override fun onCreate() {
@@ -231,7 +224,6 @@ class PlaybackService : MediaLibraryService() {
231224
): MediaSession.ConnectionResult {
232225
// Use DEFAULT_SESSION_AND_LIBRARY_COMMANDS to allow library browsing (Android Auto)
233226
val availableSessionCommands = MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
234-
.add(SessionCommand(CustomCommands.ACTION_SET_PLAYBACK_MODE, Bundle.EMPTY))
235227
.add(CustomCommands.STOP_SERVICE_COMMAND)
236228
.add(CustomCommands.CHANGE_REPEAT_MODE_COMMAND)
237229
.build()
@@ -428,14 +420,6 @@ class PlaybackService : MediaLibraryService() {
428420
.setMediaButtonPreferences(mediaButtonPreferences)
429421
.build()
430422

431-
applyPlaybackMode(playbackMode.value)
432-
433-
// Monitor playbackMode changes
434-
serviceScope.launch {
435-
playbackMode.collect { mode ->
436-
applyPlaybackMode(mode)
437-
}
438-
}
439423

440424
// Monitor skip silence setting changes
441425
skipSilenceListener = SharedContext.settingsManager.addBooleanListener(
@@ -525,17 +509,6 @@ class PlaybackService : MediaLibraryService() {
525509
args: Bundle
526510
): SessionResult {
527511
return when (command.customAction) {
528-
CustomCommands.ACTION_SET_PLAYBACK_MODE -> {
529-
val modeName = command.customExtras.getString(CustomCommands.ARG_MODE)
530-
val mode = runCatching { PlaybackMode.valueOf(modeName ?: "") }.getOrNull()
531-
if (mode != null) {
532-
SharedContext.updatePlaybackMode(mode)
533-
// applyPlaybackMode will be called automatically by the Flow collector
534-
SessionResult(SessionResult.RESULT_SUCCESS)
535-
} else {
536-
SessionResult(SessionError.ERROR_BAD_VALUE)
537-
}
538-
}
539512
CustomCommands.ACTION_STOP_SERVICE -> {
540513
saveCurrentProgress()
541514
player.stop()
@@ -588,22 +561,7 @@ class PlaybackService : MediaLibraryService() {
588561
}
589562
}
590563

591-
private fun applyPlaybackMode(mode: PlaybackMode) {
592-
val disableVideo = (mode == PlaybackMode.AUDIO_ONLY)
593-
if (disableVideo && SharedContext.sharedVideoDetailViewModel.uiState.value.pageState == VideoDetailPageState.FULLSCREEN_PLAYER) {
594-
// for unknown reason, sometimes switching from detail page -> fullscreen will cause video track disabled but playback mode still video_audio
595-
// hopefully this check should prevent it.
596-
return
597-
}
598-
val params = player.trackSelectionParameters
599-
.buildUpon()
600-
.setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, disableVideo)
601-
.build()
602-
player.trackSelectionParameters = params
603-
if (!disableVideo && player.currentMediaItem != null && player.isPlaying) {
604-
player.seekTo(player.currentMediaItemIndex, player.currentPosition)
605-
}
606-
}
564+
607565

608566
private fun buildSessionActivity(): PendingIntent {
609567
val intent = Intent(this, Class.forName("project.pipepipe.app.MainActivity"))

library/src/commonMain/kotlin/project/pipepipe/app/SharedContext.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ package project.pipepipe.app
33
import androidx.navigation.NavHostController
44
import com.fasterxml.jackson.databind.ObjectMapper
55
import kotlinx.coroutines.Dispatchers
6+
import kotlinx.coroutines.MainScope
67
import kotlinx.coroutines.flow.MutableSharedFlow
78
import kotlinx.coroutines.flow.MutableStateFlow
89
import kotlinx.coroutines.flow.SharedFlow
910
import kotlinx.coroutines.flow.StateFlow
1011
import kotlinx.coroutines.flow.asSharedFlow
1112
import kotlinx.coroutines.flow.asStateFlow
13+
import kotlinx.coroutines.launch
14+
import kotlinx.coroutines.runBlocking
1215
import kotlinx.coroutines.withContext
1316
import kotlinx.serialization.json.Json
1417
import project.pipepipe.database.AppDatabase
@@ -69,7 +72,12 @@ object SharedContext {
6972
val playbackMode: StateFlow<PlaybackMode> = _playbackMode.asStateFlow()
7073

7174
fun updatePlaybackMode(mode: PlaybackMode) {
72-
_playbackMode.value = mode
75+
runBlocking {
76+
MainScope().launch {
77+
platformMediaController!!.applyPlaybackMode(mode)
78+
_playbackMode.value = mode
79+
}
80+
}
7381
}
7482

7583
private val _playQueueVisibility = MutableStateFlow(false)

library/src/commonMain/kotlin/project/pipepipe/app/platform/PlatformMediaController.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ interface PlatformMediaController {
123123

124124
fun release()
125125

126-
fun setPlaybackMode(mode: PlaybackMode)
126+
fun applyPlaybackMode(mode: PlaybackMode)
127127

128128
fun playFromStreamInfo(streamInfo: StreamInfo)
129129

@@ -133,7 +133,7 @@ interface PlatformMediaController {
133133
}
134134

135135
fun backgroundPlay(streamInfo: StreamInfo) {
136-
setPlaybackMode(PlaybackMode.AUDIO_ONLY)
136+
SharedContext.updatePlaybackMode(PlaybackMode.AUDIO_ONLY)
137137
playFromStreamInfo(streamInfo)
138138
}
139139

@@ -149,7 +149,7 @@ interface PlatformMediaController {
149149

150150
fun playAll(items: List<StreamInfo>, startIndex: Int, shuffle: Boolean) {
151151
MainScope().launch {
152-
setPlaybackMode(PlaybackMode.AUDIO_ONLY)
152+
SharedContext.updatePlaybackMode(PlaybackMode.AUDIO_ONLY)
153153
// Save items to database
154154
GlobalScope.launch {
155155
items.forEach { item ->

library/src/commonMain/kotlin/project/pipepipe/app/ui/component/player/VideoPlayer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ fun VideoPlayer(
421421
modifier = Modifier
422422
.fillMaxSize()
423423
.clickable {
424-
mediaController.setPlaybackMode(PlaybackMode.VIDEO_AUDIO)
424+
SharedContext.updatePlaybackMode(PlaybackMode.VIDEO_AUDIO)
425425
mediaController.playFromStreamInfo(streamInfo)
426426
if (SharedContext.settingsManager.getBoolean("start_main_player_fullscreen_key")) {
427427
SharedContext.sharedVideoDetailViewModel.toggleFullscreenPlayer()

library/src/commonMain/kotlin/project/pipepipe/app/ui/screens/videodetail/VideoDetailScreen.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ fun VideoDetailScreen(modifier: Modifier, navController: NavHostController) {
141141
// Resume video playback
142142
kotlinx.coroutines.delay(500) // don't use a small value, this will interfere the animation
143143
controller?.let {
144-
controller.setPlaybackMode(PlaybackMode.VIDEO_AUDIO)
144+
SharedContext.updatePlaybackMode(PlaybackMode.VIDEO_AUDIO)
145145
if (controller.currentMediaItem.value?.mediaId == streamInfo.url && controller.isPlaying.value) {
146146
controller.playFromStreamInfo(streamInfo)
147147
}
@@ -159,7 +159,7 @@ fun VideoDetailScreen(modifier: Modifier, navController: NavHostController) {
159159

160160
if (shouldAutoPlay) {
161161
controller?.let {
162-
controller.setPlaybackMode(PlaybackMode.VIDEO_AUDIO)
162+
SharedContext.updatePlaybackMode(PlaybackMode.VIDEO_AUDIO)
163163
if (controller.currentMediaItem.value?.mediaId != streamInfo.url) {
164164
controller.playFromStreamInfo(streamInfo)
165165
} else if (!controller.isPlaying.value) {
@@ -538,7 +538,7 @@ fun VideoDetailScreen(modifier: Modifier, navController: NavHostController) {
538538
item {
539539
ActionButtons(
540540
onPlayAudioClick = {
541-
controller.setPlaybackMode(PlaybackMode.AUDIO_ONLY)
541+
SharedContext.updatePlaybackMode(PlaybackMode.AUDIO_ONLY)
542542
if (controller.currentMediaItem.value?.mediaId != streamInfo.url) {
543543
controller.playFromStreamInfo(streamInfo)
544544
} else if (!controller.isPlaying.value) {

0 commit comments

Comments
 (0)