VideoView black flash before and after playing

前端 未结 14 2180
谎友^
谎友^ 2020-12-09 04:04

I have a VideoView which I want to use to play a movieclip. I use it like this to play it and it works.

VideoView vv = new VideoView(this);
vv.setVideoURI(Ur         


        
相关标签:
14条回答
  • 2020-12-09 04:31

    Another solution that might work for people who are searching for this question:

    In my case, the video was a resource in the app (that is, I knew everything about it and it wasn't going to change) and its last 500 ms were the same frame, so I ended up doing the following:

    mVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.splash));
    mVideoView.start();
    
    findViewById(android.R.id.content).postDelayed(new WaitForSplashScreenToFinish(), mVideoView.getDuration() - 1000);
    

    and the referenced class is:

    private class WaitForSplashScreenToFinish implements Runnable {
        @Override
        public void run() {
            if (mVideoView.isPlaying() && mVideoView.getCurrentPosition() >= mVideoView.getDuration() - 500) {
                mVideoView.pause();
    
                // Now do something else, like changing activity
            } else {
                findViewById(android.R.id.content).postDelayed(this, 100);
            }
        }
    }
    

    Explanation: Immediately after starting the video I create a Runnable and postDelayed it to the root view (android.R.id.content) to the duration of the video, minus the length at which I'm willing to pause the video (and a generous buffer, because postDelayed isn't guaranteed to play exactly after the requested time)

    Then, the runnable checks if the video arrived at its pause-time, if so it pauses it and does whatever else we want it to do. If it doesn't, it runs postDelayed again with itself, for a shortened time (100 ms in my case, but could be shorter)

    Granted, this is far from being an ideal solution, but it might help someone with a specific problem similar to the one that stumbled me for half a day :)

    0 讨论(0)
  • 2020-12-09 04:31

    I know it's old question but if you can add some code to MediaPlayer listeners there is very simple answer. It turned out that setBackgroundColor for VideoView changes the foreground color ( https://groups.google.com/forum/?fromgroups=#!topic/android-developers/B8CEC64qYhQ ).
    So the only thing you have to do is switching between setBackgroundColor(Color.WHITE) and setBackgroundColor(Color.TRANSPARENT).

    0 讨论(0)
  • 2020-12-09 04:32

    i had the same problem and white instead of black was ok for me.. i tried all of solutions above i came up with the following

    vv.setBackgroundColor(Color.WHITE);
    vv.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        vv.setVideoURI(videoUri);
                    }
                }, 100);
    vv.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        vv.setBackgroundColor(Color.TRANSPARENT);
                    }
                }, 300);
                vv.requestFocus();
                vv.start();
    

    and delayed my video 400 ms start fading from white works like a charm for me

    0 讨论(0)
  • 2020-12-09 04:40

    I ended up having to do something very similar to @tommyd to avoid the black surfaceView flash at the beginning and end of my videos. However, I found that setting/nulling the background drawable for the videoView was not occurring instantly on many phones. There could be about a half-second delay between my call to set the background and when it was actually displayed.

    What I ended up doing was creating a custom SurfaceView that showed a single, solid color, then overlayed this on top of the VideoView and made use of SurfaceView.setZOrderMediaOverlay().

    My custom SurfaceView was heavily informed by: http://android-er.blogspot.com/2010/05/android-surfaceview.html

    public class SolidSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    
        private static final String TAG = SolidSurfaceView.class.getSimpleName();
    
        private SolidSurfaceThread mThread;
        private boolean mSurfaceIsValid;
        private int mColor;
    
        public SolidSurfaceView(Context context) {
            super(context);
            init();
        }
    
        public SolidSurfaceView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public SolidSurfaceView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        private void init() {
            Log.verbose(TAG, "init");
    
            getHolder().addCallback(this);
            setZOrderMediaOverlay(true);
        }
    
        public void setColor(int color) {
            mColor = color;
            invalidate();
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            Log.verbose(TAG, "surfaceCreated");
    
            mSurfaceIsValid = true;
    
            mThread = new SolidSurfaceThread(getHolder(), this);
            mThread.setRunning(true);
            mThread.start();
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.verbose(TAG, "surfaceDestroyed");
            mSurfaceIsValid = false;
    
            boolean retry = true;
            mThread.setRunning(false);
            while (retry) {
                try {
                    mThread.join();
                    retry = false;
                }
                catch (InterruptedException e) {
                    Log.warning(TAG, "Thread join interrupted");
                }
            }
            mThread = null;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if ( ! mSurfaceIsValid) {
                return;
            }
    
            canvas.drawColor(mColor);
        }
    
        private static class SolidSurfaceThread extends Thread {
    
            private final SurfaceHolder mSurfaceHolder;
            private final SolidSurfaceView mSurfaceView;
            private boolean mIsRunning;
    
            public SolidSurfaceThread(SurfaceHolder surfaceHolder, SolidSurfaceView surfaceView) {
                mSurfaceHolder = surfaceHolder;
                mSurfaceView = surfaceView;
            }
    
            public void setRunning(boolean running) {
                mIsRunning = running;
            }
    
            @Override
            public void run() {
                while (mIsRunning) {
                    Canvas c = null;
                    try {
                        c = mSurfaceHolder.lockCanvas(null);
                        synchronized (mSurfaceHolder) {
                            mSurfaceView.onDraw(c);
                        }
                    }
                    finally {
                        // do this in a finally so that if an exception is thrown
                        // during the above, we don't leave the Surface in an
                        // inconsistent state
                        if (c != null) {
                            mSurfaceHolder.unlockCanvasAndPost(c);
                        }
                    }
                }
            }
        }
    }
    

    And in the parent activity that hosts the views:

        mVideoView = (VideoView)findViewById(R.id.video_view);
        mVideoMask = (SolidSurfaceView)findViewById(R.id.video_mask);
        mVideoMask.setColor(Color.BLUE);
    

    You can then do things like mVideoMask.setVisibility(View.GONE) to hide the mask or mVideoMask.setVisibility(View.VISIBLE) to show the mask (and hide the black-screened VideoView).

    In my experiments on various phones, this method provided very fast showing/hiding of the video mask, as opposed to setting/nulling the background.

    0 讨论(0)
  • 2020-12-09 04:40

    here is simple trick

    check the condition media player.getCurrentPosition == 0 in on prepared listener of video view ,black screen will appear when position is zero so display an image untill the video will load

    mycode:

    mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(final MediaPlayer mediaPlayer) {
                    mVideoView.start();
    
    
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
    
                            while (mediaPlayer.isPlaying()) {
                                Log.d("MainActivity", "position " + mediaPlayer.getCurrentPosition());
                                if (mediaPlayer.getCurrentPosition() == 0) {
                                    videoStillImageView.setVisibility(View.VISIBLE);
                                } else {
                                    videoStillImageView.setVisibility(View.GONE);
    
    
                                    break;
                                }
                            }
    
                        }
                    });
                }
            }
        });
    
    0 讨论(0)
  • 2020-12-09 04:40

    That flash comes from changing the current content view to another one. You could try adding a VideoView to your layout xml file then referencing it with (VideoView) findViewById(R.id.vid); instead of new VideoView(this); and setting the content view to that layout.

    0 讨论(0)
提交回复
热议问题