-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathPillarboxMediaSessionService.kt
More file actions
111 lines (104 loc) · 3.64 KB
/
Copy pathPillarboxMediaSessionService.kt
File metadata and controls
111 lines (104 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* Copyright (c) SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
package ch.srgssr.pillarbox.player.session
import android.app.PendingIntent
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import ch.srgssr.pillarbox.player.PillarboxPlayer
import ch.srgssr.pillarbox.player.extension.setHandleAudioFocus
import ch.srgssr.pillarbox.player.utils.PendingIntentUtils
/**
* `PillarboxMediaSessionService` implementation of [MediaSessionService].
* It is the recommended way to make background playback for Android.
*
* It handles only one [MediaSession] with one [PillarboxPlayer].
*
* Usage:
* Add these permissions inside your manifest:
*
* ```xml
* <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
* <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
* ```
*
* And add your `PlaybackService` to the application manifest as follow:
*
* ```xml
* <service
* android:name=".service.DemoMediaSessionService"
* android:exported="true"
* android:stopWithTask="true"
* android:foregroundServiceType="mediaPlayback">
* <intent-filter>
* <action android:name="androidx.media3.session.MediaSessionService" />
* </intent-filter>
* </service>
* ```
*
* Use [PillarboxMediaController.Builder] to connect this Service to a [PillarboxMediaController]:
* ```kotlin
* coroutineScope.launch() {
* val mediaController: PillarboxPlayer = PillarboxMediaController.Builder(application, DemoMediaLibraryService::class.java)
* doSomethingWith(mediaController)
* }
* ...
* mediaController.release() // when the MediaController is no longer needed.
* ```
*/
@Suppress("MemberVisibilityCanBePrivate")
abstract class PillarboxMediaSessionService : MediaSessionService() {
private var mediaSession: PillarboxMediaSession? = null
/**
* Set player to use with this Service.
* @param player [PillarboxPlayer] to link to this service.
* @param mediaSessionCallback The [PillarboxMediaSession.Callback]
* @param sessionId The ID. Must be unique among all sessions per package.
*/
fun setPlayer(
player: PillarboxPlayer,
mediaSessionCallback: PillarboxMediaSession.Callback = PillarboxMediaSession.Callback.Default,
sessionId: String? = null,
) {
if (this.mediaSession == null) {
player.setHandleAudioFocus(true)
mediaSession = PillarboxMediaSession.Builder(this, player).apply {
sessionActivity()?.let {
setSessionActivity(it)
}
setCallback(mediaSessionCallback)
sessionId?.let {
setId(it)
}
}.build()
} else {
mediaSession?.player = player
}
}
/**
* Session activity use with [mediaSession] called when [setPlayer]
*/
open fun sessionActivity(): PendingIntent? = PendingIntentUtils.getDefaultPendingIntent(this)
override fun onDestroy() {
super.onDestroy()
release()
}
/**
* Release the player and the MediaSession.
* The [mediaSession] is set to null after this call
* Called automatically in [onDestroy]
*/
open fun release() {
mediaSession?.run {
player.release()
release()
}
mediaSession = null
}
// Return a MediaSession to link with the MediaController that is making
// this request.
override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? {
return mediaSession?.mediaSession
}
}