move listerners and player in playerFragment

This commit is contained in:
Felix 2017-10-01 20:45:03 +02:00
parent 477aa35218
commit f2b0fe82b7
5 changed files with 192 additions and 124 deletions

View file

@ -5,6 +5,8 @@ import android.arch.lifecycle.ViewModel;
import android.arch.lifecycle.ViewModelProvider; import android.arch.lifecycle.ViewModelProvider;
import android.util.Log; import android.util.Log;
import com.google.android.exoplayer2.SimpleExoPlayer;
import java.util.List; import java.util.List;
import de.nicidienase.chaosflix.common.entities.PlaybackProgress; import de.nicidienase.chaosflix.common.entities.PlaybackProgress;
@ -32,6 +34,7 @@ public class ChaosflixViewModel extends ViewModel {
private static final String TAG = ChaosflixViewModel.class.getSimpleName(); private static final String TAG = ChaosflixViewModel.class.getSimpleName();
private final StreamingService mStreamingApi; private final StreamingService mStreamingApi;
private final RecordingService mRecordingApi; private final RecordingService mRecordingApi;
private SimpleExoPlayer exoPlayer;
public ChaosflixViewModel(String recordingUrl, String streamingUrl){ public ChaosflixViewModel(String recordingUrl, String streamingUrl){
OkHttpClient client = new OkHttpClient(); OkHttpClient client = new OkHttpClient();
@ -115,6 +118,14 @@ public class ChaosflixViewModel extends ViewModel {
}).subscribeOn(Schedulers.io()); }).subscribeOn(Schedulers.io());
} }
public SimpleExoPlayer getExoPlayer(){
return exoPlayer;
}
public void setExoPlayer(SimpleExoPlayer exoPlayer) {
this.exoPlayer = exoPlayer;
}
public static class Factory extends ViewModelProvider.NewInstanceFactory{ public static class Factory extends ViewModelProvider.NewInstanceFactory{
private final String recordingUrl; private final String recordingUrl;

View file

@ -6,29 +6,24 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory; import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.LoadControl; import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource; import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.dash.DashMediaSource; import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource; import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource; import com.google.android.exoplayer2.source.hls.HlsMediaSource;
@ -36,7 +31,6 @@ import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView; import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
@ -50,10 +44,9 @@ import butterknife.ButterKnife;
import de.nicidienase.chaosflix.R; import de.nicidienase.chaosflix.R;
import de.nicidienase.chaosflix.common.entities.recording.Event; import de.nicidienase.chaosflix.common.entities.recording.Event;
import de.nicidienase.chaosflix.common.entities.recording.Recording; import de.nicidienase.chaosflix.common.entities.recording.Recording;
import de.nicidienase.chaosflix.touch.ChaosflixViewModel;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
public class ExoPlayerFragment extends ChaosflixFragment { public class ExoPlayerFragment extends ChaosflixFragment implements MyListener.PlayerStateChangeListener{
private static final String TAG = ExoPlayerFragment.class.getSimpleName(); private static final String TAG = ExoPlayerFragment.class.getSimpleName();
public static final String PLAYBACK_STATE = "playback_state"; public static final String PLAYBACK_STATE = "playback_state";
private static final String ARG_EVENT = "event"; private static final String ARG_EVENT = "event";
@ -63,7 +56,7 @@ public class ExoPlayerFragment extends ChaosflixFragment {
private final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter(); private final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
@BindView(R.id.video_view) @BindView(R.id.video_view)
SimpleExoPlayerView mVideoView; SimpleExoPlayerView videoView;
@BindView(R.id.progressBar) @BindView(R.id.progressBar)
ProgressBar mProgressBar; ProgressBar mProgressBar;
@ -74,7 +67,6 @@ public class ExoPlayerFragment extends ChaosflixFragment {
@BindView(R.id.subtitle_text) @BindView(R.id.subtitle_text)
TextView subtitleText; TextView subtitleText;
private SimpleExoPlayer mPlayer;
private String mUserAgent; private String mUserAgent;
private Handler mainHandler = new Handler(); private Handler mainHandler = new Handler();
private boolean mPlaybackState = true; private boolean mPlaybackState = true;
@ -120,10 +112,12 @@ public class ExoPlayerFragment extends ChaosflixFragment {
if(subtitleText != null) if(subtitleText != null)
subtitleText.setText(mEvent.getSubtitle()); subtitleText.setText(mEvent.getSubtitle());
if(mPlayer == null){ SimpleExoPlayer player;
setupPlayer(); if(getViewModel().getExoPlayer() == null){
player = setupPlayer();
getViewModel().setExoPlayer(player);
} else { } else {
mVideoView.setPlayer(mPlayer); player = getViewModel().getExoPlayer();
Log.d(TAG,"Player already set up."); Log.d(TAG,"Player already set up.");
} }
@ -132,36 +126,51 @@ public class ExoPlayerFragment extends ChaosflixFragment {
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
getView().setSystemUiVisibility(View.INVISIBLE); SimpleExoPlayer player = getViewModel().getExoPlayer();
if(mPlayer != null){ if(player != null){
mPlayer.setPlayWhenReady(mPlaybackState); player.setPlayWhenReady(mPlaybackState);
getViewModel().getPlaybackProgress(mEvent.getApiID()) getViewModel().getPlaybackProgress(mEvent.getApiID())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> mPlayer.seekTo(aLong)); .subscribe(aLong -> player.seekTo(aLong));
videoView.setPlayer(player);
} }
} }
@Override
public void onStop() {
super.onStop();
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
getView().setSystemUiVisibility(View.VISIBLE); SimpleExoPlayer player = getViewModel().getExoPlayer();
if(mPlayer != null){ if(player != null){
getViewModel().setPlaybackProgress(mEvent.getApiID(),mPlayer.getCurrentPosition()); getViewModel().setPlaybackProgress(mEvent.getApiID(), player.getCurrentPosition());
mPlayer.setPlayWhenReady(false); player.setPlayWhenReady(false);
} }
} }
@Override
public void onStart() {
super.onStart();
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
if(mPlayer != null){ if(getViewModel().getExoPlayer() != null){
outState.putBoolean(PLAYBACK_STATE, mPlayer.getPlayWhenReady()); outState.putBoolean(PLAYBACK_STATE, getViewModel().getExoPlayer().getPlayWhenReady());
} }
} }
private void setupPlayer(){ private SimpleExoPlayer setupPlayer(){
Log.d(TAG,"Setting up Player."); Log.d(TAG,"Setting up Player.");
mVideoView.setKeepScreenOn(true); videoView.setKeepScreenOn(true);
mUserAgent = Util.getUserAgent(getContext(), getResources().getString(R.string.app_name)); mUserAgent = Util.getUserAgent(getContext(), getResources().getString(R.string.app_name));
@ -172,14 +181,16 @@ public class ExoPlayerFragment extends ChaosflixFragment {
DefaultRenderersFactory renderersFactory DefaultRenderersFactory renderersFactory
= new DefaultRenderersFactory(getContext(), null, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF); = new DefaultRenderersFactory(getContext(), null, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
mPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
mPlayer.addVideoListener(new MyListener());
mPlayer.addListener(new MyListener());
mVideoView.setPlayer(mPlayer); SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
mPlayer.setPlayWhenReady(mPlaybackState); MyListener listener = new MyListener(player, this);
player.addVideoListener(listener);
player.addListener(listener);
mPlayer.prepare(buildMediaSource(Uri.parse(mRecording.getRecordingUrl()),"")); player.setPlayWhenReady(mPlaybackState);
player.prepare(buildMediaSource(Uri.parse(mRecording.getRecordingUrl()),""));
return player;
} }
@Override @Override
@ -199,92 +210,26 @@ public class ExoPlayerFragment extends ChaosflixFragment {
mListener = null; mListener = null;
} }
private void showLoadingSpinner(){ @Override
public void notifyLoadingStart() {
if(mProgressBar != null){ if(mProgressBar != null){
mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.VISIBLE);
} }
} }
private void hideLoadingSpinner(){ @Override
public void notifyLoadingFinished() {
if(mProgressBar != null){ if(mProgressBar != null){
mProgressBar.setVisibility(View.INVISIBLE); mProgressBar.setVisibility(View.INVISIBLE);
} }
} }
public interface OnMediaPlayerInteractionListener { @Override
public void notifyError(String errorMessage) {
Snackbar.make(videoView, errorMessage, Snackbar.LENGTH_LONG).show();
} }
private class MyListener implements Player.EventListener, SimpleExoPlayer.VideoListener { public interface OnMediaPlayerInteractionListener {
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
@Override
public void onLoadingChanged(boolean isLoading) {
if(isLoading && mPlayer.getPlaybackState() != Player.STATE_READY){
showLoadingSpinner();
} else{
hideLoadingSpinner();
}
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState){
case Player.STATE_BUFFERING:
if(mPlayer.isLoading()){
showLoadingSpinner();
}
break;
case Player.STATE_ENDED:
Log.d(TAG,"Finished Playback");
break;
case Player.STATE_IDLE:
case Player.STATE_READY:
default:
hideLoadingSpinner();
}
}
@Override
public void onRepeatModeChanged(int repeatMode) {
}
@Override
public void onPlayerError(ExoPlaybackException error) {
String errorMessage = error.getCause().getMessage();
Snackbar.make(mVideoView,errorMessage,Snackbar.LENGTH_LONG).show();
Log.d(TAG,errorMessage,error);
}
@Override
public void onPositionDiscontinuity() {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
}
@Override
public void onRenderedFirstFrame() {
hideLoadingSpinner();
}
} }
private MediaSource buildMediaSource(Uri uri, String overrideExtension) { private MediaSource buildMediaSource(Uri uri, String overrideExtension) {

View file

@ -0,0 +1,103 @@
package de.nicidienase.chaosflix.touch.fragments;
import android.support.design.widget.Snackbar;
import android.util.Log;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
/**
* Created by felix on 27.09.17.
*/
class MyListener implements Player.EventListener, SimpleExoPlayer.VideoListener {
private static final String TAG = MyListener.class.getSimpleName();
private SimpleExoPlayer player;
private PlayerStateChangeListener listener;
public MyListener(SimpleExoPlayer player, PlayerStateChangeListener listener) {
this.player = player;
this.listener = listener;
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
@Override
public void onLoadingChanged(boolean isLoading) {
if (isLoading && player.getPlaybackState() != Player.STATE_READY) {
listener.notifyLoadingStart();
} else {
listener.notifyLoadingFinished();
}
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
if (player.isLoading()) {
listener.notifyLoadingStart();
}
break;
case Player.STATE_ENDED:
Log.d(TAG, "Finished Playback");
break;
case Player.STATE_IDLE:
case Player.STATE_READY:
default:
listener.notifyLoadingFinished();
}
}
@Override
public void onRepeatModeChanged(int repeatMode) {
}
@Override
public void onPlayerError(ExoPlaybackException error) {
String errorMessage = error.getCause().getMessage();
listener.notifyError(errorMessage);
Log.d(TAG, errorMessage, error);
}
@Override
public void onPositionDiscontinuity() {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
}
@Override
public void onRenderedFirstFrame() {
listener.notifyLoadingFinished();
}
public interface PlayerStateChangeListener{
void notifyLoadingStart();
void notifyLoadingFinished();
void notifyError(String errorMessage);
}
}

View file

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout <LinearLayout
@ -43,6 +44,28 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@drawable/player_controls_background"
android:gravity="center_horizontal|center_vertical"
android:orientation="horizontal">
<ImageButton
android:id="@id/exo_play"
android:scaleX="2"
android:scaleY="2"
style="@style/ExoMediaButton.Play"/>
<ImageButton
android:id="@id/exo_pause"
android:scaleX="2"
android:scaleY="2"
style="@style/ExoMediaButton.Pause"/>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -90,21 +113,7 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:gravity="center"
android:orientation="horizontal">
<ImageButton android:id="@id/exo_play"
style="@style/ExoMediaButton.Play"/>
<ImageButton android:id="@id/exo_pause"
style="@style/ExoMediaButton.Pause"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout> </LinearLayout>

View file

@ -3,7 +3,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
tools:context="de.nicidienase.chaosflix.touch.fragments.AboutActivity"> tools:context="de.nicidienase.chaosflix.touch.activities.AboutActivity">
<include layout="@layout/toolbar"/> <include layout="@layout/toolbar"/>