Медиа-проигрыватель вызван в состоянии 0, ошибка (-38,0)


105

В настоящее время я пытаюсь разработать простое приложение, которое транслирует интернет-радиостанции. У меня есть URL-адрес станции, и я настраиваю медиаплеер, например

    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(), даже если песня вообще не воспроизводится.

Чтобы решить эту проблему, проверьте состояние mediaPlayer перед вызовом методов. Например:

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

Кроме того, MediaPlayer отправляет сообщения о событиях. Даже если вам не нужно подготовленное событие (хотя было бы неплохо не начинать воспроизведение до того, как это событие было запущено), вы должны установить callback-listener. Это также справедливо и для OnErrorListener, OnCompletionListener, OnPreparedListenerиOnSeekCompletedListener (если вы вызываете искать метод).

Слушателей можно просто прикрепить

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

В моем случае был вызов pause () на не играющем плеере
stevo.mit 03

вызов mediaPlayer.isPlaying () в недопустимом состоянии отправит медиаплеер в состояние ошибки. Лучше поддерживать явное перечисление для поддержки состояний.
Madeyedexter

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(...)
Pierre

4

Я столкнулся с той же проблемой несколько дней назад. Мой аудио MediaPlayer отлично работает на устройствах с высокой вычислительной мощностью, но для медленных устройств медиаплеер просто не воспроизводился какое-то время, и из LogCat он часто жаловался, что вызывается в неправильном состоянии. Итак, я решил это, вызвав вызов метода start () , pause () , ... в методе 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 = new MediaPlayer () {@Override public void setOnErrorListener (android.media.MediaPlayer.OnErrorListener listener) {// Делайте что-нибудь здесь ..}}; mp.setDataSource (..
Рукмал Диас


0

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

Поэтому вы всегда должны регистрировать обработчик ошибок, чтобы отловить эти вещи (как предлагает @tidbeck).

Сначала я советую вам взглянуть на документацию к MediaPlayerклассу и понять, что это означает с состояниями. См. Http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram.

Ваша ошибка здесь может быть одной из распространенных, другие писали здесь, но в целом я бы взглянул на документацию о том, какие методы можно вызывать в каком состоянии: http://developer.android.com/ reference / 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" />

Я использовал образец кода для медиаплеера. Я использовал в 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()не в то время, вы должны установить слушателя для prepare () или 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.