我的目标是创建一个视频比较。我想显示两个视频旁边的对方,并能够自由指定的比例和翻译每一个。这两个视频应该被剪辑到它们对应的行的一半。
我创建了一个用于显示图像的解决方案,但是当我试图使用两个ExoPlayer而不是图像时,我遇到了以下问题,其中剪辑确实部分工作,但与另一个Player的重叠仍然被渲染。
ExoPlayersClipOverlapDemonstrationGif
下面是发生的情况的示意图:
ExoPlayersClipOverlapDemonstration
下面是我的Composable代码:
@Composable
fun VideoComparison(
) {
Row(modifier = Modifier.fillMaxSize()) {
//First Video
Box(
modifier = Modifier.background(Color.Blue).weight(1f).clipToBounds()
) {
//Scaled smaller
Box(modifier = Modifier.graphicsLayer { scaleX = 0.6f; scaleY = 0.6f}) {
MyPlayer(
Uri.parse("https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
)
}
}
//Second Video
Box(
modifier = Modifier.weight(1f).clipToBounds()
) {
//Scaled larger
Box(modifier = Modifier.graphicsLayer { scaleX = 1.8f; scaleY = 1.8f}) {
MyPlayer(
Uri.parse("https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
)
}
}
}
}
下面是我的Player Composable的代码:
@Composable
fun MyPlayer(uri: Uri) {
val context = LocalContext.current
val exoPlayer = remember {
ExoPlayer.Builder(context)
.build()
.also { exoPlayer ->
val mediaItem = MediaItem.Builder()
.setUri(uri)
.build()
exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
}
}
exoPlayer.playWhenReady = true
DisposableEffect(
AndroidView(factory = {
StyledPlayerView(context).apply {
hideController()
clipToOutline = true
clipChildren = true
useController = false
player = exoPlayer
}
})
) {
onDispose { exoPlayer.release() }
}
}
在上面发布的代码中,我使用了修饰符.clipToBounds
,例如它适用于图像,但不适用于两个ExoPlayers。我还尝试使用.clip()
或.graphicLayer( clip = true)
,它们的行为都很相似。我还尝试了将裁剪修饰符放在不同元素上的各种组合,例如直接放在AndroidView或父Box上。
我在这里发现了一个类似的问题SimilarQuestion
1条答案
按热度按时间lstz6jyr1#
将
StyledPlayerView
的曲面类型更改为TextureView
时,剪裁将起作用。这可以通过使用自定义XML文件覆盖标准属性来完成:通过以下方式加载:
并将其添加到StyledPlayerView中,如下所示:
然而,由于
SurfaceView
对于ExoPlayer的好处,如更低的功耗,更准确的帧定时等。(如这里所述),如何使用SurfaceView
修复它仍然会很有趣。