Media Player chamado no estado 0, erro (-38,0)

105

Atualmente, estou tentando criar um aplicativo simples que transmita uma estação de rádio da Internet. Tenho o URL da estação e estou configurando o Media Player 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();

O programa não está travando quando emulado, mas nada está sendo reproduzido e recebo o seguinte erro:

start called in state 0

e logo abaixo está

Error (-38,0)

Alguém sabe o que isso significa?

Eu li um pouco sobre esses erros de estado, mas não consegui encontrar nada que se aplique ao meu projeto.

SmashCode
fonte
possível duplicata de problemas
rds de
@SmashCode marque outra resposta como aceita, pois minha resposta é totalmente inútil.
tidbeck

Respostas:

120

Você precisa chamar mediaPlayer.start()o onPreparedmétodo usando um ouvinte. Você está recebendo este erro porque está ligando mediaPlayer.start()antes de ele atingir o estado preparado.

Veja como você pode fazer isso:

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

public void onPrepared(MediaPlayer player) {
    player.start();
}
user1492955
fonte
E se não quisermos que comece imediatamente? Mesmo se eu inicializar meu player e esperar um minuto ou mais, na primeira vez que tento jogá-lo, ele apresenta esse erro, a menos que eu chame .start () em onPrepared
Elliptica
1
Você o prepara antes e lembra que o preparou. Paralelamente, você tenta se lembrar se deseja executá-lo. Quando ele estiver preparado e você quiser executá-lo, você o inicia.
Victor Paléologue
33

Parece que o Erro -38 significa uma exceção de estado (como indica a mensagem de erro). Por exemplo, se você ligar start(), antes de a música estar pronta ou quando ligar pause(), mesmo que a música não esteja tocando.

Para corrigir esse problema, verifique o estado do mediaPlayer antes de chamar os métodos. Por exemplo:

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

Além disso, o MediaPlayer está enviando mensagens de eventos. Mesmo se você não precisar do evento preparado (embora seja uma boa ideia não iniciar a reprodução antes que esse evento seja disparado), você deve definir um ouvinte de retorno de chamada. Isso também vale para o OnErrorListener, OnCompletionListener, OnPreparedListenere OnSeekCompletedListener(se você chamar o método buscar).

Os ouvintes podem ser anexados simplesmente por

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        // Do something. For example: playButton.setEnabled(true);
    }
});
Alexander Pacha
fonte
chamar pause () sobre não jogar jogador era o meu caso
stevo.mit
chamar mediaPlayer.isPlaying () em um estado inválido enviará o reprodutor de mídia a um estado de erro. Melhor manter um enum explícito para manter os estados.
Madeyedexter
14

Recebi este erro quando estava tentando obter a posição atual (MediaPlayer.getCurrentPosition ()) do reprodutor de mídia quando não estava no estado preparado. Eu resolvi isso mantendo o controle de seu estado e chamando o método getCurrentPosition () apenas depois que onPreparedListener for chamado.

Fogo no buraco
fonte
Como você descobriu que era por esse motivo?
AdamMc331
9

Este é o meu código, testado e funcionando bem:

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
fonte
4

eu testei o código abaixo. trabalhando bem

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
fonte
Para e atualização para SetAudioStreamType(..)usoSetAudioAttributes(...)
Pierre
4

Eu encontrei o mesmo problema há alguns dias. Meu MediaPlayer de áudio funciona bem em aparelhos com alto poder de processamento, mas para aparelhos lentos, o media player simplesmente não tocava há algum tempo e do LogCat tinha muitos reclamações sobre a chamada em estado errado. Então, resolvi chamando colocando a chamada para start () , pause () , ... no método onPrepared () de OnPreparedListener () como abaixo:

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

                        }
                    });
                }
            });

Tente também lançar qualquer reprodutor de mídia de que você não precise mais. Por exemplo, se você não deseja reproduzir o áudio ou vídeo em segundo plano, deve chamar mediaPlayer.release () em onPause () .

