VideoView flash negro antes y después de jugar

Tengo un VideoView que quiero usar para reproducir un movieclip. Lo uso así para jugar y funciona.

VideoView vv = new VideoView(this); vv.setVideoURI(Uri.parse("android.resource://cortex2.hcbj/raw/intro")); setContentView(vv); vv.start(); 

Sin embargo, veo un flash negro justo antes y después del clip de película. El flash en sí mismo no es un gran problema, pero la oscuridad de lo que es. El fondo es blanco, así que si el flash es blanco, o si desaparece estará bien.

Hoy tuve el mismo problema y encontré una solución muy mala y hacky para este desagradable problema: me di cuenta de que se puede establecer un color de fondo / VideoView en el VideoView que se mezcla sobre la superficie de vídeo y lo hace completamente oculto. Esto sólo funciona aunque el vídeo subyacente sigue reproduciéndose , no cuando se detiene (ni cuando finalizó normalmente ni cuando se llamó stopPlayback() ), de lo contrario, volvería a ver un parpadeo negro. El fondo también no se debe establecer en el principio, de lo contrario el vídeo estaría completamente oculto desde el principio.

Así que el único paso lógico para mí fue publicar un evento retrasado justo antes de iniciar el video, y como sé la longitud del video, dejo que este evento ocurra unos milisegundos antes de que finalice normalmente. Tomé una captura de pantalla del último fotograma en VLC y lo mezclé de la siguiente manera:

 private void startVideo() { introVideo.setBackgroundDrawable(null); introVideo.postDelayed(new Runnable() { public void run() { if (!introVideo.isPlaying()) return; introVideo.setBackgroundResource(R.drawable.video_still_image); // other stuff here, for example a custom transition to // another activity } }, 7500); // the video is roughly 8000ms long introVideo.start(); } 

Esto, sin embargo, no fue suficiente, porque cuando el video realmente terminó, todavía tengo un pequeño parpadeo de pantalla en negro, así que también tuve que configurar la imagen fija como fondo del contenedor que contenía el video (en mi caso era el diseño de la actividad):

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/video_still_image"> <VideoView android:id="@+id/introVideo" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentRight="true" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" android:layout_marginTop="-10dip" /> </RelativeLayout> 

Esta actividad se representa en pantalla completa y el video se ajusta (en su mayoría) al tamaño total de la pantalla (pantalla 1024×600, vídeo 960×640). Digo sobre todo , porque por alguna razón desconocida la imagen de fondo de la disposición se mezcla a través de cerca de 10px en tapa. Este fue el último truco que tuve que aplicar para que funcione: mueva el contenedor de video -10dip al vacío en la parte superior.

Esto ahora se ve impresionante en mi Galaxy Tab, no me atrevo a probarlo en el teléfono SGS2, aunque …

Acabé teniendo que hacer algo muy similar a @ tommyd para evitar la superficie negra flash de vista al principio y al final de mis videos. Sin embargo, encontré que la configuración / nulling el fondo dibujable para el videoView no se producía al instante en muchos teléfonos. Podría haber un retraso de medio segundo entre mi llamada para establecer el fondo y cuando se mostrara en realidad.

Lo que acabé haciendo fue crear un SurfaceView personalizado que mostraba un solo color sólido, luego superponía esto en la parte superior del VideoView y hacía uso de SurfaceView.setZOrderMediaOverlay ().

Mi SurfaceView personalizado fue muy informado por: 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); } } } } } } 

Y en la actividad principal que aloja las vistas:

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

A continuación, puede hacer cosas como mVideoMask.setVisibility(View.GONE) para ocultar la máscara o mVideoMask.setVisibility(View.VISIBLE) para mostrar la máscara (y ocultar la pantalla negra VideoView).

En mis experimentos en varios teléfonos, este método siempre muy rápido mostrando / ocultar la máscara de vídeo, en lugar de establecer / anular el fondo.

Tuve el mismo problema y blanco en lugar de negro estaba bien para mí .. he intentado todas las soluciones por encima i se acercó con el siguiente

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

Y retrasado mi video 400 ms comienzan a desvanecerse de las obras blancas como un encanto para mí

Mi solución para este insecto diabólico utilizó una vista en blanco con el color de fondo de la opción sobre la tapa del VideoView.

 <View android:id="@+id/blankView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/white" /> 

Entonces en mi código hice esto:

  video = (VideoView) findViewById(R.id.video); // set the video URI, passing the vSourse as a URI video.setVideoURI(Uri.parse(vSource)); video.setZOrderOnTop(false); SurfaceHolder sh = video.getHolder(); sh.setFormat(PixelFormat.TRANSPARENT); ctlr = new BCDMediaController(this); ctlr.setMediaPlayer(video); video.setMediaController(ctlr); video.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { closeActivity(); } }); blankView = findViewById(R.id.blankView); video.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { blankView.postDelayed(new Runnable() { public void run() { blankView.setVisibility(View.GONE); } }, 500); } }); video.start(); video.requestFocus(); 

Que se deshizo del flash de inicio negro para mí. Luego, para el final flash negro, hice esto:

 private void closeActivity() { blankView.setVisibility(View.VISIBLE); blankView.postDelayed(new Runnable() { public void run() { video.setOnCompletionListener(null); video.stopPlayback(); video.suspend(); VideoPlayerViewController.this.finish(); } }, 1); } 

Si eso ayuda, vote esta respuesta.

