ExoPlayer media3 Jetpack Compose 中的视频播放器视图相互重叠?

问题描述 投票:0回答:1

我有一个HorizontalPager,其中包含两个页面和每个页面中的两个VideoPlayerView。问题是当我播放一个视频并滚动到另一页面时,另一个页面视频播放器显示来自其他页面的相同视频,而不是显示它自己的视频。视频需要缩放和裁剪以适合高度或全屏。我认为视频宽度太大并且溢出,因为我正在缩放以保持比例。我们可以将视频限制在一个寻呼机宽度内吗?

Code for VideoPlayerView is


@OptIn(UnstableApi::class) @Composable
fun VideoPlayerView(
    uri: String,
    modifier: Modifier = Modifier
) {
    val context = LocalContext.current
    val density = LocalDensity.current
    var isReady by remember{ mutableStateOf(false) }
    val screenWidth = LocalConfiguration.current.screenWidthDp
    val screenHeight = LocalConfiguration.current.screenHeightDp

    val model = ImageRequest.Builder(context)
        .data(uri)
        .videoFrameMillis(10000)
        .decoderFactory { result, options, _ ->
            VideoFrameDecoder(
                result.source,
                options
            )
        }
        .build()

    val exoPlayer = remember{ createExoPlayer(context, uri) }

    //exoPlayer.playWhenReady = true
    exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
    exoPlayer.repeatMode = Player.REPEAT_MODE_ONE

    exoPlayer.addListener(object : Player.Listener{
        override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {
            isReady = playWhenReady
            super.onPlayWhenReadyChanged(playWhenReady, reason)
        }
    })

    var lifecycle by remember { mutableStateOf(Lifecycle.Event.ON_CREATE) }
    val lifecycleOwner = LocalLifecycleOwner.current
    DisposableEffect(lifecycleOwner) {
        val observer = LifecycleEventObserver { _, event ->
            lifecycle = event
        }
        lifecycleOwner.lifecycle.addObserver(observer)

        onDispose {
            lifecycleOwner.lifecycle.removeObserver(observer)
            exoPlayer.release()
        }
    }

    Box(
        modifier = Modifier
            //.widthIn(max = with(density) { screenWidth.toDp() })
          //  .width(200.dp)
//            .fillMaxHeight()
            //.height(200.dp)
            .onGloballyPositioned { coordinates ->
                val parentRect = coordinates.boundsInParent()
                val isFullyVisible = parentRect.contains(coordinates.positionInWindow())

                if (isFullyVisible) {
                    exoPlayer.play()
                } else {
                    exoPlayer.pause()
                }
            },
        contentAlignment = Alignment.Center
    ){
        //if(!isReady){
        if(exoPlayer.isLoading){
            AsyncImage(
                modifier = Modifier.fillMaxSize(),
                model = model,
                contentDescription = "video thumbnail",
                contentScale = ContentScale.Crop
            )
        }else{
            AndroidView(
                factory = { context ->
                    val playerView = PlayerView(context).apply {
                        hideController()
                        useController = false
                        player = exoPlayer
                        resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
                        layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
                        setKeepContentOnPlayerReset(true)
                    }
                    playerView
                },
                update = {
                    when (lifecycle) {
                        Lifecycle.Event.ON_PAUSE -> {
                            it.onPause()
                            it.player?.pause()
                        }
                        Lifecycle.Event.ON_RESUME -> {
                            it.onResume()
                        }
                        else -> Unit
                    }
                },
                modifier = modifier
                    .fillMaxSize()

            )
        }
    }
}

@OptIn(UnstableApi::class)
private fun createExoPlayer(context: Context, uri: String): ExoPlayer{
    return ExoPlayer.Builder(context)
        .build()
        .apply {
            val defaultDataSourceFactory = DefaultDataSource.Factory(context)
            val dataSourceFactory: DataSource.Factory = DefaultDataSource.Factory(
                context,
                defaultDataSourceFactory
            )
            val source = ProgressiveMediaSource.Factory(dataSourceFactory)
                .createMediaSource(MediaItem.fromUri(uri))

            setMediaSource(source)
            prepare()
        }
}
android android-jetpack-compose exoplayer android-video-player android-media3
1个回答
0
投票

在您的

PlayerView
上,将
clipToOutline
添加为 true。

© www.soinside.com 2019 - 2024. All rights reserved.