我正在使用 VideoView 循环播放一个小视频,在模拟器上一切正常,但是当我将其部署到电视上时,第一个循环视频变黑后,但声音继续播放。这是代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
VideoView videoview = (VideoView) findViewById(R.id.videoview1);
Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.video);
videoview.setVideoURI(uri);
videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
videoview.start();
}
});
}
模拟器使用Android 6.0,电视是Sony Bravia,使用Android 6.0.1。 我使用 SurfaceView 而不是 VideoView 进行了测试 - 同样的事情发生了。
知道如何摆脱黑屏吗?
PS:有一个可行的解决方法 - 制作 OnCompletionListener 并在那里执行 videoview.start() - 这样它会循环,但循环之间有一个丑陋的间隙。
就用这个
mVideoView.setZOrderOnTop(true);
视图出现时就不会显示黑屏了。
尝试使用这样的处理程序设置您的
VideoView
。
videoview.setBackgroundColor(Color.WHITE); //color what you want as background
videoview.postDelayed(new Runnable() {
@Override
public void run() {
videoview.setVideoURI(videoUri);
}
}, 100);
videoview.postDelayed(new Runnable() {
@Override
public void run() {
vv.setBackgroundColor(Color.TRANSPARENT);
}
}, 300);
videoview.requestFocus();
videoview.start();
videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
我查看了 VideoView 的源代码,我想指出的第一件事是,在
setVideoURI()
方法中,将创建 MediaPlayer
对象,并设置 OnPreparedListener
。
您的错误是您在 MediaPlayer 可能已经准备好视频之后设置了
OnPreparedListener
,因此永远不要在您设置的侦听器中调用 onPrepared,这意味着 setLooping(true)
可能从未在 MediaPlayer
上设置.
TL;博士:
将
videoview.setVideoURI(uri);
放在videoview.setOnPreparedListener()
之后。
videoview.start()
应该在 setVideoURI()
之后。完成后,它应该再次开始,无需额外输入,因为这次 mp.setLooping(true);
已正确设置并将被执行。第一次之后就不需要 videoview.start()
了。
我实际上最终使用了 ExoPlayer 而不是默认的。 设置起来有点困难,但是这个问题并没有出现。
根据我的经验,在
VideoView
中(重新)开始视频播放时解决黑屏问题的最佳方法是使用 alpha
。
videoView.alpha = 0f
videoView.setOnInfoListener { _, what, _ ->
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
videoView.alpha = 1f
false
}
您还可以在顶部放置一个视图,显示一些加载指示,以便用户知道正在发生某些事情。
所提出的
mVideoView.setZOrderOnTop(true);
的问题在于它将把视频内容放在所有内容之上。因此,如果您有任何形式的装饰(例如加载覆盖层),则会产生干扰。