diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerHelper.kt b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerHelper.kt index 9bdf6fda52..6c6236a7b2 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerHelper.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerHelper.kt @@ -45,10 +45,10 @@ fun PlaybackController.applyMediaSegments( when (action) { MediaSegmentAction.SKIP -> addSkipAction(mediaSegment) + MediaSegmentAction.MUTE -> addMuteAction(mediaSegment) - // TODO implement these + // TODO implement the UI MediaSegmentAction.ASK_TO_SKIP -> TODO() - MediaSegmentAction.MUTE -> TODO() MediaSegmentAction.NOTHING -> Unit } @@ -60,6 +60,9 @@ fun PlaybackController.applyMediaSegments( private fun PlaybackController.addSkipAction(mediaSegment: MediaSegmentDto) { mVideoManager.mExoPlayer .createMessage { messageType: Int, payload: Any? -> + // We can't seek directly on the ExoPlayer instance as not all media is seekable + // the seek function in the PlaybackController checks this and optionally starts a transcode + // at the requested position fragment.lifecycleScope.launch(Dispatchers.Main) { seek(mediaSegment.endTicks.ticks.inWholeMilliseconds) } @@ -69,3 +72,39 @@ private fun PlaybackController.addSkipAction(mediaSegment: MediaSegmentDto) { .setDeleteAfterDelivery(false) .send() } + +@OptIn(UnstableApi::class) +private fun PlaybackController.addMuteAction(mediaSegment: MediaSegmentDto) { + // TODO: This action does not currently restore the volume if manually seeked over it + // as exoplayer only triggers a message event when the seekhead goes over its position naturally + // TODO: The action also does not enable the mute state when manually seeking into it + if (mediaSegment.endTicks <= mediaSegment.startTicks) return + + var previousVolume: Float? = null + + mVideoManager.mExoPlayer + .createMessage { messageType: Int, payload: Any? -> + fragment.lifecycleScope.launch(Dispatchers.Main) { + previousVolume = mVideoManager.mExoPlayer.volume + mVideoManager.mExoPlayer.volume = 0f + } + } + .setPosition(mediaSegment.startTicks.ticks.inWholeMilliseconds) + .setDeleteAfterDelivery(false) + .send() + + mVideoManager.mExoPlayer + .createMessage { messageType: Int, payload: Any? -> + // Only restore if the volume is still muted and previousVolume is still set + fragment.lifecycleScope.launch(Dispatchers.Main) { + if (mVideoManager.mExoPlayer.volume == 0f) { + previousVolume?.let { + mVideoManager.mExoPlayer.volume = it + } + } + } + } + .setPosition(mediaSegment.endTicks.ticks.inWholeMilliseconds) + .setDeleteAfterDelivery(false) + .send() +}