Added next/previous skip buttons.

This commit is contained in:
Koen 2023-12-06 19:40:05 +01:00
parent 58da91eae8
commit 5fffaf2f4e
6 changed files with 181 additions and 37 deletions

View file

@ -465,6 +465,8 @@ class VideoDetailView : ConstraintLayout {
nextVideo();
};
_player.onDatasourceError.subscribe(::onDataSourceError);
_player.onNext.subscribe { nextVideo(true) };
_player.onPrevious.subscribe { previousVideo(true) };
_minimize_controls_play.setOnClickListener { handlePlay(); };
_minimize_controls_pause.setOnClickListener { handlePause(); };
@ -542,7 +544,7 @@ class VideoDetailView : ConstraintLayout {
MediaControlReceiver.onPlayReceived.subscribe(this) { handlePlay() };
MediaControlReceiver.onPauseReceived.subscribe(this) { handlePause() };
MediaControlReceiver.onNextReceived.subscribe(this) { nextVideo(true) };
MediaControlReceiver.onPreviousReceived.subscribe(this) { prevVideo() };
MediaControlReceiver.onPreviousReceived.subscribe(this) { previousVideo(true) };
MediaControlReceiver.onCloseReceived.subscribe(this) {
Logger.i(TAG, "MediaControlReceiver.onCloseReceived")
onClose.emit()
@ -1532,25 +1534,63 @@ class VideoDetailView : ConstraintLayout {
_slideUpOverlay = _overlay_quality_selector;
}
fun prevVideo() {
Logger.i(TAG, "prevVideo")
val next = StatePlayer.instance.prevQueueItem(_player.duration < 100 || (_player.position.toFloat() / _player.duration) < 0.9);
if(next != null) {
setVideoOverview(next);
private fun getPreviousVideo(withoutRemoval: Boolean, forceLoop: Boolean = false): IPlatformVideo? {
if (!StatePlayer.instance.hasQueue) {
if (forceLoop) {
return StatePlayer.instance.currentVideo
} else {
return null
}
}
val shouldNotRemove = _player.duration < 100 || (_player.position.toFloat() / _player.duration) < 0.9
var previous = StatePlayer.instance.prevQueueItem(withoutRemoval || shouldNotRemove);
if(previous == null && forceLoop)
previous = StatePlayer.instance.getQueue().last();
return previous;
}
private fun getNextVideo(withoutRemoval: Boolean, forceLoop: Boolean = false): IPlatformVideo? {
if (!StatePlayer.instance.hasQueue) {
if (forceLoop) {
return StatePlayer.instance.currentVideo
} else {
return null
}
}
val shouldNotRemove = _player.duration < 100 || (_player.position.toFloat() / _player.duration) < 0.9
var next = StatePlayer.instance.nextQueueItem(withoutRemoval || shouldNotRemove);
if(next == null && forceLoop)
next = StatePlayer.instance.restartQueue();
return next;
}
fun previousVideo(forceLoop: Boolean = false): Boolean {
Logger.i(TAG, "previousVideo")
val previous = getPreviousVideo(false, forceLoop);
if(previous != null) {
setVideoOverview(previous);
return true;
} else {
StatePlayer.instance.setCurrentlyPlaying(null);
}
return false;
}
fun nextVideo(forceLoop: Boolean = false): Boolean {
Logger.i(TAG, "nextVideo")
var next = StatePlayer.instance.nextQueueItem(_player.duration < 100 || (_player.position.toFloat() / _player.duration) < 0.9);
if(next == null && forceLoop)
next = StatePlayer.instance.restartQueue();
val next = getNextVideo(false, forceLoop);
if(next != null) {
setVideoOverview(next);
return true;
}
else
} else {
StatePlayer.instance.setCurrentlyPlaying(null);
}
return false;
}
@ -1690,6 +1730,10 @@ class VideoDetailView : ConstraintLayout {
private fun updateQueueState() {
_upNext.update();
/*_player.updateNextPrevious(
getPreviousVideo(withoutRemoval = true, forceLoop = true) != null,
getNextVideo(withoutRemoval = true, forceLoop = true) != null
)*/
}
//Handlers

View file

@ -4,7 +4,6 @@ import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Handler
import android.util.AttributeSet
import android.util.Log
import android.util.TypedValue
@ -17,7 +16,6 @@ import android.widget.RelativeLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.setMargins
import androidx.lifecycle.LifecycleOwner
import com.futo.platformplayer.*
import com.futo.platformplayer.api.media.models.chapters.IChapter
import com.futo.platformplayer.api.media.models.streams.sources.IAudioSource
@ -72,6 +70,8 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
private val _control_play: ImageButton;
private val _control_chapter: TextView;
private val _time_bar: TimeBar;
private val _buttonPrevious: ImageButton;
private val _buttonNext: ImageButton;
private val _control_fullscreen_fullscreen: ImageButton;
private val _control_videosettings_fullscreen: ImageButton;
@ -82,6 +82,8 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
private val _time_bar_fullscreen: TimeBar;
private val _overlay_brightness: FrameLayout;
private val _control_chapter_fullscreen: TextView;
private val _buttonPrevious_fullscreen: ImageButton;
private val _buttonNext_fullscreen: ImageButton;
private val _title_fullscreen: TextView;
private val _author_fullscreen: TextView;
@ -110,6 +112,8 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
val onToggleFullScreen = Event1<Boolean>();
val onSourceChanged = Event3<IVideoSource?, IAudioSource?, Boolean>();
val onSourceEnded = Event0();
val onPrevious = Event0();
val onNext = Event0();
val onChapterChanged = Event2<IChapter?, Boolean>();
@ -132,6 +136,8 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
_control_play = videoControls.findViewById(com.google.android.exoplayer2.ui.R.id.exo_play);
_time_bar = videoControls.findViewById(com.google.android.exoplayer2.ui.R.id.exo_progress);
_control_chapter = videoControls.findViewById(R.id.text_chapter_current);
_buttonNext = videoControls.findViewById(R.id.button_next);
_buttonPrevious = videoControls.findViewById(R.id.button_previous);
_videoControls_fullscreen = findViewById(R.id.video_player_controller_fullscreen);
_control_fullscreen_fullscreen = _videoControls_fullscreen.findViewById(R.id.exo_fullscreen);
@ -142,11 +148,18 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
_control_play_fullscreen = videoControls.findViewById(com.google.android.exoplayer2.ui.R.id.exo_play);
_control_chapter_fullscreen = _videoControls_fullscreen.findViewById(R.id.text_chapter_current);
_time_bar_fullscreen = _videoControls_fullscreen.findViewById(com.google.android.exoplayer2.ui.R.id.exo_progress);
_buttonPrevious_fullscreen = _videoControls_fullscreen.findViewById(R.id.button_previous);
_buttonNext_fullscreen = _videoControls_fullscreen.findViewById(R.id.button_next);
val castVisibility = if (Settings.instance.casting.enabled) View.VISIBLE else View.GONE
_control_cast.visibility = castVisibility
_control_cast_fullscreen.visibility = castVisibility
_buttonPrevious.setOnClickListener { onPrevious.emit() };
_buttonNext.setOnClickListener { onNext.emit() };
_buttonPrevious_fullscreen.setOnClickListener { onPrevious.emit() };
_buttonNext_fullscreen.setOnClickListener { onNext.emit() };
_overlay_brightness = findViewById(R.id.overlay_brightness);
_title_fullscreen = _videoControls_fullscreen.findViewById(R.id.exo_title);
@ -278,6 +291,11 @@ class FutoVideoPlayer : FutoVideoPlayerBase {
}
}
/*fun updateNextPrevious(hasNext: Boolean, hasPrevious: Boolean) {
_buttonNext.visibility = if (hasNext) View.VISIBLE else View.GONE
_buttonPrevious.visibility = if (hasPrevious) View.VISIBLE else View.GONE
}*/
private val _currentChapterUpdateInterval: Long = 1000L / Settings.instance.playback.getChapterUpdateFrames();
private var _currentChapterUpdateLastPos = 0L;
private val _currentChapterUpdateExecuter = Executors.newSingleThreadScheduledExecutor();

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:pathData="M660,720L660,240L740,240L740,720L660,720ZM220,720L220,240L580,480L220,720Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:pathData="M220,720L220,240L300,240L300,720L220,720ZM740,720L380,480L740,240L740,720Z"/>
</vector>

View file

@ -56,28 +56,60 @@
</LinearLayout>
<ImageButton
android:id="@id/exo_play"
android:id="@id/button_previous"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:scaleType="centerCrop"
android:clickable="true"
app:srcCompat="@drawable/ic_play_white_nopad" />
android:layout_marginRight="40dp"
android:padding="5dp"
app:srcCompat="@drawable/ic_skip_previous"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@id/layout_play_pause"
app:layout_constraintBottom_toBottomOf="parent" />
<FrameLayout
android:id="@+id/layout_play_pause"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent">
<ImageButton
android:id="@id/exo_play"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="10dp"
android:clickable="true"
app:srcCompat="@drawable/ic_play_white_nopad" />
<ImageButton
android:id="@id/exo_pause"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="10dp"
android:clickable="true"
app:srcCompat="@drawable/ic_pause_white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</FrameLayout>
<ImageButton
android:id="@id/exo_pause"
android:id="@id/button_next"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:clickable="true"
app:srcCompat="@drawable/ic_pause_white" />
android:scaleType="centerCrop"
android:padding="5dp"
android:layout_marginLeft="40dp"
app:srcCompat="@drawable/ic_skip_next"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/layout_play_pause"
app:layout_constraintBottom_toBottomOf="parent" />
<ImageButton
android:id="@+id/exo_fullscreen"

View file

@ -84,28 +84,60 @@
</LinearLayout>
<ImageButton
android:id="@id/exo_play"
android:id="@id/button_previous"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="10dp"
android:scaleType="centerCrop"
android:clickable="true"
app:srcCompat="@drawable/ic_play_white_nopad"
android:layout_marginRight="40dp"
android:padding="5dp"
app:srcCompat="@drawable/ic_skip_previous"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@id/layout_play_pause"
app:layout_constraintBottom_toBottomOf="parent" />
<FrameLayout
android:id="@+id/layout_play_pause"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
app:layout_constraintRight_toRightOf="parent">
<ImageButton
android:id="@id/exo_play"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="10dp"
android:clickable="true"
app:srcCompat="@drawable/ic_play_white_nopad" />
<ImageButton
android:id="@id/exo_pause"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="10dp"
android:clickable="true"
app:srcCompat="@drawable/ic_pause_white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</FrameLayout>
<ImageButton
android:id="@id/exo_pause"
android:id="@id/button_next"
android:layout_width="60dp"
android:layout_height="60dp"
android:padding="10dp"
android:clickable="true"
app:srcCompat="@drawable/ic_pause_white"
android:scaleType="centerCrop"
android:padding="5dp"
android:layout_marginLeft="40dp"
app:srcCompat="@drawable/ic_skip_next"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
app:layout_constraintLeft_toRightOf="@id/layout_play_pause"
app:layout_constraintBottom_toBottomOf="parent" />
<ImageButton
android:id="@+id/exo_fullscreen"