我正在使用最新的 media3 Exoplayer 和 Jetpack Compose 构建视频播放器:
我面临的问题是,如果我将
PlayerView
设置为全屏
AndroidView(modifier = Modifier.fillMaxSize(),...)
首次打开视频时(或通过
next()
/previous()
导航至视频),视频将被拉伸:
但是,如果我翻转方向,它会正确显示,然后当我翻转回来时也会正确显示:
这就是我最终想要的样子。 我的代码:
Scaffold(
topBar = { MyAppBar() },
content = { innerPadding ->
viewModel.openMediaFile(mediaFile)
Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.background(MyTheme.colors.background),
contentAlignment = Alignment.Center
) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
PlayerView(context).apply {
player = viewModel.player
artworkDisplayMode = PlayerView.ARTWORK_DISPLAY_MODE_FIT
artworkPlaceHolder?.let { defaultArtwork = it }
}
}
)
}
},
)
如果我不设置
AndroidView(modifier = Modifier.fillMaxSize(),...)
它看起来很糟糕,因为我希望覆盖层填满整个屏幕。
我尝试过的:
artworkDisplayMode = PlayerView.ARTWORK_DISPLAY_MODE_FIT
在 Compose 的 PlayerView
块中,ExoPlayer.Builder(context)
.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT)
.build()
layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
我想要实现的是带有合适视频的全屏布局。
由于您使用 viewModel 来存储播放器,因此您很可能在不同视频之间保留相同的播放器。
基于AndroidView docs,您可以使用更新方法来修复此问题:
// Adds view to Compose
Box(
modifier = Modifier
.fillMaxSize()
.padding(50.dp),
contentAlignment = Alignment.Center
) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
PlayerView(context)
},
update = { view ->
val newPlayer = ExoPlayer.Builder(view.context)
.build()
val mediaItem = MediaItem.fromUri("https://upload.wikimedia.org/wikipedia/commons/transcoded/e/e0/Abstract_Music_Animation_%22Defend_the_Yellow_River%22.webm/Abstract_Music_Animation_%22Defend_the_Yellow_River%22.webm.360p.webm")
newPlayer.setMediaItem(mediaItem)
newPlayer.prepare()
view.apply {
player = newPlayer
}
}
)
}
首次加载结果: