You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose中ExoPlayer启动时0.3秒黑屏问题的解决方法

在Compose中使用ExoPlayer解决首次启动黑屏问题

问题描述

我在Compose中使用ExoPlayer的代码功能正常,但首次启动时会出现0.3秒的黑屏,推测是渲染问题。之前使用XML的VideoView时,通过设置videoView.setZOrderOnTop(true)解决过类似问题,想知道在Compose环境下该如何处理?

原实现代码:

val context = LocalContext.current
val exoPlayer = remember {
    ExoPlayer.Builder(context).build().apply {
        val defaultDataSourceFactory = DefaultDataSource.Factory(context)
        val dataSourceFactory: DataSource.Factory = DefaultDataSource.Factory(
            context,
            defaultDataSourceFactory
        )

        val packageName = context.applicationContext.packageName
        val uri = Uri.parse("android.resource://${packageName}/${R.raw.xeal_tutorial_compressed}")
        val source = ProgressiveMediaSource.Factory(dataSourceFactory)
            .createMediaSource(MediaItem.fromUri(uri))

        setMediaSource(source)
        prepare()
        playWhenReady = true
        repeatMode = REPEAT_MODE_ONE
    }
}

AndroidView(
    factory = { context ->
        PlayerView(context).apply {
            player = exoPlayer
        }
    }
)

解决方法

在Compose的AndroidView创建PlayerView实例时,直接调用setZOrderOnTop(true)即可,逻辑和XML环境下完全一致。修改后的代码如下:

val context = LocalContext.current
val exoPlayer = remember {
    ExoPlayer.Builder(context).build().apply {
        val defaultDataSourceFactory = DefaultDataSource.Factory(context)
        val dataSourceFactory: DataSource.Factory = DefaultDataSource.Factory(
            context,
            defaultDataSourceFactory
        )

        val packageName = context.applicationContext.packageName
        val uri = Uri.parse("android.resource://${packageName}/${R.raw.xeal_tutorial_compressed}")
        val source = ProgressiveMediaSource.Factory(dataSourceFactory)
            .createMediaSource(MediaItem.fromUri(uri))

        setMediaSource(source)
        prepare()
        playWhenReady = true
        repeatMode = REPEAT_MODE_ONE
    }
}

AndroidView(
    factory = { context ->
        PlayerView(context).apply {
            player = exoPlayer
            // 添加该行解决首次启动黑屏问题
            setZOrderOnTop(true)
        }
    }
)

额外优化建议

如果设置setZOrderOnTop(true)后仍有轻微黑屏,可尝试以下补充方案:

  • 设置视频占位图:调用PlayerView的setDefaultArtwork()方法,传入视频第一帧的图片资源,在视频加载完成前显示占位图
  • 调整预加载时机:可以在初始化播放器时提前调用prepare(),不过你的现有代码已经包含该逻辑,可根据实际场景微调

内容的提问来源于stack exchange,提问作者Alexey Simchenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:42:50