我有一个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()
}
}
在您的
PlayerView
上,将 clipToOutline
添加为 true。