mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-04 10:04:39 +02:00
Add jump back and jump forward buttons to android auto.
This commit is contained in:
parent
72744dcd29
commit
621a493c5b
6 changed files with 88 additions and 40 deletions
|
@ -37,9 +37,9 @@ data class DeviceSettings(
|
|||
}
|
||||
|
||||
@get:JsonIgnore
|
||||
val jumpBackwardsTimeMs get() = jumpBackwardsTime * 1000L
|
||||
val jumpBackwardsTimeMs get() = (jumpBackwardsTime ?: default().jumpBackwardsTime) * 1000L
|
||||
@get:JsonIgnore
|
||||
val jumpForwardTimeMs get() = jumpForwardTime * 1000L
|
||||
val jumpForwardTimeMs get() = (jumpForwardTime ?: default().jumpBackwardsTime) * 1000L
|
||||
}
|
||||
|
||||
data class DeviceData(
|
||||
|
|
|
@ -7,10 +7,8 @@ import android.os.Handler
|
|||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.support.v4.media.session.MediaSessionCompat
|
||||
import android.support.v4.media.session.PlaybackStateCompat
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import com.audiobookshelf.app.R
|
||||
import com.audiobookshelf.app.data.LibraryItemWrapper
|
||||
import com.audiobookshelf.app.data.PodcastEpisode
|
||||
import java.util.*
|
||||
|
@ -21,7 +19,6 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi
|
|||
|
||||
private var mediaButtonClickCount: Int = 0
|
||||
var mediaButtonClickTimeout: Long = 1000 //ms
|
||||
var seekAmount: Long = 20000 //ms
|
||||
|
||||
override fun onPrepare() {
|
||||
Log.d(tag, "ON PREPARE MEDIA SESSION COMPAT")
|
||||
|
@ -75,19 +72,19 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi
|
|||
}
|
||||
|
||||
override fun onSkipToPrevious() {
|
||||
playerNotificationService.seekBackward(seekAmount)
|
||||
playerNotificationService.skipToPrevious()
|
||||
}
|
||||
|
||||
override fun onSkipToNext() {
|
||||
playerNotificationService.seekForward(seekAmount)
|
||||
playerNotificationService.skipToNext()
|
||||
}
|
||||
|
||||
override fun onFastForward() {
|
||||
playerNotificationService.seekForward(seekAmount)
|
||||
playerNotificationService.jumpForward()
|
||||
}
|
||||
|
||||
override fun onRewind() {
|
||||
playerNotificationService.seekForward(seekAmount)
|
||||
playerNotificationService.jumpBackward()
|
||||
}
|
||||
|
||||
override fun onSeekTo(pos: Long) {
|
||||
|
@ -179,10 +176,10 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi
|
|||
handleMediaButtonClickCount()
|
||||
}
|
||||
KeyEvent.KEYCODE_MEDIA_NEXT -> {
|
||||
playerNotificationService.seekForward(seekAmount)
|
||||
playerNotificationService.jumpForward()
|
||||
}
|
||||
KeyEvent.KEYCODE_MEDIA_PREVIOUS -> {
|
||||
playerNotificationService.seekBackward(seekAmount)
|
||||
playerNotificationService.jumpBackward()
|
||||
}
|
||||
KeyEvent.KEYCODE_MEDIA_STOP -> {
|
||||
playerNotificationService.closePlayback()
|
||||
|
@ -226,22 +223,22 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi
|
|||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
if (2 == msg.what) {
|
||||
playerNotificationService.seekBackward(seekAmount)
|
||||
playerNotificationService.jumpBackward()
|
||||
playerNotificationService.play()
|
||||
}
|
||||
else if (msg.what >= 3) {
|
||||
playerNotificationService.seekForward(seekAmount)
|
||||
playerNotificationService.jumpForward()
|
||||
playerNotificationService.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example Using a custom action in android auto
|
||||
// override fun onCustomAction(action: String?, extras: Bundle?) {
|
||||
// super.onCustomAction(action, extras)
|
||||
//
|
||||
// if ("com.audiobookshelf.app.PLAYBACK_RATE" == action) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
override fun onCustomAction(action: String?, extras: Bundle?) {
|
||||
super.onCustomAction(action, extras)
|
||||
|
||||
when (action) {
|
||||
CUSTOM_ACTION_JUMP_FORWARD -> onFastForward()
|
||||
CUSTOM_ACTION_JUMP_BACKWARD -> onRewind()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
package com.audiobookshelf.app.player
|
||||
|
||||
const val CUSTOM_ACTION_JUMP_FORWARD = "com.audiobookshelf.customAction.jump_forward";
|
||||
const val CUSTOM_ACTION_JUMP_BACKWARD = "com.audiobookshelf.customAction.jump_backward";
|
|
@ -20,7 +20,6 @@ import android.util.Log
|
|||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.media.MediaBrowserServiceCompat
|
||||
import androidx.media.utils.MediaConstants
|
||||
import com.audiobookshelf.app.BuildConfig
|
||||
|
@ -30,9 +29,11 @@ import com.audiobookshelf.app.data.DeviceInfo
|
|||
import com.audiobookshelf.app.device.DeviceManager
|
||||
import com.audiobookshelf.app.media.MediaManager
|
||||
import com.audiobookshelf.app.server.ApiHandler
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||
import com.google.android.exoplayer2.*
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes
|
||||
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
|
||||
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector.CustomActionProvider
|
||||
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator
|
||||
import com.google.android.exoplayer2.source.MediaSource
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource
|
||||
|
@ -42,6 +43,7 @@ import com.google.android.exoplayer2.upstream.*
|
|||
import java.util.*
|
||||
import kotlin.concurrent.schedule
|
||||
|
||||
|
||||
const val SLEEP_TIMER_WAKE_UP_EXPIRATION = 120000L // 2m
|
||||
|
||||
class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||
|
@ -294,17 +296,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
|||
mediaSessionConnector.setQueueNavigator(queueNavigator)
|
||||
mediaSessionConnector.setPlaybackPreparer(MediaSessionPlaybackPreparer(this))
|
||||
|
||||
// Example adding custom action with icon in android auto
|
||||
// mediaSessionConnector.setCustomActionProviders(object : MediaSessionConnector.CustomActionProvider {
|
||||
// override fun onCustomAction(player: Player, action: String, extras: Bundle?) {
|
||||
// }
|
||||
// override fun getCustomAction(player: Player): PlaybackStateCompat.CustomAction? {
|
||||
// var icon = R.drawable.exo_icon_rewind
|
||||
// return PlaybackStateCompat.CustomAction.Builder(
|
||||
// "com.audiobookshelf.app.PLAYBACK_RATE", "Playback Rate", icon)
|
||||
// .build()
|
||||
// }
|
||||
// })
|
||||
mediaSessionConnector.setCustomActionProviders(
|
||||
JumpForwardCustomActionProvider(),
|
||||
JumpBackwardCustomActionProvider(),
|
||||
)
|
||||
|
||||
mediaSession.setCallback(MediaSessionCallback(this))
|
||||
|
||||
|
@ -320,13 +315,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
|||
1000 * 20 // 20s playback rebuffer
|
||||
).build()
|
||||
|
||||
val seekBackTime = DeviceManager.deviceData.deviceSettings?.jumpBackwardsTimeMs ?: 10000
|
||||
val seekForwardTime = DeviceManager.deviceData.deviceSettings?.jumpForwardTimeMs ?: 10000
|
||||
|
||||
mPlayer = ExoPlayer.Builder(this)
|
||||
.setLoadControl(customLoadControl)
|
||||
.setSeekBackIncrementMs(seekBackTime)
|
||||
.setSeekForwardIncrementMs(seekForwardTime)
|
||||
.setSeekBackIncrementMs(deviceSettings.jumpBackwardsTimeMs)
|
||||
.setSeekForwardIncrementMs(deviceSettings.jumpForwardTimeMs)
|
||||
.build()
|
||||
mPlayer.setHandleAudioBecomingNoisy(true)
|
||||
mPlayer.addListener(PlayerListener(this))
|
||||
|
@ -701,6 +693,22 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
|||
}
|
||||
}
|
||||
|
||||
fun skipToPrevious() {
|
||||
currentPlayer.seekToPrevious()
|
||||
}
|
||||
|
||||
fun skipToNext() {
|
||||
currentPlayer.seekToNext()
|
||||
}
|
||||
|
||||
fun jumpForward() {
|
||||
seekForward(deviceSettings.jumpForwardTimeMs)
|
||||
}
|
||||
|
||||
fun jumpBackward() {
|
||||
seekBackward(deviceSettings.jumpBackwardsTimeMs)
|
||||
}
|
||||
|
||||
fun seekForward(amount: Long) {
|
||||
seekPlayer(getCurrentTime() + amount)
|
||||
}
|
||||
|
@ -757,6 +765,9 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
|||
return DeviceInfo(Build.MANUFACTURER, Build.MODEL, Build.BRAND, Build.VERSION.SDK_INT, BuildConfig.VERSION_NAME)
|
||||
}
|
||||
|
||||
@get:JsonIgnore
|
||||
val deviceSettings get() = DeviceManager.deviceData.deviceSettings ?: DeviceSettings.default()
|
||||
|
||||
fun getPlayItemRequestPayload(forceTranscode:Boolean):PlayItemRequestPayload {
|
||||
return PlayItemRequestPayload(getMediaPlayer(), !forceTranscode, forceTranscode, getDeviceInfo())
|
||||
}
|
||||
|
@ -966,5 +977,39 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
|||
clientEventEmitter?.onNetworkMeteredChanged(unmetered)
|
||||
}
|
||||
}
|
||||
|
||||
inner class JumpBackwardCustomActionProvider : CustomActionProvider {
|
||||
override fun onCustomAction(player: Player, action: String, extras: Bundle?) {
|
||||
/*
|
||||
This does not appear to ever get called. Instead, MediaSessionCallback.onCustomAction() is
|
||||
responsible to reacting to a custom action.
|
||||
*/
|
||||
}
|
||||
|
||||
override fun getCustomAction(player: Player): PlaybackStateCompat.CustomAction? {
|
||||
return PlaybackStateCompat.CustomAction.Builder(
|
||||
CUSTOM_ACTION_JUMP_BACKWARD,
|
||||
getContext().getString(R.string.action_jump_backward),
|
||||
R.drawable.exo_icon_rewind
|
||||
).build()
|
||||
}
|
||||
}
|
||||
|
||||
inner class JumpForwardCustomActionProvider : CustomActionProvider {
|
||||
override fun onCustomAction(player: Player, action: String, extras: Bundle?) {
|
||||
/*
|
||||
This does not appear to ever get called. Instead, MediaSessionCallback.onCustomAction() is
|
||||
responsible to reacting to a custom action.
|
||||
*/
|
||||
}
|
||||
|
||||
override fun getCustomAction(player: Player): PlaybackStateCompat.CustomAction? {
|
||||
return PlaybackStateCompat.CustomAction.Builder(
|
||||
CUSTOM_ACTION_JUMP_FORWARD,
|
||||
getContext().getString(R.string.action_jump_forward),
|
||||
R.drawable.exo_icon_fastforward
|
||||
).build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,4 +6,6 @@
|
|||
<string name="custom_url_scheme">com.audiobookshelf.app</string>
|
||||
<string name="add_widget">Add widget</string>
|
||||
<string name="app_widget_description">Simple widget for audiobookshelf playback</string>
|
||||
<string name="action_jump_forward">Jump Forward</string>
|
||||
<string name="action_jump_backward">Jump Backward</string>
|
||||
</resources>
|
||||
|
|
|
@ -8,8 +8,8 @@ buildscript {
|
|||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.google.gms:google-services:4.3.5'
|
||||
classpath 'com.android.tools.build:gradle:7.2.0-beta04'
|
||||
classpath 'com.google.gms:google-services:4.3.10'
|
||||
classpath 'com.android.tools.build:gradle:7.2.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue