前言
不知道还有多少小伙伴在用系统的VideoView用来播放视频,应该一直有一个问题困扰的大家吧,那就是播放前的一小段黑屏问题。无论是首次播放黑屏还是视频切换黑屏,一个看似小小的问题,却非常难以解决。最近我们app需要播放一些简单的教程视频,不值得引入三方库增大包体积,所以就用了VideoView,黑屏问题就来了。本篇旨在彻底解决黑屏的问题。
单个视频播放前的黑屏
这个问题很好解决,网上也有一堆的教程。不过最近在我测试的过程中发现这些教程有时候并不能解决问题。所以我带来我解决问题的方式。
首先需要给VideoView
一个单独的ImageView
设置背景,并且这个ImageView
的绘制级别一定要高于VideoView
,保证VideoView
和ImageView
都显示的情况下,能让ImageView
盖住VIdeoView
。
比如说,我们用自定义一个布局:
此时ImageView肯定会盖住VideoView,显示一个背景色。
然后需要在代码中设置以下:
private fun initVideoView() {
binding.simpleVideoView.setOnPreparedListener {
it.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING)
binding.simpleVideoView.setOnInfoListener { _, what, _ ->
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
binding.simpleVideoBg.visibility = GONE
}
true
}
binding.simpleVideoView.start()
}
}
这个大家看过其他教程的情况下都理解是什么意思,唯一不同的区别在于用我们在xml中配置的ImageView来替代设置VideoView的背景。
同时给ImageView渲染下视频的第一帧,可以用Glide来实现。Glide可以加载视频资源到ImageView上,就是加载的第一帧。
这样视频播放的情况下就比较完美了,视频渲染完成前会展示视频第一帧,渲染完成后,背景ImageView会隐藏,显示出被盖住的VideoView,避开了VIdeoView渲染视频时的黑色背景。
视频来回切换导致黑屏
如果是在一个VideoView切换不同的视频源,并不会导致黑屏。出现黑屏的情况在于使用多个VideoView来回切换的情况下,比如ViewPager左右切换,首次播放的情况下,用我们上边的办法是可以解决黑屏问题,但来回切换就会发现黑屏又出现了。
问题在于切换的后VideoView会被销毁回收,下次切换回来重新渲染视频。而我们的背景ImageView已经隐藏掉了。
解决问题的关键就在于切换走的VideoView要将背景色ImageView重新显示出来就ok了。
不过不能在setOnPreparedListener中设置ImageView的显示,不会有任何效果,这种问题要结合自己使用的控件来灵活处理。比如我们使用了ViewPager2,那就这样处理:
private var oldPosition = 0
fun initValue() {
binding.commonNoviceCourseViewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
if (oldPosition == position) return
val video = adapter.getViewByPosition(oldPosition, R.id.common_novice_course_video) as SimpleVideoView
video.getVideoBg().visibility = View.VISIBLE
oldPosition = position
}
})
}
使用的BaseQuickAdapter,就可以这么处理了。
这样切换的时候,也就可以比较完美的展示首帧视频,不会出现黑屏了。