feat: automatic PiP animation (#648)
* Add automatic PiP animation * Fix linting * Fix linting * chore: fix merge conflict * fix: disable pip gesture when media is paused * fix: crash when gestures are disabled * fix: keep auto enter enabled after using button --------- Co-authored-by: Cd16d <98320806+cd16b@users.noreply.github.com> Co-authored-by: Jarne Demeulemeester <jarnedemeulemeester@gmail.com>
This commit is contained in:
parent
3ba5a73c74
commit
42df641c03
2 changed files with 51 additions and 27 deletions
|
@ -169,6 +169,11 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
viewModel.eventsChannelFlow.collect { event ->
|
||||
when (event) {
|
||||
is PlayerEvents.NavigateBack -> finish()
|
||||
is PlayerEvents.IsPlayingChanged -> {
|
||||
if (appPreferences.playerPipGesture) {
|
||||
setPictureInPictureParams(pipParams(event.isPlaying))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -263,12 +268,16 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
}
|
||||
|
||||
override fun onUserLeaveHint() {
|
||||
if (appPreferences.playerPipGesture && viewModel.player.isPlaying && !isControlsLocked) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S &&
|
||||
appPreferences.playerPipGesture &&
|
||||
viewModel.player.isPlaying &&
|
||||
!isControlsLocked
|
||||
) {
|
||||
pictureInPicture()
|
||||
}
|
||||
}
|
||||
|
||||
private fun pipParams(): PictureInPictureParams {
|
||||
private fun pipParams(enableAutoEnter: Boolean = viewModel.player.isPlaying): PictureInPictureParams {
|
||||
val displayAspectRatio = Rational(binding.playerView.width, binding.playerView.height)
|
||||
|
||||
val aspectRatio = binding.playerView.player?.videoSize?.let {
|
||||
|
@ -296,26 +305,21 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
)
|
||||
}
|
||||
|
||||
return PictureInPictureParams.Builder()
|
||||
val builder = PictureInPictureParams.Builder()
|
||||
.setAspectRatio(aspectRatio)
|
||||
.setSourceRectHint(sourceRectHint)
|
||||
.build()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
builder.setAutoEnterEnabled(enableAutoEnter)
|
||||
}
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
private fun pictureInPicture() {
|
||||
if (!isPipSupported) {
|
||||
return
|
||||
}
|
||||
binding.playerView.useController = false
|
||||
binding.playerView.findViewById<Button>(R.id.btn_skip_intro).isVisible = false
|
||||
|
||||
wasZoom = playerGestureHelper!!.isZoomEnabled
|
||||
playerGestureHelper?.updateZoomMode(false)
|
||||
|
||||
// Brightness mode Auto
|
||||
window.attributes = window.attributes.apply {
|
||||
screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
||||
}
|
||||
|
||||
try {
|
||||
enterPictureInPictureMode(pipParams())
|
||||
|
@ -327,7 +331,20 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
newConfig: Configuration,
|
||||
) {
|
||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
|
||||
if (!isInPictureInPictureMode) {
|
||||
when (isInPictureInPictureMode) {
|
||||
true -> {
|
||||
binding.playerView.useController = false
|
||||
binding.playerView.findViewById<Button>(R.id.btn_skip_intro).isVisible = false
|
||||
|
||||
wasZoom = playerGestureHelper?.isZoomEnabled ?: false
|
||||
playerGestureHelper?.updateZoomMode(false)
|
||||
|
||||
// Brightness mode Auto
|
||||
window.attributes = window.attributes.apply {
|
||||
screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
||||
}
|
||||
}
|
||||
false -> {
|
||||
binding.playerView.useController = true
|
||||
playerGestureHelper?.updateZoomMode(wasZoom)
|
||||
|
||||
|
@ -345,3 +362,4 @@ class PlayerActivity : BasePlayerActivity() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ constructor(
|
|||
} else {
|
||||
item.name
|
||||
}
|
||||
_uiState.update { it.copy(currentItemTitle = itemTitle) }
|
||||
_uiState.update { it.copy(currentItemTitle = itemTitle, fileLoaded = false) }
|
||||
|
||||
jellyfinRepository.postPlaybackStart(item.itemId)
|
||||
|
||||
|
@ -366,8 +366,14 @@ constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
super.onIsPlayingChanged(isPlaying)
|
||||
eventsChannel.trySend(PlayerEvents.IsPlayingChanged(isPlaying))
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface PlayerEvents {
|
||||
data object NavigateBack : PlayerEvents
|
||||
data class IsPlayingChanged(val isPlaying: Boolean) : PlayerEvents
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue