Skip to content

Commit

Permalink
Merge pull request #359 from THEOplayer/feature/mediaservice_improvem…
Browse files Browse the repository at this point in the history
…ents

Feature/mediaservice improvements
  • Loading branch information
tvanlaerhoven authored Aug 9, 2024
2 parents ceb1ca1 + e8607cb commit 60353e3
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 63 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added the fast-forward & rewind buttons for the Android notification when `mediaControl.mediaSessionEnabled` is set to `true`.
- Added a `mediaControl.convertSkipToSeek` player config property to allow seeking with the `NEXT` and `PREVIOUS` media buttons. Its default value is `false`.

### Fixed

- Fixed an issue on Android where the notification would not disappear when setting an undefined source.

### Changed

- Replaced the `MediaBrowserService` with a regular `Service` to facilitate background playback on Android.

## [7.7.1] - 24-07-29

### Fixed
Expand Down
11 changes: 0 additions & 11 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,8 @@
android:exported="false"
android:enabled="true"
android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</service>

<receiver android:name="androidx.media.session.MediaButtonReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>

</application>

</manifest>
58 changes: 6 additions & 52 deletions android/src/main/java/com/theoplayer/media/MediaPlaybackService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,26 @@ import android.content.pm.ServiceInfo
import android.graphics.Bitmap
import android.os.Binder
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import android.text.TextUtils
import android.util.Log
import androidx.core.app.ServiceCompat
import androidx.core.content.ContextCompat
import androidx.media.MediaBrowserServiceCompat
import androidx.media.session.MediaButtonReceiver
import com.theoplayer.BuildConfig
import com.theoplayer.ReactTHEOplayerContext
import com.theoplayer.android.api.player.Player
import com.theoplayer.android.connector.mediasession.MediaSessionConnector
import com.theoplayer.android.connector.mediasession.MediaSessionListener

private const val BROWSABLE_ROOT = "/"
private const val EMPTY_ROOT = "@empty@"
private const val STOP_SERVICE_IF_APP_REMOVED = true

private const val NOTIFICATION_ID = 1

private const val TAG = "MediaPlaybackService"

class MediaPlaybackService : MediaBrowserServiceCompat() {
class MediaPlaybackService : Service() {

private lateinit var notificationManager: NotificationManager
private lateinit var notificationBuilder: MediaNotificationBuilder
Expand Down Expand Up @@ -175,9 +169,6 @@ class MediaPlaybackService : MediaBrowserServiceCompat() {
// Set mediaSession active
setActive(BuildConfig.EXTENSION_MEDIASESSION)
}

// Set the MediaBrowserServiceCompat's media session.
sessionToken = mediaSession.sessionToken
}

private fun stopForegroundService() {
Expand Down Expand Up @@ -208,53 +199,16 @@ class MediaPlaybackService : MediaBrowserServiceCompat() {
mediaSessionConnector.removeListener(mediaSessionListener)
}

override fun onGetRoot(
clientPackageName: String,
clientUid: Int,
rootHints: Bundle?
): BrowserRoot {
// (Optional) Control the level of access for the specified package name.
// You'll need to write your own logic to do this.
return if (allowBrowsing(clientPackageName, clientUid)) {
// Returns a root ID that clients can use with onLoadChildren() to retrieve
// the content hierarchy.
BrowserRoot(BROWSABLE_ROOT, null)
} else {
// Clients can connect, but this BrowserRoot is an empty hierachy
// so onLoadChildren returns nothing. This disables the ability to browse for content.
BrowserRoot(EMPTY_ROOT, null)
}
}

@Suppress("UNUSED_PARAMETER")
private fun allowBrowsing(clientPackageName: String, clientUid: Int): Boolean {
// Only allow browsing from the same package
return TextUtils.equals(clientPackageName, packageName)
}

override fun onLoadChildren(
parentId: String,
result: Result<List<MediaBrowserCompat.MediaItem>>
) {
if (parentId == EMPTY_ROOT) {
result.sendResult(null)
return
}
result.sendResult(emptyList())
}

private fun updateNotification() {
player?.let {
if (it.isPaused) {
updateNotification(PlaybackStateCompat.STATE_PAUSED)
} else {
updateNotification(PlaybackStateCompat.STATE_PLAYING)
}
val player = player
when {
player?.source == null -> updateNotification(PlaybackStateCompat.STATE_STOPPED)
!player.isPaused -> updateNotification(PlaybackStateCompat.STATE_PLAYING)
else -> updateNotification(PlaybackStateCompat.STATE_PAUSED)
}
}

private fun updateNotification(@PlaybackStateCompat.State playbackState: Int) {

// When a service is playing, it should be running in the foreground.
// This lets the system know that the service is performing a useful function and should
// not be killed if the system is low on memory.
Expand Down

0 comments on commit 60353e3

Please sign in to comment.