diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 176dc044..ea6f3e5b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -15,7 +15,6 @@
-
10_000L;
}
}
+
+
+ @FormField(R.string.min_playback_speed, FieldForm.DROPDOWN, R.string.min_playback_speed_description, 25)
+ @DropdownFieldOptionsId(R.array.min_playback_speed)
+ var minimumPlaybackSpeed: Int = 0;
+ @FormField(R.string.max_playback_speed, FieldForm.DROPDOWN, R.string.max_playback_speed_description, 26)
+ @DropdownFieldOptionsId(R.array.max_playback_speed)
+ var maximumPlaybackSpeed: Int = 2;
+ @FormField(R.string.step_playback_speed, FieldForm.DROPDOWN, R.string.step_playback_speed_description, 26)
+ @DropdownFieldOptionsId(R.array.step_playback_speed)
+ var stepPlaybackSpeed: Int = 1;
+
+ fun getPlaybackSpeedStep(): Double {
+ return when(stepPlaybackSpeed) {
+ 0 -> 0.05
+ 1 -> 0.1
+ 2 -> 0.25
+ else -> 0.1;
+ }
+ }
+ fun getPlaybackSpeeds(): List {
+ val playbackSpeeds = mutableListOf();
+ playbackSpeeds.add(1.0);
+ val minSpeed = when(minimumPlaybackSpeed) {
+ 0 -> 0.25
+ 1 -> 0.5
+ 2 -> 1.0
+ else -> 0.25
+ }
+ val maxSpeed = when(maximumPlaybackSpeed) {
+ 0 -> 2.0
+ 1 -> 2.25
+ 2 -> 3.0
+ 3 -> 4.0
+ 4 -> 5.0
+ else -> 2.25;
+ }
+ var testSpeed = 1.0;
+
+ while(testSpeed > minSpeed) {
+ val nextSpeed = (testSpeed - 0.25) as Double;
+ testSpeed = Math.max(nextSpeed, minSpeed);
+ playbackSpeeds.add(testSpeed);
+ }
+ testSpeed = 1.0;
+ while(testSpeed < maxSpeed) {
+ val nextSpeed = (testSpeed + if(testSpeed < 2) 0.25 else 1.0) as Double;
+ testSpeed = Math.min(nextSpeed, maxSpeed);
+ playbackSpeeds.add(testSpeed);
+ }
+ playbackSpeeds.sort();
+ return playbackSpeeds;
+ }
}
@FormField(R.string.comments, "group", R.string.comments_description, 6)
diff --git a/app/src/main/java/com/futo/platformplayer/dialogs/AutoUpdateDialog.kt b/app/src/main/java/com/futo/platformplayer/dialogs/AutoUpdateDialog.kt
index 1691b9df..5e2b72de 100644
--- a/app/src/main/java/com/futo/platformplayer/dialogs/AutoUpdateDialog.kt
+++ b/app/src/main/java/com/futo/platformplayer/dialogs/AutoUpdateDialog.kt
@@ -7,9 +7,7 @@ import android.app.PendingIntent.getBroadcast
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInstaller
-import android.content.pm.PackageInstaller.SessionParams.USER_ACTION_NOT_REQUIRED
import android.graphics.drawable.Animatable
-import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -157,9 +155,6 @@ class AutoUpdateDialog(context: Context?) : AlertDialog(context) {
val packageInstaller: PackageInstaller = context.packageManager.packageInstaller;
val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
- params.setRequireUserAction(USER_ACTION_NOT_REQUIRED)
- }
val sessionId = packageInstaller.createSession(params);
session = packageInstaller.openSession(sessionId)
diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SubscriptionsFeedFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SubscriptionsFeedFragment.kt
index 83e39a88..4a3fdf91 100644
--- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SubscriptionsFeedFragment.kt
+++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/SubscriptionsFeedFragment.kt
@@ -191,7 +191,7 @@ class SubscriptionsFeedFragment : MainFragment() {
private var _bypassRateLimit = false;
private val _lastExceptions: List? = null;
- private val _taskGetPager = TaskHandler>({StateApp.instance.scope}, { withRefresh ->
+ private val _taskGetPager = TaskHandler>({fragment.lifecycleScope}, { withRefresh ->
val group = subGroup;
if(!_bypassRateLimit) {
val subRequestCounts = StateSubscriptions.instance.getSubscriptionRequestCount(group);
@@ -202,7 +202,7 @@ class SubscriptionsFeedFragment : MainFragment() {
throw RateLimitException(rateLimitPlugins.map { it.key.id });
}
_bypassRateLimit = false;
- val resp = StateSubscriptions.instance.getGlobalSubscriptionFeed(StateApp.instance.scope, withRefresh, group);
+ val resp = StateSubscriptions.instance.getGlobalSubscriptionFeed(fragment.lifecycleScope, withRefresh, group);
val feed = StateSubscriptions.instance.getFeed(group?.id);
val currentExs = feed?.exceptions ?: listOf();
diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt
index 199f5566..8e514ce0 100644
--- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt
+++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt
@@ -2149,23 +2149,40 @@ class VideoDetailView : ConstraintLayout {
val canSetSpeed = !_isCasting || StateCasting.instance.activeDevice?.canSetSpeed == true
val currentPlaybackRate = if (_isCasting) StateCasting.instance.activeDevice?.speed else _player.getPlaybackRate()
+ val qualityPlaybackSpeedTitle = if (canSetSpeed) SlideUpMenuTitle(this.context).apply { setTitle(context.getString(R.string.playback_rate) + " (${String.format("%.2f", currentPlaybackRate)})"); } else null;
_overlay_quality_selector = SlideUpMenuOverlay(this.context, _overlay_quality_container, context.getString(
R.string.quality), null, true,
- if (canSetSpeed) SlideUpMenuTitle(this.context).apply { setTitle(context.getString(R.string.playback_rate)) } else null,
+ qualityPlaybackSpeedTitle,
if (canSetSpeed) SlideUpMenuButtonList(this.context, null, "playback_rate").apply {
- setButtons(listOf("0.25", "0.5", "0.75", "1.0", "1.25", "1.5", "1.75", "2.0", "2.25"), currentPlaybackRate!!.toString());
+ val playbackSpeeds = Settings.instance.playback.getPlaybackSpeeds();
+ val format = if(playbackSpeeds.size < 20) "%.2f" else "%.1f";
+ val playbackLabels = playbackSpeeds.map { String.format(format, it) }.toMutableList();
+ playbackLabels.add("+");
+ playbackLabels.add(0, "-");
+
+ setButtons(playbackLabels, String.format(format, currentPlaybackRate));
onClick.subscribe { v ->
+ val currentPlaybackSpeed = if (_isCasting) StateCasting.instance.activeDevice?.speed else _player.getPlaybackRate();
+ var playbackSpeedString = v;
+ val stepSpeed = Settings.instance.playback.getPlaybackSpeedStep();
+ if(v == "+")
+ playbackSpeedString = String.format("%.2f", (currentPlaybackSpeed?.toDouble() ?: 1.0) + stepSpeed).toString();
+ else if(v == "-")
+ playbackSpeedString = String.format("%.2f", (currentPlaybackSpeed?.toDouble() ?: 1.0) - stepSpeed).toString();
+ val newPlaybackSpeed = playbackSpeedString.toDouble();
if (_isCasting) {
val ad = StateCasting.instance.activeDevice ?: return@subscribe
if (!ad.canSetSpeed) {
return@subscribe
}
- ad.changeSpeed(v.toDouble())
- setSelected(v);
+ qualityPlaybackSpeedTitle?.setTitle(context.getString(R.string.playback_rate) + " (${String.format("%.2f", newPlaybackSpeed)})");
+ ad.changeSpeed(newPlaybackSpeed)
+ setSelected(playbackSpeedString);
} else {
- _player.setPlaybackRate(v.toFloat());
- setSelected(v);
+ qualityPlaybackSpeedTitle?.setTitle(context.getString(R.string.playback_rate) + " (${String.format("%.2f", newPlaybackSpeed)})");
+ _player.setPlaybackRate(playbackSpeedString.toFloat());
+ setSelected(playbackSpeedString);
}
};
} else null,
diff --git a/app/src/main/java/com/futo/platformplayer/views/overlays/slideup/SlideUpMenuButtonList.kt b/app/src/main/java/com/futo/platformplayer/views/overlays/slideup/SlideUpMenuButtonList.kt
index 78031ec0..d30a4795 100644
--- a/app/src/main/java/com/futo/platformplayer/views/overlays/slideup/SlideUpMenuButtonList.kt
+++ b/app/src/main/java/com/futo/platformplayer/views/overlays/slideup/SlideUpMenuButtonList.kt
@@ -31,7 +31,7 @@ class SlideUpMenuButtonList : LinearLayout {
fun setButtons(texts: List, activeText: String? = null) {
_root.removeAllViews();
- val marginLeft = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3.0f, resources.displayMetrics).toInt();
+ val marginLeft = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1.5f, resources.displayMetrics).toInt();
val marginRight = marginLeft;
buttons.clear();
diff --git a/app/src/main/res/layout/overlay_slide_up_menu_button_list.xml b/app/src/main/res/layout/overlay_slide_up_menu_button_list.xml
index e27f28af..4b37c8f5 100644
--- a/app/src/main/res/layout/overlay_slide_up_menu_button_list.xml
+++ b/app/src/main/res/layout/overlay_slide_up_menu_button_list.xml
@@ -5,7 +5,7 @@
android:layout_marginTop="10dp"
android:id="@+id/root"
android:orientation="horizontal"
- android:paddingStart="6dp"
- android:paddingEnd="6dp">
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp">
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 98f542c0..e2b7d730 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -427,6 +427,12 @@
Delete from WatchLater when watched
After you leave a video that you mostly watched, it will be removed from watch later.
Seek duration
+ Minimum Playback Speed
+ Minimum Available Speed
+ Maximum Playback Speed
+ Maximum Available Speed
+ Playback Speed Step Size
+ The step size of playback speeds, may not affect higher playback speeds.
Fast-Forward / Fast-Rewind duration
Switch to Audio in Background
Groups
@@ -1091,6 +1097,23 @@
- 30 seconds
- 60 seconds
+
+ - 2.0
+ - 2.25
+ - 3.0
+ - 4.0
+ - 5.0
+
+
+ - 0.25
+ - 0.5
+ - 1.0
+
+
+ - 0.05
+ - 0.1
+ - 0.25
+
- 15
- 30