Media Player викликано стан 0, помилка (-38,0)


105

Наразі я намагаюся створити просту програму, яка передає інтернет-радіостанцію. У мене є URL-адреса станції і я налаштовую Media Player, як

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

Програма не завершується збоєм при емуляції, але нічого не відтворюється, і я отримую таку помилку:

start called in state 0

і прямо під ним

Error (-38,0)

Хтось знає, що це означає?

Я трохи прочитав про ці помилки стану, але не зміг знайти нічого, що стосується мого проекту.




@SmashCode, будь ласка, позначте іншу відповідь як прийняту, оскільки моя відповідь є абсолютно марною.
tidbeck

Відповіді:


120

Вам потрібно зателефонувати mediaPlayer.start()в onPreparedметод за допомогою слухача. Ви отримуєте цю помилку, тому що ви телефонуєте mediaPlayer.start()до того, як вона досягне підготовленого стану.

Ось як це можна зробити:

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

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

Що робити, якщо ми не хочемо, щоб це почалося відразу? Навіть якщо я ініціалізую свого плеєра і зачекаю хвилину або близько того, коли я вперше спробую його зіграти, у нього є ця помилка, якщо я не зателефоную .start () в onPrepared
Elliptica

1
Ви готуєте його раніше і пам’ятаєте, що ви його приготували. Паралельно ви намагаєтеся запам'ятати, чи хочете ви його запустити. Коли він і підготовлений, і ви хочете його запустити, ви запускаєте його.
Віктор Палеолог

33

Схоже, помилка -38 означає виключення стану (як вказує повідомлення про помилку). Наприклад, якщо ви телефонуєте start(), до того, як пісня була готова або коли ви телефонуєте pause(), навіть якщо пісня взагалі не грає.

Щоб виправити цю проблему, перевірте стан медіаплеєра, перш ніж викликати методи. Наприклад:

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

Крім того, MediaPlayer надсилає повідомлення про події. Навіть якщо вам не потрібна підготовлена ​​подія (хоча було б непогано не починати відтворення до запуску цієї події), ви повинні встановити слухач зворотного дзвінка. Це також справедливо і для OnErrorListener, OnCompletionListener, OnPreparedListenerі OnSeekCompletedListener(якщо ви викликаєте шукати метод).

Слухачів можна приєднати просто

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

виклик pause () на
неіграючий

виклик mediaPlayer.isPlaying () у недійсному стані перетворить медіаплеєр у стан помилки. Краще підтримувати явний перерахунок для підтримки станів.
Мадейдекстер

14

Я отримав цю помилку, коли я намагався отримати поточну позицію (MediaPlayer.getCurrentPosition ()) медіаплеєра, коли вона не була в підготовленій заяві. Я обійшов це шляхом відстеження його стану та виклику методу getCurrentPosition () лише після виклику onPreparedListener.


Як ви зрозуміли, що це саме з цієї причини?
AdamMc331

9

Це мій код, перевірений і добре працює:

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

Я перевірив нижче код. добре працює

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

Для та оновлення для SetAudioStreamType(..)використанняSetAudioAttributes(...)
П'єр

4

Я зіткнувся з тим же питанням кілька днів тому. Мій аудіо MediaPlayer чудово працює на пристроях з високою потужністю обробки, але для повільних пристроїв медіа-плеєр просто не відтворював деякий час, і з LogCat багато хто скаржився на те, що викликали його в неправильному стані. Тому я вирішив його по телефону поставити виклик почати () , пауза () , ... в onPrepared () метод OnPreparedListener () , як показано нижче:

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

                        }
                    });
                }
            });

Також спробуйте випустити будь-який медіаплеєр, який вам більше не потрібен. Наприклад, якщо ви не хочете відтворювати аудіо чи відео у фоновому режимі, вам слід зателефонувати mediaPlayer.release () у режимі onPause () .


3

Деякий раз файл кодується таким чином, що Android не може розшифрувати. Навіть деякі файли mp4 неможливо відтворити. Спробуйте інший формат файлу (більшість разів відтворюються .3gp) і див.


46
Я не можу попросити Інтернет-радіостанцію змінити їх формат файлу.
SmashCode

Чи з’являється спливаюче вікно "Не можу відтворити це відео"? Як ви з цим справляєтесь? Я вловлюю помилку, але отримую цей спосіб незалежно, і я не маю ніякого контролю над джерелом медіа, оскільки він надходить із публічного API. Якщо хтось знає, як запобігти модалю "Не можу відтворити це відео", я буду вдячний.
Krafty

Ви спробували встановити слухач помилок. MediaPlayer mp = новий MediaPlayer () {@Override public void setOnErrorListener (слухач android.media.MediaPlayer.OnErrorListener) {// Робіть сюди ..}}; mp.setDataSource (..
Rukmal Dias


0

Ви отримуєте це повідомлення в журналах, тому що ви робите те, що заборонено в поточному стані вашого екземпляра MediaPlayer.

Тому ви завжди повинні реєструвати оброблювач помилок, щоб знайти ці речі (як @tidbeck запропонував).

Спочатку я раджу поглянути на документацію до MediaPlayerкласу та зрозуміти, що це означає зі станами. Дивіться: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

Ваша помилка тут цілком може бути однією із поширених, інші писали тут, але загалом я б ознайомився з документацією про те, які методи можуть бути викликані в якому стані: http://developer.android.com/ довідка / android / media / MediaPlayer.html # Valid_and_Invalid_States

У моєму прикладі це був метод mediaPlayer.CurrentPosition, який я зателефонував, поки медіаплеєр був у стані, коли заборонено називати цю властивість.


0

Я вирішив як помилки (-19,0), так і (-38,0), створюючи новий об'єкт MediaPlayer кожного разу перед відтворенням і після цього звільняючи його.

Перед:

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

}

}

Після:

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

Це було дуже засмучено. Отже, я отримав рішення, яке працює для мене.

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

Я також отримав цю помилку, яку я спробував з onPreparedListener, але все ж отримав цю помилку. Нарешті я отримав рішення, що помилка - моя вина, тому що я забув дозвіл на Інтернет в Android Manifest xml. :)

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

Я використовував зразок кодування для mediaplayer. Я використовував метод StreamService.java
onCreate

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

-1

Я зіткнувся з тією ж проблемою безпосередньо раніше, друг на першому поверсі мав рацію, ви зателефонували start()в неправильний час, вам слід встановити слухача для підготовки () або за prepareSync()допомогою цього методу mediaPlayer.setOnPreparedListener(this); перед тим як підготуватися, у цьому зворотному дзвінку start(). Це може вирішити вашу проблему. Я вже пробував.


Чи можете ви бути більш конкретними?
Karthik AMR

Вибачте, англійська мова не є моєю першою мовою, і я теж не добре в ній ... але я просто хочу допомогти іншим, хто має ті самі запитання, ось і все.
peerless2012

-1

Я новачок в програмуванні Android, і у мене була така ж помилка, як і в цьому. тому я просто переробив mp.createmediaPlayer = MediaPlayer.create (getApplicationContext (), Settings.System.DEFAULT_RINGTONE_URI). Це може бути не істинним способом, але це спрацювало штрафом для мене:

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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.