From 0b4c999018318b3959ac71b8320ea8e318d49a9a Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 23 Apr 2022 15:06:51 -0500 Subject: [PATCH] Android persist playback rate #138 --- .../app/player/MediaSessionCallback.kt | 6 +- .../player/MediaSessionPlaybackPreparer.kt | 6 +- .../app/player/PlayerNotificationService.kt | 65 +++++++------- .../app/plugins/AbsAudioPlayer.kt | 89 ++++++++++--------- components/app/AudioPlayerContainer.vue | 7 +- 5 files changed, 90 insertions(+), 83 deletions(-) diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionCallback.kt b/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionCallback.kt index 9676fdfa..512ad91a 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionCallback.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionCallback.kt @@ -30,7 +30,7 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi playerNotificationService.mediaManager.play(li, playerNotificationService.getMediaPlayer()) { Log.d(tag, "About to prepare player with ${it.displayTitle}") Handler(Looper.getMainLooper()).post() { - playerNotificationService.preparePlayer(it,true) + playerNotificationService.preparePlayer(it,true,null) } } } @@ -52,7 +52,7 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi playerNotificationService.mediaManager.play(li, playerNotificationService.getMediaPlayer()) { Log.d(tag, "About to prepare player with ${it.displayTitle}") Handler(Looper.getMainLooper()).post() { - playerNotificationService.preparePlayer(it,true) + playerNotificationService.preparePlayer(it,true,null) } } } @@ -100,7 +100,7 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi playerNotificationService.mediaManager.play(li, playerNotificationService.getMediaPlayer()) { Log.d(tag, "About to prepare player with ${it.displayTitle}") Handler(Looper.getMainLooper()).post() { - playerNotificationService.preparePlayer(it,true) + playerNotificationService.preparePlayer(it,true,null) } } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionPlaybackPreparer.kt b/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionPlaybackPreparer.kt index a5ccd8c0..109b755d 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionPlaybackPreparer.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionPlaybackPreparer.kt @@ -32,7 +32,7 @@ class MediaSessionPlaybackPreparer(var playerNotificationService:PlayerNotificat playerNotificationService.mediaManager.getFirstItem()?.let { li -> playerNotificationService.mediaManager.play(li, playerNotificationService.getMediaPlayer()) { Handler(Looper.getMainLooper()).post() { - playerNotificationService.preparePlayer(it,playWhenReady) + playerNotificationService.preparePlayer(it,playWhenReady,null) } } } @@ -46,7 +46,7 @@ class MediaSessionPlaybackPreparer(var playerNotificationService:PlayerNotificat playerNotificationService.mediaManager.play(li, playerNotificationService.getMediaPlayer()) { Log.d(tag, "About to prepare player with ${it.displayTitle}") Handler(Looper.getMainLooper()).post() { - playerNotificationService.preparePlayer(it,playWhenReady) + playerNotificationService.preparePlayer(it,playWhenReady,null) } } } @@ -58,7 +58,7 @@ class MediaSessionPlaybackPreparer(var playerNotificationService:PlayerNotificat playerNotificationService.mediaManager.play(li, playerNotificationService.getMediaPlayer()) { Log.d(tag, "About to prepare player with ${it.displayTitle}") Handler(Looper.getMainLooper()).post() { - playerNotificationService.preparePlayer(it,playWhenReady) + playerNotificationService.preparePlayer(it,playWhenReady,null) } } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt index 6b7dff07..875ca690 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt @@ -9,7 +9,6 @@ import android.hardware.SensorManager import android.os.* import android.support.v4.media.MediaBrowserCompat import android.support.v4.media.MediaDescriptionCompat -import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.session.MediaControllerCompat import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.PlaybackStateCompat @@ -31,7 +30,6 @@ import com.google.android.exoplayer2.source.ProgressiveMediaSource import com.google.android.exoplayer2.source.hls.HlsMediaSource import com.google.android.exoplayer2.ui.PlayerNotificationManager import com.google.android.exoplayer2.upstream.* -import io.paperdb.Paper import java.util.* import kotlin.concurrent.schedule @@ -82,8 +80,9 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { private var channelName = "Audiobookshelf Channel" private var currentPlaybackSession:PlaybackSession? = null + private var initialPlaybackRate:Float? = null - var isAndroidAuto = false + private var isAndroidAuto = false // The following are used for the shake detection private var isShakeSensorRegistered:Boolean = false @@ -164,7 +163,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { ctx = this // Initialize player - var customLoadControl:LoadControl = DefaultLoadControl.Builder().setBufferDurationsMs( + val customLoadControl:LoadControl = DefaultLoadControl.Builder().setBufferDurationsMs( 1000 * 20, // 20s min buffer 1000 * 45, // 45s max buffer 1000 * 5, // 5s playback start @@ -178,7 +177,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { .build() mPlayer.setHandleAudioBecomingNoisy(true) mPlayer.addListener(PlayerListener(this)) - var audioAttributes:AudioAttributes = AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).setContentType(C.CONTENT_TYPE_SPEECH).build() + val audioAttributes:AudioAttributes = AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).setContentType(C.CONTENT_TYPE_SPEECH).build() mPlayer.setAudioAttributes(audioAttributes, true) currentPlayer = mPlayer @@ -205,7 +204,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { val sessionActivityPendingIntent = packageManager?.getLaunchIntentForPackage(packageName)?.let { sessionIntent -> - PendingIntent.getActivity(this, 0, sessionIntent, 0) + PendingIntent.getActivity(this, 0, sessionIntent, PendingIntent.FLAG_IMMUTABLE) } mediaSession = MediaSessionCompat(this, tag) @@ -275,7 +274,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { /* User callable methods */ - fun preparePlayer(playbackSession: PlaybackSession, playWhenReady:Boolean) { + fun preparePlayer(playbackSession: PlaybackSession, playWhenReady:Boolean, playbackRate:Float?) { + val playbackRateToUse = playbackRate ?: initialPlaybackRate ?: 1f + initialPlaybackRate = playbackRate + playbackSession.mediaPlayer = getMediaPlayer() if (playbackSession.mediaPlayer == "cast-player" && playbackSession.isLocal) { @@ -296,9 +298,9 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { clientEventEmitter?.onPlaybackSession(playbackSession) - var metadata = playbackSession.getMediaMetadataCompat() + val metadata = playbackSession.getMediaMetadataCompat() mediaSession.setMetadata(metadata) - var mediaItems = playbackSession.getMediaItems() + val mediaItems = playbackSession.getMediaItems() if (mediaItems.isEmpty()) { Log.e(tag, "Invalid playback session no media items to play") @@ -307,20 +309,20 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { } if (mPlayer == currentPlayer) { - var mediaSource:MediaSource + val mediaSource:MediaSource if (playbackSession.isLocal) { Log.d(tag, "Playing Local Item") - var dataSourceFactory = DefaultDataSource.Factory(ctx) + val dataSourceFactory = DefaultDataSource.Factory(ctx) mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItems[0]) } else if (!playbackSession.isHLS) { Log.d(tag, "Direct Playing Item") - var dataSourceFactory = DefaultHttpDataSource.Factory() + val dataSourceFactory = DefaultHttpDataSource.Factory() dataSourceFactory.setUserAgent(channelId) mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItems[0]) } else { Log.d(tag, "Playing HLS Item") - var dataSourceFactory = DefaultHttpDataSource.Factory() + val dataSourceFactory = DefaultHttpDataSource.Factory() dataSourceFactory.setUserAgent(channelId) dataSourceFactory.setDefaultRequestProperties(hashMapOf("Authorization" to "Bearer ${DeviceManager.token}")) mediaSource = HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItems[0]) @@ -333,8 +335,8 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { currentPlayer.addMediaItems(mediaItems.subList(1, mediaItems.size)) Log.d(tag, "currentPlayer total media items ${currentPlayer.mediaItemCount}") - var currentTrackIndex = playbackSession.getCurrentTrackIndex() - var currentTrackTime = playbackSession.getCurrentTrackTimeMs() + val currentTrackIndex = playbackSession.getCurrentTrackIndex() + val currentTrackTime = playbackSession.getCurrentTrackTimeMs() Log.d(tag, "currentPlayer current track index $currentTrackIndex & current track time $currentTrackTime") currentPlayer.seekTo(currentTrackIndex, currentTrackTime) } else { @@ -343,16 +345,15 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { Log.d(tag, "Prepare complete for session ${currentPlaybackSession?.displayTitle} | ${currentPlayer.mediaItemCount}") currentPlayer.playWhenReady = playWhenReady - currentPlayer.setPlaybackSpeed(1f) // TODO: Playback speed should come from settings + currentPlayer.setPlaybackSpeed(playbackRateToUse) currentPlayer.prepare() - } else if (castPlayer != null) { - var currentTrackIndex = playbackSession.getCurrentTrackIndex() - var currentTrackTime = playbackSession.getCurrentTrackTimeMs() - var mediaType = playbackSession.mediaType + val currentTrackIndex = playbackSession.getCurrentTrackIndex() + val currentTrackTime = playbackSession.getCurrentTrackTimeMs() + val mediaType = playbackSession.mediaType Log.d(tag, "Loading cast player $currentTrackIndex $currentTrackTime $mediaType") - castPlayer?.load(mediaItems, currentTrackIndex, currentTrackTime, playWhenReady, 1f, mediaType) + castPlayer?.load(mediaItems, currentTrackIndex, currentTrackTime, playWhenReady, playbackRateToUse, mediaType) } } @@ -360,14 +361,14 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { // On error and was attempting to direct play - fallback to transcode currentPlaybackSession?.let { playbackSession -> if (playbackSession.isDirectPlay) { - var mediaPlayer = getMediaPlayer() + val mediaPlayer = getMediaPlayer() Log.d(tag, "Fallback to transcode $mediaPlayer") - var libraryItemId = playbackSession.libraryItemId ?: "" // Must be true since direct play - var episodeId = playbackSession.episodeId + val libraryItemId = playbackSession.libraryItemId ?: "" // Must be true since direct play + val episodeId = playbackSession.episodeId apiHandler.playLibraryItem(libraryItemId, episodeId, true, mediaPlayer) { Handler(Looper.getMainLooper()).post() { - preparePlayer(it, true) + preparePlayer(it, true, null) } } } else { @@ -378,7 +379,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { } fun switchToPlayer(useCastPlayer: Boolean) { - var wasPlaying = currentPlayer.isPlaying + val wasPlaying = currentPlayer.isPlaying if (useCastPlayer) { if (currentPlayer == castPlayer) { Log.d(tag, "switchToPlayer: Already using Cast Player " + castPlayer?.deviceInfo) @@ -420,7 +421,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { if (wasPlaying) { // media is paused when switching players clientEventEmitter?.onPlayingUpdate(false) } - preparePlayer(it, false) + preparePlayer(it, false, null) } } @@ -499,8 +500,8 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { Log.d(tag, "seekPlayer mediaCount = ${currentPlayer.mediaItemCount} | $time") if (currentPlayer.mediaItemCount > 1) { currentPlaybackSession?.currentTime = time / 1000.0 - var newWindowIndex = currentPlaybackSession?.getCurrentTrackIndex() ?: 0 - var newTimeOffset = currentPlaybackSession?.getCurrentTrackTimeMs() ?: 0 + val newWindowIndex = currentPlaybackSession?.getCurrentTrackIndex() ?: 0 + val newTimeOffset = currentPlaybackSession?.getCurrentTrackTimeMs() ?: 0 currentPlayer.seekTo(newWindowIndex, newTimeOffset) } else { currentPlayer.seekTo(time) @@ -528,7 +529,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { } fun sendClientMetadata(playerState: PlayerState) { - var duration = currentPlaybackSession?.getTotalDuration() ?: 0.0 + val duration = currentPlaybackSession?.getTotalDuration() ?: 0.0 clientEventEmitter?.onMetadata(PlaybackMetadata(duration, getCurrentTimeSeconds(), playerState)) } @@ -593,7 +594,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { override fun onLoadChildren(parentMediaId: String, result: Result>) { Log.d(tag, "ON LOAD CHILDREN $parentMediaId") - var flag = if (parentMediaId == AUTO_MEDIA_ROOT) MediaBrowserCompat.MediaItem.FLAG_BROWSABLE else MediaBrowserCompat.MediaItem.FLAG_PLAYABLE + val flag = if (parentMediaId == AUTO_MEDIA_ROOT) MediaBrowserCompat.MediaItem.FLAG_BROWSABLE else MediaBrowserCompat.MediaItem.FLAG_PLAYABLE result.detach() @@ -652,7 +653,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { shakeSensorUnregisterTask?.cancel() Log.d(tag, "Registering shake SENSOR ${mAccelerometer?.isWakeUpSensor}") - var success = mSensorManager!!.registerListener( + val success = mSensorManager!!.registerListener( mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI diff --git a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsAudioPlayer.kt b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsAudioPlayer.kt index 2d62af52..3bf086d8 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsAudioPlayer.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsAudioPlayer.kt @@ -23,8 +23,8 @@ class AbsAudioPlayer : Plugin() { private val tag = "AbsAudioPlayer" var jacksonMapper = jacksonObjectMapper().enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature()) - lateinit var mainActivity: MainActivity - lateinit var apiHandler:ApiHandler + private lateinit var mainActivity: MainActivity + private lateinit var apiHandler:ApiHandler lateinit var castManager:CastManager lateinit var playerNotificationService: PlayerNotificationService @@ -37,7 +37,7 @@ class AbsAudioPlayer : Plugin() { initCastManager() - var foregroundServiceReady : () -> Unit = { + val foregroundServiceReady : () -> Unit = { playerNotificationService = mainActivity.foregroundService playerNotificationService.clientEventEmitter = (object : PlayerNotificationService.ClientEventEmitter { @@ -58,7 +58,7 @@ class AbsAudioPlayer : Plugin() { } override fun onPrepare(audiobookId: String, playWhenReady: Boolean) { - var jsobj = JSObject() + val jsobj = JSObject() jsobj.put("audiobookId", audiobookId) jsobj.put("playWhenReady", playWhenReady) notifyListeners("onPrepareMedia", jsobj) @@ -89,13 +89,13 @@ class AbsAudioPlayer : Plugin() { } fun emit(evtName: String, value: Any) { - var ret = JSObject() + val ret = JSObject() ret.put("value", value) notifyListeners(evtName, ret) } - fun initCastManager() { - var connListener = object: CastManager.ChromecastListener() { + private fun initCastManager() { + val connListener = object: CastManager.ChromecastListener() { override fun onReceiverAvailableUpdate(available: Boolean) { Log.d(tag, "ChromecastListener: CAST Receiver Update Available $available") isCastAvailable = available @@ -141,9 +141,10 @@ class AbsAudioPlayer : Plugin() { } } - var libraryItemId = call.getString("libraryItemId", "").toString() - var episodeId = call.getString("episodeId", "").toString() - var playWhenReady = call.getBoolean("playWhenReady") == true + val libraryItemId = call.getString("libraryItemId", "").toString() + val episodeId = call.getString("episodeId", "").toString() + val playWhenReady = call.getBoolean("playWhenReady") == true + var playbackRate = call.getFloat("playbackRate",1f) ?: 1f if (libraryItemId.isEmpty()) { Log.e(tag, "Invalid call to play library item no library item id") @@ -153,8 +154,8 @@ class AbsAudioPlayer : Plugin() { if (libraryItemId.startsWith("local")) { // Play local media item DeviceManager.dbManager.getLocalLibraryItem(libraryItemId)?.let { var episode: PodcastEpisode? = null - if (!episodeId.isNullOrEmpty()) { - var podcastMedia = it.media as Podcast + if (episodeId.isNotEmpty()) { + val podcastMedia = it.media as Podcast episode = podcastMedia.episodes?.find { ep -> ep.id == episodeId } if (episode == null) { Log.e(tag, "prepareLibraryItem: Podcast episode not found $episodeId") @@ -162,21 +163,21 @@ class AbsAudioPlayer : Plugin() { } } - Handler(Looper.getMainLooper()).post() { + Handler(Looper.getMainLooper()).post { Log.d(tag, "prepareLibraryItem: Preparing Local Media item ${jacksonMapper.writeValueAsString(it)}") - var playbackSession = it.getPlaybackSession(episode) - playerNotificationService.preparePlayer(playbackSession, playWhenReady) + val playbackSession = it.getPlaybackSession(episode) + playerNotificationService.preparePlayer(playbackSession, playWhenReady, playbackRate) } return call.resolve(JSObject()) } } else { // Play library item from server - var mediaPlayer = playerNotificationService.getMediaPlayer() + val mediaPlayer = playerNotificationService.getMediaPlayer() apiHandler.playLibraryItem(libraryItemId, episodeId, false, mediaPlayer) { - Handler(Looper.getMainLooper()).post() { + Handler(Looper.getMainLooper()).post { Log.d(tag, "Preparing Player TEST ${jacksonMapper.writeValueAsString(it)}") - playerNotificationService.preparePlayer(it, playWhenReady) + playerNotificationService.preparePlayer(it, playWhenReady, playbackRate) } call.resolve(JSObject(jacksonMapper.writeValueAsString(it))) @@ -186,9 +187,9 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun getCurrentTime(call: PluginCall) { - Handler(Looper.getMainLooper()).post() { - var currentTime = playerNotificationService.getCurrentTimeSeconds() - var bufferedTime = playerNotificationService.getBufferedTimeSeconds() + Handler(Looper.getMainLooper()).post { + val currentTime = playerNotificationService.getCurrentTimeSeconds() + val bufferedTime = playerNotificationService.getBufferedTimeSeconds() val ret = JSObject() ret.put("value", currentTime) ret.put("bufferedTime", bufferedTime) @@ -198,7 +199,7 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun pausePlayer(call: PluginCall) { - Handler(Looper.getMainLooper()).post() { + Handler(Looper.getMainLooper()).post { playerNotificationService.pause() call.resolve() } @@ -206,7 +207,7 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun playPlayer(call: PluginCall) { - Handler(Looper.getMainLooper()).post() { + Handler(Looper.getMainLooper()).post { playerNotificationService.play() call.resolve() } @@ -214,16 +215,16 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun playPause(call: PluginCall) { - Handler(Looper.getMainLooper()).post() { - var playing = playerNotificationService.playPause() + Handler(Looper.getMainLooper()).post { + val playing = playerNotificationService.playPause() call.resolve(JSObject("{\"playing\":$playing}")) } } @PluginMethod fun seek(call: PluginCall) { - var time:Int = call.getInt("value", 0) ?: 0 // Value in seconds - Handler(Looper.getMainLooper()).post() { + val time:Int = call.getInt("value", 0) ?: 0 // Value in seconds + Handler(Looper.getMainLooper()).post { playerNotificationService.seekPlayer(time * 1000L) // convert to ms call.resolve() } @@ -231,8 +232,8 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun seekForward(call: PluginCall) { - var amount:Int = call.getInt("value", 0) ?: 0 - Handler(Looper.getMainLooper()).post() { + val amount:Int = call.getInt("value", 0) ?: 0 + Handler(Looper.getMainLooper()).post { playerNotificationService.seekForward(amount * 1000L) // convert to ms call.resolve() } @@ -240,8 +241,8 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun seekBackward(call: PluginCall) { - var amount:Int = call.getInt("value", 0) ?: 0 // Value in seconds - Handler(Looper.getMainLooper()).post() { + val amount:Int = call.getInt("value", 0) ?: 0 // Value in seconds + Handler(Looper.getMainLooper()).post { playerNotificationService.seekBackward(amount * 1000L) // convert to ms call.resolve() } @@ -249,9 +250,9 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun setPlaybackSpeed(call: PluginCall) { - var playbackSpeed:Float = call.getFloat("value", 1.0f) ?: 1.0f + val playbackSpeed:Float = call.getFloat("value", 1.0f) ?: 1.0f - Handler(Looper.getMainLooper()).post() { + Handler(Looper.getMainLooper()).post { playerNotificationService.setPlaybackSpeed(playbackSpeed) call.resolve() } @@ -259,7 +260,7 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun closePlayback(call: PluginCall) { - Handler(Looper.getMainLooper()).post() { + Handler(Looper.getMainLooper()).post { playerNotificationService.closePlayback() call.resolve() } @@ -267,11 +268,11 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun setSleepTimer(call: PluginCall) { - var time:Long = call.getString("time", "360000")!!.toLong() - var isChapterTime:Boolean = call.getBoolean("isChapterTime", false) == true + val time:Long = call.getString("time", "360000")!!.toLong() + val isChapterTime:Boolean = call.getBoolean("isChapterTime", false) == true - Handler(Looper.getMainLooper()).post() { - var success:Boolean = playerNotificationService.sleepTimerManager.setSleepTimer(time, isChapterTime) + Handler(Looper.getMainLooper()).post { + val success:Boolean = playerNotificationService.sleepTimerManager.setSleepTimer(time, isChapterTime) val ret = JSObject() ret.put("success", success) call.resolve(ret) @@ -280,7 +281,7 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun getSleepTimerTime(call: PluginCall) { - var time = playerNotificationService.sleepTimerManager.getSleepTimerTime() + val time = playerNotificationService.sleepTimerManager.getSleepTimerTime() val ret = JSObject() ret.put("value", time) call.resolve(ret) @@ -288,9 +289,9 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun increaseSleepTime(call: PluginCall) { - var time:Long = call.getString("time", "300000")!!.toLong() + val time:Long = call.getString("time", "300000")!!.toLong() - Handler(Looper.getMainLooper()).post() { + Handler(Looper.getMainLooper()).post { playerNotificationService.sleepTimerManager.increaseSleepTime(time) val ret = JSObject() ret.put("success", true) @@ -300,9 +301,9 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun decreaseSleepTime(call: PluginCall) { - var time:Long = call.getString("time", "300000")!!.toLong() + val time:Long = call.getString("time", "300000")!!.toLong() - Handler(Looper.getMainLooper()).post() { + Handler(Looper.getMainLooper()).post { playerNotificationService.sleepTimerManager.decreaseSleepTime(time) val ret = JSObject() ret.put("success", true) @@ -338,7 +339,7 @@ class AbsAudioPlayer : Plugin() { @PluginMethod fun getIsCastAvailable(call: PluginCall) { - var jsobj = JSObject() + val jsobj = JSObject() jsobj.put("value", isCastAvailable) call.resolve(jsobj) } diff --git a/components/app/AudioPlayerContainer.vue b/components/app/AudioPlayerContainer.vue index b90a373b..584239fb 100644 --- a/components/app/AudioPlayerContainer.vue +++ b/components/app/AudioPlayerContainer.vue @@ -184,8 +184,13 @@ export default { this.serverLibraryItemId = null + var playbackRate = 1 + if (this.$refs.audioPlayer) { + playbackRate = this.$refs.audioPlayer.currentPlaybackRate || 1 + } + console.log('Called playLibraryItem', libraryItemId) - AbsAudioPlayer.prepareLibraryItem({ libraryItemId, episodeId, playWhenReady: true }) + AbsAudioPlayer.prepareLibraryItem({ libraryItemId, episodeId, playWhenReady: true, playbackRate }) .then((data) => { console.log('Library item play response', JSON.stringify(data)) if (!libraryItemId.startsWith('local')) {