1 package com.moiseum.wolnelektury.view.player;
3 import android.content.Context;
4 import android.os.Bundle;
5 import android.support.annotation.NonNull;
6 import android.support.v4.media.MediaBrowserCompat;
7 import android.support.v4.media.MediaMetadataCompat;
8 import android.support.v4.media.session.MediaControllerCompat;
9 import android.support.v4.media.session.MediaSessionCompat;
10 import android.support.v4.media.session.PlaybackStateCompat;
11 import android.util.Log;
13 import com.moiseum.wolnelektury.base.WLApplication;
14 import com.moiseum.wolnelektury.base.mvp.FragmentPresenter;
15 import com.moiseum.wolnelektury.connection.models.BookDetailsModel;
16 import com.moiseum.wolnelektury.connection.models.BookModel;
17 import com.moiseum.wolnelektury.storage.BookStorage;
18 import com.moiseum.wolnelektury.view.player.service.AudiobookLibrary;
19 import com.moiseum.wolnelektury.view.player.service.AudiobookService;
20 import com.moiseum.wolnelektury.view.player.service.MediaBrowserHelper;
22 import java.util.List;
23 import java.util.Locale;
26 * Created by Piotr Ostrowski on 22.05.2018.
28 public class PlayerPresenter extends FragmentPresenter<PlayerView> {
30 private final BookDetailsModel book;
31 private final BookModel storedBook;
33 private final BookStorage storage = WLApplication.getInstance().getBookStorage();
34 private MediaBrowserHelper mMediaBrowserHelper;
35 private boolean mIsPlaying;
38 * Customize the connection to our {@link android.support.v4.media.MediaBrowserServiceCompat}
39 * and implement our app specific desires.
41 private class MediaBrowserConnection extends MediaBrowserHelper {
42 private MediaBrowserConnection(Context context) {
43 super(context, AudiobookService.class);
47 protected void onChildrenLoaded(@NonNull String parentId,
48 @NonNull List<MediaBrowserCompat.MediaItem> children) {
49 super.onChildrenLoaded(parentId, children);
51 final MediaControllerCompat mediaController = getMediaController();
52 mediaController.getTransportControls().sendCustomAction(AudiobookService.ACTION_CLEAR_PLAYLIST, null);
54 AudiobookLibrary.createAudiobookMetadata(book);
55 for (final MediaBrowserCompat.MediaItem mediaItem : AudiobookLibrary.getMediaItems()) {
56 mediaController.addQueueItem(mediaItem.getDescription());
59 // Call prepare now so pressing play just works.
60 mediaController.getTransportControls().prepare();
61 if (storedBook != null) {
62 mediaController.getTransportControls().skipToQueueItem(storedBook.getCurrentAudioChapter());
63 mediaController.getTransportControls().pause();
69 * Implementation of the {@link MediaControllerCompat.Callback} methods we're interested in.
71 * Here would also be where one could override
72 * {@code onQueueChanged(List<MediaSessionCompat.QueueItem> queue)} to get informed when items
73 * are added or removed from the queue. We don't do this here in order to keep the UI
76 private class PlayerMediaControllerCallback extends MediaControllerCompat.Callback {
78 public void onPlaybackStateChanged(PlaybackStateCompat playbackState) {
79 if (playbackState != null) {
80 if (playbackState.getState() == PlaybackStateCompat.STATE_ERROR) {
81 getView().onPlayerError();
84 mIsPlaying = playbackState.getState() == PlaybackStateCompat.STATE_PLAYING;
85 getView().setPlayButtonState(mIsPlaying);
87 if (mIsPlaying && playbackState.getExtras() != null) {
88 int total = playbackState.getExtras().getInt(AudiobookService.EXTRA_PLAYBACK_TOTAL);
89 getView().setTrackDuration(total, getCurrentTimerText(total));
95 public void onMetadataChanged(MediaMetadataCompat mediaMetadata) {
96 if (mediaMetadata == null) {
99 if (!book.getAudiobookFilesUrls().contains(mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID))) {
103 int currentChapter = (int) mediaMetadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER);
104 if (storedBook != null) {
105 storedBook.setCurrentAudioChapter(currentChapter);
106 storage.update(storedBook);
109 String chapterTitle = mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE);
110 getView().setTrackTexts(chapterTitle, currentChapter);
114 public void onExtrasChanged(Bundle extras) {
115 if (extras.containsKey(AudiobookService.EXTRA_PLAYBACK_CURRENT)) {
116 int position = extras.getInt(AudiobookService.EXTRA_PLAYBACK_CURRENT);
117 getView().setTrackPosition(position, getCurrentTimerText(position));
119 if (extras.containsKey(AudiobookService.EXTRA_PLAYBACK_TOTAL)) {
120 int total = extras.getInt(AudiobookService.EXTRA_PLAYBACK_TOTAL);
121 getView().setTrackDuration(total, getCurrentTimerText(total));
126 public void onSessionDestroyed() {
127 super.onSessionDestroyed();
131 public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) {
132 super.onQueueChanged(queue);
136 PlayerPresenter(BookDetailsModel book, String slug, PlayerView view, Context context) {
139 this.storedBook = storage.find(slug);
140 mMediaBrowserHelper = new MediaBrowserConnection(context);
141 mMediaBrowserHelper.registerCallback(new PlayerMediaControllerCallback());
145 public void onStart() {
147 mMediaBrowserHelper.onStart();
151 public void onStop() {
153 mMediaBrowserHelper.onStop();
156 public void playOrPause(boolean pauseCall) {
158 mMediaBrowserHelper.getTransportControls().pause();
160 mMediaBrowserHelper.getTransportControls().play();
164 public void changeChapter(boolean next) {
166 mMediaBrowserHelper.getTransportControls().skipToNext();
168 mMediaBrowserHelper.getTransportControls().skipToPrevious();
172 public void seekToButton(boolean forward) {
174 mMediaBrowserHelper.getTransportControls().fastForward();
176 mMediaBrowserHelper.getTransportControls().rewind();
180 public void seekTo(int userSelectedPosition) {
181 mMediaBrowserHelper.getTransportControls().seekTo(userSelectedPosition);
184 public String getCurrentTimerText(int currentPosition) {
185 StringBuilder sb = new StringBuilder();
186 int minutes = (currentPosition % (1000 * 60 * 60)) / (1000 * 60);
187 int seconds = ((currentPosition % (1000 * 60 * 60)) % (1000 * 60) / 1000);
188 if (currentPosition > (1000 * 60 * 60)) {
189 int hours = (currentPosition / (1000 * 60 * 60));
190 sb.append(String.format(Locale.getDefault(), "%01d", hours));
193 sb.append(String.format(Locale.getDefault(), "%02d", minutes));
195 sb.append(String.format(Locale.getDefault(), "%02d", seconds));
196 return sb.toString();