Media Player wywołał w stanie 0, błąd (-38,0)

105

Obecnie próbuję zaprojektować prostą aplikację, która przesyła strumieniowo internetową stację radiową. Mam adres URL stacji i konfiguruję odtwarzacz multimedialny

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

Program nie zawiesza się podczas emulacji, ale nic nie gra i pojawia się następujący błąd:

start called in state 0

a tuż poniżej jest

Error (-38,0)

Czy ktokolwiek wie, co to znaczy?

Czytałem trochę o tych błędach stanu, ale nie mogłem znaleźć niczego, co dotyczy mojego projektu.

SmashCode
źródło
możliwy duplikat problemów
rds
@SmashCode proszę oznacz inną odpowiedź jako zaakceptowaną, ponieważ moja odpowiedź jest całkowicie bezużyteczna.
tidbeck

Odpowiedzi:

120

Trzeba zadzwonić mediaPlayer.start()w onPreparedmetodzie za pomocą detektora. Otrzymujesz ten błąd, ponieważ dzwonisz, mediaPlayer.start()zanim osiągnie stan przygotowania.

Oto jak możesz to zrobić:

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

public void onPrepared(MediaPlayer player) {
    player.start();
}
user1492955
źródło
A jeśli nie chcemy, żeby zaczęło się od razu? Nawet jeśli zainicjalizuję odtwarzacz i poczekam około minuty, przy pierwszej próbie odtworzenia występuje ten błąd, chyba że wywołam .start () w onPrepared
Elliptica
1
Przygotowujesz go wcześniej i pamiętasz, że go przygotowałeś. Równolegle starasz się zapamiętać, czy chcesz go uruchomić. Kiedy jest gotowy i chcesz go uruchomić, zaczynasz go.
Victor Paléologue,
33

Wygląda na to, że Błąd -38 oznacza wyjątek stanu (jak wskazuje komunikat o błędzie). Na przykład, jeśli zadzwonisz start(), zanim piosenka była gotowa lub gdy zadzwonisz pause(), nawet jeśli piosenka w ogóle nie jest odtwarzana.

Aby rozwiązać ten problem, sprawdź stan mediaPlayer przed wywołaniem metod. Na przykład:

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

Dodatkowo MediaPlayer wysyła komunikaty o zdarzeniach. Nawet jeśli nie potrzebujesz przygotowanego zdarzenia (chociaż dobrze byłoby nie rozpoczynać odtwarzania przed uruchomieniem tego zdarzenia), musisz ustawić odbiornik wywołań zwrotnych. Dotyczy to również dla OnErrorListener, OnCompletionListener, OnPreparedListeneroraz OnSeekCompletedListener(jeśli nazywają poszukują metody).

Słuchacze mogą być dołączani po prostu przez

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        // Do something. For example: playButton.setEnabled(true);
    }
});
Alexander Pacha
źródło
wywołanie pause () przy braku odtwarzacza było moim przypadkiem
stevo.mit
wywołanie mediaPlayer.isPlaying () w nieprawidłowym stanie spowoduje przejście odtwarzacza multimedialnego w stan błędu. Lepiej jest zachować jawne wyliczenie, aby zachować stany.
Madeyedexter
14

Otrzymałem ten błąd, gdy próbowałem uzyskać bieżącą pozycję (MediaPlayer.getCurrentPosition ()) odtwarzacza multimedialnego, gdy nie było go w przygotowanym podanym. Obejrzałem ten problem, śledząc jego stan i wywołując metodę getCurrentPosition () dopiero po wywołaniu onPreparedListener.

Ognia
źródło
Jak to się stało, że to z tego powodu?
AdamMc331
9

Oto mój kod, przetestowany i działający dobrze:

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
źródło
4

przetestowałem poniższy kod. pracować w porządku

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
źródło
Dla i aktualizacja do SetAudioStreamType(..)użyciaSetAudioAttributes(...)
Pierre,
4

Kilka dni temu napotkałem ten sam problem. Mój odtwarzacz audio MediaPlayer działa dobrze na urządzeniach o dużej mocy obliczeniowej, ale w przypadku wolnych urządzeń odtwarzacz multimedialny po prostu nie grał przez jakiś czas, a od LogCat wiele narzekało, że został wywołany w złym stanie. Więc postanowiłem go nazywając oddanie wywołanie start () , pause () , ... w onPrepared () metody OnPreparedListener () jak poniżej:

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

                        }
                    });
                }
            });

