Android MediaPlayer stuck in prepare()

I'm facing a serious problem with the Media Player(MP) being stuck at the prepare() method. My app runs prepare() in an AsyncTask to avoid blocking the UI, since the sources are from the web. There are several 'play' buttons that the user can click at any time, so I added the prepare() inside a synchronized method to better control the state of the MP. My app also call a release() onPause to free the used resources.

Thing is, I noticed that if release() is called while preparing, prepare() never returns, and so I'm stuck inside a synchronized method. The worst of it is that the AsyncTask thread is in a deadlock, and every time that the user click on play in that state another thread is wasted since it keeps waiting to acquire the monitor that is in possesion of the never-returning prepare(). Soon all my AsyncTasks threads are wasted and since I use them extensively, my app stops working.

So my question is: do anyone has an idea of how overcoming this problem? I'm seriously thinking of redoing all my work with the MediaPlayer, but I need to know the best way to handle situations like this one beforehand.

You should use prepareAsync() instead. And you won't need AsyncTask just for the sake of MediaPlayer preparation.

media player - Android MediaPlayer stuck in prepare(), You should use prepareAsync() instead. And you won't need AsyncTask just for the sake of MediaPlayer preparation. The Android multimedia framework includes support for playing variety of common media types, so that you can easily integrate audio, video and images into your applications.

The problem with using Asyntasks or prepareAsync() for that matter is that it doesn't automatically switch the MediaPlayer's state to prepared. You would think it does, but for some reason it doesn't. I got stuck with this same problem for a few days until someone suggested me to implement the OnPreparedListener, and use that to use my MediaPlayer.

Adding it is quite simple.

First, implement the listener in your class: (I'm using this for a Service so yours will look slightly different.)

public class MusicService extends Service implements OnPreparedListener

Next, in your play / prepare statement, use prepareAsync, and set the listener.

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

Next, add the onPrepared method and add your starting code:

public void onPrepared(MediaPlayer mediaplayer) {
        // We now have buffered enough to be able to play
        mp.start();
    }

That should do the trick.

How to solve Android mediaplayer.prepare(), setOnPreparedListener(new MediaPlayer.OnPreparedListener() {. public void onPrepared(MediaPlayer mp) {. mp.start();. }. does this method take less time to mediaPlayer.prepareAsync() and to mediaPlayer.start() – Naz141 Mar 30 '16 at 8:57 Actually this method is about "how to stop MP without ANR" only. Its up to you how long app will wait for MP to pass prepare state.

Thanks for all the answers, but I fixed this not using the prepareAsync() as was mentioned in previous answers. I think that if a synchronous method of preparing was made available, there should be a way of making it work correctly.

The fix, although not elegant IMO, is simple: avoid calling release() inside a prepare(). Although the state diagram in the Media Player docs says that release() can be called in any state, experimentation proved that calling it inside a prepare() (presumably in the 'Preparing' state) will hang your app. So I added a check to see if the MP is in this state and I am now avoding calling release() if it is. I needed to add a boolean in my code to check this, since there is no isPreparing() method in the MP.

I'm confident that this shouldn't happen and is a bug in Android itself. As can be seen in the comments, there is a contradiction in the docs: it says that release() can be called at any state, but also says that calling any state changing commands while in the Preparing state has an undefined outcome. Hope that this will help other people.

Player stuck intermittently, handleMessage(ExoPlayerImpl.java:1555) at android.os. The underlying media player returned an error code of -38 from onError callback 01-16 18:00: 46.280 D/LclPlaybackSvcMPlayer(18190): getPosition() -> 0 01-16 intermittent incorrect sequence of of prepare and start calls when AntennaPod is� Android provides many ways to control playback of audio/video files and streams. One of this way is through a class called MediaPlayer. Android is providing MediaPlayer class to access built-in mediaplayer services like playing audio,video e.t.c. In order to use MediaPlayer, we have to call a static Method create() of this class. This method

I solved this issue in my app like this:

Create objects for the AsyncTasks (so you can check if they're in progress):

private AsyncTask<String, Void, String> releaseMP;
private AsyncTask<String, Void, String> setSource;

Create an AsyncTask for the prepare call:

private class setSource extends AsyncTask<String, Void, String> {
    @Override
    protected synchronized String doInBackground(final String... urls) {
        try {
            mMediaPlayer.prepare();
        } catch (final IllegalStateException e) {
            e.printStackTrace();
            return e.getMessage();
        } catch (final IOException e) {
            e.printStackTrace();
            return e.getMessage();
        } catch (final Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }

        return null;
    }

    @Override
    protected void onCancelled() {
        if (setSource != null)
            setSource = null;

        // Send error to listener
        mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);

        releaseMP = new releaseMP().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
    }

    @Override
    protected void onPostExecute(final String result) {
        if (setSource != null)
            setSource = null;

        // Check for error result
        if (result != null) {
            mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
        }
    }

    @Override
    protected void onPreExecute() {

    }

}

Now your prepare code:

    try {
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnPreparedListener(mPreparedListener);
        mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
        mDuration = -1;
        mMediaPlayer.setOnCompletionListener(mCompletionListener);
        mMediaPlayer.setOnErrorListener(mErrorListener);
        mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
        mCurrentBufferPercentage = 0;
        mMediaPlayer.setDataSource(getContext(), mUri, mHeaders);
        mMediaPlayer.setDisplay(mSurfaceHolder);
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mMediaPlayer.setScreenOnWhilePlaying(true);

        // mMediaPlayer.prepareAsync();
        // we don't set the target state here either, but preserve the
        // target state that was there before.
        mCurrentState = STATE_PREPARING;
    } catch (final IOException ex) {
        Log.w(TAG, "Unable to open content: " + mUri, ex);
        mCurrentState = STATE_ERROR;
        mTargetState = STATE_ERROR;
        mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
        return;
    } catch (final IllegalArgumentException ex) {
        Log.w(TAG, "Unable to open content: " + mUri, ex);
        mCurrentState = STATE_ERROR;
        mTargetState = STATE_ERROR;
        mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
        return;
    } catch (final Exception ex) {
        Log.w(TAG, "Unable to open content: " + mUri, ex);
        mCurrentState = STATE_ERROR;
        mTargetState = STATE_ERROR;
        mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
        return;
    }

    setSource = new setSource().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);

And lastly, when you need to kill the mediaPlayer, you'll check the setSource object to see if it is preparing before you release it. If it is preparing, you'll cancel the AsyncTask and in the AsyncTask onCancelled, you'll reset and release the object:

public void release(final boolean cleartargetstate) {
    if (mMediaPlayer != null) {
        if (setSource != null) {
            setSource.cancel(true);
        } else {
            releaseMP = new releaseMP().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
        }
    }
}

And this is my releaseMP AsyncTask (which just resets and releases the object):

private class releaseMP extends AsyncTask<String, Void, String> {

    @Override
    protected synchronized String doInBackground(final String... urls) {
        Log.i(MethodNameTest.className() + "." + MethodNameTest.methodName(), "called");
        if (mMediaPlayer != null) {
            // Release listeners to avoid leaked window crash
            mMediaPlayer.setOnPreparedListener(null);
            mMediaPlayer.setOnVideoSizeChangedListener(null);
            mMediaPlayer.setOnCompletionListener(null);
            mMediaPlayer.setOnErrorListener(null);
            mMediaPlayer.setOnBufferingUpdateListener(null);
            mMediaPlayer.reset();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        mCurrentState = STATE_IDLE;
        mTargetState = STATE_IDLE;
        return null;
    }

    @Override
    protected void onPostExecute(final String result) {
        Log.i(MethodNameTest.className() + "." + MethodNameTest.methodName(), "called");

        if (releaseMP != null)
            releaseMP = null;
    }

}

MediaPlayer overview | Android-Entwickler, mediaPlayer?.start() // no need to call prepare(); create() does that for When the media is done preparing, the onPrepared() method of the� The Android multimedia framework includes support for capturing and encoding a variety of common audio and video formats. You can use the MediaRecorder APIs if supported by the device hardware. This document shows you how to use MediaRecorder to write an application that captures audio from a device microphone, save the audio, and play it back

My Media Player was stuck in Prepare because I was using non-secure URLs, (HTTP instead of HTTPS)

I had to add the following in the android manifest.

<application
    ...
    android:usesCleartextTraffic="true"
    ...
</application>

android.media.MediaPlayer.setAudioStreamType java code , Android MediaPlayer - how to play in the STREAM_ALARM? @Override public void prepare() { try { mediaPlayer = new MediaPlayer(); mediaPlayer. mp. prepare(); mp.start(); } catch(Exception e) { //exception caught in the end zone }. In the meantime, my main activity calls prepareAsync method to prepare the mediaplayer. This uses my VideoDataSource methods getSize and readAt. I have getSize always return -1 (size unknown), while readAt sleeps until the local file is unlocked, then proceeds to lock it and check if the data requested by the mediaplayer is ready.

android.media.MediaPlayer.setDataSource java code examples , Best Java code snippets using android.media. new MediaPlayer(); Codota Icon @Override public void prepare() { try { mediaPlayer = new MediaPlayer(); mp .prepare(); mp.start(); } catch(Exception e) { //exception caught in the end zone }. Android MediaPlayer Class. Android SDK is providing MediaPlayer Class to access android in built mediaplayer services like playing audio, video etc., In this tutorial i am using following functions of this class to control audio player.

13.1: Playing video with VideoView � GitBook, Android provides an overall architecture for audio and video apps, and large number of Handle the time period in your app where the media is being prepared (buffering or The VideoView class combines a media player (the MediaPlayer class) with a In onCreate() , get a reference to the VideoView in the layout: Android MediaPlayer se está preparando demasiado tiempo. Hola, estoy usando MediaPlayer para reproducir un flujo regular de ShoutCast. El código es sencillo con prepareAsync y un controlador para iniciar la reproducción.

android, 我面临着一个严重的问题,Media Player MP 被卡在prepare 方法上。 我的应用程序在AsyncTask Android MediaPlayer stuck in prepare(). MediaPlayer.setDataSource() and prepare() not working-android I'm having a crack at using the MediaPlayer object and not having much success. If I add a sound asset to my raw folder and call it using the int value within R, it works fine.

Comments
  • I thought of that, but I'm not quit sure that it would solve the problem at hand. The MediaPlayer docs says that "It is important to note that the Preparing state is a transient state, and the behavior of calling any method with side effect while a MediaPlayer object is in the Preparing state is undefined." So the problem would remain, I would call release() in the 'preparing' state, and the outcome is undefined. I suspect that inside my synchronous prepare(), the MediaPlayer shifts to this 'preparing' state and that results in the erros that I'm receiving.
  • According to diagram and state table you can call release() from any state. Give it a go. I think you're just facing multithreading related bug. And excluding multiple threads should "fix" it.
  • It does say that I can call release() at any time, but even so I'm facing the problem of being stuck if I call this inside a prepare(). This shouldn't happen and is a bug in Android IMO.
  • No, I was saying that even though the docs says that I can call release() at any time, I'm facing the original problem of being stuck inside a prepare(). I don't think that is a bad idea using prepareAsync(), but I do believe that there should exist a way of making it work correctly with prepare().
  • This is the proper solution. The solution you marked as an answer is merely working around the functionality already provided to you by MediaPlayer.