Tony Vu
fonte
3

Algumas vezes, os arquivos são codificados de uma forma que o Android não consegue decodificar. Mesmo alguns arquivos mp4 não podem ser reproduzidos. Tente um formato de arquivo diferente (.3gp são reproduzidos na maioria das vezes) e veja ..

Rukmal Dias
fonte
46
Não posso pedir a uma estação de rádio da Internet para alterar o formato do arquivo.
SmashCode
Você obtém o pop-up "Não é possível reproduzir este vídeo"? Como você lida com isso? Eu percebo o erro, mas obtenho este modal independentemente e não tenho controle sobre a fonte da mídia, pois ela vem de uma API pública. Se alguém souber como evitar o modal "Não consigo reproduzir este vídeo" ficaria muito grato.
Krafty
Você tentou definir um listener de erro. MediaPlayer mp = new MediaPlayer () {@Override public void setOnErrorListener (android.media.MediaPlayer.OnErrorListener listener) {// Faça coisas aqui ..}}; mp.setDataSource (..
Rukmal Dias
1

insira a descrição da imagem aqui

acima da imagem, você pode obter o caminho certo.

Longalei
fonte
0

Você recebe esta mensagem nos logs, porque você faz algo que não é permitido no estado atual da sua instância do MediaPlayer.

Portanto, você deve sempre registrar um manipulador de erros para capturar essas coisas (como @tidbeck sugeriu).

A princípio, aconselho você a dar uma olhada na documentação da MediaPlayerclasse e entender o que isso significa com estados. Consulte: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

Seu erro aqui pode muito bem ser um dos mais comuns, os outros escreveram aqui, mas em geral, eu daria uma olhada na documentação de quais métodos são válidos para chamar em qual estado: http://developer.android.com/ reference / android / media / MediaPlayer.html # Valid_and_Invalid_States

No meu exemplo, foi o método mediaPlayer.CurrentPositionque chamei enquanto o media player estava em um estado em que não era permitido chamar esta propriedade.

SimonSimCity
fonte
0

Resolvi os erros (-19,0) e (-38,0), criando um novo objeto de MediaPlayer todas as vezes antes de jogar e liberando-o depois disso.

Antes :

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

}

}

Depois de:

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
fonte
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
fonte
0

Estava muito frustrado. Então, eu tenho uma solução que funciona para mim.

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
fonte
0

Para mim isso funcionou

mp.seekTo(0);
mp.start();
Piyush Jajoo
fonte
0

Também recebi este erro que tentei com onPreparedListener, mas ainda recebi esse erro. Finalmente encontrei a solução que o erro é minha culpa porque esqueci a permissão de internet no Android Manifest xml. :)

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

Usei codificação de amostra para mediaplayer. Eu usei no 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();
BM
fonte
-1

Eu encontrei o mesmo problema um pouco antes, o amigo do primeiro andar estava certo, você ligou para o start()na hora errada, você deveria definir um ouvinte para prepare () ou prepareSync()com este método mediaPlayer.setOnPreparedListener(this); antes de se preparar, nesta chamada de retorno start(). Pode resolver seu problema. Eu já tentei.

incomparável2012
fonte
Você poderia ser mais específico?
Karthik AMR
Desculpe, o inglês não é minha língua materna, e também não sou bom nisso ... mas eu só quero ajudar outras pessoas que têm as mesmas dúvidas, só isso.
peerless2012
-1

Eu sou novo na programação Android e tive o mesmo erro que este. então, simplesmente redefini o mp.createmediaPlayer = MediaPlayer.create (getApplicationContext (), Settings.System.DEFAULT_RINGTONE_URI). Pode não ser a maneira verdadeira de fazer isso, mas funcionou muito bem para mim:

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

mp.start();
Monsoon khadka
fonte
-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
fonte