Videos in RecyclerView: any way to prevent restarting when off-screen? - android

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
}
}
});

Related

I need to play a video when Iam touching on that video . And need to pause when video in list scrolls out

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

ExoPlayer , Loop Ended/ Started listener for LoopingMediaSource

I am using ExoPlayer for playing video in loop, but before source video is started each loop I need to reset some states of my Layout. I know ExoPlayer is calling onPlayerStateChanged with ExoPlayer.STATE_ENDED paramter when video is ended for usual MediaSources, but it is not called for LoopingMediaSource.
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (playbackState == ExoPlayer.STATE_ENDED) {
showControls();
resetLayoutStates(); //I need it here, even in LoopingMediaSource
}
updateButtonVisibilities();
}
Does the Exoplayer have any Callback when Source is restarted or ended in loop ? Or does it have any workaround for my situation ?
You can detect that a video loops when the media item changes. This callback will be fired at the end of the media item and give you the new item to play even if that's the same when repeat mode is ONE. You can detect that with the reason parameter that tells you why the media changed (either naturally, seeking or looping):
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
super.onMediaItemTransition(mediaItem, reason)
if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT) {
// Reset your state
}
}
You may want to assert that it's the right media item with the given mediaItem argument. Especially since it will behave differently whether your repeat mode is ONE or ALL (the media item will be the same for ONE while the first or last item of your timeline for ALL).

VideoView turn into black screen

I am developing multi player video app, so in that i created 9 views 3*3.
when i initialize all (3*3) videoview then working properly for few seconds and after some time video is goes to black screen, not show single video, i am not understand this issue is device oriented or android not supports more than 1 video in activity, anyone know how to resolve this issue, otherwise if video is turn into black then how to identify video is turned into black screen, if we found this then i will refresh view and again start video, i don't know it is correct way or not.
please anyone know about how to resolve this issue then please share information !
i use below code for show multiple video view in one activity
videoPlayer.setVideoPath("path");
videoPlayer.start();
videoPlayer.requestFocus();
videoPlayer.setKeepScreenOn(true);
set prepare listener
videoPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
}
set completion listener
videoPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//play next
}
});
handle error listener
videoPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
// play next
return true;
}
});
when video play next before that i set some propertied to mediaplyer object
mediaPlayer.setDisplay(null);
mediaPlayer.reset();
mediaPlayer.setDisplay(videoPlayer.getHolder());
i share basic code of my project, please tell me if anything is missing from me or android is not supported multiple videos in same activity.

Should I release or reset the MediaPlayer?

I haave my own Custom Adapter Class called WordAdapter, and I am using a Media Player(named pronounce-global variable in the WordAdapter class). I have different activities in which each list item has a linear layout(named as linearLayout). I am setting onClickListener to it so that when the Linear Layout is clicked, a sound file is played. On completion of playing that sound, I want to free off any unwanted memory. But I do not know if I should use release() or reset(). I have checked previous questions asked on SO before, but I don't think it provides precise explanation for my situation so as to use which method.
NOTE: I should be able to play other audio files after this one too (After completing playing this audio file, when I click on other items in the same activity, I should be able to get the sound.)
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pronounce = MediaPlayer.create(context, currentWord.getPronounceResourceID());
pronounce.start();
pronounce.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer player) {
//pronounce.release();
//pronounce.reset();
}
});
}
});
Do a reset before a release, but I suspect that only release is needed.
This might be easier to manage:
public void onClick(View view) {
if (pronounce != null) {
pronounce.reset();
pronounce.release();
pronounce = null;
}
pronounce = MediaPlayer.create(context, currentWord.getPronounceResourceID());
pronounce.start();
}
The reset method will simply stop any media and send the MediaPlayer instance back to the idle state. Exactly in the same state when it was created.
The release method destroys the media player and frees the majority of the unmanaged resources. When you call release, you should set the instance variable to null so that the remainder of the object is a candidate for garbage collection.
You might have some better performance if you just use reset and then reuse the existing mediaplayer instance on subsequent clicks.

retain videoview in fragment when rotating

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...

Categories

Resources