Media Player appelé à l'état 0, erreur (-38,0)

105

J'essaie actuellement de concevoir une application simple qui diffuse une station de radio Internet. J'ai l'URL de la station et je configure le lecteur multimédia comme

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

Le programme ne plante pas lorsqu'il est émulé, mais rien ne joue et j'obtiens l'erreur suivante:

start called in state 0

et juste en dessous se trouve

Error (-38,0)

Est-ce que quelqu'un sait ce que cela signifie?

J'ai lu un peu sur ces erreurs d'état, mais je n'ai rien trouvé qui s'applique à mon projet.

SmashCode
la source
@SmashCode veuillez marquer une autre réponse comme acceptée car ma réponse est totalement inutile.
tidbeck

Réponses:

120

Vous devez appeler mediaPlayer.start()la onPreparedméthode en utilisant un écouteur. Vous obtenez cette erreur car vous appelez mediaPlayer.start()avant qu'il n'ait atteint l'état préparé.

Voici comment vous pouvez le faire:

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

public void onPrepared(MediaPlayer player) {
    player.start();
}
user1492955
la source
Et si nous ne voulons pas que cela commence tout de suite? Même si j'initialise mon lecteur et que j'attends une minute environ, la première fois que j'essaie de le lire, il y a cette erreur à moins que j'appelle .start () dans onPrepared
Elliptica
1
Vous le préparez avant et vous vous souvenez que vous l'avez préparé. En parallèle, vous essayez de vous rappeler si vous souhaitez l'exécuter. Lorsqu'il est à la fois préparé et que vous souhaitez l'exécuter, vous le démarrez.
Victor Paléologue
33

Il semble que l'erreur -38 signifie une exception d'état (comme l'indique le message d'erreur). Par exemple, si vous appelez start(), avant que la chanson ne soit prête, ou lorsque vous appelez pause(), même si la chanson ne joue pas du tout.

Pour résoudre ce problème, vérifiez l'état du mediaPlayer avant d'appeler les méthodes. Par exemple:

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

De plus, le MediaPlayer envoie des messages d'événement. Même si vous n'avez pas besoin de l'événement préparé (même si ce serait une bonne idée de ne pas démarrer la lecture avant que cet événement ne soit déclenché), vous devez définir un écouteur de rappel. Cela est également vrai pour le OnErrorListener, OnCompletionListener, OnPreparedListeneret OnSeekCompletedListener(si vous appelez la méthode seek).

Les auditeurs peuvent être attachés simplement par

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        // Do something. For example: playButton.setEnabled(true);
    }
});
Alexandre Pacha
la source
appeler pause () sur ne pas jouer au joueur était mon cas
stevo.mit
appeler mediaPlayer.isPlaying () dans un état invalide enverra le lecteur multimédia dans un état d'erreur. Mieux vaut maintenir une énumération explicite pour maintenir les états.
Madeyedexter
14

J'ai eu cette erreur lorsque j'essayais d'obtenir la position actuelle (MediaPlayer.getCurrentPosition ()) du lecteur multimédia alors qu'elle n'était pas dans la position préparée. J'ai contourné cela en gardant une trace de son état et en n'appelant la méthode getCurrentPosition () qu'après l'appel de onPreparedListener.

feu dans le trou
la source
Comment avez-vous compris que c'était pour cette raison?
AdamMc331
9

Ceci est mon code, testé et fonctionne 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);
        }
      }
    });
  }
}
MAK
la source
4

J'ai testé ci-dessous le code. fonctionne 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;
}
}
Emran Hamza
la source
Pour et mise à jour à SetAudioStreamType(..)utiliserSetAudioAttributes(...)
Pierre
4

J'ai rencontré le même problème il y a quelques jours. Mon MediaPlayer audio fonctionne bien sur les appareils avec une puissance de traitement élevée, mais pour les appareils lents, le lecteur multimédia n'a tout simplement pas joué un certain temps et de LogCat, beaucoup se sont plaints d'appeler dans un état incorrect. J'ai donc résolu le problème en appelant l'appel à start () , pause () , ... dans la méthode onPrepared () de OnPreparedListener () comme ci-dessous:

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

                        }
                    });
                }
            });

Essayez également de libérer tout lecteur multimédia dont vous n'avez plus besoin. Par exemple, si vous ne souhaitez pas lire l'audio ou la vidéo en arrière-plan, vous devez appeler mediaPlayer.release () dans onPause () .

