EXOPlayer播放VAST广告时后台重启后黑屏问题求助
解决EXOPlayer播放VAST广告后台返回黑屏的问题
核心思路
问题本质是应用进入后台时,EXOPlayer默认会释放资源、销毁播放器,导致重启后无画面。需要从播放器生命周期管理和画面留存两个方向入手解决:
1. 避免后台直接销毁播放器
修改Player的释放超时配置,延长后台保留播放器的时长,或者在特定生命周期场景下只暂停不释放:
// 初始化播放器时设置后台保留超时(示例为60秒,可按需调整) val player = ExoPlayer.Builder(context) .setReleaseTimeoutMs(60000) .build() // 页面生命周期中仅在销毁时释放播放器 override fun onPause() { super.onPause() player.pause() // 暂停而非释放 } override fun onDestroy() { super.onDestroy() player.release() // 仅在页面销毁时执行释放 }
2. 留存广告最后一帧画面
即使播放器被释放,也可以在广告播放结束时捕获最后一帧,用ImageView覆盖在PlayerView上层,后台返回时先显示这张图片,待播放器就绪后再隐藏:
// 监听广告播放结束事件,捕获最后一帧 player.addListener(object : Player.Listener { override fun onPlaybackStateChanged(playbackState: Int) { if (playbackState == Player.STATE_ENDED) { playerView.screenshot { bitmap -> bitmap?.let { coverImageView.setImageBitmap(it) coverImageView.visibility = View.VISIBLE } } } } override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { // 针对广告结束的场景单独处理 if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_AD_ENDED) { playerView.screenshot { bitmap -> bitmap?.let { coverImageView.setImageBitmap(it) coverImageView.visibility = View.VISIBLE } } } } }) // 后台返回时先显示覆盖图,播放器就绪后隐藏 override fun onResume() { super.onResume() coverImageView.visibility = View.VISIBLE player.playWhenReady = true player.addListener(object : Player.Listener { override fun onPlaybackStateChanged(playbackState: Int) { if (playbackState == Player.STATE_READY) { coverImageView.visibility = View.GONE player.removeListener(this) } } }) }
3. VAST广告专属优化
加载VAST广告时,直接使用广告自带的封面图作为PlayerView的默认占位图,避免黑屏:
val adLoader = AdLoader.Builder(context, adTagUri) .addVastAdListener(object : VastAdListener { override fun onAdLoaded(ad: Ad) { // 优先使用广告封面图作为占位 ad.mediaMetadata?.artworkUri?.let { uri -> Glide.with(context).asBitmap().load(uri).into(object : CustomTarget<Bitmap>() { override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) { playerView.defaultArtwork = resource } }) } } }) .build()
为什么SilenceMediaSource没生效?
SilenceMediaSource仅提供静音媒体流,无法阻止EXOPlayer在后台被系统或框架释放资源,也不能留存已播放完成的广告画面,因此解决不了核心问题。
内容的提问来源于stack exchange,提问作者Reason
相关产品推荐
相关产品推荐

