I have been looking for a way to get rid of the nasty black initial screen on a VideoView before the start() method is run.
I have tried with background image on the
I got the same problem and i found a solution. Its a little bit hacky but it do the trick. So basically you need to put your VideoView into a FrameLayout. Over the videoview you need to add another FrameLayout with the background of your video and when your video is loaded and ready to play you hide the placeholder.
<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>
In your activity you need to implements OnPreparedListener and add this
//Called when the video is ready to play
public void onPrepared(MediaPlayer mp) {
View placeholder = (View) findViewById(R.id.placeholder);
placeholder.setVisibility(View.GONE);
}
So when the video is ready we hide our placeholder and that trick avoid the black flicker screen.
Hope this help someone.
By extending a TextureView, I get no black screens in the beginning or end. This is if you want to avoid using 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) {}
}
This is definitely hacky, but better than overlaying an image (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);
}
Assuming you are putting things into savedInstanceState
in onSaveInstanceState
.
I had same problem and this has worked for me ..
When you want to show video, make videoView.setZOrderOnTop(false); and when you want to hide video, just make videoView.setZOrderOnTop(true);
This one works for me :
In XML : VideoView hide behind a Relative layout with white Background
<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>
and in 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();
Hope this helps.
This is a nice solution:
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>