Ese flash viene de cambiar la vista de contenido actual a otra. Puede intentar agregar un VideoView a su archivo xml de diseño y luego hacer referencia a él con (VideoView) findViewById(R.id.vid); En lugar de new VideoView(this); Y establecer la vista de contenido en ese diseño.

¿Por qué no usar estilos y temas?

¿Puedes probar esto? Esto podría ayudar

Colors.xml

 <drawable name="transparent">#00000000</drawable> 

Styles.xml

 <style name="Transparent"> <item name="android:windowIsTranslucent">true</item> <item name="android:windowAnimationStyle"> @android:style/Animation.Translucent </item> <item name="android:windowBackground">@drawable/transparent</item> <item name="android:windowNoTitle">true</item> <item name="android:colorForeground">#fff</item> </style> 

Para establecer un tema para todas las actividades de su aplicación, abra el archivo AndroidManifest.xml y edite la etiqueta para incluir el atributo android: theme con el nombre del estilo.

 <application android:theme="@style/Transparent"> 

¿Dónde está cambiando el contentView (en qué método escribió las cuatro líneas de código anteriores)?

Sólo debe establecer el contentView en el método onCreate() de una Activity . Si lo está haciendo en otro lugar (por ejemplo en la devolución de llamada de un botón), debería iniciar una nueva actividad.

Hay una alternativa que se utiliza controlador de medios para esto. Aquí hay código de ejemplo

 videoView = (VideoView) this.findViewById(R.id.videoView); MediaController mc = new MediaController(this); videoView.setMediaController(mc); videoView.setVideoURI(Uri.parse("http://c421470.r70.cf2.rackcdn.com/video_5983079.m4v")); videoView.start(); videoView.requestFocus(); 

Prueba esto.

Otra solución que podría funcionar para las personas que están buscando esta pregunta:

En mi caso, el video era un recurso de la aplicación (es decir, sabía todo sobre él y no iba a cambiar) y sus últimos 500 ms eran el mismo cuadro, así que terminé haciendo lo siguiente:

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

Y la clase referenciada es:

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

Explicación: Inmediatamente después de iniciar el video, creo un Runnable y postDelayed a la vista de root ( android.R.id.content ) a la duración del video, menos la longitud a la que estoy dispuesto a pausar el video (y un Generoso, porque postDelayed no está garantizado para jugar exactamente después de la hora solicitada)

Entonces, el runnable comprueba si el video llegó a su tiempo de pausa, si es que lo detiene y hace cualquier otra cosa que queramos que haga. Si no lo hace, se ejecuta postDelayed de nuevo con sí mismo, por un tiempo acortado (100 ms en mi caso, pero podría ser más corto)

Por supuesto, esto está lejos de ser una solución ideal, pero podría ayudar a alguien con un problema específico similar al que me tropezó por medio día 🙂

Sé que es vieja pregunta pero si usted puede agregar un cierto código a los oyentes de MediaPlayer hay respuesta muy simple. Resultó que setBackgroundColor para VideoView cambia el color de primer plano ( https://groups.google.com/forum/?fromgroups=#!topic/android-developers/B8CEC64qYhQ ).
Así que lo único que tienes que hacer es cambiar entre setBackgroundColor (Color.WHITE) y setBackgroundColor (Color.TRANSPARENT).

Mi variación en el tema @tommyd:

Establezca el dibujable en un marco de vídeo estático y, a continuación, haga spam en la cola de mensajes. Después de algún tiempo, borrar el dibujable para que los fotogramas de vídeo render. A continuación, antes de finalizar, vuelva a establecer la imagen estática.

  mMovieView.setBackgroundDrawable(bg); mMovieView.start(); final int kPollTime= 25; mMovieView.postDelayed(new Runnable() { private final int kStartTransitionInThreshold= 50; private final int kStartTransitionOutThreshold= 250; private boolean mTransitioned= false; @Override public void run() { if (mMovieView.isPlaying()) { if (mMovieView.getCurrentPosition() > kStartTransitionInThreshold && !mTransitioned) { mMovieView.setBackgroundDrawable(null); // clear to video mTransitioned= true; } if (mMovieView.getDuration() - mMovieView.getCurrentPosition() < kStartTransitionOutThreshold) mMovieView.setBackgroundDrawable(bg); } mMovieView.postDelayed(this, kPollTime); // come back in a bit and try again } }, kPollTime); 

Tuve el mismo problema que esto ha funcionado para mí ..

Cuando quiera mostrar video haga videoView.setZOrderOnTop (false); Y cuando desea ocultar la vista de vídeo sólo tiene que hacer videoView.setZOrderOnTop (true);

Prueba esta línea. Esto funcionó para mí. If (player! = Null) player.release ();

 @Override protected void onDestroy() { super.onDestroy(); player.pause(); if(player!=null)player.release(); player = null; videoSurface = null; controller = null; } 
  • Uso de VideoView para streaming o video de descarga progresiva
  • Tamaño de la memoria intermedia de Android VideoView
  • Cómo configurar la imagen de vista previa en videoview antes de jugar
  • Android carga la animación antes de iniciar VideoView
  • Problema de parpadeo de VideoView
  • ¿Por qué mi aplicación Android dice "No se puede reproducir el vídeo" después de la reproducción?
  • Android VideoView inicia muchos videos secuencialmente
  • Cómo detectar si VideoView está reproduciendo video o Buffering?
  • Android: VideoView dentro de Fragmento sólo reproduce audio, no muestra vídeo
  • VideoView en bucle de videos Replenish
  • Reproducción de vídeo desde el estado de pausa en VideoView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.