Android VideoView黑屏

Android VideoView黑屏,android,flicker,android-videoview,Android,Flicker,Android Videoview,我一直在寻找一种方法,在运行start()方法之前,消除VideoView上令人讨厌的黑色初始屏幕 我已经尝试过在小部件上使用背景图像,但它根本没有按预期工作。 我还尝试将视频中第一帧的图像放在VideoView的顶部,并在start()方法之后隐藏它。 添加onPrepared侦听器以启动视频,然后隐藏图像。这是可行的,但在转换过程中出现了可怕的闪烁,我不知道如何消除它 添加MediaController没有任何效果。问题依然存在(我仍然看到黑色闪烁),我根本不想让视频控件可见。 我的代码如

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

我已经尝试过在小部件上使用背景图像,但它根本没有按预期工作。 我还尝试将视频中第一帧的图像放在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);
看到这个了吗

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

我遇到了同样的问题,我找到了解决办法。这有点老套,但确实很管用。 所以基本上你需要把你的视频视图放到一个框架布局中。 在视频视图上,您需要添加另一个带有视频背景的框架布局,当您的视频加载并准备播放时,您可以隐藏占位符

<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>
因此,当视频准备好时,我们隐藏占位符,这样可以避免黑色闪烁屏幕


希望这能帮助到别人。

我也遇到过同样的问题,这对我来说很有效


当你想显示视频时,使videoView.setZOrderOnTop(false);当你想隐藏视频时,只需设置videoView.setZOrderOnTop(true)

现在回答这个问题有点晚了,但也许其他用户也有同样的问题,并找到了这个问题

我已经处理过了,首先设置了背景资源,然后在开始视频时,我将背景设置为不可见的颜色

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

这无疑是一个骇客,但比叠加图像(IMO)要好


假设你把东西放到saveInstanceState的
savedInstanceState
中,我也遇到了同样的问题,我刚刚用了videov.setBackgroundColor(Color.WHITE),然后用了prepare,我用了Color.TRANSPARENT)白色对我来说仍然比黑色好

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

Do
videoView.setZOrderOnTop(true)和下一步
videoView.start()


它对我来说很好。

通过扩展TextureView,我在开始或结束时都不会出现黑屏。如果您希望避免使用
ZOrderOnTop(true)
,则可以使用此选项

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

  • 初始设置

    VideoView.setBackgroundDrawable(yourdrawableid);
    
  • 开始视频

    VideoView.start();
    VideoView.setBackgroundDrawable(0);
    
  • 这对我很有用:

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

    至少两年后,但我希望这会有所帮助。

    这是一个很好的解决方案:

    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();
    }
    
    }
    
    <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>
    
    活动\u main.xml:

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

    使用svVideoView.seekTo(位置)

    在5(ms)内给出位置


    我遇到了同样的问题,并用上述公认的解决方案加上:

      @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上,此解决方案运行良好。

    只需将视频中的一帧显示为预览

    vSurface.SeekTo(100);
    

    为了避免令人讨厌的闪烁和黑屏问题,我写了一篇文章

    它从“占位符解决方案”和
    TextureView
    中(如果您的设备运行的是API级别14或更高)中获益,后者比
    VideoView
    效率更高

    我在我们的博客上写下了它的实际功能

    使用简单:

    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();
    }
    
    }
    
    <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
    添加到布局:

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

    对于仍在寻找答案的人来说,在
    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>
    
    启动:

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

    希望这对我有帮助。

    以上这些都不适合我。 在我的例子中,
    onPrepared
    在黑框消失之前被调用,所以我仍然可以看到黑框

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

    因此,我在xml中将VideoView alpha设置为0:

    android:alpha="0"
    
    然后在开始视频之前,我将alpha设置为1:

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

    或者,您可以发布一个延迟的Runnable,将alpha设置为1,而不是设置动画

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

    的父布局,它对我的活动和片段都有效

    VideoView mVideo = (VideoView) findViewById(R.id.yourViewViewId);
              mVideo.setVideoURI(mUri);
              mVideo.setZOrderOnTop(false);
    
    SurfaceHolder surfaceholder = mVideo.getHolder();
    surfaceholder.setFormat(PixelFormat.TRANSPARENT);
    

    修改@emmgfx的答案对我很有用:

    videoView.setBackgroundColor(Color.WHITE); // Your color.
    videoView.start();
    videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            videoView.setBackgroundColor(Color.TRANSPARENT);
        }
    });
    
    videoView.setBackgroundColor(Color.WHITE)
    videoView.start()
    Timer().schedule(100){
      videoView?.setBackgroundColor(Color.TRANSPARENT)
    }
    
    诀窍是延迟视频查看直到加载视频。
    PS:我是kotlin。

    对我来说,在播放mp4视频时设置
    setZOrderOnTop
    并没有完全删除初始黑框。然而,它确实缩短了黑框出现的时间。我想完全删除最初的黑色帧,所以我四处玩,发现将视频向前搜索100毫秒对我来说是个好办法

    请注意,我正在循环使用视频,因此如果您不想循环视频,请删除
    mp.isLooping=true

    以下是我用来解决此问题的代码段:

    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 
    }
    

    如果有人认为上面的方法有用,我能得到一个确切的解释,说明为什么它会起作用,那就太好了。

    我找到了解决这个问题的好办法。(科特林)

    在视频视图上方创建图像视图。 使用处理程序创建函数,并检查(videoview.duration>0)

    如果持续时间大于零,则将imageview.visibility设置为不可见,然后立即
        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)
    
    }
    
            prepareSizing(it)
            initializeProgressBar()
            showVideoView()
            
        }