X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff..269195b3729c1bdc22e9053ee4ebca667ea8549d:/Android/app/src/main/java/com/moiseum/wolnelektury/view/player/PlayerPresenter.java diff --git a/Android/app/src/main/java/com/moiseum/wolnelektury/view/player/PlayerPresenter.java b/Android/app/src/main/java/com/moiseum/wolnelektury/view/player/PlayerPresenter.java new file mode 100644 index 0000000..c409c75 --- /dev/null +++ b/Android/app/src/main/java/com/moiseum/wolnelektury/view/player/PlayerPresenter.java @@ -0,0 +1,198 @@ +package com.moiseum.wolnelektury.view.player; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.media.MediaBrowserCompat; +import android.support.v4.media.MediaMetadataCompat; +import android.support.v4.media.session.MediaControllerCompat; +import android.support.v4.media.session.MediaSessionCompat; +import android.support.v4.media.session.PlaybackStateCompat; +import android.util.Log; + +import com.moiseum.wolnelektury.base.WLApplication; +import com.moiseum.wolnelektury.base.mvp.FragmentPresenter; +import com.moiseum.wolnelektury.connection.models.BookDetailsModel; +import com.moiseum.wolnelektury.connection.models.BookModel; +import com.moiseum.wolnelektury.storage.BookStorage; +import com.moiseum.wolnelektury.view.player.service.AudiobookLibrary; +import com.moiseum.wolnelektury.view.player.service.AudiobookService; +import com.moiseum.wolnelektury.view.player.service.MediaBrowserHelper; + +import java.util.List; +import java.util.Locale; + +/** + * Created by Piotr Ostrowski on 22.05.2018. + */ +public class PlayerPresenter extends FragmentPresenter { + + private final BookDetailsModel book; + private final BookModel storedBook; + + private final BookStorage storage = WLApplication.getInstance().getBookStorage(); + private MediaBrowserHelper mMediaBrowserHelper; + private boolean mIsPlaying; + + /** + * Customize the connection to our {@link android.support.v4.media.MediaBrowserServiceCompat} + * and implement our app specific desires. + */ + private class MediaBrowserConnection extends MediaBrowserHelper { + private MediaBrowserConnection(Context context) { + super(context, AudiobookService.class); + } + + @Override + protected void onChildrenLoaded(@NonNull String parentId, + @NonNull List children) { + super.onChildrenLoaded(parentId, children); + + final MediaControllerCompat mediaController = getMediaController(); + mediaController.getTransportControls().sendCustomAction(AudiobookService.ACTION_CLEAR_PLAYLIST, null); + + AudiobookLibrary.createAudiobookMetadata(book); + for (final MediaBrowserCompat.MediaItem mediaItem : AudiobookLibrary.getMediaItems()) { + mediaController.addQueueItem(mediaItem.getDescription()); + } + + // Call prepare now so pressing play just works. + mediaController.getTransportControls().prepare(); + if (storedBook != null) { + mediaController.getTransportControls().skipToQueueItem(storedBook.getCurrentAudioChapter()); + mediaController.getTransportControls().pause(); + } + } + } + + /** + * Implementation of the {@link MediaControllerCompat.Callback} methods we're interested in. + *

+ * Here would also be where one could override + * {@code onQueueChanged(List queue)} to get informed when items + * are added or removed from the queue. We don't do this here in order to keep the UI + * simple. + */ + private class PlayerMediaControllerCallback extends MediaControllerCompat.Callback { + @Override + public void onPlaybackStateChanged(PlaybackStateCompat playbackState) { + if (playbackState != null) { + if (playbackState.getState() == PlaybackStateCompat.STATE_ERROR) { + getView().onPlayerError(); + } + + mIsPlaying = playbackState.getState() == PlaybackStateCompat.STATE_PLAYING; + getView().setPlayButtonState(mIsPlaying); + + if (mIsPlaying && playbackState.getExtras() != null) { + int total = playbackState.getExtras().getInt(AudiobookService.EXTRA_PLAYBACK_TOTAL); + getView().setTrackDuration(total, getCurrentTimerText(total)); + } + } + } + + @Override + public void onMetadataChanged(MediaMetadataCompat mediaMetadata) { + if (mediaMetadata == null) { + return; + } + if (!book.getAudiobookFilesUrls().contains(mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID))) { + return; + } + + int currentChapter = (int) mediaMetadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER); + if (storedBook != null) { + storedBook.setCurrentAudioChapter(currentChapter); + storage.update(storedBook); + } + + String chapterTitle = mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE); + getView().setTrackTexts(chapterTitle, currentChapter); + } + + @Override + public void onExtrasChanged(Bundle extras) { + if (extras.containsKey(AudiobookService.EXTRA_PLAYBACK_CURRENT)) { + int position = extras.getInt(AudiobookService.EXTRA_PLAYBACK_CURRENT); + getView().setTrackPosition(position, getCurrentTimerText(position)); + } + if (extras.containsKey(AudiobookService.EXTRA_PLAYBACK_TOTAL)) { + int total = extras.getInt(AudiobookService.EXTRA_PLAYBACK_TOTAL); + getView().setTrackDuration(total, getCurrentTimerText(total)); + } + } + + @Override + public void onSessionDestroyed() { + super.onSessionDestroyed(); + } + + @Override + public void onQueueChanged(List queue) { + super.onQueueChanged(queue); + } + } + + PlayerPresenter(BookDetailsModel book, String slug, PlayerView view, Context context) { + super(view); + this.book = book; + this.storedBook = storage.find(slug); + mMediaBrowserHelper = new MediaBrowserConnection(context); + mMediaBrowserHelper.registerCallback(new PlayerMediaControllerCallback()); + } + + @Override + public void onStart() { + super.onStart(); + mMediaBrowserHelper.onStart(); + } + + @Override + public void onStop() { + super.onStop(); + mMediaBrowserHelper.onStop(); + } + + public void playOrPause(boolean pauseCall) { + if (mIsPlaying) { + mMediaBrowserHelper.getTransportControls().pause(); + } else { + mMediaBrowserHelper.getTransportControls().play(); + } + } + + public void changeChapter(boolean next) { + if (next) { + mMediaBrowserHelper.getTransportControls().skipToNext(); + } else { + mMediaBrowserHelper.getTransportControls().skipToPrevious(); + } + } + + public void seekToButton(boolean forward) { + if (forward) { + mMediaBrowserHelper.getTransportControls().fastForward(); + } else { + mMediaBrowserHelper.getTransportControls().rewind(); + } + } + + public void seekTo(int userSelectedPosition) { + mMediaBrowserHelper.getTransportControls().seekTo(userSelectedPosition); + } + + public String getCurrentTimerText(int currentPosition) { + StringBuilder sb = new StringBuilder(); + int minutes = (currentPosition % (1000 * 60 * 60)) / (1000 * 60); + int seconds = ((currentPosition % (1000 * 60 * 60)) % (1000 * 60) / 1000); + if (currentPosition > (1000 * 60 * 60)) { + int hours = (currentPosition / (1000 * 60 * 60)); + sb.append(String.format(Locale.getDefault(), "%01d", hours)); + sb.append(":"); + } + sb.append(String.format(Locale.getDefault(), "%02d", minutes)); + sb.append(":"); + sb.append(String.format(Locale.getDefault(), "%02d", seconds)); + return sb.toString(); + } +}