web-dev-qa-db-fra.com

Écran noir Android VideoView

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);
48
SergioM

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.

35
M to the K

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.

45
wizardlee

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.

38
jc_35

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

25
Ravi Bhojani

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

20

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) {}
}
15
Carl B

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.

7
emmgfx

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.

4
Paul Burke

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. 

3
Siavash

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

Utilisez simplement VideoView # setBackgroundDrawable (), je pense.

  1. paramètres initiaux.

    VideoView.setBackgroundDrawable(yourdrawableid);
    
  2. démarrer la vidéo

    VideoView.start();
    VideoView.setBackgroundDrawable(0);
    
2
Takeaki Kubota

Il suffit d'afficher une image de la vidéo en tant qu'aperçu.

vSurface.SeekTo(100);
2
j7nn7k

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);
1
Nam lê đình

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.

1
Ramza

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

0
Vinil Chandran

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 .. 

0
Maher Abuthraa

Utilisez svVideoView.seekTo (position)

Donner la position dans les 5 (ms).

onPause():
position=svVideoView.getCurrentPosition()

onResume():
svVideoView.seekTo(position);
0
Raj

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

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

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>
0
OShiffer