Tony Vu
la source
3

Parfois, les fichiers sont encodés d'une manière qu'Android ne peut pas décoder. Même certains fichiers mp4 ne peuvent pas être lus. Veuillez essayer un autre format de fichier (.3gp sont lus la plupart du temps) et voir ..

Rukmal Dias
la source
46
Je ne peux pas demander à une station de radio Internet de modifier son format de fichier.
SmashCode
La fenêtre contextuelle "Impossible de lire cette vidéo" s'affiche-t-elle? Comment gères-tu cela? J'attrape l'erreur mais j'obtiens ce modal malgré tout et je n'ai aucun contrôle sur la source du média car il provient d'une API publique. Si quelqu'un sait comment empêcher le modal "Impossible de lire cette vidéo", je serais reconnaissant.
Krafty
Avez-vous essayé de définir un écouteur d'erreur. MediaPlayer mp = new MediaPlayer () {@Override public void setOnErrorListener (android.media.MediaPlayer.OnErrorListener listener) {// Faites des choses ici ..}}; mp.setDataSource (..
Rukmal Dias
1

entrez la description de l'image ici

au-dessus de l'image, vous pouvez obtenir le bon chemin.

Longalei
la source
0

Vous obtenez ce message dans les journaux, car vous faites quelque chose qui n'est pas autorisé dans l'état actuel de votre instance MediaPlayer.

Par conséquent, vous devez toujours enregistrer un gestionnaire d'erreurs pour attraper ces choses (comme @tidbeck l'a suggéré).

Dans un premier temps, je vous conseille de jeter un œil à la documentation de la MediaPlayerclasse et de comprendre ce que cela signifie avec les états. Voir: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

Votre erreur ici pourrait bien être l'une des plus courantes, les autres ont écrit ici, mais en général, je voudrais jeter un coup d'œil à la documentation sur les méthodes valides pour appeler dans quel état: http://developer.android.com/ reference / android / media / MediaPlayer.html # Valid_and_Invalid_States

Dans mon exemple, c'était la méthode mediaPlayer.CurrentPositionque j'ai appelée alors que le lecteur multimédia était dans un état où il n'était pas autorisé à appeler cette propriété.

SimonSimCity
la source
0

J'ai résolu les erreurs (-19,0) et (-38,0), en créant un nouvel objet de MediaPlayer à chaque fois avant de jouer et en le relâchant après cela.

Avant :

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

}

}

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

}

}

Saurabh Padwekar
la source
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();
kamakshi
la source
0

C'était très frustrant. Donc, j'ai une solution qui fonctionne pour moi.

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();
                    }
Aman Srii
la source
0

Pour moi, cela a fonctionné

mp.seekTo(0);
mp.start();
Piyush Jajoo
la source
0

J'ai également eu cette erreur que j'ai essayée avec onPreparedListener mais j'ai toujours cette erreur. Enfin, j'ai eu la solution que l'erreur est de ma faute parce que j'ai oublié l'autorisation Internet dans Android Manifest xml. :)

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

J'ai utilisé un exemple de codage pour Mediaplayer. J'ai utilisé dans la méthode StreamService.java
onCreate

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

J'ai rencontré le même problème juste avant, l'ami du premier étage avait raison, vous avez appelé le start()au mauvais moment, vous devez définir un auditeur pour prepare () ou prepareSync()avec cette méthode mediaPlayer.setOnPreparedListener(this); avant de se préparer, dans cet appel de rappel start(). Cela peut résoudre votre problème. J'ai déjà essayé.

sans égal2012
la source
Pourriez-vous être plus précis?
Karthik AMR
Désolé, l'anglais n'est pas ma langue maternelle, et je ne suis pas non plus doué pour ça ... mais je veux juste aider les autres qui ont les mêmes questions, c'est tout.
peerless2012
-1

Je suis nouveau dans la programmation Android et j'ai eu la même erreur que celle-ci. donc j'ai simplement redéfini le mp.createmediaPlayer = MediaPlayer.create (getApplicationContext (), Settings.System.DEFAULT_RINGTONE_URI). Ce n'est peut-être pas la vraie façon de procéder, mais cela a fonctionné avec une amende pour moi:

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

mp.start();
Mousson khadka
la source
-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();
HuynhHan
la source