mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-09-26 03:09:04 +00:00
Fixes to connectivity loss playback restart and fixes to added ensureEnoughContentVisible.
This commit is contained in:
parent
fc5888d57e
commit
23d1085755
3 changed files with 43 additions and 25 deletions
|
@ -390,7 +390,7 @@ class Settings : FragmentedStorageFileJson() {
|
|||
@DropdownFieldOptionsId(R.array.restart_playback_after_loss)
|
||||
var restartPlaybackAfterLoss: Int = 1;
|
||||
|
||||
@FormField(R.string.restart_after_connectivity_loss, FieldForm.DROPDOWN, R.string.restart_playback_when_gaining_connectivity_after_a_loss, 11)
|
||||
@FormField(R.string.restart_after_connectivity_loss, FieldForm.DROPDOWN, R.string.restart_playback_when_gaining_connectivity_after_a_loss, 12)
|
||||
@DropdownFieldOptionsId(R.array.restart_playback_after_loss)
|
||||
var restartPlaybackAfterConnectivityLoss: Int = 1;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView.LayoutManager
|
|||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.futo.platformplayer.*
|
||||
import com.futo.platformplayer.api.media.IPlatformClient
|
||||
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||
import com.futo.platformplayer.api.media.platforms.js.models.JSPager
|
||||
import com.futo.platformplayer.api.media.structures.*
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
|
@ -21,7 +20,6 @@ import com.futo.platformplayer.constructs.TaskHandler
|
|||
import com.futo.platformplayer.engine.exceptions.PluginException
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.views.FeedStyle
|
||||
import com.futo.platformplayer.views.adapters.ContentPreviewViewHolder
|
||||
import com.futo.platformplayer.views.others.ProgressBar
|
||||
import com.futo.platformplayer.views.others.TagsView
|
||||
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
|
||||
|
@ -64,6 +62,7 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
|
|||
val fragment: TFragment;
|
||||
|
||||
private val _scrollListener: RecyclerView.OnScrollListener;
|
||||
private var _automaticNextPageCounter = 0;
|
||||
|
||||
constructor(fragment: TFragment, inflater: LayoutInflater, cachedRecyclerData: RecyclerData<InsertedViewAdapterWithLoader<TViewHolder>, LinearLayoutManager, TPager, TResult, TConverted, InsertedViewHolder<TViewHolder>>? = null) : super(inflater.context) {
|
||||
this.fragment = fragment;
|
||||
|
@ -122,7 +121,6 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
|
|||
|
||||
_toolbarContentView = findViewById(R.id.container_toolbar_content);
|
||||
|
||||
var filteredNextPageCounter = 0;
|
||||
_nextPageHandler = TaskHandler<TPager, List<TResult>>({fragment.lifecycleScope}, {
|
||||
if (it is IAsyncPager<*>)
|
||||
it.nextPageAsync();
|
||||
|
@ -142,15 +140,8 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
|
|||
val filteredResults = filterResults(it);
|
||||
recyclerData.results.addAll(filteredResults);
|
||||
recyclerData.resultsUnfiltered.addAll(it);
|
||||
if(filteredResults.isEmpty()) {
|
||||
filteredNextPageCounter++
|
||||
if(filteredNextPageCounter <= 4)
|
||||
loadNextPage()
|
||||
}
|
||||
else {
|
||||
filteredNextPageCounter = 0;
|
||||
recyclerData.adapter.notifyItemRangeInserted(recyclerData.adapter.childToParentPosition(posBefore), filteredResults.size);
|
||||
}
|
||||
recyclerData.adapter.notifyItemRangeInserted(recyclerData.adapter.childToParentPosition(posBefore), filteredResults.size);
|
||||
ensureEnoughContentVisible(filteredResults)
|
||||
}.exception<Throwable> {
|
||||
Logger.w(TAG, "Failed to load next page.", it);
|
||||
UIDialogs.showGeneralRetryErrorDialog(context, context.getString(R.string.failed_to_load_next_page), it, {
|
||||
|
@ -170,8 +161,10 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
|
|||
|
||||
val visibleItemCount = _recyclerResults.childCount;
|
||||
val firstVisibleItem = recyclerData.layoutManager.findFirstVisibleItemPosition();
|
||||
//Logger.i(TAG, "onScrolled loadNextPage visibleItemCount=$visibleItemCount firstVisibleItem=$visibleItemCount")
|
||||
|
||||
if (!_loading && firstVisibleItem + visibleItemCount + visibleThreshold >= recyclerData.results.size && firstVisibleItem > 0) {
|
||||
//Logger.i(TAG, "loadNextPage(): firstVisibleItem=$firstVisibleItem visibleItemCount=$visibleItemCount visibleThreshold=$visibleThreshold _results.size=${_results.size}")
|
||||
//Logger.i(TAG, "onScrolled loadNextPage(): firstVisibleItem=$firstVisibleItem visibleItemCount=$visibleItemCount visibleThreshold=$visibleThreshold recyclerData.results.size=${recyclerData.results.size}")
|
||||
loadNextPage();
|
||||
}
|
||||
}
|
||||
|
@ -180,6 +173,33 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
|
|||
_recyclerResults.addOnScrollListener(_scrollListener);
|
||||
}
|
||||
|
||||
private fun ensureEnoughContentVisible(filteredResults: List<TConverted>) {
|
||||
val canScroll = if (recyclerData.results.isEmpty()) false else {
|
||||
val layoutManager = recyclerData.layoutManager
|
||||
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
|
||||
|
||||
if (firstVisibleItemPosition != RecyclerView.NO_POSITION) {
|
||||
val firstVisibleView = layoutManager.findViewByPosition(firstVisibleItemPosition)
|
||||
val itemHeight = firstVisibleView?.height ?: 0
|
||||
val occupiedSpace = recyclerData.results.size * itemHeight
|
||||
val recyclerViewHeight = _recyclerResults.height
|
||||
Logger.i(TAG, "ensureEnoughContentVisible loadNextPage occupiedSpace=$occupiedSpace recyclerViewHeight=$recyclerViewHeight")
|
||||
occupiedSpace >= recyclerViewHeight
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
}
|
||||
Logger.i(TAG, "ensureEnoughContentVisible loadNextPage canScroll=$canScroll _automaticNextPageCounter=$_automaticNextPageCounter")
|
||||
if (!canScroll || filteredResults.isEmpty()) {
|
||||
_automaticNextPageCounter++
|
||||
if(_automaticNextPageCounter <= 4)
|
||||
loadNextPage()
|
||||
} else {
|
||||
_automaticNextPageCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected fun setTextCentered(text: String?) {
|
||||
_textCentered.text = text;
|
||||
}
|
||||
|
@ -369,6 +389,7 @@ abstract class FeedView<TFragment, TResult, TConverted, TPager, TViewHolder> : L
|
|||
recyclerData.resultsUnfiltered.addAll(toAdd);
|
||||
recyclerData.adapter.notifyDataSetChanged();
|
||||
recyclerData.loadedFeedStyle = feedStyle;
|
||||
ensureEnoughContentVisible(filteredResults)
|
||||
}
|
||||
|
||||
private fun detachPagerEvents() {
|
||||
|
|
|
@ -156,22 +156,21 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
|
|||
val dur = duration;
|
||||
var shouldRestartPlayback = false
|
||||
if (_shouldPlaybackRestartOnConnectivity && abs(pos - dur) > 2000) {
|
||||
if (Settings.instance.playback.restartPlaybackAfterLoss == 1) {
|
||||
if (Settings.instance.playback.restartPlaybackAfterConnectivityLoss == 1) {
|
||||
val lossTime_ms = _connectivityLossTime_ms
|
||||
if (lossTime_ms != null && System.currentTimeMillis() - lossTime_ms < 1000 * 30) {
|
||||
shouldRestartPlayback = true
|
||||
}
|
||||
} else if (Settings.instance.playback.restartPlaybackAfterLoss == 2) {
|
||||
} else if (Settings.instance.playback.restartPlaybackAfterConnectivityLoss == 2) {
|
||||
val lossTime_ms = _connectivityLossTime_ms
|
||||
if (lossTime_ms != null && System.currentTimeMillis() - lossTime_ms < 1000 * 10) {
|
||||
shouldRestartPlayback = true
|
||||
}
|
||||
} else if (Settings.instance.playback.restartPlaybackAfterLoss == 3) {
|
||||
} else if (Settings.instance.playback.restartPlaybackAfterConnectivityLoss == 3) {
|
||||
shouldRestartPlayback = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (shouldRestartPlayback) {
|
||||
Logger.i(TAG, "Playback ended due to connection loss, resuming playback since connection is restored.");
|
||||
exoPlayer?.player?.playWhenReady = true;
|
||||
|
@ -529,13 +528,13 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
|
|||
PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS -> {
|
||||
onDatasourceError.emit(error);
|
||||
}
|
||||
PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED,
|
||||
PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND,
|
||||
PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE,
|
||||
//PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED,
|
||||
//PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND,
|
||||
//PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE,
|
||||
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
|
||||
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT,
|
||||
PlaybackException.ERROR_CODE_IO_NO_PERMISSION,
|
||||
PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE,
|
||||
//PlaybackException.ERROR_CODE_IO_NO_PERMISSION,
|
||||
//PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE,
|
||||
PlaybackException.ERROR_CODE_IO_UNSPECIFIED -> {
|
||||
Logger.i(TAG, "IO error, set _shouldPlaybackRestartOnConnectivity=true");
|
||||
_shouldPlaybackRestartOnConnectivity = true;
|
||||
|
@ -557,8 +556,6 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
|
|||
Logger.i(TAG, "_shouldPlaybackRestartOnConnectivity=false");
|
||||
_shouldPlaybackRestartOnConnectivity = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue