添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
霸气的大葱  ·  Issue getting any QT ...·  2 月前    · 
想出家的水煮鱼  ·  金中都的社稷坛·  2 月前    · 
深沉的手套  ·  SftPrintPreview/OCX ...·  3 月前    · 
讲道义的甘蔗  ·  java ...·  4 月前    · 

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

我试着在小组件上添加背景图片,但是根本没有达到预期的效果。 我也试过把视频中第一帧的图像放在VideoView的顶部,并在 start() 方法后将其隐藏。 添加一个onPrepared监听器来启动视频,然后隐藏图像。这很有效,但在过渡过程中出现了可怕的闪烁,我不知道如何摆脱它。

添加MediaController完全没有效果。问题仍然存在(我仍然看到黑色的闪烁),我根本不想让视频控件可见。 我的代码看起来像这样。

    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);
    
5 个评论
你找到解决问题的办法了吗?我也遇到了同样的情况
我做了,最好的方法是下面这个。但当你试图移除视图时,问题仍然存在(如果是这样的话)。它仍然会闪动。希望不是你的情况。
如果你检查的话,这个问题要老得多。谢谢
谁能告诉我为什么会发生这种情况?
android
flicker
android-videoview
SergioM
SergioM
发布于 2012-03-19
24 个回答
wizardlee
wizardlee
发布于 2012-03-19
已采纳
0 人赞同

我遇到了同样的问题,用上面接受的解决方案加上这个来解决。

  @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只是意味着视频准备好了,但不意味着视频开始播放。如果在onPrepared中隐藏占位符,屏幕仍然显示黑屏。

在我的Note3和Nexus上,这个解决方案运作良好。

mwm
当MEDIA_INFO_VIDEO_RENDERING_START被触发时,我隐藏了ImageView。
Keke
请注意,MEDIA_INFO_VIDEO_RENDERING_START需要api 17以上。
Hugo
绝对应该是正确的答案!+1 我的朋友;)
在安卓5.1系统上没有区别。
我试了一下,在物理设备上没有看到任何闪烁,但在模拟器上仍然看到闪烁(API 23)。这样看来,等待MEDIA_INFO_VIDEO_RENDERING_START并不能保证什么。不过我不知道有什么更好的选择。
jc_35
jc_35
发布于 2012-03-19
0 人赞同

我在Galaxy tab 2上有同样的问题,Android 4.1.1。

Do videoView.setZOrderOnTop(true); and next videoView.start()

It works fine for me.

只有在你没有在videoview上设置小部件的情况下,它才能发挥作用。
在安卓7.0系统上为我工作,非常感谢!这让我很头疼
M to the K
M to the K
发布于 2012-03-19
0 人赞同

我也遇到了同样的问题,我找到了一个解决方案。虽然有点麻烦,但还是有效果的。 所以基本上你需要把你的VideoView放到一个FrameLayout中。 在视频视图上,你需要添加另一个带有视频背景的FrameLayout,当你的视频被加载并准备好播放时,你要隐藏这个占位符。

<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>
public void onPrepared(MediaPlayer mp) {
    View placeholder = (View) findViewById(R.id.placeholder);
    placeholder.setVisibility(View.GONE);

因此,当视频准备好后,我们隐藏我们的占位符,这一招避免了黑色闪烁的屏幕。

Hope this help someone.

这是一个非常糟糕的解决方法,因为它意味着不透明的drawable与布局相匹配。此外,我发现闪烁的持续时间在每个设备上都是不同的,当onPrepared()被调用时,第一帧不一定显示。令人失望的是。
Mark
如果它能起作用,那么谁会在乎它是否是一个 "黑客"--在生活中,一切都不完美!你总是可以在占位符的框架上设置一个简短的阿尔法动画,这样就可以减少 "闪烁 "的效果--或者用这样的东西来玩玩。
但在调用onPrepared后也出现了黑屏,这该怎么办呢?
我在安卓5.1系统上使用这个方案,仍然有黑色的闪烁。
视图仍然导致闪烁。@wizardlee有一个正确的答案
Ravi Bhojani
Ravi Bhojani
发布于 2012-03-19
0 人赞同

我也有同样的问题,这个方法对我有用。

当你想显示视频时,让videoView.setZOrderOnTop(false);而当你想隐藏视频时,只要让videoView.setZOrderOnTop(true)。

Moak
由于某些原因,这improves绩效,但并没有完全防止黑闪。谢谢
elL
这个答案帮助了我,但正如@Moak所说,它并不能完全防止黑闪。我所做的是if(videoView.isPlaying()),然后设置videoView.setZOrderOnTop(false)来防止它。
它应该对所有的人都有效。首先设置videoView.setZOrderOnTop(true); 然后在OnPreparedListener回调中设置videoView.setZOrderOnTop(true); 。
Ahmad Dwaik 'Warlock'
Ahmad Dwaik 'Warlock'
发布于 2012-03-19
0 人赞同

我也有同样的问题,我只是用videov.setBackgroundColor(Color.WHITE),然后在prepare时用Color.TRANSPARENT),对我来说白色还是比黑色好。

