Sabatino
Sabatino

Reputation: 123

ANDROID: MediaPlayer shows error (1, -19)

I'm working on a Service that plays a song picked from an ArrayList. The problem comes when I use prepare() and prepareAsync()methods, so here's the code:

public class MusicService extends Service implements MediaPlayer.OnPreparedListener{
    private final static int DEF_VALUE = -1;
    private Context mContext;
    private ArrayList<Song> mSongsList;
    private MediaPlayer mPlayer;
    private boolean isPlaying = false;
    private int mPosition;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate(){
        super.onCreate();
        mContext = getApplicationContext();
        mSongsList = new ArrayList<Song>();
        mPlayer = new MediaPlayer();
        setMusicPlayer();
    }

    public void setMusicPlayer(){
        //Setting player properties
        mPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
        mPlayer.setAudioSessionId(AudioManager.STREAM_MUSIC);
        mPlayer.setOnPreparedListener(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int mCommand = intent.getIntExtra("CMD", DEF_VALUE);
        int mTrackSelected = intent.getIntExtra("TRACK_CLICKED", DEF_VALUE);

        /** SERVICE COMMANDS
         *  0 = SERVICE PERMISSIONS
         *  1 = PLAY_PAUSE
         *  2 = NEXT TRACK
         *  3 = PREV TRACK
         *  4 = SONG IN LIST
         */

        switch (mCommand){
            case 0:
                GetTracks mGetSongs = new GetTracks();
                mSongsList = mGetSongs.listAllSongs(mContext);
                Log.d("test size arrayList", ""+mSongsList.size());
                break;
            case 1:
                setPlayPause();
                break;
            case 2:
                skipNextTrack();
                break;
            case 3:
                skipPrevTrack();
                break;
            case 4:
                if(mTrackSelected != DEF_VALUE){
                    mPosition = mTrackSelected;
                    setSongToPlay(mPosition);
                }
                break;
            default:
                Log.d("error cmd", "You shouldn't be here!");
                break;
        }

        return START_STICKY;
    }

    private void skipPrevTrack() {
        Log.d("method called:", "skipPrevTrack()");
        if(mPosition == 0){
            setSongToPlay(mPosition = mSongsList.size()-1);
        } else setSongToPlay(--mPosition);
        Log.d("test mPosition service", ""+mPosition);
    }

    private void skipNextTrack() {
        Log.d("method called:", "skipNextTrack()");
        if(mPosition == mSongsList.size()-1){
            setSongToPlay(mPosition = 0);
        } else setSongToPlay(++mPosition);
        Log.d("test mPosition service", ""+mPosition);
    }


    private void setSongToPlay(int pos) {
        Log.d("method called:", "setSongToPlay("+pos+")");
        startSong(mSongsList.get(pos).getSongUri());
    }
    private void startSong(Uri uri){

        try{
            mPlayer.reset();
            mPlayer.setDataSource(mContext, uri);
            mPlayer.prepareAsync();

            /** +++WORKS FINE WITH THIS CODE+++
             mPlayer = MediaPlayer.create(mContext, uri);
             mPlayer.start();
             */

        } catch (Exception e){
            e.printStackTrace();
        }
    }

    private void setPlayPause() {
        Log.d("method called:", "setPlayPause()");
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }
}

LOG:

 12-19 16:12:18.325 4013-4013/sebbsoft.myApp D/method called:: setSongToPlay(3)
12-19 16:12:18.341 4013-4013/sebbsoft.myApp D/test song playing: Fiori del male ft. Sfera Ebbasta
12-19 16:12:18.363 4013-4013/sebbsoft.myApp D/MediaPlayer: setSubtitleAnchor in MediaPlayer
12-19 16:12:18.428 4013-4028/sebbsoft.myApp E/MediaPlayer: error (1, -19)

How can I solve it?

Upvotes: 3

Views: 8068

Answers (5)

Mark Nashat
Mark Nashat

Reputation: 768

I was getting the same problem, I solved it by adding the following code to release the player:

1- get Audio use Assets File

MediaPlayer mediaPlayer = new MediaPlayer();
AssetFileDescriptor afd;  
mediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
         mediaPlayer.prepare();
          mediaPlayer.start();
        mp1.setOnCompletionListener(new OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
                mp.release();}; });

2- get Audio use res/raw folder.

mp1 = MediaPlayer.create(sound.this, R.raw.pan1);
mp1.start();
mp1.setOnCompletionListener(new OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {
        mp.release();

    }; });

Upvotes: 0

I had the same problem. Uploading many diferent audios to a Mediaplayer.

after 15 times it stopped to work.

I just add release every time before upload a new audio in the same Mediaplayer and this worked for me!

no more Error (1, -19)

hope helps!

Upvotes: 1

Mon
Mon

Reputation: 1110

Finally solved it! After a lot of trial & error!! This is the line that causes it for me:

mMediaPlayer.setAudioSessionId(AudioManager.STREAM_MUSIC);

The API doc for setAudioSessionId doesn't indicate any alternative or any issue on still using it which made it hard to debug. But I saw setAudioStreamType just below it, which is deprecated and suggests setAudioAttributes instead, w/c is added in API 21.

So I changed the above code to this:

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        mMediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build());
} else {
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}

And now it works!

By the way, as you can see, I checked only against version N (API 24) and above instead of from LOLLIPOP even though setAudioAttributes was added in API 21, because I only encounter this issue on Nougat devices, setAudioSessionId works up to Marshmallow devices for me so... don't wanna break anything that's already working.

I do hope someone would stop by and explain why this happens and what the error really means.

Hope this saves anyone days of headache :)

EDIT: For anyone Googling around, I also changed the original mMediaPlayer.setAudioSessionId to mMediaPlayer.setAudioStreamType, as pointed out by Eugen Pechanec. See his comment and answer for details. You would also want to change from checking against Build.VERSION_CODES.N to Build.VERSION_CODES.LOLLIPOP with that.

Upvotes: 4

Eugen Pechanec
Eugen Pechanec

Reputation: 38243

You're using setAudioSessionId incorrectly.

The audio session ID is a system wide unique identifier for the audio stream played by this MediaPlayer instance.

[...]

When created, a MediaPlayer instance automatically generates its own audio session ID. However, it is possible to force this player to be part of an already existing audio session by calling this method. This method must be called before one of the overloaded setDataSource methods.

You would obtain an audio session ID by calling AudioManager.generateAudioSessionId().


What you're probably looking for if you want to set the stream type is MediaPlayer.setAudioStreamType(int).

Newer API for this available since Android 5 is MediaPlayer.setAudioAttributes(AudioAttibutes).

Upvotes: 2

Charuka Silva
Charuka Silva

Reputation: 13153

Make sure you don't have too many MediaPlayer objects active at once.

Implement the OnCompletionListener and register it with your MediaPlayer instance. onCompletion called when the end of a media source is reached during playback.

void onCompletion(MediaPlayer mp){
   //Here you stop it.
   mp.stop();
   mPlayer.reset()
   //Reset the data source path to the new file
   mp.setDataSource(<uri>);
   mPlayer.prepare(); // or mPlayer.prepareAsync();
   // start the mediaplayer after the prepare has completed.
}

Release the mediaplayer instance once you are done playing all the files.


May be your listener only listen one time, then when it try to play the next one without prepared then it can crash.. try this too

add this -- > mPlayer.setOnPreparedListener(this); in your startSong() method before your prepareAsync

Upvotes: 0

Related Questions