Below is My fragment that contains exoplayer which will inflate with draggable panel in Activity. My problem is while swiping the draggable panel left or right video is closing but audio is still playing in background. If I swipe off the draggable panel audio also needs to closed.Tried many sources couldn't found any solutions.Also In both fragment and Activity while swipping off the draggable panel onPause() method is not triggred. Also public void onClosedToLeft() method also not getting called.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dragpanelone, container, false);
try {
exoPlayerView = (SimpleExoPlayerView)v.findViewById(R.id.exoplayer);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthMeter));
exoplayer = ExoPlayerFactory.newSimpleInstance(getActivity(), trackSelector);
Uri uri = Uri.parse(videoURL);
DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory("exoplayer_video");
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource mediaSource = new ExtractorMediaSource(uri, dataSourceFactory, extractorsFactory, null, null);
exoPlayerView.setPlayer(exoplayer);
exoplayer.prepare(mediaSource);
exoplayer.setPlayWhenReady(true);
} catch (Exception e){
e.printStackTrace();
}
return v;
}
#Override
public void onDestroy() {
super.onDestroy();
exoplayer.release();
}
#Override
public void onStop() {
super.onStop();
exoplayer.setPlayWhenReady(false);
}
public void pausePlayback() {
exoplayer.setPlayWhenReady(false); //pauses the playback if it's playing
}
private void releasePlayer() {
if (exoplayer != null) {
exoplayer.release();
exoplayer.setPlayWhenReady(false);
exoplayer = null;
}
}
public static void closePlayer()
{
exoplayer.clearVideoSurface();
}
}
This is my Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeDraggablepanel();
hookDraggablePanelListners();
}
public void initializeDraggablepanel(){
draggablepanel = (DraggablePanel)findViewById(R.id.draggable_panel);
draggablepanel.setFragmentManager(getSupportFragmentManager());
draggablepanel.setTopFragment(new DragpanelFragOne());
draggablepanel.setBottomFragment(new DragPanelTwo());
draggablepanel.setTopViewHeight(550);
draggablepanel.initializeView();
}
private void hookDraggablePanelListners(){
draggablepanel.setDraggableListener(new DraggableListener() {
#Override
public void onMaximized() {
}
#Override
public void onMinimized() {
}
#Override
public void onClosedToLeft() {
DragpanelFragOne.closePlayer();
Intent i = new Intent(MainActivity.this,HomeScreen.class);
startActivity(i);
}
#Override
public void onClosedToRight() {
DragpanelFragOne.closePlayer();
Intent i = new Intent(MainActivity.this,HomeScreen.class);
startActivity(i);
}
});
}
#Override
public void onPause() {
super.onPause();
DragpanelFragOne.closePlayer();
}
#Override
public void onStop() {
super.onStop();
draggablepanel.closeToLeft();
}
#Override
public void onBackPressed() {
draggablepanel.isClickToMinimizeEnabled();
Intent i = new Intent(MainActivity.this,HomeScreen.class);
startActivity(i);
}
}
Solution:
You need to call the method stop() on the exoplayer object whenever you are closing the player, like this:
if (exoPlayer != null) {
exoPlayer.setPlayWhenReady(false);
exoPlayer.stop();
exoPlayer.seekTo(0);
}
Hope this helps.
Related
I want to play a radio channel from url by using SimpleExoPlayer, the code works only for the first time, i.e., when I press play it works, then I press again it stops. But if I press again play button it doesn't play.
I tried to delete cache in every stop event but it also didn't solve the problem.
public class MainActivity extends AppCompatActivity {
private String source;
private SimpleExoPlayer simpleExoPlayer;
private boolean isPlaying;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageButton btnPlay = findViewById(R.id.image_play);
source = "http://mp3stream7.apasf.apa.at/stream/1/";
isPlaying = false;
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!isPlaying) {
setupPlayer();
simpleExoPlayer.setPlayWhenReady(true);
isPlaying = true;
} else {
simpleExoPlayer.stop();
simpleExoPlayer.setPlayWhenReady(false);
isPlaying = false;
}
}
});
}
private void setupPlayer() {
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(MainActivity.this, null,
DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
TrackSelector trackSelector = new DefaultTrackSelector();
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector);
String userAgent = Util.getUserAgent(MainActivity.this, "Play Audio");
ExtractorMediaSource mediaSource = new ExtractorMediaSource(Uri.parse(source),
new CacheDataSourceFactory(MainActivity.this, 100 * 1024 * 1024, 5 * 1024 * 1024),
new DefaultExtractorsFactory(), null, null);
simpleExoPlayer.prepare(mediaSource);
}
private void release_player() {
simpleExoPlayer.release();
}
#Override
protected void onDestroy() {
simpleExoPlayer.release();
super.onDestroy();
}
#Override
protected void onPause() {
simpleExoPlayer.release();
super.onPause();
}
}
try this:
public class MainActivity extends AppCompatActivity {
private String source;
private SimpleExoPlayer simpleExoPlaye = null;
private boolean isPlaying;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageButton btnPlay = findViewById(R.id.image_play);
source = "http://mp3stream7.apasf.apa.at/stream/1/";
isPlaying = false;
//add this
setupPlayer();
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!isPlaying) {
//remove setupPlayer(); from here
simpleExoPlayer.setPlayWhenReady(true);
isPlaying = true;
} else {
//remove simpleExoPlayer.stop(); from here
simpleExoPlayer.setPlayWhenReady(false);
isPlaying = false;
}
}
});
}
#Override
public void onResume() {
super.onResume();
if (simpleExoPlayer != null) {
simpleExoPlayer.setPlayWhenReady(isPlaying);
} else {
setupPlayer();
}
}
private void setupPlayer() {
if (simpleExoPlayer != null) {
simpleExoPlayer.stop();
}
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(MainActivity.this, null,
DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
TrackSelector trackSelector = new DefaultTrackSelector();
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector);
String userAgent = Util.getUserAgent(MainActivity.this, "Play Audio");
ExtractorMediaSource mediaSource = new ExtractorMediaSource(Uri.parse(source),
new CacheDataSourceFactory(MainActivity.this, 100 * 1024 * 1024, 5 * 1024 * 1024),
new DefaultExtractorsFactory(), null, null);
simpleExoPlayer.prepare(mediaSource);
}
#Override
protected void onDestroy() {
//remove releaze from onDestroy and onPause
simpleExoPlayer.stop();
super.onDestroy();
}
In my App, I have fragment in which I, alongside with other, play video in ExoPlayer. I set it up as simple as possible and the player itself works flawlessly, even with media session.
But the problem is that on device rotation, the video loads again in background (there seems to be two layers - one standard, functioning normally, loading video and playing it; and second layer in background. I can hear the sound of the video shortly after the activity recreates.
I am stopping and releasing the player and media session, but it didn't help.
MediaFragment.java
public class StepViewFragment extends Fragment implements Player.EventListener{
//vars
public StepViewFragment() {
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
//attach callbacks for buttons
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_step_view, container, false);
//Bind view ButterKnife
ButterKnife.bind(this, rootView);
//get Step from Bundle
Bundle bundle = this.getArguments();
if (bundle != null) {
step = bundle.getParcelable(AppConstants.STEP_BUNDLE_KEY);
recipe = bundle.getParcelable(AppConstants.RECIPE_BUNDLE_KEY);
}
mainHandler = new Handler();
//...
//setup ui
//...
if (step.videoURL.equals("")) {
mediaCard.setVisibility(View.GONE);
} else {
playVideo();
initMediaSession();
}
return rootView;
}
public void initMediaSession (){
mExoPlayer.addListener(this);
mMediaSession = new MediaSessionCompat(getContext(), TAG);
mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
mMediaSession.setMediaButtonReceiver(null);
mStateBuilder = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_PLAY_PAUSE
);
mMediaSession.setPlaybackState(mStateBuilder.build());
mMediaSession.setCallback(new MySessionCallback());
mMediaSession.setActive(true);
}
public void playVideo() {
if (mExoPlayer == null) {
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
LoadControl loadControl = new DefaultLoadControl();
RenderersFactory renderersFactory = new DefaultRenderersFactory(getContext());
mExoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
mPlayerView.setPlayer(mExoPlayer);
String videoUrl = step.videoURL;
Uri mp4VideoUri = Uri.parse(videoUrl);
String userAgent = Util.getUserAgent(getContext(), "BakingApp");
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(), userAgent);
ExtractorMediaSource.Factory mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory);
mExoPlayer.prepare(mediaSource.createMediaSource(mp4VideoUri));
mPlayerView.hideController();
mExoPlayer.setPlayWhenReady(true);
}
}
public void releasePlayer() {
mExoPlayer.stop();
mExoPlayer.release();
mExoPlayer = null;
mMediaSession.release();
mPlayerView = null;
}
#Override
public void onStop() {
if (mExoPlayer != null) {
releasePlayer();
}
super.onStop();
}
#Override
public void onDestroyView() {
super.onDestroyView();
if (mExoPlayer != null) {
releasePlayer();
}
}
#Override
public void onPause() {
super.onPause();
if (mExoPlayer != null) {
releasePlayer();
}
}
#Override
public void onDetach() {
super.onDetach();
if (mExoPlayer != null) {
releasePlayer();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (mExoPlayer != null){
releasePlayer();
}
}
#Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if ((playbackState == Player.STATE_READY) && playWhenReady) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PLAYING, mExoPlayer.getCurrentPosition(), 1f);
} else if ((playbackState == Player.STATE_READY)){
mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED, mExoPlayer.getCurrentPosition(), 1f);
}
mMediaSession.setPlaybackState(mStateBuilder.build());
Log.d("HOVNOOOO", "Playback State Changed");
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
private class MySessionCallback extends MediaSessionCompat.Callback {
#Override
public void onPlay() {
mExoPlayer.setPlayWhenReady(true);
}
#Override
public void onPause() {
mExoPlayer.setPlayWhenReady(false);
}
}
Solved...
I was using add() to create the Fragment, so on rotation it added new one.
Using replace instead solved the problem.
I have created an ExoPlayer inside a fragment. If during the playback I press the Home button, and get back to the player, the player seems to be empty, the play/pause button does not work anymore. The video is gone. The video player view seems to be completely empty.
public class PlaybackFragment extends Fragment implements View.OnClickListener, EventListener, PlaybackControlView.VisibilityListener {
private static final String TAG = PlaybackFragment.class.getSimpleName();
Video mVideo; //Video object passed in for playback
SimpleExoPlayerView mExoPlayerView;
private TextView mVideoTitle;
private SimpleExoPlayer mExoPlayer;
private FrameLayout mFullScreenButton; //Holds the fullscreen icon
private Dialog mFullScreenDialog;
private ImageView mFullScreenIcon;
private boolean mExoPlayerFullScreen; //full-screen dialog
private static final String LOG_TAG = PlaybackFragment.class.getSimpleName();
/**
* Root ViewGroup holding the fragment
*/
private ViewGroup mPlayerViewContainer;
/**
* Context used across the class
*/
private Context mContext;
/**
* Activity to which the fragment is added
*/
private Activity mActivity;
/**
* Uri received from calling activity containing Uri to the video to be played
*/
private Uri mUri;
public PlaybackFragment() {
super();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreate: ");
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: ");
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_playback, container, false);
mVideoTitle = root.findViewById(R.id.playback_video_title);
mExoPlayerView = root.findViewById(R.id.exoPlayerView);
mPlayerViewContainer = (ViewGroup) mExoPlayerView.getParent();
return root;
}
/**
* Sets the Uri to video to be played
* #param mediaUri
*/
public void playUri(Uri mediaUri) {
mUri = mediaUri;
}
#Override
public void onViewStateRestored(#Nullable Bundle savedInstanceState) {
Log.d(TAG, "onViewStateRestored: ");
super.onViewStateRestored(savedInstanceState);
}
private void preparePlayback() {
mExoPlayerView.setControllerVisibilityListener(this);
mExoPlayerView.requestFocus();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(trackSelectionFactory);
mExoPlayer =
ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector);
mExoPlayerView.setPlayer(mExoPlayer);
DataSource.Factory dsFactory = new DefaultDataSourceFactory(mContext,
com.google.android.exoplayer2.util.Util.getUserAgent(mContext, mActivity.getApplicationInfo().processName), null);
// Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource videoSource = new ExtractorMediaSource(mUri,
dsFactory, extractorsFactory, null, null);
// Prepare the player with the source.
mExoPlayer.prepare(videoSource);
//start player
mExoPlayer.setPlayWhenReady(true);
mExoPlayer.addListener(this);
// initFullscreenDialog();
initFullscreenButton();
}
#Override
public void onVisibilityChange(int visibility) {
}
#Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
Log.d(TAG, "onActivityCreated: ");
super.onActivityCreated(savedInstanceState);
mContext = mActivity = getActivity();
preparePlayback();
}
#Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart: ");
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onClick(View v) {
}
public void pause() {
mExoPlayer.stop();
}
//Interface to trigger playback-finish event in the parent activity
public interface OnPlayStateListener {
void onPlayFinish();
}
OnPlayStateListener mCallback;
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if(playbackState == Player.STATE_ENDED) {
quitFullScreen(); //Leave fullscreen after playback finished
mCallback.onPlayFinish();
Log.i(LOG_TAG,"onPlayFinish() triggered");
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mCallback = (OnPlayStateListener) context;
} catch (ClassCastException e){
throw new ClassCastException(context.toString() + " must implement OnPlayStateListener");
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
Toast.makeText(mContext,error.getLocalizedMessage(),Toast.LENGTH_SHORT).show();
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
private void goFullScreen() {
Util.showFullScreen(mActivity, mExoPlayerView);
// ((ViewGroup) mExoPlayerView.getParent()).removeView(mExoPlayerView);
// mFullScreenDialog.addContentView(mExoPlayerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mFullScreenIcon.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_fullscreen_exit));
mExoPlayerFullScreen = true;
// mFullScreenDialog.show();
}
private void quitFullScreen() {
Util.quitFullScreen(mActivity, mPlayerViewContainer, mExoPlayerView);
// ((ViewGroup) mExoPlayerView.getParent()).removeView(mExoPlayerView);
// FrameLayout frame = mActivity.findViewById(R.id.main_media_frame);
// frame.addView(mExoPlayerView);
mExoPlayerFullScreen = false;
// mFullScreenDialog.dismiss();
mFullScreenIcon.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_fullscreen_expand));
}
private void initFullscreenButton() {
PlaybackControlView controlView = mExoPlayerView.findViewById(R.id.exo_controller);
mFullScreenIcon = controlView.findViewById(R.id.exo_fullscreen_icon);
mFullScreenButton = controlView.findViewById(R.id.exo_fullscreen_button);
mFullScreenButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mExoPlayerFullScreen) {
goFullScreen();
}
else {
quitFullScreen();
}
}
});
}
private void initFullscreenDialog() {
//The following uses anonymous class to create a custom dialog
mFullScreenDialog = new Dialog(mContext, android.R.style.Theme_DeviceDefault_NoActionBar_Fullscreen) {
#Override
public void onBackPressed() {
if(mExoPlayerFullScreen) {
quitFullScreen();
}
super.onBackPressed();
}
};
}
#Override
public void onDestroy() {
super.onDestroy();
if(mExoPlayer != null) mExoPlayer.release();
Log.d(TAG, "onDestroy: ");
}
/**
* Moves forward or backward by step milliseconds <br/>
* #param step specifies step size. It is a positive or negative integer for moving forward and
* backward, respectively.
*/
public void movePlayPos(int step) {
mExoPlayer.seekTo(mExoPlayer.getCurrentPosition() + step);
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
Log.d(TAG, "onSaveInstanceState: ");
super.onSaveInstanceState(outState);
outState.putLong("position", mExoPlayer.getCurrentPosition());
}
}
I have checked the fragment lifecycle in Logcat, but it seems that after I get back to the player activity, only the fragment's onStart() is called. So, there is no way to restore the state. Any ideas how I can save a video playback position upon pause and resume playback on the activity's onResume?
You can save the current position of exoplayer in onPause() and then seek to that position in onResume().
try this:
long position;
#Override
protected void onPause() {
super.onPause();
if(mExoPlayerView != null && mExoPlayerView.getPlayWhenReady()) {
position = mExoPlayerView.getCurrentPosition();
mExoPlayerView.setPlayWhenReady(false);
}
}
#Override
protected void onResume() {
super.onResume();
if(mExoPlayerView != null) {
mExoPlayerView.seekTo(position);
mExoPlayerView.setPlayWhenReady(true);
}
}
I am using Exo-Player.My video is playing fine but when i press back button and exit from activity my video keeps on playing in background.I don't how to stop it from playing when activity is finished.Please help
This is my code for exo player in recycler view adaptor
String my_date = data.get(position).getCreated_at();
String returneDate = setDateAndTime(my_date);
String img_url = data.get(position).getUser().getProfileUrl();
String videoUrl = data.get(position).getFile_url();
if (videoUrl != null) {
uri = Uri.parse(videoUrl);
} else {
holder.videoFrame.setVisibility(View.GONE);
}
holder.userVideoStatus.setText(data.get(position).getText());
holder.userNameVideoStatus.setText((CharSequence) data.get(position).getUser().getName());
holder.timeVideoStatus.setText(returneDate);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthMeter));
player = ExoPlayerFactory.newSimpleInstance(activity, trackSelector);
DefaultHttpDataSourceFactory defaultHttpDataSourceFactory = new DefaultHttpDataSourceFactory("exo player");
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
final MediaSource mediaSource = new ExtractorMediaSource(uri, defaultHttpDataSourceFactory, extractorsFactory, null, null);
holder.playVideo.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
holder.playVideo.setVisibility(View.GONE);
holder.userVideoUpdate.setPlayer(player);
player.prepare(mediaSource);
player.setPlayWhenReady(true);
holder.volumeUp.setVisibility(View.VISIBLE);
return true;
}
});
Ok Pavel B. gave the right answer but I am elaborating and making it clearer...
Adapter
public class ChatsAdapter extends RecyclerView {
public SimpleExoPlayer exoPlayer; // Do this at top
}
Activity
public class TestActivity extends AppCompatActivity {
private ChatsAdapter chatsAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
chatsAdapter = new ChatsAdapter();
}
#Override
protected void onPause() {
super.onPause();
pausePlayer(chatsAdapter.exoPlayer);
}
#Override
protected void onStop() {
super.onStop();
pausePlayer(chatsAdapter.exoPlayer);
}
#Override
protected void onDestroy() {
super.onDestroy();
releaseExoPlayer(chatsAdapter.exoPlayer);
}
#Override
protected void onResume() {
super.onResume();
startPlayer(chatsAdapter.exoPlayer);
}
public static void startPlayer(SimpleExoPlayer exoPlayer) {
if (exoPlayer != null) {
exoPlayer.setPlayWhenReady(true);
}
}
public static void pausePlayer(SimpleExoPlayer exoPlayer) {
if (exoPlayer != null) {
exoPlayer.setPlayWhenReady(false);
}
}
public static void releaseExoPlayer(SimpleExoPlayer exoPlayer) {
if (exoPlayer != null) {
exoPlayer.release();
}
}
}
in Your adapter - make player a public class member.
in Your activivty onStop() add:
yourAdapter.player.stopPlayback();
If you want to stop exoplayer , upgrade the latest Version of exoplayer and then try using
implementation 'com.google.android.exoplayer:exoplayer:2.14.2'
I tried using playerview.OnPause but that doesnt work .
player.setPlayWhenReady(true) - Used to Pause the player
player.setPlayWhenReady(false) - Used to Resume player .
Make sure you get the same instance of exoplayer everywhere , better if you can make a singleton class.
**
Need to implement video stream within a fragment using exoplayer. Streaming works fine but when moved from the fragment activity to other activity or if the screen is rotated, multiple copys of same audio plays in background continuously until the app is killed.how to handle this please help. Thanks in advance.
**
public class VideoFragment extends Fragment {
private SimpleExoPlayerView simpleExoPlayerView;
public SimpleExoPlayer player;
Uri mp4VideoUri;
String TAG ="LOGG";
SharedPrefs sharedPrefs;
TextView notavailable;
String url;
Connection connection;
long media_length;
public VideoFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.video_fragment,container,false);
sharedPrefs = new SharedPrefs(getContext());
connection = new Connection(getContext());
notavailable= (TextView) rootView.findViewById(R.id.videonotavailable);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
LoadControl loadControl = new DefaultLoadControl();
player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, loadControl);
simpleExoPlayerView = new SimpleExoPlayerView(getContext());
simpleExoPlayerView = (SimpleExoPlayerView) rootView.findViewById(R.id.player_view);
simpleExoPlayerView.setUseController(true);
simpleExoPlayerView.requestFocus();
simpleExoPlayerView.setPlayer(player);
DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(getContext(), Util.getUserAgent(getContext(), "exoplayer2example"), bandwidthMeterA);
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
url=sharedPrefs.getvideoUrl();
if (url==null || url.equals("")){
simpleExoPlayerView.setVisibility(View.GONE);
notavailable.setVisibility(View.VISIBLE);
}else if (connection.isInternet()){
mp4VideoUri=Uri.parse(sharedPrefs.getvideoUrl());
MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri,dataSourceFactory,extractorsFactory,null,null);
final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
player.prepare(loopingSource);
player.addListener(new ExoPlayer.EventListener() {
#Override
public void onLoadingChanged(boolean isLoading) {
Log.v(TAG,"Listener-onLoadingChanged...");
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.v(TAG,"Listener-onPlayerStateChanged...");
}
#Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
Log.v(TAG,"Listener-onTimelineChanged...");
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
Log.v(TAG,"Listener-onPlayerError...");
player.stop();
}
#Override
public void onPositionDiscontinuity() {
Log.v("LOG","Listener-onPositionDiscontinuity...");
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
});
player.setPlayWhenReady(true);
}else {
simpleExoPlayerView.setVisibility(View.GONE);
notavailable.setVisibility(View.VISIBLE);
notavailable.setText(getString(R.string.nointernet));
}
return rootView;
}
#Override
public void onPause() {
super.onPause();
if(player != null) {
player.stop();
player.release();
media_length = player.getCurrentPosition();
}
}
#Override
public void onResume() {
super.onResume();
if(player != null) {
player.seekTo(media_length);
player.setPlayWhenReady(true);
}
}
}
In your fragment-holding activity, you need to handle the situation in the onPause method:
#Override
protected void onPause() {
super.onPause();
mPlayerFragment.pause();
}
You can define a method in your fragment to pause playback by passing false to setPlayWhenReady().
public void pausePlayback() {
mExoPlayer.setPlayWhenReady(false); //pauses the playback if it's playing
}
I am facing same issue and problem resolved after implement below code in my existing code
First You need to create global variable
boolean isActivityRunning = false;
Set this value in onCreate() and onResume() of activity to true.
You need to set Player if value isActivityRunning is true
After that you need to release player and set isActivityRunning = false in onPause(), onStop() and onDestroy() that look like
#Override
public void onPause() {
super.onPause();
isActivityRunning = false;
releasePlayer();
}
#Override
public void onStop() {
super.onStop();
isActivityRunning = false;
releasePlayer();
}
#Override
public void onBackPressed() {
super.onBackPressed();
releasePlayer();
}
#Override
protected void onDestroy(){
super.onDestroy();
releasePlayer();
}
and releasePlayer() implementation look like is
SimpleExoPlayer player;
PlayerView playerUI;
private void releasePlayer(){
if(player!=null){
player.release();
player.clearVideoSurface();
playerUI.getPlayer().release();;
player = null;
playerUI =null;
}
}
Where player and player UI is Global variable that need to set null
This solution work well for me.