Jetpack Compose中ExoPlayer生命周期切换的帧异常问题求助
修复ExoPlayer后台切前台暂停状态下视频帧跳动问题
1. 采用官方推荐的生命周期自动绑定方案
放弃手动在ON_PAUSE调用pause(),直接将ExoPlayer与页面生命周期绑定,让框架自动处理状态切换,避免手动管理的疏漏:
val exoPlayer = ExoPlayer.Builder(context) .setLifecycle(lifecycle) // 绑定页面生命周期 .build() // 初始化配置 exoPlayer.repeatMode = Player.REPEAT_MODE_ONE exoPlayer.playWhenReady = false exoPlayer.setMediaItem(MediaItem.fromUri(uri)) exoPlayer.prepare() exoPlayer.play()
如果使用PlayerView承载视频,直接赋值即可自动关联生命周期:
playerView.player = exoPlayer
2. 手动处理生命周期时补充资源清理逻辑
若必须手动管控生命周期,除ON_PAUSE暂停播放外,需在ON_STOP阶段清除视频Surface资源,避免前台恢复时渲染缓存帧:
lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onPause(owner: LifecycleOwner) { exoPlayer.pause() } override fun onStop(owner: LifecycleOwner) { exoPlayer.clearVideoSurface() // 清除关联的Surface,阻断缓存帧渲染 } override fun onStart(owner: LifecycleOwner) { // 恢复Surface关联 playerView.player = exoPlayer } })
3. 调整渲染视图的缓存设置
如果使用TextureView作为视频载体,禁用不必要的缓存配置:
textureView.isOpaque = true textureView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
布局文件中也可直接设置:
<TextureView android:id="@+id/textureView" android:layout_width="match_parent" android:layout_height="match_parent" android:layerType="hardware"/>
4. 前台恢复时强制同步播放位置
在页面回到前台时,手动调用seekTo同步当前播放位置,强制刷新渲染帧:
override fun onResume(owner: LifecycleOwner) { if (!exoPlayer.isPlaying) { exoPlayer.seekTo(exoPlayer.currentPosition) } }
内容的提问来源于stack exchange,提问作者Mustafa Tatarhan
相关产品推荐
相关产品推荐