简单的解决方案。如果你有可能设置一个不与你的视图风格冲突的颜色,那是最好的。
我有一个连续的黑屏,只播放声音,没有视频。在onPreparedListener中,Color.TRANSPARENT对我有用...非常感谢
Carl B
Carl B
发布于 2012-03-19
0 人赞同

通过扩展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) {}
    
有一个精度,TextureView是在api14中的。
@Carl B 如何从一个视频切换到另一个视频,请你帮助,,我必须调用哪种方法
在视频课上做什么?
谁能更好地解释一下这个问题?如果我使用上面的代码,它不包含常见的VIdeoView方法,如start(),等等。
好吧,我使用上述逻辑成功实现了一个自定义的VideoView,但仍然有黑色的闪烁。所以,对我来说,在Android 5.1上没有好处。
Siavash
Siavash
发布于 2012-03-19
0 人赞同

上述方法对我都不起作用。 在我的例子中,onPrepared是在黑框消失之前被调用的,所以我还是会看到黑框。

我需要一个解决方案,视频在第一帧后不久出现。

所以我所做的是在xml中把VideoView的alpha设置为0。

android:alpha="0"

然后在我开始视频之前,我把阿尔法动画化为1。

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

或者,你可以直接发布一个延迟的Runnable,将alpha设置为1,而不是将其做成动画。

emmgfx
emmgfx
发布于 2012-03-19
0 人赞同

This worked for me:

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

至少两年后,但我希望这对你有帮助。

Paul Burke
Paul Burke
发布于 2012-03-19
0 人赞同

这绝对是黑客行为,但比叠加图像要好(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);

假设你把东西放进savedInstanceState中的onSaveInstanceState

在安卓5.1系统上没有任何区别。
j7nn7k
j7nn7k
发布于 2012-03-19
0 人赞同

只需从视频中显示一帧作为预览。

vSurface.SeekTo(100);
    
Takeaki Kubota
Takeaki Kubota
发布于 2012-03-19
0 人赞同

