androidx / androidx/media

Media3 ExoPlayer stops playback of audio after phone sleeps

Open
#22 5 comments 0 reactions 1 assignee View on GitHub

@marcbaechinger is already working on this.

Since Dec 16, 2021.

bug
Dominant language
Java
Stars
3k
Forks
955
Avg merge
12d 14h
Merged PRs (30d)
2

Description

Extending MediaLibraryService and setting the wake mode - C.WAKE_MODE_LOCAL, playback stops after the phone goes to sleep.

Player class;

@SuppressLint("UnsafeOptInUsageError")
class MusicPlayerService @Inject constructor(): MediaLibraryService() {

    private lateinit var player: ExoPlayer
    private lateinit var mediaLibrarySession: MediaLibrarySession
    private val librarySessionCallback = CustomMediaLibrarySessionCallback()

    companion object {
        val TAG: String = MusicPlayerService::class.java.simpleName
        const val PLAY = 0
        const val PLAY_NEXT = 1
        const val ADD_TO_QUEUE = 2
    }

    override fun onCreate() {
        super.onCreate()
        initializeSessionAndPlayer()
    }

    override fun onDestroy() {
        player.release()
        mediaLibrarySession.release()
        super.onDestroy()
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaLibrarySession {
        return mediaLibrarySession
    }

    // https://www.youtube.com/watch?v=sTIBDcyCmCg
    private fun initializeSessionAndPlayer() {
        player = Builder(this)
            .setAudioAttributes(AudioAttributes.DEFAULT, true)
            .setHandleAudioBecomingNoisy(true)
            .setWakeMode(C.WAKE_MODE_LOCAL)
            .build()

        mediaLibrarySession =
            MediaLibrarySession.Builder(this, player, librarySessionCallback)
                .setMediaItemFiller(CustomMediaItemFiller())
                .setId("1")
                .build()
    }

    private inner class CustomMediaLibrarySessionCallback :
        MediaLibrarySession.MediaLibrarySessionCallback

    inner class CustomMediaItemFiller : MediaSession.MediaItemFiller {
        override fun fillInLocalConfiguration(
            session: MediaSession,
            controller: MediaSession.ControllerInfo,
            mediaItem: MediaItem
        ): MediaItem {
            // Return the media item that it will be played
            return mediaItem.buildUpon()
                .setMediaId(mediaItem.mediaId)
                .setUri(mediaItem.mediaMetadata.mediaUri)
                .setMediaMetadata(mediaItem.mediaMetadata)
                .build()
        }
    }
}

initialised from a fragment;


@AndroidEntryPoint
class ExoplayerFragment @Inject constructor() :
    BaseAudioFragment(),
    View.OnClickListener {

   override fun onStart() {
        initializeController()
        super.onStart()
    }

    override fun onStop() {
        super.onStop()
        releaseController()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mDisposable.dispose()
        bottomSheetFragment = null
    }

    override fun onDestroy() {
        super.onDestroy()
        if (!mDisposable.isDisposed) {
            mDisposable.dispose()
        }
    }

    @androidx.annotation.OptIn(UnstableApi::class)
    private fun initializeController() {
        val sessionToken = SessionToken(
            requireContext(),
            ComponentName(requireContext(), MusicPlayerService::class.java)
        )
        controllerFuture =
            MediaController.Builder(
                requireContext(),
                sessionToken
            ).buildAsync()

        controllerFuture.addListener({ setController() }, MoreExecutors.directExecutor())
    }

    private fun releaseController() {
        MediaController.releaseFuture(controllerFuture)
    }
 ...
}

In android manifest included both;

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.