Spróbuj także zwolnić dowolny odtwarzacz multimedialny, którego już nie potrzebujesz. Na przykład, jeśli nie chcesz odtwarzać dźwięku lub wideo w tle, powinieneś wywołać mediaPlayer.release () w onPause () .

Tony Vu
źródło
3

Czasami plik jest kodowany w sposób, którego Android nie może zdekodować. Nie można odtworzyć nawet niektórych plików mp4. Spróbuj użyć innego formatu pliku (przez większość czasu odtwarzane są pliki .3gp) i zobacz ...

Rukmal Dias
źródło
46
Nie mogę poprosić internetowej stacji radiowej o zmianę formatu pliku.
SmashCode
Czy pojawia się wyskakujące okienko „Nie można odtworzyć tego wideo”? Jak sobie z tym radzisz? Łapię błąd, ale mimo to otrzymuję ten modal i nie mam kontroli nad źródłem multimediów, ponieważ pochodzi z publicznego API. Byłbym wdzięczny, gdyby ktoś wiedział, jak zapobiec wyświetlaniu komunikatu „Nie można odtworzyć tego wideo”.
Krafty
Czy próbowałeś ustawić nasłuchiwanie błędów. MediaPlayer mp = new MediaPlayer () {@Override public void setOnErrorListener (android.media.MediaPlayer.OnErrorListener listener) {// Zrób coś tutaj ..}}; mp.setDataSource (..
Rukmal Dias
1

wprowadź opis obrazu tutaj

nad zdjęciem możesz uzyskać właściwą drogę.

Longalei
źródło
0

Otrzymujesz ten komunikat w dziennikach, ponieważ robisz coś, co jest niedozwolone w obecnym stanie Twojej instancji MediaPlayer.

Dlatego zawsze powinieneś zarejestrować program obsługi błędów, aby wychwycić te rzeczy (jak sugerował @tidbeck).

Na początku radzę zapoznać się z dokumentacją MediaPlayerzajęć i zrozumieć, co to oznacza ze stanami. Zobacz: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

Twój błąd może być jednym z powszechnych, inni napisali tutaj, ale ogólnie przyjrzałbym się dokumentacji tego, jakie metody są ważne do wywołania w jakim stanie: http://developer.android.com/ reference / android / media / MediaPlayer.html # Valid_and_Invalid_States

W moim przykładzie była to metoda mediaPlayer.CurrentPosition, którą wywołałem, gdy odtwarzacz multimedialny był w stanie, w którym nie można było wywołać tej właściwości.

SimonSimCity
źródło
0

Rozwiązałem zarówno błędy (-19,0), jak i (-38,0), tworząc za każdym razem nowy obiekt MediaPlayera przed rozpoczęciem odtwarzania i puszczając go później.

Przed :

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

}

}

Po:

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
źródło
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
źródło
0

To było bardzo sfrustrowane. Otrzymałem rozwiązanie, które mi odpowiada.

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
źródło
0

U mnie to zadziałało

mp.seekTo(0);
mp.start();
Piyush Jajoo
źródło
0

Otrzymałem również ten błąd, który próbowałem z onPreparedListener, ale nadal mam ten błąd. W końcu otrzymałem rozwiązanie, że błąd jest moją winą, ponieważ zapomniałem uprawnienia do Internetu w pliku Android Manifest xml. :)

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

Użyłem przykładowego kodowania dla mediaplayera. Użyłem w metodzie StreamService.java
onCreate

String url = "http://s17.myradiostream.com:11474/";
mediaPlayer = new MediaPlayer();            
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
BM
źródło
-1

Tuż przedtem spotkałem się z tym samym problemem, kolega na pierwszym piętrze miał rację, dzwoniłeś start()w złym czasie, należy ustawić słuchacza na przygotowanie () lub prepareSync()tą metodą mediaPlayer.setOnPreparedListener(this); przed przygotowaniem, w tym wywołaniu zwrotnym start(). Może to rozwiązać Twój problem. Już próbowałem.

niezrównany2012
źródło
Możesz być bardziej dokładny?
Karthik AMR
Przepraszam, angielski nie jest moim pierwszym językiem i nie jestem w nim dobry ... ale chcę tylko pomóc innym, którzy mają te same pytania, to wszystko.
niezrównany 2012,
-1

Jestem nowy w programowaniu na Androida i miałem ten sam błąd co ten. więc po prostu przedefiniowałem mp.createmediaPlayer = MediaPlayer.create (getApplicationContext (), Settings.System.DEFAULT_RINGTONE_URI). Może to nie jest prawdziwy sposób, ale dla mnie zadziałało grzywną:

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

mp.start();
Monsoon khadka
źródło
-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
źródło