[Android] Add support for speed adjustment and bookmarking to Android Auto
Robert Stone
git at videolan.org
Tue Nov 9 08:42:24 UTC 2021
vlc-android | branch: master | Robert Stone <rhstone at gmail.com> | Sun Nov 7 22:27:37 2021 -0800| [f0fbdc2c75fa949766cb249e54d7777ae4c9e065] | committer: Nicolas Pomepuy
Add support for speed adjustment and bookmarking to Android Auto
> https://code.videolan.org/videolan/vlc-android/commit/f0fbdc2c75fa949766cb249e54d7777ae4c9e065
---
.../resources/src/main/res/values/strings.xml | 6 ++++-
.../vlc-android/res/xml/preferences_audio.xml | 6 +++++
.../src/org/videolan/vlc/MediaSessionCallback.kt | 17 ++++++++++++++
.../src/org/videolan/vlc/PlaybackService.kt | 26 ++++++++++++++++++++--
.../vlc/gui/helpers/BookmarkListDelegate.kt | 1 +
5 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/application/resources/src/main/res/values/strings.xml b/application/resources/src/main/res/values/strings.xml
index e1179f700..18a9bdbc1 100644
--- a/application/resources/src/main/res/values/strings.xml
+++ b/application/resources/src/main/res/values/strings.xml
@@ -326,8 +326,10 @@
<string name="enable_volume_gesture_summary">Control volume by gesture during video playback</string>
<string name="enable_seek_buttons">Seek buttons</string>
<string name="enable_seek_buttons_summary">Show rewind and fast forward buttons on the video interface</string>
+ <string name="enable_android_auto_speed_buttons">Android Auto playback speed</string>
+ <string name="enable_android_auto_speed_buttons_summary">Show speed control in the overflow menu</string>
<string name="enable_android_auto_seek_buttons">Android Auto seek buttons</string>
- <string name="enable_android_auto_seek_buttons_summary">Show rewind and fast forward on the Android Auto interface. Try holding steering wheel previous and next buttons before enabling.</string>
+ <string name="enable_android_auto_seek_buttons_summary">Show rewind and fast forward in the overflow menu. Try holding steering wheel previous and next buttons before enabling.</string>
<string name="enable_double_tap_seek_title">Double tap to seek</string>
<string name="enable_double_tap_seek_summary">Double tap on screen edges to seek by 10 seconds</string>
<string name="popup_keepscreen_title">Keep screen ON in Pop-Up mode</string>
@@ -574,6 +576,7 @@
<string name="existing_custom_set_save_message">Save equalizer-set as…</string>
<string name="new_custom_set_save_message">Save new equalizer-set as…</string>
<string name="save">Save</string>
+ <string name="saved">Saved %s</string>
<string name="do_not_save">Do not save</string>
<string name="custom_set_deleted_message">Custom equalizer-set \"%1$s\" deleted.</string>
<string name="custom_set_wrong_input">Invalid name.</string>
@@ -849,6 +852,7 @@
<string name="bookmarks_title">Bookmarks</string>
<string name="no_bookmark">No bookmark yet</string>
<string name="bookmark_name">Bookmark %s</string>
+ <string name="add_bookmark">Add bookmark</string>
<string name="optional_features">Optional features</string>
<string name="optional_features_summary">Beta features that are currently being tested and may not be stable</string>
<string name="optional_features_warning">This feature is in beta and may cause crashes and instabilities</string>
diff --git a/application/vlc-android/res/xml/preferences_audio.xml b/application/vlc-android/res/xml/preferences_audio.xml
index e366fe719..7304ca993 100644
--- a/application/vlc-android/res/xml/preferences_audio.xml
+++ b/application/vlc-android/res/xml/preferences_audio.xml
@@ -56,6 +56,12 @@
</PreferenceCategory>
<PreferenceCategory android:title="@string/controls_prefs_category">
+ <CheckBoxPreference
+ app:singleLineTitle="false"
+ android:defaultValue="false"
+ android:key="enable_android_auto_speed_buttons"
+ android:summary="@string/enable_android_auto_speed_buttons_summary"
+ android:title="@string/enable_android_auto_speed_buttons"/>
<CheckBoxPreference
app:singleLineTitle="false"
android:defaultValue="false"
diff --git a/application/vlc-android/src/org/videolan/vlc/MediaSessionCallback.kt b/application/vlc-android/src/org/videolan/vlc/MediaSessionCallback.kt
index d1e17546e..e643e1af2 100644
--- a/application/vlc-android/src/org/videolan/vlc/MediaSessionCallback.kt
+++ b/application/vlc-android/src/org/videolan/vlc/MediaSessionCallback.kt
@@ -27,6 +27,7 @@ import org.videolan.vlc.util.VoiceSearchParams
import org.videolan.vlc.util.awaitMedialibraryStarted
import java.security.SecureRandom
import java.util.*
+import kotlin.math.abs
import kotlin.math.min
@Suppress("unused")
@@ -108,6 +109,22 @@ internal class MediaSessionCallback(private val playbackService: PlaybackService
override fun onCustomAction(actionId: String?, extras: Bundle?) {
when (actionId) {
+ "${BuildConfig.APP_ID}.speed" -> {
+ val steps = listOf(0.50f, 0.80f, 1.00f, 1.10f, 1.20f, 1.50f, 2.00f)
+ val index = 1 + steps.indexOf(steps.minByOrNull { abs(playbackService.rate - it) })
+ playbackService.setRate(steps[index % steps.size], false)
+ }
+ "${BuildConfig.APP_ID}.bookmark" -> {
+ playbackService.lifecycleScope.launch {
+ val context = playbackService.applicationContext
+ playbackService.currentMediaWrapper?.let {
+ val bookmark = it.addBookmark(playbackService.getTime())
+ val bookmarkName = context.getString(R.string.bookmark_name, it.bookmarks.size.toString())
+ bookmark?.setName(bookmarkName)
+ playbackService.displayPlaybackMessage(R.string.saved, bookmarkName)
+ }
+ }
+ }
"${BuildConfig.APP_ID}.rewind" -> onRewind()
"${BuildConfig.APP_ID}.fast_forward" -> onFastForward()
"${BuildConfig.APP_ID}.shuffle" -> if (playbackService.canShuffle()) playbackService.shuffle()
diff --git a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
index cc6c50f1b..93e8642b2 100644
--- a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
@@ -82,6 +82,7 @@ import org.videolan.vlc.widget.VLCAppWidgetProviderBlack
import org.videolan.vlc.widget.VLCAppWidgetProviderWhite
import videolan.org.commontools.LiveEvent
import java.util.*
+import kotlin.math.abs
private const val TAG = "VLC/PlaybackService"
@@ -1002,6 +1003,8 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
actions = actions or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
if (podcastMode) {
addCustomSeekActions(pscb)
+ addCustomSpeedActions(pscb)
+ pscb.addCustomAction("${BuildConfig.APP_ID}.bookmark", getString(R.string.add_bookmark), R.drawable.ic_bookmark_add)
} else {
if (playlistManager.canRepeat())
actions = actions or PlaybackStateCompat.ACTION_SET_REPEAT_MODE
@@ -1019,7 +1022,8 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
else -> R.drawable.ic_auto_repeat_normal
}
pscb.addCustomAction("${BuildConfig.APP_ID}.repeat", getString(R.string.repeat_title), repeatResId)
- if (settings.getBoolean("enable_android_auto_seek_buttons", false)) addCustomSeekActions(pscb)
+ addCustomSpeedActions(pscb, settings.getBoolean("enable_android_auto_speed_buttons", false))
+ addCustomSeekActions(pscb, settings.getBoolean("enable_android_auto_seek_buttons", false))
}
actions = actions or PlaybackStateCompat.ACTION_FAST_FORWARD or PlaybackStateCompat.ACTION_REWIND or PlaybackStateCompat.ACTION_SEEK_TO
pscb.setActions(actions)
@@ -1044,7 +1048,8 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
}
}
- private fun addCustomSeekActions(pscb: PlaybackStateCompat.Builder) {
+ private fun addCustomSeekActions(pscb: PlaybackStateCompat.Builder, showSeekActions: Boolean = true) {
+ if (!showSeekActions) return
pscb.addCustomAction(PlaybackStateCompat.CustomAction.Builder("${BuildConfig.APP_ID}.rewind",
getString(R.string.playback_rewind), R.drawable.ic_auto_rewind_10)
.setExtras(Bundle().apply { putBoolean(WEARABLE_SHOW_CUSTOM_ACTION, true) })
@@ -1055,6 +1060,23 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner {
.build())
}
+ private fun addCustomSpeedActions(pscb: PlaybackStateCompat.Builder, showSpeedActions: Boolean = true) {
+ val speed = playlistManager.player.speed.value ?: 1.0F
+ if (speed != 1.0F || showSpeedActions) {
+ val speedIcons = hashMapOf(
+ 0.50f to R.drawable.ic_auto_speed_0_50,
+ 0.80f to R.drawable.ic_auto_speed_0_80,
+ 1.00f to R.drawable.ic_auto_speed_1_00,
+ 1.10f to R.drawable.ic_auto_speed_1_10,
+ 1.20f to R.drawable.ic_auto_speed_1_20,
+ 1.50f to R.drawable.ic_auto_speed_1_50,
+ 2.00f to R.drawable.ic_auto_speed_2_00
+ )
+ val speedResId = speedIcons[speedIcons.keys.minByOrNull { abs(speed - it) }] ?: R.drawable.ic_auto_speed
+ pscb.addCustomAction("${BuildConfig.APP_ID}.speed", getString(R.string.playback_speed), speedResId)
+ }
+ }
+
fun notifyTrackChanged() {
updateMetadata()
updateWidget()
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/BookmarkListDelegate.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/BookmarkListDelegate.kt
index 155d7348f..29536cda7 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/BookmarkListDelegate.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/BookmarkListDelegate.kt
@@ -117,6 +117,7 @@ class BookmarkListDelegate(val activity: FragmentActivity, val service: Playback
})
bookmarkModel.refresh()
}
+ bookmarkModel.refresh()
rootView.setVisible()
markerContainer.setVisible()
visibilityListener.invoke()
More information about the Android
mailing list