diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java index 6a5eed4e20..6f2f00f192 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java @@ -86,6 +86,7 @@ public class PlaybackController { private VideoOptions mCurrentOptions; private int mDefaultSubIndex = -1; private int mDefaultAudioIndex = -1; + private double mRequestedPlaybackSpeed = -1.0; private PlayMethod mPlaybackMethod = PlayMethod.Transcode; @@ -154,7 +155,10 @@ public void setPlaybackMethod(PlayMethod value) { } public void setPlaybackSpeed(Double speed){ - mVideoManager.setPlaybackSpeed(speed); + mRequestedPlaybackSpeed = speed; + if (hasInitializedVideoManager()) { + mVideoManager.setPlaybackSpeed(speed); + } } public BaseItemDto getCurrentlyPlayingItem() { @@ -676,6 +680,7 @@ private void startItem(BaseItemDto item, long position, StreamInfo response) { // get subtitle info mSubtitleStreams = response.GetSubtitleProfiles(false, apiClient.getValue().getApiUrl(), apiClient.getValue().getAccessToken()); + mVideoManager.setPlaybackSpeed(mRequestedPlaybackSpeed); if (mFragment != null) mFragment.updateDisplay(); diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/overlay/CustomPlaybackTransportControlGlue.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/overlay/CustomPlaybackTransportControlGlue.java index 6c4cd1ab84..d33b3ac35d 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/overlay/CustomPlaybackTransportControlGlue.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/overlay/CustomPlaybackTransportControlGlue.java @@ -175,7 +175,7 @@ private void initActions(Context context) { selectAudioAction.setLabels(new String[]{context.getString(R.string.lbl_audio_track)}); closedCaptionsAction = new ClosedCaptionsAction(context, this); closedCaptionsAction.setLabels(new String[]{context.getString(R.string.lbl_subtitle_track)}); - playbackSpeedAction = new PlaybackSpeedAction(context, this); + playbackSpeedAction = new PlaybackSpeedAction(context, this, playbackController); playbackSpeedAction.setLabels(new String[]{context.getString(R.string.lbl_playback_speed)}); adjustAudioDelayAction = new AdjustAudioDelayAction(context, this); adjustAudioDelayAction.setLabels(new String[]{context.getString(R.string.lbl_audio_delay)}); diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/overlay/action/PlaybackSpeedAction.kt b/app/src/main/java/org/jellyfin/androidtv/ui/playback/overlay/action/PlaybackSpeedAction.kt index c80cd2776a..7329cde07c 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/overlay/action/PlaybackSpeedAction.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/overlay/action/PlaybackSpeedAction.kt @@ -13,8 +13,10 @@ import org.jellyfin.androidtv.ui.playback.VideoSpeedController class PlaybackSpeedAction( context: Context, - customPlaybackTransportControlGlue: CustomPlaybackTransportControlGlue + customPlaybackTransportControlGlue: CustomPlaybackTransportControlGlue, + playbackController: PlaybackController ) : CustomAction(context, customPlaybackTransportControlGlue) { + private val speedController = VideoSpeedController(playbackController) private val speeds = VideoSpeedController.Companion.SpeedSteps.values() init { @@ -26,11 +28,10 @@ class PlaybackSpeedAction( leanbackOverlayFragment: LeanbackOverlayFragment, context: Context, view: View ) { - val speedController = VideoSpeedController(playbackController) val speedMenu = populateMenu(context, view, speedController) speedMenu.setOnDismissListener { leanbackOverlayFragment.setFading(true) } - + speedMenu.setOnMenuItemClickListener { menuItem -> speedController.setNewSpeed(speeds[menuItem.itemId]) speedMenu.dismiss() diff --git a/app/src/test/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerTest.kt b/app/src/test/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerTest.kt index 65ae0a59ca..e92f2f73cd 100644 --- a/app/src/test/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerTest.kt +++ b/app/src/test/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerTest.kt @@ -4,7 +4,12 @@ import io.mockk.* import org.jellyfin.androidtv.preference.Preference import org.jellyfin.androidtv.preference.UserPreferences import org.jellyfin.androidtv.preference.constant.PreferredVideoPlayer +import org.jellyfin.androidtv.util.Utils +import org.jellyfin.apiclient.interaction.ApiClient import org.jellyfin.apiclient.model.dto.BaseItemDto +import org.jellyfin.apiclient.model.dto.BaseItemType +import org.jellyfin.apiclient.model.entities.LocationType +import org.jellyfin.apiclient.model.library.PlayAccess import org.junit.After import org.junit.Assert.* import org.junit.Before @@ -17,21 +22,26 @@ import org.koin.test.KoinTest class PlaybackControllerTest : KoinTest { // Mockk managed deps - private val mockBaseItems = mockk>() + private val mockBaseItems = listOf(mockk()) private val mockFragment = mockk() lateinit var playbackController: PlaybackController // Koin managed modules + lateinit var mockApiClient: ApiClient lateinit var mockUserPreferences: UserPreferences private fun prepDiMocks(): Module { + mockApiClient = mockk(relaxed = true) mockUserPreferences = mockk(relaxed = true) + + // Required in the constructor every { mockUserPreferences.get(any>()) } returns PreferredVideoPlayer.EXOPLAYER return module { + single { mockApiClient } single { mockUserPreferences } } } @@ -58,9 +68,17 @@ class PlaybackControllerTest : KoinTest { doubleArrayOf(0.25, 0.5, 1.0, 2.5, 200.0).forEach { i -> val mockVideoManager = mockk(relaxed = true) playbackController.mVideoManager = mockVideoManager + every { mockVideoManager.isInitialized } returns true + playbackController.setPlaybackSpeed(i) + verify { mockVideoManager.setPlaybackSpeed(i) } } } + @Test + fun testSetupPlaybackSpeedHandlesNoVideo() { + playbackController.mVideoManager = null + playbackController.setPlaybackSpeed(2.0) + } }