diff --git a/app/src/main/java/de/nicidienase/chaosflix/PlaybackHelper.java b/app/src/main/java/de/nicidienase/chaosflix/PlaybackHelper.java index 1c7fe283..df384516 100644 --- a/app/src/main/java/de/nicidienase/chaosflix/PlaybackHelper.java +++ b/app/src/main/java/de/nicidienase/chaosflix/PlaybackHelper.java @@ -1,25 +1,32 @@ package de.nicidienase.chaosflix; +import android.annotation.TargetApi; import android.content.Context; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.media.MediaMetadata; import android.media.session.MediaController; +import android.media.session.PlaybackState; +import android.os.Build; import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v17.leanback.app.PlaybackControlGlue; -import android.view.View; - -import com.bumptech.glide.Glide; +import android.support.v17.leanback.widget.Action; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.ControlButtonPresenterSelector; +import android.support.v17.leanback.widget.OnActionClickedListener; +import android.support.v17.leanback.widget.PlaybackControlsRow; +import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; +import android.support.v17.leanback.widget.SparseArrayObjectAdapter; +import de.nicidienase.chaosflix.activities.ExoPlayerActivity; import de.nicidienase.chaosflix.entities.recording.Event; import de.nicidienase.chaosflix.entities.recording.Recording; import de.nicidienase.chaosflix.entities.streaming.Room; -import de.nicidienase.chaosflix.entities.streaming.Stream; import de.nicidienase.chaosflix.entities.streaming.StreamUrl; import de.nicidienase.chaosflix.fragments.ExoOverlayFragment; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; /** * Created by felix on 26.03.17. @@ -31,47 +38,153 @@ public class PlaybackHelper extends PlaybackControlGlue { private static final int DEFAULT_UPDATE_PERIOD = 500; private static final int UPDATE_PERIOD = 16; private static final String TAG = PlaybackHelper.class.getSimpleName(); - private final Context mContext; - private final ExoOverlayFragment mFragment; + private ExoOverlayFragment.PlaybackControlListener controlListener; private BitmapDrawable mDrawable = null; private Room room; private StreamUrl stream; + private ExoOverlayFragment fragment; private Event event; private Recording recording; private Runnable mUpdateProgressRunnable; private Handler mHandler = new Handler(); + PlaybackControlsRow.PlayPauseAction mPlayPauseAction; + PlaybackControlsRow.FastForwardAction mFastForwardAction; + PlaybackControlsRow.RewindAction mRewindAction; + PlaybackControlsRow.SkipNextAction mSkipNextAction; + PlaybackControlsRow.SkipPreviousAction mSkipPreviousAction; + private ExoOverlayFragment.PlaybackControlListener mCallback; + + private MediaController mMediaController; + private MediaController.TransportControls mTransportControls; + private ArrayObjectAdapter adapter; + public PlaybackHelper(Context context, ExoOverlayFragment fragment, Event event, Recording recording){ - super(context, fragment,SEEK_SPEEDS); - this.mContext = context; - this.mFragment = fragment; + super(context,SEEK_SPEEDS); + controlListener = (ExoOverlayFragment.PlaybackControlListener) context; + this.fragment = fragment; this.event = event; this.recording = recording; - controlListener = (ExoOverlayFragment.PlaybackControlListener) context; + setup(); - if(event != null){ - Observable.fromCallable(() -> - new BitmapDrawable( - mContext.getResources(), - Glide.with(getContext()) - .load(event.getThumbUrl()) - .asBitmap() - .into(-1, -1) - .get())) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .doOnError(Throwable::printStackTrace) - .subscribe(bitmapDrawable -> mDrawable = bitmapDrawable); - } +// if(event != null){ +// Observable.fromCallable(() -> +// new BitmapDrawable( +// mContext.getResources(), +// Glide.with(getContext()) +// .load(event.getThumbUrl()) +// .asBitmap() +// .into(-1, -1) +// .get())) +// .subscribeOn(Schedulers.io()) +// .observeOn(AndroidSchedulers.mainThread()) +// .doOnError(Throwable::printStackTrace) +// .subscribe(bitmapDrawable -> mDrawable = bitmapDrawable); +// } } public PlaybackHelper(Context context, ExoOverlayFragment fragment, Room room, StreamUrl stream ){ super(context, SEEK_SPEEDS); - this.mContext = context; - this.mFragment = fragment; + controlListener = (ExoOverlayFragment.PlaybackControlListener) context; + this.fragment = fragment; this.room = room; this.stream = stream; + + setup(); + } + +// @Override +// public PlaybackControlsRowPresenter createControlsRowAndPresenter() { +// PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter(); +// SparseArrayObjectAdapter primaryActionsAdapter = (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter(); +// +// ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector()); +// getControlsRow().setSecondaryActionsAdapter(adapter); +// +// mPlayPauseAction = (PlaybackControlsRow.PlayPauseAction) primaryActionsAdapter.lookup(ACTION_PLAY_PAUSE); +// mFastForwardAction = (PlaybackControlsRow.FastForwardAction) primaryActionsAdapter.lookup(ACTION_FAST_FORWARD); +// mRewindAction = (PlaybackControlsRow.RewindAction) primaryActionsAdapter.lookup(ACTION_REWIND); +// mSkipNextAction = (PlaybackControlsRow.SkipNextAction) primaryActionsAdapter.lookup(ACTION_SKIP_TO_NEXT); +// mSkipPreviousAction = (PlaybackControlsRow.SkipPreviousAction) primaryActionsAdapter.lookup(ACTION_SKIP_TO_PREVIOUS); +// +//// presenter.setOnActionClickedListener(action -> dispatch(action)); +// return presenter; +// } + + private void setup() { + mMediaController = fragment.getActivity().getMediaController(); + mTransportControls = mMediaController.getTransportControls(); + } + + @Override + public PlaybackControlsRowPresenter createControlsRowAndPresenter() { + PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter(); + adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector()); + getControlsRow().setSecondaryActionsAdapter(adapter); + + presenter.setOnActionClickedListener(new OnActionClickedListener() { + @Override + public void onActionClicked(Action action) { + dispatchAction(action); + } + }); + return presenter; + } + + @TargetApi(Build.VERSION_CODES.N) + public void dispatchAction(Action action) { + if(action instanceof PlaybackControlsRow.MultiAction){ + PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action; + multiAction.nextIndex(); + notifyActionChanged(multiAction); + } + super.onActionClicked(action); + } + + private void notifyActionChanged(PlaybackControlsRow.MultiAction multiAction) { + int index; + index = getPrimaryActionsAdapter().indexOf(multiAction); + if (index >= 0) { + getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1); + } else { + index = getSecondaryActionsAdapter().indexOf(multiAction); + if (index >= 0) { + getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1); + } + } + } + + @Override + public void enableProgressUpdating(boolean enable) { + mHandler.removeCallbacks(mUpdateProgressRunnable); + if(enable){ + mHandler.post(mUpdateProgressRunnable); + } + } + + @Override + public void updateProgress() { + if(mUpdateProgressRunnable == null){ + mUpdateProgressRunnable = new Runnable() { + @Override + public void run() { + int totalTime = getControlsRow().getTotalTime(); + long currentPosition = controlListener.getCurrentPosition(); + getControlsRow().setCurrentTimeLong(currentPosition); + + long bufferedPosition = controlListener.getBufferedPosition(); + getControlsRow().setBufferedProgressLong(bufferedPosition); + + if (totalTime > 0 && totalTime <= currentPosition) { + stopProgressAnimation(); + } else { + updateProgress(); + } + } + }; + } + mHandler.postDelayed(mUpdateProgressRunnable, getUpdatePeriod()); } @Override @@ -81,7 +194,7 @@ public class PlaybackHelper extends PlaybackControlGlue { @Override public boolean isMediaPlaying() { - return mFragment.isMediaPlaying(); + return controlListener.isMediaPlaying(); } @Override @@ -120,40 +233,19 @@ public class PlaybackHelper extends PlaybackControlGlue { } @Override - public int getUpdatePeriod() { - View view = mFragment.getView(); - int totalTime = getControlsRow().getTotalTime(); - if (view == null || totalTime <= 0 || view.getWidth() == 0) { - return DEFAULT_UPDATE_PERIOD; + protected void startPlayback(int speed) { + if(getCurrentSpeedId() == speed){ + return; } - return Math.max(UPDATE_PERIOD, totalTime / view.getWidth()); + mTransportControls.play(); } @Override - public void updateProgress() { - if (mUpdateProgressRunnable == null) { - mUpdateProgressRunnable = new Runnable() { - @Override - public void run() { - int totalTime = getControlsRow().getTotalTime(); - int currentTime = getCurrentPosition(); - getControlsRow().setCurrentTime(currentTime); - - int progress = mFragment.getCurrentPosition(); - getControlsRow().setBufferedProgress(progress); - - if (totalTime > 0 && totalTime <= currentTime) { - stopProgressAnimation(); - } else { - updateProgress(); - } - } - }; - } - - mHandler.postDelayed(mUpdateProgressRunnable, getUpdatePeriod()); + protected void pausePlayback() { + mTransportControls.pause(); } + private void stopProgressAnimation() { if (mHandler != null && mUpdateProgressRunnable != null) { mHandler.removeCallbacks(mUpdateProgressRunnable); @@ -173,7 +265,11 @@ public class PlaybackHelper extends PlaybackControlGlue { @Override public int getCurrentPosition() { - return mFragment.getCurrentPosition(); + return (int) controlListener.getCurrentPosition(); + } + + public long getCurrentPositionLong(){ + return controlListener.getCurrentPosition(); } private boolean mediaIsStream() { @@ -183,5 +279,32 @@ public class PlaybackHelper extends PlaybackControlGlue { return (event != null && recording != null); } + public MediaController.Callback createMediaControllerCallback() { + return new ChaosflixMediaControllerCallback(); + } + private SparseArrayObjectAdapter getPrimaryActionsAdapter() { + return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter(); + } + + private ArrayObjectAdapter getSecondaryActionsAdapter(){ + return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter(); + } + + private class ChaosflixMediaControllerCallback extends MediaController.Callback { + + @Override + public void onPlaybackStateChanged(@NonNull PlaybackState state) { + if(state.getState() != PlaybackState.STATE_NONE){ + updateProgress(); + } + onStateChanged(); + } + + @Override + public void onMetadataChanged(@Nullable MediaMetadata metadata) { + PlaybackHelper.this.onMetadataChanged(); + PlaybackHelper.this.adapter.notifyArrayItemRangeChanged(0,1); + } + } } diff --git a/app/src/main/java/de/nicidienase/chaosflix/activities/ExoPlayerActivity.java b/app/src/main/java/de/nicidienase/chaosflix/activities/ExoPlayerActivity.java index 5d726d73..d638409f 100644 --- a/app/src/main/java/de/nicidienase/chaosflix/activities/ExoPlayerActivity.java +++ b/app/src/main/java/de/nicidienase/chaosflix/activities/ExoPlayerActivity.java @@ -1,9 +1,12 @@ package de.nicidienase.chaosflix.activities; +import android.content.Context; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; +import android.support.v4.os.BuildCompat; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; @@ -56,6 +59,7 @@ public class ExoPlayerActivity extends AbstractServiceConnectedAcitivty private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter(); private Handler mainHandler; + private DefaultTrackSelector trackSelector; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -76,7 +80,7 @@ public class ExoPlayerActivity extends AbstractServiceConnectedAcitivty @Override protected void onStart() { super.onStart(); - mPlaybackControllFragment.startEntranceTransition(); +// mPlaybackControllFragment.startEntranceTransition(); } @Override @@ -93,7 +97,7 @@ public class ExoPlayerActivity extends AbstractServiceConnectedAcitivty bandwidthMeter = new DefaultBandwidthMeter(); TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter); - TrackSelector trackSelector + trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); LoadControl loadControl = new DefaultLoadControl(); @@ -111,7 +115,6 @@ public class ExoPlayerActivity extends AbstractServiceConnectedAcitivty setupPlayer(); } } -// source = "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8"; MediaSource mediaSource = buildMediaSource(Uri.parse(source), ""); player.setPlayWhenReady(true); player.prepare(mediaSource); @@ -134,7 +137,7 @@ public class ExoPlayerActivity extends AbstractServiceConnectedAcitivty } @Override - public void seekTo(int sec) { + public void seekTo(long sec) { player.seekTo(sec * 1000); } @@ -156,6 +159,29 @@ public class ExoPlayerActivity extends AbstractServiceConnectedAcitivty } } + @Override + public void releasePlayer() { + if(player != null){ + player.release(); + } + } + + @Override + public long getPosition() { + if(player != null){ + return player.getCurrentPosition(); + } + return 0; + } + + @Override + public long getBufferedPosition() { + if(player != null){ + return player.getBufferedPosition(); + } + return 0; + } + @Override public void skipForward(int sec){ player.seekTo(player.getCurrentPosition()+(sec*1000)); @@ -191,12 +217,12 @@ public class ExoPlayerActivity extends AbstractServiceConnectedAcitivty return buildDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null); } - public DataSource.Factory buildDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) { + private DataSource.Factory buildDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) { return new DefaultDataSourceFactory(this, bandwidthMeter, buildHttpDataSourceFactory(bandwidthMeter)); } - public HttpDataSource.Factory buildHttpDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) { + private HttpDataSource.Factory buildHttpDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) { return new DefaultHttpDataSourceFactory(mUserAgent, bandwidthMeter); } } diff --git a/app/src/main/java/de/nicidienase/chaosflix/entities/recording/Recording.java b/app/src/main/java/de/nicidienase/chaosflix/entities/recording/Recording.java index 461b10fe..2b26f782 100644 --- a/app/src/main/java/de/nicidienase/chaosflix/entities/recording/Recording.java +++ b/app/src/main/java/de/nicidienase/chaosflix/entities/recording/Recording.java @@ -34,6 +34,8 @@ public class Recording extends SugarRecord implements Parcelable { @SerializedName("conference_url") private String conferenceUrl; + public Recording(){} + protected Recording(Parcel in) { size = in.readInt(); length = in.readInt(); diff --git a/app/src/main/java/de/nicidienase/chaosflix/entities/streaming/StreamUrl.java b/app/src/main/java/de/nicidienase/chaosflix/entities/streaming/StreamUrl.java index 297b3e8d..7567e807 100644 --- a/app/src/main/java/de/nicidienase/chaosflix/entities/streaming/StreamUrl.java +++ b/app/src/main/java/de/nicidienase/chaosflix/entities/streaming/StreamUrl.java @@ -8,8 +8,10 @@ import android.os.Parcelable; */ public class StreamUrl implements Parcelable { + String display; String tech; + String url; protected StreamUrl(Parcel in) { @@ -30,6 +32,14 @@ public class StreamUrl implements Parcelable { } }; + public StreamUrl(){} + + public StreamUrl(String display, String tech, String url){ + this.display = display; + this.tech = tech; + this.url = url; + } + public String getDisplay() { return display; } diff --git a/app/src/main/java/de/nicidienase/chaosflix/fragments/ExoOverlayFragment.java b/app/src/main/java/de/nicidienase/chaosflix/fragments/ExoOverlayFragment.java index 1144330a..cdc6f9f8 100644 --- a/app/src/main/java/de/nicidienase/chaosflix/fragments/ExoOverlayFragment.java +++ b/app/src/main/java/de/nicidienase/chaosflix/fragments/ExoOverlayFragment.java @@ -1,17 +1,27 @@ package de.nicidienase.chaosflix.fragments; -import android.app.Activity; +import android.content.Context; import android.content.Intent; +import android.media.AudioManager; +import android.media.session.MediaController; +import android.media.session.MediaSession; +import android.media.session.PlaybackState; import android.os.Bundle; import android.support.v17.leanback.app.PlaybackFragment; +import android.support.v17.leanback.widget.Action; import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.ClassPresenterSelector; import android.support.v17.leanback.widget.HeaderItem; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.ObjectAdapter; +import android.support.v17.leanback.widget.OnActionClickedListener; import android.support.v17.leanback.widget.PlaybackControlsRow; import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.SparseArrayObjectAdapter; +import android.support.v4.media.session.MediaSessionCompat; +import android.util.Log; import de.nicidienase.chaosflix.CardPresenter; import de.nicidienase.chaosflix.PlaybackHelper; @@ -22,22 +32,43 @@ import de.nicidienase.chaosflix.entities.recording.Recording; import de.nicidienase.chaosflix.entities.streaming.Room; import de.nicidienase.chaosflix.entities.streaming.StreamUrl; +import static android.support.v17.leanback.app.PlaybackControlSupportGlue.ACTION_FAST_FORWARD; +import static android.support.v17.leanback.app.PlaybackControlSupportGlue.ACTION_PLAY_PAUSE; +import static android.support.v17.leanback.app.PlaybackControlSupportGlue.ACTION_REWIND; +import static android.support.v17.leanback.app.PlaybackControlSupportGlue.ACTION_SKIP_TO_NEXT; +import static android.support.v17.leanback.app.PlaybackControlSupportGlue.ACTION_SKIP_TO_PREVIOUS; +import static android.support.v4.media.session.MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS; +import static android.support.v4.media.session.MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS; + /** * Created by felix on 26.03.17. */ -public class ExoOverlayFragment extends android.support.v17.leanback.app.PlaybackOverlayFragment { +public class ExoOverlayFragment extends PlaybackFragment{ + + private static final String TAG = ExoOverlayFragment.class.getSimpleName(); private Recording mSelectedRecording; private Event mSelectedEvent; - private Room mSelectedRoom; + private Room mSelectedRoom; private PlaybackHelper mHelper; private PlaybackControlListener mCallback; private ArrayObjectAdapter mRowsAdapter; + private MediaSession mSession; + private boolean mHasAudioFocus; + private AudioManager mAudioManager; + private MediaController mMediaControler; private int eventType; private StreamUrl mSelectedStream; + private PlaybackControlsRow.PlayPauseAction mPlayPauseAction; + private PlaybackControlsRow.FastForwardAction mFastForwardAction; + private PlaybackControlsRow.RewindAction mRewindAction; + private PlaybackControlsRow.SkipNextAction mSkipNextAction; + private PlaybackControlsRow.SkipPreviousAction mSkipPreviousAction; + private MediaController.Callback mMediaControllerCallback; + public interface PlaybackControlListener { void play(); void pause(); @@ -45,14 +76,18 @@ public class ExoOverlayFragment extends android.support.v17.leanback.app.Playbac void setVideoSource(String source); void skipForward(int sec); void skipBackward(int sec); - void seekTo(int sec); + void seekTo(long sec); boolean isMediaPlaying(); long getCurrentPosition(); + void releasePlayer(); + long getPosition(); + long getBufferedPosition(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Log.d(TAG,"OnCreate"); Intent intent = getActivity() .getIntent(); @@ -66,25 +101,25 @@ public class ExoOverlayFragment extends android.support.v17.leanback.app.Playbac mSelectedStream = intent.getParcelableExtra(DetailsActivity.STREAM_URL); mHelper = new PlaybackHelper(getActivity(),this,mSelectedRoom,mSelectedStream); } else { + Log.d(TAG,"No Media found, finishing"); getActivity().finish(); } mAudioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE); - setBackgroundType(PlaybackFragment.BG_LIGHT); setFadingEnabled(false); + } + @Override + public synchronized void onStart() { + super.onStart(); + Log.d(TAG,"OnStart"); - PlaybackControlsRowPresenter playbackControlsRowPresenter = mHelper.getControlsRowPresenter(); -// playbackControlsRowPresenter.setOnActionClickedListener(mHelper.getOnActionClickedListener()); + PlaybackControlsRowPresenter playbackControlsRowPresenter = mHelper.createControlsRowAndPresenter(); PlaybackControlsRow controlsRow = mHelper.getControlsRow(); - - + mMediaControllerCallback = mHelper.createMediaControllerCallback(); mMediaControler = getActivity().getMediaController(); - if(mMediaControler != null){ - mMediaControler.registerCallback(mHelper.createMediaControllerCallback()); - } - + mMediaControler.registerCallback(mMediaControllerCallback); ClassPresenterSelector ps = new ClassPresenterSelector(); ps.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter); ps.addClassPresenter(ListRow.class, new ListRowPresenter()); @@ -93,6 +128,13 @@ public class ExoOverlayFragment extends android.support.v17.leanback.app.Playbac // mRowsAdapter.add(getRelatedItems()); setAdapter(mRowsAdapter); + if(mCallback != null && eventType == DetailsActivity.TYPE_STREAM){ + mCallback.setVideoSource(mSelectedStream.getUrl()); + } else if(mCallback != null && eventType == DetailsActivity.TYPE_RECORDING){ + mCallback.setVideoSource(mSelectedRecording.getRecordingUrl()); + } else { + Log.d(TAG,"Callback not set or not event/stream"); + } } private Row getRelatedItems() { @@ -116,23 +158,121 @@ public class ExoOverlayFragment extends android.support.v17.leanback.app.Playbac return 0; } - @Override - public void onStart() { - super.onStart(); - if(eventType == DetailsActivity.TYPE_STREAM){ - mCallback.setVideoSource(mSelectedStream.getUrl()); - } else if(eventType == DetailsActivity.TYPE_RECORDING){ - mCallback.setVideoSource(mSelectedRecording.getRecordingUrl()); + public long getCurrentBufferedPosition(){ + if(mCallback != null){ + return mCallback.getBufferedPosition(); } + return 0; } @Override - public void onAttach(Activity context) { + public void onStop() { + super.onStop(); + mSession.release(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mSession.release(); + mCallback.releasePlayer(); + } + + @SuppressWarnings("WrongConstant") + @Override + public void onAttach(Context context) { super.onAttach(context); + Log.d(TAG,"OnAttach"); if(context instanceof PlaybackControlListener){ mCallback = (PlaybackControlListener) context; } else { throw(new RuntimeException("Activity must implement PlaybackControlListener")); } + + if(mSession == null){ + mSession = new MediaSession(getActivity(),"chaosflix"); + mSession.setCallback(new ChaosflixSessionCallback()); + mSession.setFlags(FLAG_HANDLES_MEDIA_BUTTONS| FLAG_HANDLES_TRANSPORT_CONTROLS); + mSession.setActive(true); + + PlaybackState state = new PlaybackState.Builder() + .setActions(getAvailableActions()) + .setState(PlaybackState.STATE_STOPPED, PlaybackState.PLAYBACK_POSITION_UNKNOWN, 0) + .build(); + mSession.setPlaybackState(state); + + getActivity().setMediaController( + new MediaController(getActivity(),mSession.getSessionToken())); + } + } + + private void setPlaybackState(int state){ + int currentPosition = getCurrentPosition(); + + PlaybackState.Builder stateBuilder = new PlaybackState.Builder() + .setActions(getAvailableActions()); + stateBuilder.setState(state,currentPosition,1.0f); + mSession.setPlaybackState(stateBuilder.build()); + } + + private long getAvailableActions() { + long actions = PlaybackState.ACTION_PLAY | + PlaybackState.ACTION_SKIP_TO_NEXT | + PlaybackState.ACTION_SKIP_TO_PREVIOUS | + PlaybackState.ACTION_FAST_FORWARD | + PlaybackState.ACTION_REWIND | + PlaybackState.ACTION_PAUSE; + return actions; + } + + private class ChaosflixSessionCallback extends MediaSession.Callback { + @Override + public void onPlay() { + mCallback.play(); + } + + @Override + public void onPause() { + mCallback.pause(); + } + + @Override + public void onFastForward() { + mCallback.skipForward(30); + } + + @Override + public void onRewind() { + mCallback.skipBackward(30); + } + + @Override + public void onSkipToNext() { + mCallback.skipForward(5*60); + } + + @Override + public void onSkipToPrevious() { + mCallback.skipBackward(5*60); + } + + @Override + public void onSeekTo(long pos) { + mCallback.seekTo(pos); + } + } + + private class ChaosflixActionClickListener implements OnActionClickedListener { + + @Override + public void onActionClicked(Action action) { + if(action.getId() == mPlayPauseAction.getId()){ + if(mPlayPauseAction.getIndex() == PlaybackControlsRow.PlayPauseAction.PLAY){ + mCallback.play(); + } else if(mPlayPauseAction.getIndex() == PlaybackControlsRow.PlayPauseAction.PAUSE){ + mCallback.pause(); + } + } + } } } diff --git a/app/src/main/java/de/nicidienase/chaosflix/fragments/PlaybackOverlayFragment.java b/app/src/main/java/de/nicidienase/chaosflix/fragments/PlaybackOverlayFragment.java index fa932fc2..673cd654 100644 --- a/app/src/main/java/de/nicidienase/chaosflix/fragments/PlaybackOverlayFragment.java +++ b/app/src/main/java/de/nicidienase/chaosflix/fragments/PlaybackOverlayFragment.java @@ -14,14 +14,11 @@ package de.nicidienase.chaosflix.fragments; -import android.app.Activity; import android.content.Context; import android.content.Intent; import android.media.MediaMetadataRetriever; -import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.support.v17.leanback.app.PlaybackFragment; import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter; import android.support.v17.leanback.widget.Action; import android.support.v17.leanback.widget.ArrayObjectAdapter; @@ -33,7 +30,6 @@ import android.support.v17.leanback.widget.OnActionClickedListener; import android.support.v17.leanback.widget.PlaybackControlsRow; import android.support.v17.leanback.widget.PlaybackControlsRow.FastForwardAction; import android.support.v17.leanback.widget.PlaybackControlsRow.PlayPauseAction; -import android.support.v17.leanback.widget.PlaybackControlsRow.RepeatAction; import android.support.v17.leanback.widget.PlaybackControlsRow.RewindAction; import android.support.v17.leanback.widget.PlaybackControlsRowPresenter; import android.widget.Toast; @@ -53,7 +49,7 @@ import de.nicidienase.chaosflix.entities.recording.Recording; /* * Class for video playback with media control */ -public class PlaybackOverlayFragment extends PlaybackFragment { +public class PlaybackOverlayFragment extends android.support.v17.leanback.app.PlaybackOverlayFragment { private static final String TAG = "PlaybackControlsFragmnt"; private static final boolean SHOW_DETAIL = true;