Media Player llamado en estado 0, error (-38,0)


105

Actualmente estoy tratando de diseñar una aplicación simple que transmita una estación de radio por Internet. Tengo la URL de la estación y estoy configurando el reproductor multimedia como

    MediaPlayer mediaPlayer = new MediaPlayer();
    try {
        mediaPlayer.setDataSource(URL);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        mediaPlayer.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    mediaPlayer.start();

El programa no se bloquea cuando se emula, pero no se reproduce nada y aparece el siguiente error:

start called in state 0

y justo debajo está

Error (-38,0)

Alguien sabe que significa esto?

Leí un poco sobre estos errores de estado, pero no pude encontrar nada que se aplique a mi proyecto.



posible duplicado de problemas
rds

@SmashCode por favor marque otra respuesta como la aceptada ya que mi respuesta es totalmente inútil.
tidbeck

Respuestas:


120

Necesita llamar mediaPlayer.start()al onPreparedmétodo usando un oyente. Recibe este error porque está llamando mediaPlayer.start()antes de que haya alcanzado el estado preparado.

Aquí sabrás como podrás hacerlo :

mp.setDataSource(url); 
mp.setOnPreparedListener(this);
mp.prepareAsync();

public void onPrepared(MediaPlayer player) {
    player.start();
}

¿Qué pasa si no queremos que comience de inmediato? Incluso si inicializo mi reproductor y espero un minuto más o menos, la primera vez que intento reproducirlo, tiene este error a menos que llame a .start () en onPrepared
Elliptica

1
Lo preparas antes y recuerdas que lo preparaste. Paralelamente, intenta recordar si desea ejecutarlo. Cuando esté preparado y desee ejecutarlo, lo inicia.
Victor Paléologue

33

Parece que el Error -38 significa una excepción de estado (como indica el mensaje de error). Por ejemplo, si llama start(), antes de que la canción esté lista, o cuando llama pause(), incluso si la canción no se reproduce en absoluto.

Para solucionar este problema, compruebe el estado de mediaPlayer antes de llamar a los métodos. Por ejemplo:

if(mediaPlayer.isPlaying()) {
    mediaPlayer.pause();
}

Además, el MediaPlayer está enviando mensajes de eventos. Incluso si no necesita el evento preparado (aunque sería una buena idea no iniciar la reproducción antes de que se active este evento), debe configurar un oyente de devolución de llamada. Esto también es válido para el OnErrorListener, OnCompletionListener, OnPreparedListenery OnSeekCompletedListener(si se llama al método Seek).

Los oyentes se pueden adjuntar simplemente

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        // Do something. For example: playButton.setEnabled(true);
    }
});

llamar a pause () en no jugar jugador fue mi caso
stevo.mit

llamar a mediaPlayer.isPlaying () en un estado no válido enviará al reproductor multimedia a un estado de error. Es mejor mantener una enumeración explícita para mantener los estados.
Madeyedexter

14

Recibí este error cuando intentaba obtener la posición actual (MediaPlayer.getCurrentPosition ()) del reproductor multimedia cuando no estaba en el estado preparado. Lo solucioné haciendo un seguimiento de su estado y solo llamando al método getCurrentPosition () después de que se llama a onPreparedListener.


¿Cómo averiguaste que era por esa razón?
AdamMc331

9

Este es mi código, probado y funcionando bien:

package com.example.com.mak.mediaplayer;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.app.Activity;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final MediaPlayer mpp = MediaPlayer.create(this, R.raw.red); //mp3 file in res/raw folder

    Button btnplay = (Button) findViewById(R.id.btnplay); //Play
    btnplay.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View vone) {
        mpp.start();
      }
    });

    Button btnpause = (Button) findViewById(R.id.btnpause); //Pause
    btnpause.setOnClickListener(new View.OnClickListener() {

      @Override
      public void onClick(View vtwo) {
        if (mpp.isPlaying()) {
          mpp.pause();
          mpp.seekTo(0);
        }
      }
    });
  }
}

4

Probé el siguiente código. funcionando bien

public class test extends Activity implements OnErrorListener, OnPreparedListener {

private MediaPlayer player;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    player = new MediaPlayer();
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);
    try {
        player.setDataSource("http://www.hubharp.com/web_sound/BachGavotte.mp3");
        player.setOnErrorListener(this);
        player.setOnPreparedListener(this);
        player.prepareAsync();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }       
}
@Override
public void onDestroy() {
    super.onDestroy();
    player.release();
    player = null;
}
@Override
public void onPrepared(MediaPlayer play) {
    play.start();
}
@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
    return false;
}
}

Para y actualizar para SetAudioStreamType(..)usarSetAudioAttributes(...)
Pierre

4

Encontré el mismo problema hace unos días. Mi MediaPlayer de audio funciona bien en dispositivos con alta potencia de procesamiento, pero para dispositivos lentos, el reproductor de medios simplemente no se reprodujo durante algún tiempo y desde LogCat hubo muchas quejas de llamadas en estado incorrecto. Así que decidí que llamando a poner la llamada a start () , pausa () , ... en onPrepared () método de OnPreparedListener () de la siguiente manera:

mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    ........
                    mediaPlayer.start();
                    ....
                    songControlBtn.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (mediaPlayer.isPlaying()) {
                                mediaPlayer.pause();

                            } else {
                                mediaPlayer.start();

                            }
                        }
                    });

                    mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            ............

                        }
                    });
                }
            });

También intente lanzar cualquier reproductor multimedia que ya no necesite. Por ejemplo, si no desea reproducir el audio o el video en segundo plano, debe llamar a mediaPlayer.release () en onPause () .


3

Algunas veces, los archivos están codificados de una manera que Android no puede decodificar. Incluso algunos archivos mp4 no se pueden reproducir. Pruebe con un formato de archivo diferente (.3gp se reproducen la mayor parte del tiempo) y vea ...


46
No puedo pedirle a una estación de radio por Internet que cambie su formato de archivo.
SmashCode

¿Aparece la ventana emergente "No se puede reproducir este video"? ¿Cómo lo afrontas? Detecto el error pero obtengo este modal independientemente y no tengo control sobre la fuente de los medios, ya que proviene de una API pública. Si alguien sabe cómo prevenir el modal "No se puede reproducir este video", se lo agradecería.
Krafty

¿Intentó configurar un detector de errores? MediaPlayer mp = new MediaPlayer () {@Override public void setOnErrorListener (android.media.MediaPlayer.OnErrorListener listener) {// Haz cosas aquí ..}}; mp.setDataSource (..
Rukmal Dias


0

Obtienes este mensaje en los registros porque haces algo que no está permitido en el estado actual de tu instancia de MediaPlayer.

Por lo tanto, siempre debe registrar un controlador de errores para detectar esas cosas (como sugirió @tidbeck).

Al principio, te aconsejo que eches un vistazo a la documentación de la MediaPlayerclase y comprendas lo que significa eso con estados. Ver: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

Su error aquí bien podría ser uno de los comunes, los demás escribieron aquí, pero en general, echaría un vistazo a la documentación de qué métodos son válidos para llamar en qué estado: http://developer.android.com/ reference / android / media / MediaPlayer.html # Valid_and_Invalid_States

En mi ejemplo, fue el método mediaPlayer.CurrentPositionque llamé mientras el reproductor multimedia estaba en un estado en el que no estaba permitido llamar a esta propiedad.


0

Resolví los errores (-19,0) y (-38,0), creando un nuevo objeto de MediaPlayer cada vez antes de jugar y soltándolo después de eso.

Antes de :

void play(int resourceID) {
if (getActivity() != null) {

     //Using the same object - Problem persists
    player = MediaPlayer.create(getActivity(), resourceID);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            player.release();
        }
    });

    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });

}

}

Después:

void play(int resourceID) {

if (getActivity() != null) {

    //Problem Solved
    //Creating new MediaPlayer object every time and releasing it after completion
    final MediaPlayer player = MediaPlayer.create(getActivity(), resourceID);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            player.release();
        }
    });

    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });

}

}


0
  if(length>0)
        {
            mediaPlayer = new MediaPlayer();
            Log.d("length",""+length);
            try {
                mediaPlayer.setDataSource(getApplication(),Uri.parse(uri));
            } catch(IOException e) {
                e.printStackTrace();
            }
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.seekTo(length);
                    mediaPlayer.start();

                }
            });
            mediaPlayer.prepareAsync();

0

Fue muy frustrado. Entonces, tengo una solución que funciona para mí.

try {
                        if (mediaPlayer != null) {
                            mediaPlayer.release();
                            mediaPlayer = null;

                        }
                        mediaPlayer = new MediaPlayer();
                        mediaPlayer.setDataSource(file.getAbsolutePath());
                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
                        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                            @Override
                            public void onPrepared(MediaPlayer mediaPlayer) {
                                mediaPlayer.start();
                                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                                    @Override
                                    public void onCompletion(MediaPlayer mediaPlayer) {
                                        mediaPlayer.stop();
                                        mediaPlayer.release();
                                        mediaPlayer = null;
                                    }
                                });
                            }
                        });
                        mediaPlayer.prepare();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }


0

También recibí este error que probé con onPreparedListener pero aún así recibí este error. Finalmente obtuve la solución de que el error es mi culpa porque olvidé el permiso de Internet en Android Manifest xml. :)

<uses-permission android:name="android.permission.INTERNET" />

Usé código de muestra para mediaplayer. Utilicé en el método StreamService.java
onCreate

String url = "http://s17.myradiostream.com:11474/";
mediaPlayer = new MediaPlayer();            
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();

-1

Me encontré con el mismo problema justo antes, el amigo del primer piso tenía razón, llamaste al start()en el momento equivocado, deberías establecer un oyente para prepare () o prepareSync()con este método mediaPlayer.setOnPreparedListener(this); antes de prepararse, en esta llamada de devolución de llamada start(). Puede resolver su problema. Ya lo he intentado.


¿Podrías ser más específico?
Karthik AMR

Lo siento, el inglés no es mi primer idioma, y ​​tampoco soy bueno en eso ... pero solo quiero ayudar a otros que tienen las mismas preguntas, eso es todo.
Peerless2012

-1

Soy nuevo en la programación de Android y tuve el mismo error que este. así que simplemente redefiní el mp.createmediaPlayer = MediaPlayer.create (getApplicationContext (), Settings.System.DEFAULT_RINGTONE_URI). Puede que no sea la verdadera forma de hacerlo, pero funcionó con una multa para mí:

try {
  mp = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);
} catch (Exception e) {
  e.printStackTrace();
}

mp.start();

-2
mp = new MediaPlayer();
AssetFileDescriptor afd = mContext.getAssets().openFd(fileName);
mp.reset();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  public void onPrepared(MediaPlayer mp) {
    mp.start();
  }
});

mp.prepareAsync();
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.