我想,只要使用VideoView#setBackgroundDrawable()就可以了。

  • 初始设置。

    VideoView.setBackgroundDrawable(yourdrawableid);
    
    VideoView.start();
    VideoView.setBackgroundDrawable(0);
        
  • Gagan
    Gagan
    发布于 2012-03-19
    0 人赞同

    对于仍在寻找答案的人来说,在onPrepared中连续调用VideoView.start()VideoView.pause()对我来说是有效的。我知道这可能不是实现这一目标的理想方法,但它可能是代码中需要的最小的变通方法。希望这对你也有用。

    @Override
    public void onPrepared(MediaPlayer mp) {
        mVideoView.start();
        mVideoView.pause();
        
    在安卓5.1系统上没有任何区别。
    Ramza
    Ramza
    发布于 2012-03-19
    0 人赞同

    This one works for me :

    在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>
    

    并在活动中: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();
    

    Hope this helps.

    FutureJJ
    FutureJJ
    发布于 2012-03-19
    0 人赞同

    对我来说,设置setZOrderOnTop并没有完全消除播放mp4视频时的初始黑框。然而,它确实减少了黑框出现的时间。我想完全消除最初的黑框,所以我玩了一下,发现将视频向前推进100ms就可以了。

    注意,我正在循环使用该视频,所以如果你不想循环使用该视频,只需删除
    mp.isLooping = true

    Following is the snippet which I used to fix the issue:

    val path = "android.resource://" + packageName + "/" + R.raw.my_video
    videoView.setVideoURI(Uri.parse(path))
    videoView.setZOrderOnTop(true)
    videoView.seekTo(100)
    videoView.start()
    videoView.setOnPreparedListener { mp ->
       videoView.setZOrderOnTop(false)
       mp.isLooping = true // Loops the video 
    

    如果我得到一个确切的解释,说明上述工作的原因,如果有人觉得有帮助,那还是很好的。

    Raj
    Raj
    发布于 2012-03-19
    0 人赞同

    Use svVideoView.seekTo(position).

    Give Position within 5 (ms).

    onPause():
    position=svVideoView.getCurrentPosition()
    onResume():
    svVideoView.seekTo(position);
        
    Nam lê đình
    Nam lê đình
    发布于 2012-03-19
    0 人赞同

    它对我来说在活动和片段上都有效。

    VideoView mVideo = (VideoView) findViewById(R.id.yourViewViewId);
              mVideo.setVideoURI(mUri);
              mVideo.setZOrderOnTop(false);
    SurfaceHolder surfaceholder = mVideo.getHolder();
    surfaceholder.setFormat(PixelFormat.TRANSPARENT);
        
    MalaKa
    MalaKa
    发布于 2012-03-19
    0 人赞同

    这个答案有点晚了,但也许其他用户有同样的问题并发现这个问题。
    我已经处理了这个问题,最初设置了一个BackgroundResource,然后在启动视频时,我将背景设置为不可见的颜色。

    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();
        
    在开始视频之前,只需video.setBackgroundColor(Color.WHITE);。然后video.setBackgroundColor(Color.TRANSPARENT);当准备好。
    OShiffer
    OShiffer
    发布于 2012-03-19
    0 人赞同

    这是一个不错的解决方案。

    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>
        
    klimat
    klimat
    发布于 2012-03-19
    0 人赞同

    为了避免恼人的闪烁和黑屏问题,我写道帧视频视图.

    它从 "占位符解决方案 "和(如果你的设备运行API级别14或更高)TextureView中获取好处,这比VideoView更有效。

    I wrote 文章在我们的博客上,涵盖了它的实际作用。

    It's simple to use:

    Add FrameVideoView to layout:

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

    Activity中找到其实例,并在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();
        
    这是一个很好的解决方案,但视频是无限循环的,在一些视频上,右边缘有绿线,底部有黑线(项目中的原始视频没有,H.264,MP4)。有谁遇到过这个问题?解决方案?
    Vinil Chandran
    Vinil Chandran
    发布于 2012-03-19
    0 人赞同

    我也有同样的问题。我发现,主要原因是使用FrameLayout作为父布局。使用RelativeLayout作为VideoView的父布局

    Fawaz
    Fawaz
    发布于 2012-03-19
    0 人赞同

    修改@emmgfx的答案对我有用。

    videoView.setBackgroundColor(Color.WHITE)
    videoView.start()
    Timer().schedule(100){
      videoView?.setBackgroundColor(Color.TRANSPARENT)
    

    技巧是在视频加载前延迟视频浏览。 PS : 这是kotlin。

    Colin Williams
    Colin Williams
    发布于 2012-03-19
    0 人赞同

    我发现了一个解决这个问题的好办法。( 在Kotlin中 )

    Create an imageview over top of your videoview. Create a function with a handler, and check if ( videoview.duration > 0 )

    如果持续时间大于0,则将imageview.visibility设置为INVISABLE,并立即用handler.removeCallbacks(this)进行跟踪。

    在调用videoview.start后再调用上述函数。

    Code below:

    fun showVideoView() {

        val handler = Handler()
        handler.postDelayed(object : Runnable {
            override fun run() {
                try {
                    if (videoplayer_topthree.currentPosition > 0) {
                        videoview_topthreeloadingimage.visibility = View.INVISIBLE
                        videoview_topthreeprogressbar.visibility = View.VISIBLE
                        videoview_topthreefullname.visibility = View.VISIBLE
                        videoview_topthreeviews.visibility = View.VISIBLE
                        videoview_topthreedate.visibility = View.VISIBLE
                        videoview_topthreedescription.visibility = View.VISIBLE
                        videoview_topthreedimview.visibility = View.VISIBLE
                        handler.removeCallbacks(this)
                    handler.postDelayed(this, 250)
                } catch (e: Exception) {
                    println("SHOW VIDEOVIEW CATCH WAS CAUGHT")
        }, 0)
    

    这就是我调用这个函数的地方。

    videoplayer_topthree.setOnPreparedListener {

            prepareSizing(it)
            initializeProgressBar()
            showVideoView()
        
    David Kirkpatrick
    David Kirkpatrick
    发布于 2012-03-19
    0 人赞同

    试图在一个大部分为白色的布局上播放一个大部分为白色的视频时,这些故障会以一种非常明显和恼人的方式显示出来,特别是在活动过渡期间。我设法完全摆脱这些故障的唯一方法是把这个主题的几个不同的答案和elprl的答案混在一起,即https://stackoverflow.com/a/9089245/3997253.

    创建一个覆盖VideoView的纯色视图。

    android:id="@+id/coverView" android:background="@color/white" android:layout_width="match_parent" android:layout_height="match_parent" />

    在onCreate中

    coverView = findViewById(R.id.coverView) videoView = findViewById(R.id.videoView) videoView.setZOrderOnTop(false) val surfaceHolder = videoView.holder surfaceHolder.setFormat(PixelFormat.TRANSPARENT)

    在onStart

    videoView.setOnPreparedListener { mp -> // Fade out cover View to show VideoView once rendering has started mp.setOnInfoListener { _, what, _ -> if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) { coverView.animate().alpha(0F) return@setOnInfoListener true return@setOnInfoListener false mp.isLooping = true videoView.start() videoView.requestFocus()

    When done with the VideoView

    // Fade in cover View to hide the VideoView
    coverView.animate().alpha(1F)
        
    Venkata Krishna
    Venkata Krishna
    发布于 2012-03-19
    0 人赞同

    see this

    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);