올바른 시간에 PiP를 입력합니다.

다음과 같은 상황에서는 앱이 PIP 모드로 전환되어서는 안 됩니다.

  • 동영상이 중지되거나 일시중지된 경우
  • 동영상 플레이어가 아닌 앱의 다른 페이지에 있는 경우

앱이 PIP 모드로 전환되는 시점을 제어하려면 mutableStateOf를 사용하여 동영상 플레이어의 상태를 추적하는 변수를 추가합니다.

동영상 재생 여부에 따라 상태 전환

동영상 플레이어 재생 여부에 따라 상태를 전환하려면 동영상 플레이어에 리스너를 추가합니다. 플레이어가 재생 중인지 여부에 따라 상태 변수의 상태를 전환합니다.

player.addListener(object : Player.Listener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
        shouldEnterPipMode = isPlaying
    }
})

플레이어의 출시 여부에 따라 상태 전환

플레이어가 해제되면 상태 변수를 false로 설정합니다.

fun releasePlayer() {
    shouldEnterPipMode = false
}

상태를 사용하여 PIP 모드가 시작되었는지 정의합니다 (Android 12 이전).

  1. PiP 12 미만을 추가할 때는 DisposableEffect가 사용되므로 newValue를 상태 변수로 설정하여 rememberUpdatedState를 사용하여 새 변수를 만들어야 합니다. 이렇게 하면 업데이트된 버전이 DisposableEffect 내에서 사용됩니다.
  2. OnUserLeaveHintListener가 트리거될 때의 동작을 정의하는 람다에서 enterPictureInPictureMode() 호출 주위에 상태 변수가 있는 if 문을 추가합니다.

    val currentShouldEnterPipMode by rememberUpdatedState(newValue = shouldEnterPipMode)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
        Build.VERSION.SDK_INT < Build.VERSION_CODES.S
    ) {
        val context = LocalContext.current
        DisposableEffect(context) {
            val onUserLeaveBehavior: () -> Unit = {
                if (currentShouldEnterPipMode) {
                    context.findActivity()
                        .enterPictureInPictureMode(PictureInPictureParams.Builder().build())
                }
            }
            context.findActivity().addOnUserLeaveHintListener(
                onUserLeaveBehavior
            )
            onDispose {
                context.findActivity().removeOnUserLeaveHintListener(
                    onUserLeaveBehavior
                )
            }
        }
    } else {
        Log.i("PiP info", "API does not support PiP")
    }

상태를 사용하여 PIP 모드가 시작되었는지 정의합니다 (Android 12 이후).

앱이 적절한 시점에만 PIP 모드로 전환되도록 상태 변수를 setAutoEnterEnabled에 전달합니다.

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()

    // Add autoEnterEnabled for versions S and up
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)

setSourceRectHint를 사용하여 부드러운 애니메이션 구현

setSourceRectHint API는 PIP 모드로 전환할 때 더 부드러운 애니메이션을 만듭니다. Android 12 이상에서는 PIP 모드를 종료할 때 더 매끄러운 애니메이션도 만듭니다. 이 API를 PIP 빌더에 추가하여 PIP로 전환된 후 표시되는 활동 영역을 나타냅니다.

  1. 상태에서 앱이 PiP 모드로 전환되어야 한다고 정의하는 경우에만 buildersetSourceRectHint()를 추가합니다. 이렇게 하면 앱이 PiP를 시작할 필요가 없는 경우 sourceRect를 계산하지 않아도 됩니다.
  2. sourceRect 값을 설정하려면 수정자의 onGloballyPositioned 함수에서 제공된 layoutCoordinates를 사용합니다.
  3. builder에서 setSourceRectHint()을 호출하고 sourceRect 변수를 전달합니다.

val context = LocalContext.current

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()
    if (shouldEnterPipMode) {
        val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
        builder.setSourceRectHint(sourceRect)
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)