crash fixes; random play fixes

This commit is contained in:
Yuriy Liskov
2025-05-25 13:56:23 +03:00
parent 828c73344a
commit 0dbc470e16
5 changed files with 84 additions and 37 deletions

View File

@@ -19,6 +19,7 @@ import com.liskovsoft.smartyoutubetv2.common.app.models.data.Playlist;
import com.liskovsoft.smartyoutubetv2.common.app.models.data.Video;
import com.liskovsoft.smartyoutubetv2.common.app.models.data.VideoGroup;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.BasePlayerController;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.manager.PlayerConstants;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.OptionItem;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.SeekBarSegment;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.UiOptionItem;
@@ -27,6 +28,7 @@ import com.liskovsoft.smartyoutubetv2.common.app.presenters.PlaybackPresenter;
import com.liskovsoft.smartyoutubetv2.common.misc.DeArrowProcessor;
import com.liskovsoft.smartyoutubetv2.common.misc.MediaServiceManager;
import com.liskovsoft.smartyoutubetv2.common.prefs.GeneralData;
import com.liskovsoft.smartyoutubetv2.common.utils.UniqueRandom;
import com.liskovsoft.smartyoutubetv2.common.utils.Utils;
import com.liskovsoft.youtubeapi.service.YouTubeServiceManager;
import io.reactivex.Observable;
@@ -41,7 +43,7 @@ public class SuggestionsController extends BasePlayerController {
private MediaItemService mMediaItemService;
private ContentService mContentService;
private DeArrowProcessor mDeArrowProcessor;
private Video mNextVideo;
private Video mNextSectionVideo;
private int mFocusCount;
private int mNextRetryCount;
private List<ChapterItem> mChapters;
@@ -279,8 +281,8 @@ public class SuggestionsController extends BasePlayerController {
if (next != null) {
next.fromQueue = true;
result = next;
} else if (mNextVideo != null) {
result = mNextVideo;
} else if (mNextSectionVideo != null) {
result = mNextSectionVideo;
} else if (current != null && current.nextMediaItem != null) {
result = Video.from(current.nextMediaItem);
}
@@ -531,12 +533,12 @@ public class SuggestionsController extends BasePlayerController {
private void appendSectionPlaylistIfNeeded(Video video) {
if (!video.isSectionPlaylistEnabled(getContext())) {
// Important fix. Gives priority to playlist or suggestion.
mNextVideo = null;
mNextSectionVideo = null;
return;
}
getPlayer().updateSuggestions(video.getGroup());
focusAndContinueIfNeeded(video.getGroup(), () -> appendNextSectionVideoIfNeeded(video));
focusAndContinueIfNeeded(video.getGroup(), () -> findNextSectionVideoIfNeeded(video));
}
private void markAsQueueIfNeeded(Video item) {
@@ -644,12 +646,37 @@ public class SuggestionsController extends BasePlayerController {
}
}
private void appendNextSectionVideoIfNeeded(Video video) {
private void findNextSectionVideoIfNeeded(Video video) {
if (!video.isSectionPlaylistEnabled(getContext())) {
return;
}
mNextVideo = null;
if (getPlayerData().getPlaybackMode() == PlayerConstants.PLAYBACK_MODE_SHUFFLE) {
findRandomSectionVideo(video);
} else {
findNextSectionVideo(video);
}
}
private void findRandomSectionVideo(Video video) {
mNextSectionVideo = null;
VideoGroup group = video.getGroup();
if (group == null || group.isEmpty()) {
return;
}
int currentIdx = group.indexOf(video);
int nextIdx = UniqueRandom.getRandomIndex(currentIdx, group.getSize());
mNextSectionVideo = group.get(nextIdx);
getPlayer().setNextTitle(mNextSectionVideo);
}
private void findNextSectionVideo(Video video) {
mNextSectionVideo = null;
VideoGroup group = video.getGroup();
@@ -663,8 +690,8 @@ public class SuggestionsController extends BasePlayerController {
for (Video current : videos) {
if (found && current.hasVideo() && !current.isUpcoming) {
mNextRetryCount = 0;
mNextVideo = current;
getPlayer().setNextTitle(mNextVideo);
mNextSectionVideo = current;
getPlayer().setNextTitle(mNextSectionVideo);
return;
}
@@ -676,7 +703,7 @@ public class SuggestionsController extends BasePlayerController {
if (mNextRetryCount > 0) {
mNextRetryCount = 0;
} else {
continueGroup(group, continuation -> appendNextSectionVideoIfNeeded(video), getPlayer().isSuggestionsShown());
continueGroup(group, continuation -> findNextSectionVideoIfNeeded(video), getPlayer().isSuggestionsShown());
mNextRetryCount++;
}
}
@@ -770,7 +797,7 @@ public class SuggestionsController extends BasePlayerController {
private void disposeActions() {
RxHelper.disposeActions(mActions);
mChapters = null;
mNextVideo = null;
mNextSectionVideo = null;
}
private void appendDislikes(Video video) {

View File

@@ -44,7 +44,6 @@ public class VideoLoaderController extends BasePlayerController implements OnDat
private static final long BUFFERING_WINDOW_MS = 60_000;
private static final long BUFFERING_RECURRENCE_COUNT = (long) (BUFFERING_WINDOW_MS * 0.5 / BUFFERING_THRESHOLD_MS);
private final Playlist mPlaylist;
private final UniqueRandom mRandom;
private Video mPendingVideo;
private int mLastErrorType = -1;
private SuggestionsController mSuggestionsController;
@@ -84,7 +83,6 @@ public class VideoLoaderController extends BasePlayerController implements OnDat
public VideoLoaderController() {
mPlaylist = Playlist.instance();
mRandom = new UniqueRandom();
}
@Override
@@ -832,7 +830,10 @@ public class VideoLoaderController extends BasePlayerController implements OnDat
Video video = new Video();
video.playlistId = getVideo().playlistId;
VideoGroup topRow = getPlayer().getSuggestionsByIndex(0);
video.playlistIndex = mRandom.getPlaylistIndex(getVideo().getPlaylistId(),
//video.playlistIndex = mRandom.getPlaylistIndex(getVideo().getPlaylistId(),
// getVideo().playlistInfo.getSize() != -1 ? getVideo().playlistInfo.getSize() : topRow != null ? topRow.getVideos().size() : -1);
video.playlistIndex = UniqueRandom.getRandomIndex(getVideo().getPositionInsideGroup(),
getVideo().playlistInfo.getSize() != -1 ? getVideo().playlistInfo.getSize() : topRow != null ? topRow.getVideos().size() : -1);
MediaServiceManager.instance().loadMetadata(video, randomMetadata -> {

View File

@@ -408,7 +408,7 @@ public class VideoStateController extends BasePlayerController {
savePosition();
if (!isBeginEmbed()) {
if (!isBegin()) {
updateHistory();
syncWithPlaylists();
}
@@ -430,7 +430,7 @@ public class VideoStateController extends BasePlayerController {
private void persistState() {
// Skip mini player, but don't save for the previews (mute enabled)
if (isMutedEmbed() || isBeginEmbed()) {
if (isMutedEmbed() || isBegin()) {
return;
}
@@ -682,4 +682,8 @@ public class VideoStateController extends BasePlayerController {
private boolean isBeginEmbed() {
return isEmbedPlayer() && System.currentTimeMillis() - mNewVideoTimeMs <= EMBED_THRESHOLD_MS;
}
private boolean isBegin() {
return System.currentTimeMillis() - mNewVideoTimeMs <= EMBED_THRESHOLD_MS;
}
}

View File

@@ -2,36 +2,50 @@ package com.liskovsoft.smartyoutubetv2.common.utils;
import com.liskovsoft.sharedutils.helpers.Helpers;
import java.util.ArrayList;
import java.util.List;
public class UniqueRandom {
private static final int RANDOM_FAIL_REPEAT_TIMES = 10;
private List<Integer> mUsedIndexes;
private int mPlaylistSize;
private String mPlaylistId;
//private List<Integer> mUsedIndexes;
//private int mPlaylistSize;
//private String mPlaylistId;
public int getPlaylistIndex(int playlistSize) {
return getPlaylistIndex(null, playlistSize);
}
//public int getPlaylistIndex(int playlistSize) {
// return getPlaylistIndex(null, playlistSize);
//}
//
//public int getPlaylistIndex(String playlistId, int playlistSize) {
// if (mUsedIndexes == null) {
// mUsedIndexes = new ArrayList<>();
// }
//
// if (!Helpers.equals(mPlaylistId, playlistId) || mPlaylistSize != playlistSize || mUsedIndexes.size() == playlistSize) {
// mUsedIndexes.clear();
// mPlaylistSize = playlistSize;
// mPlaylistId = playlistId;
// }
//
// int randomIndex = 0;
//
// for (int i = 0; i < RANDOM_FAIL_REPEAT_TIMES; i++) {
// randomIndex = Helpers.getRandomIndex(playlistSize);
// if (!mUsedIndexes.contains(randomIndex)) {
// mUsedIndexes.add(randomIndex);
// break;
// }
// }
//
// return randomIndex;
//}
public int getPlaylistIndex(String playlistId, int playlistSize) {
if (mUsedIndexes == null) {
mUsedIndexes = new ArrayList<>();
}
if (!Helpers.equals(mPlaylistId, playlistId) || mPlaylistSize != playlistSize || mUsedIndexes.size() == playlistSize) {
mUsedIndexes.clear();
mPlaylistSize = playlistSize;
mPlaylistId = playlistId;
public static int getRandomIndex(int currentIdx, int playlistSize) {
if (playlistSize <= 1) {
return 0;
}
int randomIndex = 0;
for (int i = 0; i < RANDOM_FAIL_REPEAT_TIMES; i++) {
randomIndex = Helpers.getRandomIndex(playlistSize);
if (!mUsedIndexes.contains(randomIndex)) {
mUsedIndexes.add(randomIndex);
if (randomIndex != currentIdx) {
break;
}
}

View File

@@ -2320,7 +2320,8 @@ final class GridLayoutManager extends RecyclerView.LayoutManager {
try {
appendVisibleItems();
prependVisibleItems();
} catch (NullPointerException e) {
} catch (IndexOutOfBoundsException | NullPointerException e) {
// IndexOutOfBoundsException: Invalid item position -1(-1). Item count:12 androidx.leanback.widget.VerticalGridView
// NullPointerException: Attempt to invoke virtual method 'android.view.ViewGroup$LayoutParams android.view.View.getLayoutParams()'
e.printStackTrace();
}