Android VideoView黑屏

Ser*_*ioM 56 android flicker android-videoview

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

我已尝试在窗口小部件上使用背景图像,但它根本无法正常工作.我还尝试在视频顶部的视频中放置第一帧的图像,并将其隐藏在stars()方法之后.添加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);
Run Code Online (Sandbox Code Playgroud)

wiz*_*lee 51

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

  @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;
      }
    });
Run Code Online (Sandbox Code Playgroud)

我认为onPrepared只是意味着视频已准备就绪,但并不意味着视频开始播放.如果在onPrepared中隐藏占位符,则屏幕仍显示黑屏.

在我的Note3和Nexus上,此解决方案运行良好.


jc_*_*_35 41

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

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

这对我来说可以.

  • 仅当您没有在视频视图上设置窗口小部件时,它才有效 (4认同)

M t*_*e K 37

我遇到了同样的问题,我找到了解决方案.它有点hacky但它​​可以做到这一点.所以基本上你需要把你的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>
Run Code Online (Sandbox Code Playgroud)

在您的活动中,您需要实现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);
}
Run Code Online (Sandbox Code Playgroud)

因此,当视频准备就绪时,我们会隐藏我们的占位符,并避开黑色闪烁屏幕.

希望这能有所帮助.

  • 有更好的解决方案吗? (61认同)
  • 这是一个非常差的解决方法,因为它意味着不透明的drawable匹配布局.此外,我发现闪烁的持续时间因设备而异,第一帧不一定显示在调用`onPrepared()`时.令人失望. (4认同)
  • 但是即使在onPrepared调用后,我的黑屏仍然出现,该怎么办? (2认同)
  • 该视图仍然会导致闪烁。@wizardlee 有正确答案 (2认同)

Rav*_*ani 26

我有同样的问题,这对我有用..

当你想要显示视频时,请制作videoView.setZOrderOnTop(false); 当你想要隐藏视频时,只需制作videoView.setZOrderOnTop(true);

  • 出于某种原因,这*提高了*性能,但并不能完全防止黑闪。不过谢谢 (2认同)

Ahm*_*ck' 21

我有同样的问题,我刚刚使用了videov.setBackgroundColor(Color.WHITE)然后onprepare我使用了Color.TRANSPARENT)白色仍然比黑色更适合我


Car*_*l B 17

通过扩展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) {}
}
Run Code Online (Sandbox Code Playgroud)


emm*_*gfx 12

这对我有用:

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

至少两年后,但我希望这是有帮助的.


Sia*_*ash 5

以上都不对我有用。就我而言,onPrepared在黑框消失之前被称为,因此我仍然会看到黑框。

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

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

android:alpha="0"
Run Code Online (Sandbox Code Playgroud)

然后在开始播放视频之前,我将Alpha动画设置回1:

videoView.animate().alpha(1);
videoView.seekTo(0);
videoView.start();
Run Code Online (Sandbox Code Playgroud)

或者,您可以发布一个延迟的Runnable来将Alpha设置为1,而不是对其进行动画处理。