studio programacion para libros gratis español edición desarrollo desarrollar con aprende aplicaciones java android android-videoview

java - para - manual programacion android español pdf



VideoView flash negro antes y después de jugar (14)

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

Solo debe configurar contentView en el método onCreate() de una Activity . Si lo estás haciendo en otro lugar (por ejemplo, en la devolución de llamada de un botón), deberías comenzar una nueva actividad en su lugar.

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í no es un gran problema, pero la negrura sí lo es. El fondo es blanco, por lo que si el flash es blanco, o si desaparece, estará bien.


¿Por qué no usar estilos y temas?

¿Puedes probar esto? Esto podría ayudar

colores.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 configurar 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">


Aquí hay un truco simple

verifique la condición media player.getCurrentPosition == 0 en el oyente preparado de la vista de video, aparecerá una pantalla negra cuando la posición sea cero, así que muestre una imagen hasta que se cargue el video

mi código:

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


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 referenciarlo con (VideoView) findViewById(R.id.vid); en lugar de new VideoView(this); y configurando la vista de contenido para ese diseño.


Hay una alternativa que utiliza el controlador de medios para esto. Aquí está el código de muestra

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.


Hoy tuve el mismo problema y encontré una solución muy mala e intrépida para este problema desagradable: me di cuenta de que se puede establecer un color de fondo / VideoView en el VideoView que se mezcla con la superficie del video y lo hace completamente oculto. Sin embargo, esto solo funciona cuando el video subyacente aún se está reproduciendo , no cuando se detiene (ni cuando se terminó normalmente ni cuando se llamó a stopPlayback() ), de lo contrario, vería nuevamente un parpadeo negro. El fondo tampoco se debe configurar al principio, de lo contrario, el video quedaría completamente oculto desde el principio.

Así que el único paso lógico para mí fue publicar un evento retrasado justo antes de comenzar el video, y como sé la duración del video, dejé que este evento ocurriera solo unos pocos milisegundos antes de que termine normalmente. Tomé una captura de pantalla del último fotograma en VLC y luego lo combiné así:

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

Sin embargo, esto no fue suficiente, porque cuando el video realmente terminó, aún tuve un pequeño parpadeo en la pantalla negra, así que también tuve que configurar la imagen fija como fondo del contenedor que contenía el video (en mi caso, fue el diseño del 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 1024x600, video 960x640). Digo principalmente , porque por alguna razón desconocida, la imagen de fondo del diseño se fusiona en aproximadamente 10 píxeles en la parte superior. Este fue el último truco que tuve que aplicar para que funcionara: mueva el contenedor de video -10dip al vacío en la parte superior.

Esto ahora se ve increíble en mi Galaxy Tab, aunque no me atrevo a probarlo en el teléfono SGS2 ...


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


Mi solución para este error diabólico utilizó una vista en blanco con el color de fondo de elección en la parte superior de la VideoView.

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

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

Eso me libró del comienzo del flash negro. Luego, para el destello negro final, 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); }


Mi variación sobre el tema @tommyd:

Establezca el dibujo en un marco de video estático, luego haga spam en la cola de mensajes. Después de algún tiempo, borre el dibujo para que se procesen los cuadros de video. Luego, antes de completar, restablezca 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);


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

En mi caso, el video era un recurso en la aplicación (es decir, sabía todo sobre él y no iba a cambiar) y sus últimos 500 ms fueron el mismo fotograma, 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 lo postDelayed en la vista raíz ( android.R.id.content ) durante la duración del video, menos la duración a la que estoy dispuesto a pausar el video (y una generoso búfer, porque no se garantiza que postDelayed se ejecute exactamente después de la hora solicitada)

Luego, el ejecutable comprueba si el video llegó a su tiempo de pausa, si es así, lo detiene y hace lo que queramos que haga. Si no lo hace, se ejecuta postDelayed de nuevo consigo mismo, durante un tiempo más corto (100 ms en mi caso, pero podría ser más corto)

Por supuesto, esto dista mucho de ser una solución ideal, pero podría ayudar a alguien con un problema específico similar al que me tropezó durante medio día :)


Sé que es una pregunta antigua, pero si puedes agregar algo de código a los oyentes de MediaPlayer, la respuesta es muy simple. Resultó que setBackgroundColor for VideoView cambia el color de primer plano ( https://groups.google.com/forum/?fromgroups=#!topic/android-developers/B8CEC64qYhQ ).
Entonces, lo único que tienes que hacer es cambiar entre setBackgroundColor (Color.WHITE) y setBackgroundColor (Color.TRANSPARENT).


Terminé teniendo que hacer algo muy similar a @tommyd para evitar el flash de SurfaceView negro al principio y al final de mis videos. Sin embargo, encontré que la configuración / anulación del dibujable de fondo para el videoView no se producía instantáneamente en muchos teléfonos. Podría haber una demora de aproximadamente medio segundo entre mi llamada para establecer el fondo y cuándo se mostró.

Lo que terminé haciendo fue crear un SurfaceView personalizado que mostraba un solo color sólido, luego lo superponía sobre VideoView y utilizaba SurfaceView.setZOrderMediaOverlay ().

Mi SurfaceView personalizado fue fuertemente informada 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 alberga las vistas:

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

Luego 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 el VideoView con pantalla negra).

En mis experimentos en varios teléfonos, este método proporcionó una visualización / ocultación muy rápida de la máscara de video, en lugar de establecer / anular el fondo.


Tuve el mismo problema que esto me ha funcionado ..

Cuando quiera mostrar un video, haga que videoView.setZOrderOnTop (false); y cuando quiera ocultar la vista de video, simplemente haga videoView.setZOrderOnTop (true);


Tuve el mismo problema y el blanco en lugar del negro estaba bien para mí. Probé todas las soluciones anteriores. Se me ocurrió lo 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 retrasó mi video 400 ms, empezando a desvanecerse de las obras blancas como un encanto para mí