I have a activity who hold 2 fragments (one SlidingMenu and other a VideoPlayer with control and other views).
How Can I retain the video playing status when I'm rotating the device? the video is a HLS Stream, so, I don't need to start again the buffering when rotate.
I start playing with the savedInstanceState, but i can't get it work
If you are using the same resources on on different screen orientations, you can prevent fragment from recreating.
If you need to recreate fragment, you can store playback progress, and after recreation scroll video to stored position
#Override
protected void onPause() {
...
if(playbackWasStarted) {
video.pause();
videoProgress = video.getCurrentPosition();
}
...
}
#Override
protected void onResume() {
...
if(playbackWasStarted && videoProgress!=0) {
video.seekTo(videoProgress);
video.start();
}
...
}
EDIT Oh, I didn't noticed that this question is veeeery old...
Related
I currently have an app (Java) that uses the Navigation Component with Bottom Navigation. I have a fragment for each tab.
One of the fragments navigates to a secondary fragment that features an audio player (using Media Player). This audi fragment has the following code that stops the audio when I go back to the parent fragment:
#Override
public void onDestroy() {
super.onDestroy();
if (mp != null) {
mp.pause();
mp = null;
}
}
The problem is that when the audio is playing and I tap on a different tab from the bottom navigation, the audio continues to play. I thought of using the following:
#Override
public void onStop() {
super.onStop();
if (mp != null) {
mp.pause();
mp = null;
}
}
And this solves the problem but it also prevents the audio from playing when the screen is turned off. (This doesn't happen when the onStop is not there).
The idea is to have the pause() function execute when the user taps on any of the bottom navigation tabs.
With my current structure, how can I get the sound to stop when the user taps on a bottom tab?
You can use "setOnItemSelectedListener()" to listen for clicks on Bottom Navigation.
If the user selects an item other than the one inside the audio player, stopAudioPlayer function is called
Example :-
navBottom.setOnNavigationItemSelectedListener(item -> {
if (item.getItemId() != R.id.nav_bottom_audio_player)
stopAudioPlayer();
return true;
});
In my app I just added RecyclerView that list contains multiple videos . I need to play video when Iam touching on that video . And need to pause when video scrolls out .
mVideoPlayer_1.addMediaPlayerListener(new SimpleMainThreadMediaPlayerListener(){
#Override
public void onVideoPreparedMainThread() {
// We hide the cover when video is prepared. Playback is about to start
mVideoCover.setVisibility(View.INVISIBLE);
}
#Override
public void onVideoStoppedMainThread() {
// We show the cover when video is stopped
mVideoCover.setVisibility(View.VISIBLE);
}
#Override
public void onVideoCompletionMainThread() {
// We show the cover when video is completed
mVideoCover.setVisibility(View.VISIBLE);
}
});
mVideoPlayerManager.playNewVideo(null, mVideoPlayer_1, "http:\\url_to_you_video_1_source");
I need to pause the currently playing video when it scrolls out .
Use onClickListener in RecyclerviewAdapter and onScrollListener in your Activity
I have a RecyclerView with some video elements and they get restarted every time they get off-screen. I tried:
recyclerView.getRecycledViewPool().setMaxRecycledViews(RecyclerViewAdapter.TYPE_VIDEO, 0);
but no success. I also tried to do:
holder.setIsRecyclable(false)
inside my adapter, but videos still restart every time.
Is there any way to stop restarting videos, and somehow pause them and resume them once they are on screen again?
The videos are remote, not local. And I am using a class extending TextureView, not the Android's VideoView
Edit: I missunderstood the question. See original answer below.
I guess you have two possibilities:
Ugly, only possible if the list is not going to be too long™ and undermining the purpose of the recyclerview: use setItemViewCacheSize(int) to increase the number of viewholders that are cached to the number of videos you have and just pause and play during attach / detach.
much better: Store and restore the current playback timestamp of each video when the viewholder gets attached/dettached.
You can use an RecyclerView.OnChildAttachStateChangeListener that will be called whenever a view is attached / removed.
Do it like this:
mRecyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(View view) {
YourTextureView yourTextureView = (YourTextureView) view.findViewById(R.id.yourvideoviewid);
if (yourTextureView != null) {
// start your video
}
}
#Override
public void onChildViewDetachedFromWindow(View view) {
YourTextureView yourTextureView = (YourTextureView) view.findViewById(R.id.yourvideoviewid);
if (yourTextureView != null) {
// stop your video
}
}
});
(Sorry for my english)
I 'm trying to show video using TextureView, but I need to know if there is a way to hide the video without stopping audio playback.
Thus I am doing:
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mySurface = new Surface(surface);
if(MyService.mMediaPlayer != null) MyService.mMediaPlayer.setSurface(mySurface);
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
if(MyService.mMediaPlayer != null) MyService.mMediaPlayer.setSurface(null);
return false;
}
You can see that I'm trying using setSurface(null) but the audio does not remain when I try this.
EDIT:
I have a button in my main activity ( "show video") ; this button starts the second activity where I put the above code .
I need the audio keeps playing when I press the Back button or the home button
Set the visibility of your TextureView to INVISIBLE
mTextureView.setVisibility(View.INVISIBLE);
I have an AsyncTask, where I hide a video view, start the video playback, and show the video view when the video is playing.
But the video would just not start when the video view is set to invisible, the async task keeps hanging in onBackground. If I comment out this line, the video starts playing.
Why does the video view require a visible surface?
public void walk(final View v) {
new AsyncTask() {
#Override
protected void onPreExecute() {
super.onPreExecute();
mVideoView.setVisibility(View.INVISIBLE); // this line causes video not to start
mVideoView.start();
}
#Override
protected Object doInBackground(Object... objects) {
while (!mVideoView.isPlaying()) {}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
mVideoView.setVisibility(View.VISIBLE);
}
}.execute();
A bit of background why I'm doing this: I try to avoid the well-known issue of the black flash that you usually have when starting a video:
https://stackoverflow.com/search?q=%5Bandroid%5D+videoview+black
https://stackoverflow.com/search?q=%5Bandroid%5D+video+%5Bmediaplayer%5D+black
The VideoView is really a specialised SurfaceView. A SurfaceView works by creating another window behind the normal window (containing all of the views), and then having an area of transparency so that the new window (with its own drawing surface) can be seen behind it.
If a SurfaceView is no longer visible, its surface will be destroyed i.e. SurfaceHolder.Callback.surfaceDestroyed is called. The VideoView will not try to play its video if there is not a valid surface, hence your AsyncTask will be able to never leave doInBackground.
The Surface will be created for you while the SurfaceView's window is visible; you should implement surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden.