Android VideoView黑屏

我一直在寻找一种方法,在start()方法运行之前摆脱VideoView上令人讨厌的黑色初始屏幕。

我已经尝试与小部件上的背景图像,但它并不像预期的那样工作。 我也尝试在VideoView顶部的video中放置第一帧的图像,并在stars()方法之后隐藏它。 添加onPrepared侦听器来启动video,然后隐藏图像。 这种方法很有效,但是在转换中有一个可怕的闪烁,我不知道如何摆脱它。


感谢您的回复。 添加MediaController根本没有效果。 问题依然存在(我仍然看到黑色闪烁),我不想让video控件可见。 我的代码如下所示:

VideoView vSurface= (VideoView) findViewById(R.id.surfaceView1); vSurface.setVideoURI(Uri.parse("android.resource://com.mypackage/" + R.raw.video1)); vSurface.setVisibility(View.VISIBLE); vSurface.setOnPreparedListener(this); vSurface.setDrawingCacheEnabled(true); vSurface.setOnErrorListener(this); 

我得到了同样的问题,我find了解决scheme。 它有点hacky,但它伎俩。 所以基本上你需要把你的VideoView放到FrameLayout中。 在video视图中,您需要添加另一个带有video背景的FrameLayout,并且当您的video加载并准备播放时,您可以隐藏占位符。

 <FrameLayout android:id="@+id/frameLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:layout_marginTop="50dip" > <VideoView android:id="@+id/geoloc_anim" android:layout_width="fill_parent" android:layout_height="172dip" android:layout_gravity="top|center" android:visibility="visible"/> <FrameLayout android:id="@+id/placeholder" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/fondvert_anim"> </FrameLayout> 

在你的活动中,你需要实现OnPreparedListener并添加这个

 //Called when the video is ready to play public void onPrepared(MediaPlayer mp) { View placeholder = (View) findViewById(R.id.placeholder); placeholder.setVisibility(View.GONE); } 

所以,当video准备好了,我们隐藏了我们的占位符,这个技巧避免了黑色的闪烁屏幕。

希望这可以帮助别人。

我遇到了同样的问题,并用上面所接受的解决scheme加以解决:

  @Override public void onPrepared(MediaPlayer mp) { mp.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { Log.d(TAG, "onInfo, what = " + what); if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) { // video started; hide the placeholder. placeholder.setVisibility(View.GONE); return true; } return false; } }); 

我认为onPrepared只是意味着video已经准备好播放,但并不意味着video开始播放。 如果在onPrepared中隐藏占位符,屏幕仍然显示黑屏。

在我的Note3和Nexus上,这个解决scheme运行良好。

我在Galaxy Tab 2,Android 4.1.1上遇到了同样的问题。

videoView.setZOrderOnTop(true); 和下一个videoView.start()

它对我来说工作正常。

我有同样的问题,这对我工作..

当你想显示video,使videoView.setZOrderOnTop(假); 当你想要隐藏video,只需要videoView.setZOrderOnTop(true);

我有同样的问题,我只是用videov.setBackgroundColor(Color.WHITE),然后onprepare我使用Color.TRANSPARENT)白色仍然比黑色更好

通过扩展一个TextureView,我在开头或结尾都没有黑屏。 这是如果你想避免使用ZOrderOnTop(true)

 public class MyVideoView extends TextureView implements TextureView.SurfaceTextureListener { private MediaPlayer mMediaPlayer; private Uri mSource; private MediaPlayer.OnCompletionListener mCompletionListener; private boolean isLooping = false; public MyVideoView(Context context) { this(context, null, 0); } public MyVideoView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyVideoView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setSurfaceTextureListener(this); } public void setSource(Uri source) { mSource = source; } public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) { mCompletionListener = listener; } public void setLooping(boolean looping) { isLooping = looping; } @Override protected void onDetachedFromWindow() { // release resources on detach if (mMediaPlayer != null) { mMediaPlayer.release(); mMediaPlayer = null; } super.onDetachedFromWindow(); } /* * TextureView.SurfaceTextureListener */ @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { Surface surface = new Surface(surfaceTexture); try { mMediaPlayer = new MediaPlayer(); mMediaPlayer.setOnCompletionListener(mCompletionListener); mMediaPlayer.setOnBufferingUpdateListener(this); mMediaPlayer.setOnErrorListener(this); mMediaPlayer.setLooping(isLooping); mMediaPlayer.setDataSource(getContext(), mSource); mMediaPlayer.setSurface(surface); mMediaPlayer.prepare(); mMediaPlayer.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); mMediaPlayer.reset(); } catch (IOException e) { e.printStackTrace(); } } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {} @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { surface.release(); return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) {} } 

这对我工作:

 videoView.setBackgroundColor(Color.WHITE); // Your color. videoView.start(); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { videoView.setBackgroundColor(Color.TRANSPARENT); } }); 

至less两年后,但我希望这是有帮助的。

这绝对是不吉利的,但比覆盖图像(IMO)更好。

 boolean mRestored = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mRestored = savedInstanceState != null; } @Override public void onPrepared(MediaPlayer mp) { if (!mRestored) vSurface.seekTo(1); } 

假设你将东西放入onSaveInstanceState savedInstanceState中。

只要使用VideoView#setBackgroundDrawable(),我想。

  1. 初始设置。

     VideoView.setBackgroundDrawable(yourdrawableid); 
  2. 开始video

     VideoView.start(); VideoView.setBackgroundDrawable(0); 

只需从video中显示一帧即可预览。

 vSurface.SeekTo(100); 

