|
|
@ -5,7 +5,6 @@ import android.content.Context; |
|
|
|
import android.content.Intent; |
|
|
|
import android.graphics.Rect; |
|
|
|
import android.net.Uri; |
|
|
|
import android.util.Log; |
|
|
|
import android.view.View; |
|
|
|
import android.widget.ImageView; |
|
|
|
|
|
|
@ -17,7 +16,10 @@ import com.google.android.exoplayer2.Player; |
|
|
|
import com.google.android.exoplayer2.SimpleExoPlayer; |
|
|
|
import com.google.android.exoplayer2.source.ProgressiveMediaSource; |
|
|
|
import com.google.android.exoplayer2.ui.PlayerView; |
|
|
|
import com.google.android.exoplayer2.upstream.DataSource; |
|
|
|
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; |
|
|
|
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory; |
|
|
|
import com.google.android.exoplayer2.upstream.cache.SimpleCache; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
|
@ -30,18 +32,23 @@ import awais.instagrabber.utils.Utils; |
|
|
|
|
|
|
|
import static awais.instagrabber.utils.Utils.settingsHelper; |
|
|
|
|
|
|
|
// wasted around 3 hours to get this working, made from scrach, forgot to take a shower so i'm gonna go take a shower (time: May 11, 2020 @ 8:09:30 PM) |
|
|
|
public class VideoAwareRecyclerScroller extends RecyclerView.OnScrollListener { |
|
|
|
private static final String TAG = "VideoAwareRecScroll"; |
|
|
|
private static final Object LOCK = new Object(); |
|
|
|
|
|
|
|
private LinearLayoutManager layoutManager; |
|
|
|
private View firstItemView, lastItemView; |
|
|
|
private int videoPosShown = -1, lastVideoPos = -1, lastChangedVideoPos, lastStoppedVideoPos, lastPlayedVideoPos; |
|
|
|
private boolean videoAttached = false; |
|
|
|
private final List<FeedModel> feedModels; |
|
|
|
//////////////////////////////////////////////////// |
|
|
|
private SimpleExoPlayer player; |
|
|
|
private ImageView btnMute; |
|
|
|
private CacheDataSourceFactory cacheDataSourceFactory; |
|
|
|
|
|
|
|
private final List<FeedModel> feedModels; |
|
|
|
private final Context context; |
|
|
|
private final VideoChangeCallback videoChangeCallback; |
|
|
|
private final DefaultDataSourceFactory dataSourceFactory; |
|
|
|
|
|
|
|
private final View.OnClickListener commentClickListener = new View.OnClickListener() { |
|
|
|
@Override |
|
|
|
public void onClick(@NonNull final View v) { |
|
|
@ -55,128 +62,135 @@ public class VideoAwareRecyclerScroller extends RecyclerView.OnScrollListener { |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
private final View.OnClickListener muteClickListener = v -> { |
|
|
|
if (player == null) return; |
|
|
|
final float intVol = player.getVolume() == 0f ? 1f : 0f; |
|
|
|
player.setVolume(intVol); |
|
|
|
if (btnMute != null) btnMute.setImageResource(intVol == 0f ? R.drawable.mute : R.drawable.vol); |
|
|
|
if (btnMute != null) |
|
|
|
btnMute.setImageResource(intVol == 0f ? R.drawable.mute : R.drawable.vol); |
|
|
|
Utils.sessionVolumeFull = intVol == 1f; |
|
|
|
}; |
|
|
|
private final VideoChangeCallback videoChangeCallback; |
|
|
|
// private final ScrollerVideoCallback videoCallback; |
|
|
|
// private View lastVideoHolder; |
|
|
|
// private int videoState = -1; |
|
|
|
|
|
|
|
public VideoAwareRecyclerScroller(final Context context, final List<FeedModel> feedModels, |
|
|
|
final VideoChangeCallback videoChangeCallback) { |
|
|
|
this.context = context; |
|
|
|
this.feedModels = feedModels; |
|
|
|
this.videoChangeCallback = videoChangeCallback; |
|
|
|
dataSourceFactory = new DefaultDataSourceFactory(context, "instagram"); |
|
|
|
final SimpleCache simpleCache = Utils.getSimpleCacheInstance(context); |
|
|
|
if (simpleCache != null) { |
|
|
|
cacheDataSourceFactory = new CacheDataSourceFactory(simpleCache, dataSourceFactory); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) { |
|
|
|
if (layoutManager == null) { |
|
|
|
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); |
|
|
|
if (layoutManager instanceof LinearLayoutManager) this.layoutManager = (LinearLayoutManager) layoutManager; |
|
|
|
if (layoutManager instanceof LinearLayoutManager) |
|
|
|
this.layoutManager = (LinearLayoutManager) layoutManager; |
|
|
|
} |
|
|
|
if (feedModels.size() == 0 || layoutManager == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
int firstVisibleItemPos = layoutManager.findFirstCompletelyVisibleItemPosition(); |
|
|
|
int lastVisibleItemPos = layoutManager.findLastCompletelyVisibleItemPosition(); |
|
|
|
|
|
|
|
if (feedModels.size() > 0 && layoutManager != null) { |
|
|
|
int firstVisibleItemPos = layoutManager.findFirstCompletelyVisibleItemPosition(); |
|
|
|
int lastVisibleItemPos = layoutManager.findLastCompletelyVisibleItemPosition(); |
|
|
|
|
|
|
|
if (firstVisibleItemPos == -1 && lastVisibleItemPos == -1) { |
|
|
|
firstVisibleItemPos = layoutManager.findFirstVisibleItemPosition(); |
|
|
|
lastVisibleItemPos = layoutManager.findLastVisibleItemPosition(); |
|
|
|
} |
|
|
|
if (firstVisibleItemPos == -1 && lastVisibleItemPos == -1) { |
|
|
|
firstVisibleItemPos = layoutManager.findFirstVisibleItemPosition(); |
|
|
|
lastVisibleItemPos = layoutManager.findLastVisibleItemPosition(); |
|
|
|
} |
|
|
|
|
|
|
|
boolean processFirstItem = false, processLastItem = false; |
|
|
|
View currView; |
|
|
|
if (firstVisibleItemPos != -1) { |
|
|
|
currView = layoutManager.findViewByPosition(firstVisibleItemPos); |
|
|
|
if (currView != null && currView.getId() == R.id.videoHolder) { |
|
|
|
firstItemView = currView; |
|
|
|
processFirstItem = true; |
|
|
|
} |
|
|
|
boolean processFirstItem = false, processLastItem = false; |
|
|
|
View currView; |
|
|
|
if (firstVisibleItemPos != -1) { |
|
|
|
currView = layoutManager.findViewByPosition(firstVisibleItemPos); |
|
|
|
if (currView != null && currView.getId() == R.id.videoHolder) { |
|
|
|
firstItemView = currView; |
|
|
|
processFirstItem = true; |
|
|
|
} |
|
|
|
if (lastVisibleItemPos != -1) { |
|
|
|
currView = layoutManager.findViewByPosition(lastVisibleItemPos); |
|
|
|
if (currView != null && currView.getId() == R.id.videoHolder) { |
|
|
|
lastItemView = currView; |
|
|
|
processLastItem = true; |
|
|
|
} |
|
|
|
} |
|
|
|
if (lastVisibleItemPos != -1) { |
|
|
|
currView = layoutManager.findViewByPosition(lastVisibleItemPos); |
|
|
|
if (currView != null && currView.getId() == R.id.videoHolder) { |
|
|
|
lastItemView = currView; |
|
|
|
processLastItem = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
final Rect visibleItemRect = new Rect(); |
|
|
|
final Rect visibleItemRect = new Rect(); |
|
|
|
|
|
|
|
int firstVisibleItemHeight = 0, lastVisibleItemHeight = 0; |
|
|
|
int firstVisibleItemHeight = 0, lastVisibleItemHeight = 0; |
|
|
|
|
|
|
|
final boolean isFirstItemVideoHolder = firstItemView != null && firstItemView.getId() == R.id.videoHolder; |
|
|
|
if (isFirstItemVideoHolder) { |
|
|
|
firstItemView.getGlobalVisibleRect(visibleItemRect); |
|
|
|
firstVisibleItemHeight = visibleItemRect.height(); |
|
|
|
} |
|
|
|
final boolean isLastItemVideoHolder = lastItemView != null && lastItemView.getId() == R.id.videoHolder; |
|
|
|
if (isLastItemVideoHolder) { |
|
|
|
lastItemView.getGlobalVisibleRect(visibleItemRect); |
|
|
|
lastVisibleItemHeight = visibleItemRect.height(); |
|
|
|
} |
|
|
|
final boolean isFirstItemVideoHolder = firstItemView != null && firstItemView.getId() == R.id.videoHolder; |
|
|
|
if (isFirstItemVideoHolder) { |
|
|
|
firstItemView.getGlobalVisibleRect(visibleItemRect); |
|
|
|
firstVisibleItemHeight = visibleItemRect.height(); |
|
|
|
} |
|
|
|
final boolean isLastItemVideoHolder = lastItemView != null && lastItemView.getId() == R.id.videoHolder; |
|
|
|
if (isLastItemVideoHolder) { |
|
|
|
lastItemView.getGlobalVisibleRect(visibleItemRect); |
|
|
|
lastVisibleItemHeight = visibleItemRect.height(); |
|
|
|
} |
|
|
|
|
|
|
|
if (processFirstItem && firstVisibleItemHeight > lastVisibleItemHeight) videoPosShown = firstVisibleItemPos; |
|
|
|
else if (processLastItem && lastVisibleItemHeight != 0) videoPosShown = lastVisibleItemPos; |
|
|
|
if (processFirstItem && firstVisibleItemHeight > lastVisibleItemHeight) |
|
|
|
videoPosShown = firstVisibleItemPos; |
|
|
|
else if (processLastItem && lastVisibleItemHeight != 0) videoPosShown = lastVisibleItemPos; |
|
|
|
|
|
|
|
if (firstItemView != lastItemView) { |
|
|
|
final int mox = lastVisibleItemHeight - firstVisibleItemHeight; |
|
|
|
if (processLastItem && lastVisibleItemHeight > firstVisibleItemHeight) videoPosShown = lastVisibleItemPos; |
|
|
|
if ((processFirstItem || processLastItem) && mox >= 0) videoPosShown = lastVisibleItemPos; |
|
|
|
if (firstItemView != lastItemView) { |
|
|
|
final int mox = lastVisibleItemHeight - firstVisibleItemHeight; |
|
|
|
if (processLastItem && lastVisibleItemHeight > firstVisibleItemHeight) |
|
|
|
videoPosShown = lastVisibleItemPos; |
|
|
|
if ((processFirstItem || processLastItem) && mox >= 0) |
|
|
|
videoPosShown = lastVisibleItemPos; |
|
|
|
} |
|
|
|
|
|
|
|
if (lastChangedVideoPos != -1 && lastVideoPos != -1) { |
|
|
|
currView = layoutManager.findViewByPosition(lastChangedVideoPos); |
|
|
|
if (currView != null && currView.getId() == R.id.videoHolder && |
|
|
|
lastStoppedVideoPos != lastChangedVideoPos && lastPlayedVideoPos != lastChangedVideoPos) { |
|
|
|
lastStoppedVideoPos = lastChangedVideoPos; |
|
|
|
stopVideo(lastChangedVideoPos, recyclerView, currView); |
|
|
|
} |
|
|
|
|
|
|
|
if (lastChangedVideoPos != -1 && lastVideoPos != -1) { |
|
|
|
currView = layoutManager.findViewByPosition(lastChangedVideoPos); |
|
|
|
if (currView != null && currView.getId() == R.id.videoHolder && |
|
|
|
lastStoppedVideoPos != lastChangedVideoPos && lastPlayedVideoPos != lastChangedVideoPos) { |
|
|
|
lastStoppedVideoPos = lastChangedVideoPos; |
|
|
|
stopVideo(lastChangedVideoPos, recyclerView, currView); |
|
|
|
} |
|
|
|
currView = layoutManager.findViewByPosition(lastVideoPos); |
|
|
|
if (currView != null && currView.getId() == R.id.videoHolder) { |
|
|
|
final Rect rect = new Rect(); |
|
|
|
currView.getGlobalVisibleRect(rect); |
|
|
|
|
|
|
|
currView = layoutManager.findViewByPosition(lastVideoPos); |
|
|
|
if (currView != null && currView.getId() == R.id.videoHolder) { |
|
|
|
final Rect rect = new Rect(); |
|
|
|
currView.getGlobalVisibleRect(rect); |
|
|
|
|
|
|
|
final int holderTop = currView.getTop(); |
|
|
|
final int holderHeight = currView.getBottom() - holderTop; |
|
|
|
final int halfHeight = holderHeight / 2; |
|
|
|
//halfHeight -= halfHeight / 5; |
|
|
|
|
|
|
|
if (rect.height() < halfHeight) { |
|
|
|
if (lastStoppedVideoPos != lastVideoPos) { |
|
|
|
lastStoppedVideoPos = lastVideoPos; |
|
|
|
stopVideo(lastVideoPos, recyclerView, currView); |
|
|
|
} |
|
|
|
} else if (lastPlayedVideoPos != lastVideoPos) { |
|
|
|
lastPlayedVideoPos = lastVideoPos; |
|
|
|
playVideo(lastVideoPos, recyclerView, currView); |
|
|
|
final int holderTop = currView.getTop(); |
|
|
|
final int holderHeight = currView.getBottom() - holderTop; |
|
|
|
final int halfHeight = holderHeight / 2; |
|
|
|
//halfHeight -= halfHeight / 5; |
|
|
|
|
|
|
|
if (rect.height() < halfHeight) { |
|
|
|
if (lastStoppedVideoPos != lastVideoPos) { |
|
|
|
lastStoppedVideoPos = lastVideoPos; |
|
|
|
stopVideo(lastVideoPos, recyclerView, currView); |
|
|
|
} |
|
|
|
} else if (lastPlayedVideoPos != lastVideoPos) { |
|
|
|
lastPlayedVideoPos = lastVideoPos; |
|
|
|
playVideo(lastVideoPos, recyclerView, currView); |
|
|
|
} |
|
|
|
|
|
|
|
if (lastChangedVideoPos != lastVideoPos) lastChangedVideoPos = lastVideoPos; |
|
|
|
} |
|
|
|
|
|
|
|
if (lastVideoPos != -1 && lastVideoPos != videoPosShown) { |
|
|
|
if (videoAttached) { |
|
|
|
//if ((currView = layoutManager.findViewByPosition(lastVideoPos)) != null && currView.getId() == R.id.videoHolder) |
|
|
|
releaseVideo(lastVideoPos, recyclerView, null); |
|
|
|
videoAttached = false; |
|
|
|
} |
|
|
|
if (lastChangedVideoPos != lastVideoPos) lastChangedVideoPos = lastVideoPos; |
|
|
|
} |
|
|
|
|
|
|
|
if (lastVideoPos != -1 && lastVideoPos != videoPosShown) { |
|
|
|
if (videoAttached) { |
|
|
|
//if ((currView = layoutManager.findViewByPosition(lastVideoPos)) != null && currView.getId() == R.id.videoHolder) |
|
|
|
releaseVideo(lastVideoPos, recyclerView, null); |
|
|
|
videoAttached = false; |
|
|
|
} |
|
|
|
if (videoPosShown != -1) { |
|
|
|
lastVideoPos = videoPosShown; |
|
|
|
if (!videoAttached) { |
|
|
|
if ((currView = layoutManager.findViewByPosition(videoPosShown)) != null && currView.getId() == R.id.videoHolder) |
|
|
|
attachVideo(videoPosShown, recyclerView, currView); |
|
|
|
videoAttached = true; |
|
|
|
} |
|
|
|
} |
|
|
|
if (videoPosShown != -1) { |
|
|
|
lastVideoPos = videoPosShown; |
|
|
|
if (!videoAttached) { |
|
|
|
if ((currView = layoutManager.findViewByPosition(videoPosShown)) != null && currView.getId() == R.id.videoHolder) |
|
|
|
attachVideo(videoPosShown, recyclerView, currView); |
|
|
|
videoAttached = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -197,7 +211,11 @@ public class VideoAwareRecyclerScroller extends RecyclerView.OnScrollListener { |
|
|
|
player = null; |
|
|
|
} |
|
|
|
|
|
|
|
player = new SimpleExoPlayer.Builder(context).build(); |
|
|
|
final boolean shouldAutoplay = settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS); |
|
|
|
player = new SimpleExoPlayer.Builder(context) |
|
|
|
.setUseLazyPreparation(!shouldAutoplay) |
|
|
|
.build(); |
|
|
|
player.setPlayWhenReady(shouldAutoplay); |
|
|
|
|
|
|
|
if (itemView != null) { |
|
|
|
final Object tag = itemView.getTag(); |
|
|
@ -218,39 +236,26 @@ public class VideoAwareRecyclerScroller extends RecyclerView.OnScrollListener { |
|
|
|
if (playerView == null) return; |
|
|
|
playerView.setPlayer(player); |
|
|
|
|
|
|
|
if (player != null) { |
|
|
|
btnMute = itemView.findViewById(R.id.btnMute); |
|
|
|
btnMute = itemView.findViewById(R.id.btnMute); |
|
|
|
|
|
|
|
float vol = settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f; |
|
|
|
if (vol == 0f && Utils.sessionVolumeFull) vol = 1f; |
|
|
|
player.setVolume(vol); |
|
|
|
|
|
|
|
if (btnMute != null) { |
|
|
|
btnMute.setVisibility(View.VISIBLE); |
|
|
|
btnMute.setImageResource(vol == 0f ? R.drawable.vol : R.drawable.mute); |
|
|
|
btnMute.setOnClickListener(muteClickListener); |
|
|
|
} |
|
|
|
float vol = settingsHelper.getBoolean(Constants.MUTED_VIDEOS) ? 0f : 1f; |
|
|
|
if (vol == 0f && Utils.sessionVolumeFull) vol = 1f; |
|
|
|
player.setVolume(vol); |
|
|
|
|
|
|
|
player.setPlayWhenReady(settingsHelper.getBoolean(Constants.AUTOPLAY_VIDEOS)); |
|
|
|
|
|
|
|
final ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(new DefaultDataSourceFactory(context, "instagram")) |
|
|
|
.createMediaSource(Uri.parse(feedModels.get(itemPos).getDisplayUrl())); |
|
|
|
|
|
|
|
player.setRepeatMode(Player.REPEAT_MODE_ALL); |
|
|
|
player.prepare(mediaSource); |
|
|
|
player.setVolume(vol); |
|
|
|
|
|
|
|
playerView.setOnClickListener(v -> { |
|
|
|
if (player.getPlayWhenReady() == true) { |
|
|
|
player.setPlayWhenReady(false); |
|
|
|
player.getPlaybackState(); |
|
|
|
} |
|
|
|
else { |
|
|
|
player.setPlayWhenReady(true); |
|
|
|
player.getPlaybackState(); |
|
|
|
} |
|
|
|
}); |
|
|
|
if (btnMute != null) { |
|
|
|
btnMute.setVisibility(View.VISIBLE); |
|
|
|
btnMute.setImageResource(vol == 0f ? R.drawable.vol : R.drawable.mute); |
|
|
|
btnMute.setOnClickListener(muteClickListener); |
|
|
|
} |
|
|
|
final DataSource.Factory factory = cacheDataSourceFactory != null ? cacheDataSourceFactory : dataSourceFactory; |
|
|
|
final ProgressiveMediaSource.Factory sourceFactory = new ProgressiveMediaSource.Factory(factory); |
|
|
|
final ProgressiveMediaSource mediaSource = sourceFactory.createMediaSource(Uri.parse(feedModels.get(itemPos).getDisplayUrl())); |
|
|
|
|
|
|
|
player.setRepeatMode(Player.REPEAT_MODE_ALL); |
|
|
|
player.prepare(mediaSource); |
|
|
|
player.setVolume(vol); |
|
|
|
|
|
|
|
playerView.setOnClickListener(v -> player.setPlayWhenReady(!player.getPlayWhenReady())); |
|
|
|
} |
|
|
|
|
|
|
|
if (videoChangeCallback != null) videoChangeCallback.playerChanged(itemPos, player); |
|
|
@ -259,11 +264,11 @@ public class VideoAwareRecyclerScroller extends RecyclerView.OnScrollListener { |
|
|
|
|
|
|
|
private void releaseVideo(final int itemPos, final RecyclerView recyclerView, final View itemView) { |
|
|
|
// Log.d("AWAISKING_APP", "release: " + itemPos); |
|
|
|
// if (player != null) { |
|
|
|
// player.stop(true); |
|
|
|
// player.release(); |
|
|
|
// } |
|
|
|
// player = null; |
|
|
|
// if (player != null) { |
|
|
|
// player.stop(true); |
|
|
|
// player.release(); |
|
|
|
// } |
|
|
|
// player = null; |
|
|
|
} |
|
|
|
|
|
|
|
private void playVideo(final int itemPos, final RecyclerView recyclerView, final View itemView) { |
|
|
|