From 0e71eb030868545ead3f84ba08f76f992087eedd Mon Sep 17 00:00:00 2001 From: huggenknubbel Date: Sun, 30 Aug 2026 23:38:27 +0200 Subject: [PATCH] cast: let the sleep timer fade out on a cast device too The sleep timer fades playback down to 10% over its last minute by setting the player's volume. CastPlayer.setVolume was an empty stub and getVolume returned zero, so while casting the fade did nothing at all. Both now go through the media stream volume the Cast SDK offers. That is the receiver's volume for this stream only: the device volume stays where the user put it, and on a cast group the balance between its members is untouched, because the receiver applies the stream volume to the group's output. --- .../com/audiobookshelf/app/player/CastPlayer.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt b/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt index a31bacf4..56687a8d 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt @@ -815,12 +815,21 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { return AudioAttributes.DEFAULT } + /** + * The volume of the media stream, which is what the sleep timer fades - not the volume of the + * receiver. The device volume stays where the user put it, and on a cast group the balance + * between its members is left alone, because the receiver applies this to the group's output. + */ override fun setVolume(audioVolume: Float) { - + try { + remoteMediaClient?.setStreamVolume(audioVolume.toDouble().coerceIn(0.0, 1.0)) + } catch (e: Exception) { + Log.e(tag, "Failed to set the cast stream volume", e) + } } override fun getVolume(): Float { - return 0F + return remoteMediaClient?.mediaStatus?.streamVolume?.toFloat() ?: 1F } override fun clearVideoSurface() {