对于仍在寻找答案的人来说,在onPrepared中连续调用VideoView.start()VideoView.pause()为我工作。 我知道这可能不是实现这一目标的理想方式,但是它可能是代码中所需的最小解决方法之一。 希望这也适用于你。

 @Override public void onPrepared(MediaPlayer mp) { mVideoView.start(); mVideoView.pause(); } 

这个为我工作:

在XML中:VideoView隐藏在具有白色背景的相对布局之后

  <VideoView android:id="@+id/myVideo" android:layout_below="@+id/logo_top" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerHorizontal="true" /> <RelativeLayout android:id="@+id/mask" android:background="#FFFFFF" android:layout_below="@+id/logo_top" android:layout_centerHorizontal="true" android:layout_width="200dp" android:layout_height="200dp" > </RelativeLayout> 

并在Activity:onCreate

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.acceuil); myVideo = (VideoView) findViewById(R.id.myVideo); mask = (RelativeLayout) findViewById(R.id.mask); String path = "android.resource://" + getPackageName() + "/" + R.raw.anim_normal; myVideo.setVideoURI(Uri.parse(path)); myVideo.start(); } 

onStart:

  public void onStart() { final long time = System.currentTimeMillis(); super.onStart(); new CountDownTimer(5000, 100) { @Override public void onTick(long l) { long time2 = System.currentTimeMillis(); if((time2 - time) > 500) { mask.setVisibility(View.GONE); } } }.start(); 

希望这可以帮助。

这个答案有点晚,但也许其他用户有同样的问题,并find这个问题..

我已经处理了它,通过最初设置一个BackgroundResource,然后,当开始video,我已经把背景设置为一个不可见的颜色..

 VideoView myView = findViewById(R.id.my_view); myView.setBackgroundResource(R.drawable.some_resource); // some stuff // this is when starting the video myView.setVideoUri(someUri); // also set MediaController somewhere... //... // now set the backgroundcolor to be not visible (first val of Color.argb(..) is the alpha) myView.setBackGroundColor(Color.argb(0, 0, 0, 0)); //... myView.start(); 

我更喜欢这个解决scheme: https : //stackoverflow.com/a/11016465/2267723

它的表面,所以创build一个虚拟的@片段布局,你不会再看到这个黑色闪光..

这是一个很好的解决scheme:

 package com.example.videoviewpractice; import android.app.Activity; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.MediaController; import android.widget.VideoView; public class MainActivity extends Activity { VideoView myVideoView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initVideo(); } private void initVideo() { myVideoView = (VideoView) findViewById(R.id.videoView1); String url = "http://mtc.cdn.vine.co/r/videos/3DF00EB7001110633055418310656_1e50d6d9a65.3.2.mp4?" + "versionId=KVMUFFGqe6rYRrGKgl8hxL6eakVAErPy"; myVideoView.setVideoURI(Uri.parse(url)); myVideoView.setMediaController(new MediaController(this)); myVideoView.requestFocus(); } public void gone(View v){ myVideoView.setZOrderOnTop(true); View placeholder = (View) findViewById(R.id.placeholder); placeholder.setVisibility(View.GONE); myVideoView.start(); } } 

activity_main.xml中:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="${relativePackage}.${activityClass}" > <FrameLayout android:id="@+id/frameLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:layout_marginTop="50dip" > <VideoView android:id="@+id/videoView1" android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="top|center" android:visibility="visible" /> <FrameLayout android:id="@+id/placeholder" android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="top|center" android:background="@drawable/ic_launcher" android:onClick="gone" > </FrameLayout> </FrameLayout> </LinearLayout> 

为了避免恼人的闪烁和黑屏问题,我写了FrameVideoView

它从TextureView获取“占位符解决scheme”和(如果您的设备运行API级别14或更高)的TextureView ,它比VideoView更有效率。

我在我们的博客上写了一篇文章来介绍它实际上做了什么。

使用起来很简单:

FrameVideoView添加到布局:

 <mateuszklimek.framevideoview.FrameVideoView android:id="@+id/frame_video_view" android:layout_width="@dimen/video_width" android:layout_height="@dimen/video_height" /> 

Activityfind它的实例并在onResumeonPause调用相应的方法:

 public class SampleActivity extends Activity { private FrameVideoView videoView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple); String uriString = "android.resource://" + getPackageName() + "/" + R.raw.movie; videoView = (FrameVideoView) findViewById(R.id.frame_video_view); videoView.setup(Uri.parse(uriString), Color.GREEN); } @Override protected void onResume() { super.onResume(); videoView.onResume(); } @Override protected void onPause() { videoView.onPause(); super.onPause(); } } 

使用svVideoView.seekTo(位置)

在5(ms)内给位置。

 onPause(): position=svVideoView.getCurrentPosition() onResume(): svVideoView.seekTo(position); 

以上都没有为我工作。 在我的情况下, onPrepared被调用之前,黑框消失,所以我仍然会看到黑框。

我需要一个解决scheme,在第一帧之后不久出现video。

所以我所做的是将VideoView alpha设置为0:

 android:alpha="0" 

然后在我开始video之前,我将alpha设置回1:

 videoView.animate().alpha(1); videoView.seekTo(0); videoView.start(); 

或者,您可以发布一个延迟的Runnable来将alpha设置为1,而不是将其设置为animation。

我遇到过同样的问题。 我发现主要原因是使用FrameLayout作为父级布局。 使用RelativeLayout作为VideoView的父级布局

看到这个

 VideoView videoView = (VideoView) findViewById(R.id.VideoView); MediaController mediaController = new MediaController(this); mediaController.setAnchorView(videoView); Uri video = Uri.parse("android.resource://your_package_name/"+R.raw.monkeysonthebed_video); videoView.setMediaController(mediaController); videoView.setVideoURI(video); videoView.start();