Avant de lancer la méthode start (), je cherchais un moyen de se débarrasser du mauvais écran noir initial sur VideoView.
J'ai essayé d'utiliser une image d'arrière-plan sur le widget mais cela ne fonctionne pas du tout comme prévu .. J'ai également essayé de placer une image de la première image de la vidéo au-dessus de VideoView et de la masquer après la méthode stars (). Ajout d’un écouteur préparé pour lancer la vidéo, puis masquer l’image. Cela fonctionne mais il y a un horrible scintillement dans la transition et je ne sais pas comment m'en débarrasser.
Merci pour votre réponse. L'ajout du MediaController n'a eu aucun effet. Le problème persiste (je vois toujours le scintillement noir) et je ne veux pas que les commandes vidéo soient visibles. Mon code ressemble à ceci:
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);
J'ai eu le même problème et j'ai trouvé une solution. C'est un peu hacky mais ça fait l'affaire . Donc, en gros, vous devez placer votre VideoView dans un FrameLayout . Sur la vidéo, vous devez ajouter un autre FrameLayout avec l'arrière-plan de votre vidéo et le chargement de votre vidéo et prêt à jouer, cachez l’espace réservé.
<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>
Dans votre activité, vous devez implémenter OnPreparedListener et ajouter ceci.
//Called when the video is ready to play
public void onPrepared(MediaPlayer mp) {
View placeholder = (View) findViewById(R.id.placeholder);
placeholder.setVisibility(View.GONE);
}
Ainsi, lorsque la vidéo est prête, nous masquons notre espace réservé et cette astuce évite l’écran de scintillement noir.
J'espère que cela aidera quelqu'un.
Je rencontre le même problème et le résout avec la solution acceptée ci-dessus, plus ceci:
@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;
}
});
Je pense que onPrepared signifie simplement que la vidéo est prête à être lue, mais pas que la vidéo a commencé à être lue. Si masquer un espace réservé dans onPrepared, l'écran affiche toujours un écran noir.
Sur ma Note3 et Nexus, cette solution fonctionne bien.
J'ai eu le même problème sur Galaxy Tab 2, Android 4.1.1.
Est-ce que videoView.setZOrderOnTop(true);
et next videoView.start()
Ça fonctionne bien pour moi.
J'ai eu le même problème et cela a fonctionné pour moi ..
Lorsque vous souhaitez afficher une vidéo, définissez videoView.setZOrderOnTop (false); et lorsque vous souhaitez masquer une vidéo, il suffit de créer videoView.setZOrderOnTop (true);
J'ai le même problème que je viens d'utiliser videov.setBackgroundColor (Color.WHITE) puis onprepare j'ai utilisé Color.TRANSPARENT) le blanc est toujours meilleur que le noir pour moi
En prolongeant un TextureView, je n’obtiens pas d’écrans noirs au début ou à la fin. C'est si vous voulez éviter d'utiliser 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) {}
}
Cela a fonctionné pour moi:
videoView.setBackgroundColor(Color.WHITE); // Your color.
videoView.start();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.setBackgroundColor(Color.TRANSPARENT);
}
});
Au moins deux ans plus tard, mais j'espère que cela a été utile.
C'est certainement hacky, mais c'est mieux que de superposer une 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);
}
En supposant que vous mettez des éléments dans savedInstanceState
dans onSaveInstanceState
.
Aucune des personnes ci-dessus n'a fonctionné pour moi. Dans mon cas, onPrepared
est appelé AVANT que le cadre noir disparaisse, je verrais toujours le cadre noir.
J'avais besoin d'une solution où la vidéo est apparue peu de temps après la première image.
Donc, ce que j'ai fait a été de régler l'alpha VideoView sur 0 en xml:
Android:alpha="0"
et puis avant de commencer la vidéo, j'anime l'alpha en 1:
videoView.animate().alpha(1);
videoView.seekTo(0);
videoView.start();
alternativement, vous pouvez simplement poster un Runnable retardé pour définir l'alpha sur 1, au lieu de l'animer.
Pour les personnes qui recherchaient toujours une réponse, appeler VideoView.start()
et VideoView.pause()
successivement à l'intérieur de onPrepared
fonctionnait pour moi. Je sais que ce n'est peut-être pas le moyen idéal d'y parvenir, mais peut-être avec la solution de contournement minimale requise dans le code. J'espère que cela fonctionne pour vous aussi.
@Override
public void onPrepared(MediaPlayer mp) {
mVideoView.start();
mVideoView.pause();
}
Utilisez simplement VideoView # setBackgroundDrawable (), je pense.
paramètres initiaux.
VideoView.setBackgroundDrawable(yourdrawableid);
démarrer la vidéo
VideoView.start();
VideoView.setBackgroundDrawable(0);
Il suffit d'afficher une image de la vidéo en tant qu'aperçu.
vSurface.SeekTo(100);
Cela fonctionne pour moi à la fois sur l'activité et sur le fragment.
VideoView mVideo = (VideoView) findViewById(R.id.yourViewViewId);
mVideo.setVideoURI(mUri);
mVideo.setZOrderOnTop(false);
SurfaceHolder surfaceholder = mVideo.getHolder();
surfaceholder.setFormat(PixelFormat.TRANSPARENT);
Celui-ci fonctionne pour moi:
En XML: VideoView se cache derrière une mise en page relative avec un arrière-plan blanc
<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>
et dans Activité: 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();
J'espère que cela t'aides.
J'ai eu le même problème. J'ai trouvé que la raison principale en était l'utilisation de FrameLayout
en tant que disposition parent. Utilisez RelativeLayout
comme disposition parent de la VideoView
Je préférerais cette solution: https://stackoverflow.com/a/11016465/2267723
son à propos de la surface afin de créer une mise en page factice @ fragment et vous ne verrez plus ce flash noir ..
Utilisez svVideoView.seekTo (position) .
Donner la position dans les 5 (ms).
onPause():
position=svVideoView.getCurrentPosition()
onResume():
svVideoView.seekTo(position);
C'est un peu tard pour cette réponse, mais peut-être que d'autres utilisateurs ont le même problème et trouvent cette question.
J'ai réglé le problème, en définissant initialement BackgroundResource puis, lors du démarrage de la vidéo, j'ai défini une couleur invisible pour l'arrière-plan.
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();
Pour éviter les problèmes d’écran noir vacillant et clignotant, j’ai écrit FrameVideoView .
Il tire parti de la 'solution de substitution' et (si votre appareil exécute une API de niveau 14 ou supérieur) de TextureView
, ce qui est beaucoup plus efficace que VideoView
.
J'ai écrit article sur notre blog pour couvrir ce qu'il fait réellement.
C'est simple à utiliser:
Ajoutez FrameVideoView
à la mise en page:
<mateuszklimek.framevideoview.FrameVideoView
Android:id="@+id/frame_video_view"
Android:layout_width="@dimen/video_width"
Android:layout_height="@dimen/video_height"
/>
trouver son instance dans Activity
et appeler les méthodes correspondantes dans onResume
et onPause
:
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();
}
}
C'est une bonne 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>