reproductor - Android: Reproducción de video sin pausas o sin medios de MediaPlayer
reproductor de musica android studio (7)
¿Intentó tener listos (abiertos / preparados) 2 VideoView, con uno siendo visible, otro invisible y detenido, y pronto obtendrá la devolución de llamada de OnCompletionListener, hará que el segundo sea visible, lo inicie y oculte el primero. Mientras tanto, cuando toque 2nd, puede llamar abrir / preparar en 1st VideoView para abrir / preparar otro archivo.
Puedo reproducir los videos de forma correcta una tras otra implementando OnCompletionListener para configurar el origen de datos en un archivo diferente. No hay problemas allí. Llamo a reset () y prepare () muy bien.
Lo que no he podido descifrar, es cómo deshacerse del parpadeo de la pantalla de brecha de 1 a 2 segundos entre el cambio de fuente de datos y el inicio del nuevo video. La brecha muestra una pantalla negra, y no he encontrado ninguna forma de evitarlo.
Intenté establecer el fondo de la vista padre en una imagen, pero se las arregla para eludir eso. Incluso si el SurfaceView es transparente (que es de manera predeterminada). También intenté reproducir los múltiples archivos de video al mismo tiempo y cambiar la visualización del reproductor de medios cuando uno termina y se supone que el otro comienza.
Lo último que intenté fue tener una segunda vista en segundo plano que muestre temporalmente mientras el video se está "preparando" y quitándolo cuando el video esté listo para comenzar. Eso tampoco fue muy perfecto.
¿Hay alguna forma de deshacerse de esa brecha? Ejecutar un video en un bucle funciona maravillosamente y hace exactamente lo que quiero, con la excepción de que está mirando el mismo video en lugar de reproducir uno diferente que elijo.
main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:background="@drawable/background"
android:layout_height="fill_parent">
<SurfaceView
android:id="@+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center">
</SurfaceView>
</FrameLayout>
Player.java
public class Player extends Activity implements
OnCompletionListener, MediaPlayer.OnPreparedListener, SurfaceHolder.Callback {
private MediaPlayer player;
private SurfaceView surface;
private SurfaceHolder holder;
public void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.main);
surface = (SurfaceView)findViewById(R.id.surface);
holder = surface.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void onCompletion(MediaPlayer arg0) {
File clip = new File(Environment.getExternalStorageDirectory(),"file2.mp4");
playVideo(clip.getAbsolutePath());
}
public void onPrepared(MediaPlayer mediaplayer) {
holder.setFixedSize(player.getVideoWidth(), player.getVideoHeight());
player.start();
}
private void playVideo(String url) {
try {
File clip = new File(Environment.getExternalStorageDirectory(),"file1.mp4");
if (player == null) {
player = new MediaPlayer();
player.setScreenOnWhilePlaying(true);
}
else {
player.stop();
player.reset();
}
player.setDataSource(url);
player.setDisplay(holder);
player.setOnPreparedListener(this);
player.prepare();
player.setOnCompletionListener(this);
}
catch (Throwable t) {
Log.e("ERROR", "Exception Error", t);
}
}
@ user1263019 - ¿Pudiste conectar Android 4.0 MediaPlayer a tu aplicación? Estoy enfrentando el mismo problema y estoy buscando una buena solución. Mi caso es tener una imagen sobre el SurfaceView que debe ocultarse para mostrar la reproducción del video, pero hay un espacio entre el inicio de la llamada () y el inicio real del video. La única solución hasta el momento es iniciar un hilo que compruebe si getCurrentPosition () es> 0.
Sobre el tema: creo que no es posible tener una reproducción sin pausas, aunque Winamp afirma tener tales habilidades. Un hack sucio es preparar al segundo jugador varios segundos antes del final de la reproducción del primer jugador y luego llamar a start () del segundo jugador 100-200ms antes del final de la reproducción.
En su implementación exoplayer (o reproductor de medios) use un controlador para publicar repetidamente un ejecutable, mientras se reproduce, que obtiene el tiempo de seguimiento actual y lo pasa a una devolución de llamada:
public interface MediaAction {
public void onTrackingChanged(long currentPosition);
}
public class ExoPlayerImplementation implements Exoplayer {
..
private MediaAction mediaActionCallback;
public void setMediaActionCallback(MediaAction ma) {
mediaActionCallback = ma;
}
public void releaseMediaAction() { mediaActionCallback = null; }
private Handler trackingCallback = new Handler(Looper.getMainLooper());
Runnable trackingTask;
private Runnable getTrackingTask() {
Runnable r = new Runnable {
@Override public void run() {
long currentPosition = getCurrentPosition();
if (mediaActionCallback != null) {
mediaActionCallback.onTrackingChanged(currentPosition);
}
// 60hz is 16 ms frame delay...
trackingCallback.postDelayed(getTrackingTask(), 15);
}
};
trackingTask = r;
return r;
}
public void play() {
// exoplayer start code
trackingCallback.post(getTrackingTask());
}
public void pause/stop() {
trackingCallback.removeCallbacks(trackingTask);
}
..
}
Y ahora puede rastrear cuándo la posición actual realmente ha cambiado: si ha cambiado, puede mostrar su vista de salida de video / intercambiar vistas / eliminar vista previa (es decir, usar MediaExtractor para captar fotogramas iniciales, superposición como vista previa en un ImageView y luego ocultar una vez que la posición actual está aumentando). Puede hacer este código más completo combinándolo con el oyente de estado: entonces sabe si está almacenando en el búfer (consulte la posición de almacenamiento en búfer frente a la posición actual), reproduciendo, deteniendo o deteniendo con las devoluciones de llamada adecuadas (en MediaAction). Puede aplicar este método a las clases MediaPlayer y ExoPlayer (ya que solo es una interfaz y controlador).
¡Espero que ayude!
No creo que sea posible.
Motivo: Mortplayer también estaba disponible para Windows Mobile y uno de sus puntos fuertes era que admitía el juego gapless. Sin embargo, no aparece en la versión de Android de la aplicación, y el desarrollador mismo escribe que el SDK no lo permite en xda: http://forum.xda-developers.com/showpost.php?p=5364530&postcount=5
HTH, Daniele
No he hecho esto con la reproducción de video en un MediaPlayer, pero he hecho algo similar con los archivos de audio cuando se interrumpe una transmisión porque un usuario ha cambiado de 3G a Wifi.
Creo que la demora que está viendo es mientras el reproductor de medios está almacenando el archivo de entrada. ¿Entonces quizás puedas definir ambos jugadores al principio? Debería definir la fuente de datos y preparar a ambos jugadores, pero solo debe comenzar uno de ellos.
Luego, en su onCompletionListener puede voltearlos en lugar de restablecer el existente y establecer un nuevo origen de datos.
player.release();
player = flipPlayer;
flipPlayer = null;
player.start();
Obviamente, necesitaría utilizar un onPreparedListener diferente para flipPlayer o sacar el player.start () de onPrepare. (Dado que lo estás llamando sincrónicamente, no hubiera pensado que esto era un problema).
Yo también tengo el mismo problema que se describe en el siguiente enlace
VideoView desaparece por un segundo cuando se cambia el video
Pero este problema no ocurrirá si intentas usar Android 4.0+ (ICS). Empecé a portar VideoView.java y MediaPlayer.java de 4.0 a mi aplicación, pero eso parece complejo y no tiene suerte hasta ahora. Básicamente parece un error en el código nativo de las versiones anteriores.
después de perder demasiado tiempo tratando de descubrir cómo reproducir videos consecutivos sin la "brecha", me estoy inclinando por lo imposible. a menos que, por supuesto, puedas profundizar en el nivel nativo e implementar tu propio reproductor, el reproductor multimedia de Android simplemente no admite la reproducción continua a partir del momento.