Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there support of sleep timer? #1544

Closed
akshdeep-singh opened this issue Jul 13, 2024 · 2 comments
Closed

Is there support of sleep timer? #1544

akshdeep-singh opened this issue Jul 13, 2024 · 2 comments
Assignees
Labels

Comments

@akshdeep-singh
Copy link

Most music players have the option of a sleep timer:

  • sleep after N number of songs
  • sleep at specified time

Since, the timer should work in background (MediaSessionService), I wanted to know if media3 supports sleep timers? If not, what is the preferred way for sleep timer to work with MediaSessionService?

@marcbaechinger
Copy link
Contributor

marcbaechinger commented Jul 15, 2024

Most music players have the option of a sleep timer:

An implementation by an app sounds pretty straight-forward to me, where calling stop() or play() would stop or pause the player, which then would take the service out of the foreground which makes the system terminate the service after a given time.

There isn't a way to let the player pause at a given time by API. There are APIs though that can help you do that.

  1. You can calculate from what you put into the playlist and the do
    player.createMessage((messageType, payload)
            -> player.pause())
        .setDeleteAfterDelivery(true)
        .setLooper(player.getApplicationLooper())
        .setPosition(player.getCurrentMediaItemIndex(), positionAtWhichToPause)
        .send();

to pause at the given position.

  1. You may don't know the durations of the items you put into the playlist ahead of time or the user may manipulate this after the timer is set. So you can add an listener that is called each time when the media items changes. I assume your app provides a method getSleepTimerEndMs() that gives us the time in millisecond, at which the sleep timer ends:
@Override
public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
  if (reason != Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) {
    return;
  }
  long nowMs = SystemClock.currentThreadTimeMillis();
  long timeAtWhichCurrentItemEnds = nowMs   player.getDuration();
  long timeAtWhichTimerEnds = getSleepTimerEndTimeMs(); // app knows whether timer is on
  if (timeAtWhichTimerEnds != C.TIME_UNSET && timeAtWhichCurrentItemEnds > timeAtWhichTimerEnds) {
    long positionAtWhichToPause = timeAtWhichTimerEnds - nowMs;
    player
        .createMessage((messageType, payload) -> player.pause())
        .setDeleteAfterDelivery(true)
        .setPosition(player.getCurrentMediaItemIndex(), positionAtWhichToPause)
        .setLooper(player.getApplicationLooper())
        .send();
  }
}

You may want to monitor other events, that cancel, send or update the message in case the user manipulates the player during 'sleeping'.

Keep your message in case the user changes or cancels the timer. The you can call message.cancel().

@debz-eight
Copy link

You can use CountDownTimer and a handler to handle the scenario. I have implemented using the same with 30, 45, 60 mins and an End of Episode sleep timer. When the timer runs out, an onTimerCompleted is called if you use CountDownTimer. Inside the onTimerCompleted, I am simply doing controller.pause() or cotroller.stop() depending use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants