• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

App Inventor Problem with MediaPlayer.create() when recreating with same files after mediaPlayer.release()

I have a simple media player app that works fine for a while (like each song will play about 50 times) and then starts to crash on almost all the media files (a few still work but lag really bad; there is no lag until the errors). These errors continue even after stopping the activity and reopening!

These same media files work with other media players after they quit working in mine, so there is clearly something very wrong. I have to restart my device for my Activity to be able to call MediaPlayer.create() on the files without errors again. This behavior is so obscure!

One create:
Code:
E/MediaPlayer: error (1, -38)
E/MediaPlayer: error (1, -2147483648)
E/MediaPlayer: Error (1,-38)
E/MediaPlayer: error (1, -2147479551)
E/MediaPlayer: error (1, -38)
Another:
Code:
E/MediaPlayer: error (1, -2147479551)
E/MediaPlayer: Error (1,-2147479551)
E/MediaPlayer: error (1, -38)
Yet another:
Code:
E/MediaPlayer: error (1, -38)
E/MediaPlayer: error (1, -2147479551)
E/MediaPlayer: error (1, -38)
E/MediaPlayer: Error (1,-38)

So the errors are inconsistent in order, but there are recurring numbers. One of the numbers are not in the MediaPlayer.java file for the target SDK 30, but the device I am testing is using Android 6.0.1 which I believe is SDK 23. I am not entirely sure how to find the relevent Android source. Using Google search "site:https://android.googlesource.com/ mediaplayer.java" is the best way I have found.

I did find
Code:
MEDIA_ERROR_SYSTEM = -2147483648
and
Code:
MEDIA_ERROR_UNKNOWN = 1
. I have an unknown media error from the system.

What about -2147479551? It appears to be MEDIA_ERROR_SYSTEM | 0x1001. 0x1001 does not appear in MediaPlayer.java. It is another unknown media error. What extra information was attached? What about -38?!

What could cause such a bug. I don't even know how to wrap my head around this behavior. Is MediaPlayer not releasing correctly? Am I leaking resources that don't go away when the app closes? My code is fairly simple and it appears to release everything like it is supposed to. How come a restart fixes the issue?

Here is the relevant code:
Code:
    Playlist masterPlaylist;
    public boolean surfaceCreated;
    AudioURI currentSong;
    AudioURI nextSong;
    MediaPlayer mediaPlayer;
    MediaPlayer nextMediaPlayer;
    VideoView videoView;
    final Object lock = new Object();

    MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer2) {
            synchronized (lock) {
                Log.i(TAG, "onCompletion started");
                currentSong = nextSong;
                mediaPlayer.release();
                mediaPlayer = nextMediaPlayer;
                if (surfaceCreated) {
                    mediaPlayer.setDisplay(videoView.getHolder());
                    mediaPlayer.start();
                }
                nextSong = masterPlaylist.next();
                executorService.submit(runnableNextMediaPlayer);
                Log.i(TAG, "onCompletion ended");
            }
        }
    };

    View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Log.i(TAG, "onClick started");
            currentSong = nextSong;
            mediaPlayer.release();
            mediaPlayer = nextMediaPlayer;
            if (surfaceCreated) {
                mediaPlayer.setDisplay(videoView.getHolder());
                mediaPlayer.start();
            }
            nextSong = masterPlaylist.next();
            executorService.submit(runnableNextMediaPlayer);
            Log.i(TAG, "onClick ended");
        }
    };

    ExecutorService executorService = Executors.newSingleThreadExecutor();

    Runnable runnableNextMediaPlayer = new Runnable() {
        @Override
        public void run() {
            synchronized (lock) {
                Log.i(TAG, "creating next MediaPlayer");
                nextMediaPlayer = MediaPlayer.create(getApplicationContext(), nextSong.getUri());                nextMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
                nextMediaPlayer.setOnCompletionListener(onCompletionListener);
                Log.i(TAG, "next MediaPlayer created");
            }
        }
    };

    public void calledAtTheEndOfOnCreate() {
        videoView = findViewById(R.id.video_view);
        currentSong = masterPlaylist.next();
        mediaPlayer = MediaPlayer.create(getApplicationContext(), currentSong.getUri());
        mediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
        mediaPlayer.setOnCompletionListener(onCompletionListener);
        nextSong = masterPlaylist.next();
        executorService.submit(runnableNextMediaPlayer);
        videoView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
                surfaceCreated = true;
                mediaPlayer.setDisplay(surfaceHolder);
                mediaPlayer.start();
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {}

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {surfaceCreated = false;}
        });
        FloatingActionButton floatingActionButton = findViewById(R.id.fab);
        floatingActionButton.setOnClickListener(onClickListener);
    }
 

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones