mediaplayer error on soundboard app

2019-02-25 19:30发布

问题:

I have a soundboard app that calls that calls audio files when their button is pressed. However, after most of the buttons havebeen pressed and played, I start to get these mediaplayer errors. Does anyone know How to detect it and just restart or stop it completely from happening? Thanks for your time.

-colby

    for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
        ImageButton button = (ImageButton) findViewById(entry.getKey());
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                try {
                    int sound = map.get(v.getId());
                    mp = MediaPlayer.create(myMain.this, sound);
                    mp.prepare();
                } catch (IllegalStateException e) {



                } catch (IOException e) {

                }
                mp.seekTo(0);
                mp.start();

            }
        }

        );

    }

04-13 10:11:39.873: INFO/MediaPlayer(23152): MediaPlayer start()
04-13 10:11:39.873: VERBOSE/MediaPlayerService(18229): [666] setLooping(0)
04-13 10:11:39.873: VERBOSE/MediaPlayerService(18229): [666] setVolume(1.000000, 1.000000)
04-13 10:11:39.873: VERBOSE/AudioSink(18229): setVolume(1.000000, 1.000000)
04-13 10:11:39.873: VERBOSE/MediaPlayerService(18229): [666] start
04-13 10:11:39.873: DEBUG/AwesomePlayer(18229): [U5B] play (556)
04-13 10:11:39.873: DEBUG/AwesomePlayer(18229): [U5B] play_l (562) 04-13 10:11:39.873: VERBOSE/AudioSink(18229): open(44100, 1, 1, 4)
04-13 10:11:39.873: ERROR/AudioFlinger(18229): no more track names available
04-13 10:11:39.873: ERROR/AudioTrack(18229): AudioFlinger could not create track, status: 12
04-13 10:11:39.873: ERROR/AudioSink(18229): Unable to create audio track
04-13 10:11:39.873: ERROR/MediaPlayer(23152): error (-19, 0)
04-13 10:11:39.894: INFO/MediaPlayer(23152): MediaPlayer handleMessage what=5
04-13 10:11:39.894: INFO/MediaPlayer(23152): MediaPlayer handleMessage what=1
04-13 10:11:39.894: INFO/MediaPlayer(23152): MediaPlayer handleMessage what=4
04-13 10:11:42.114: INFO/MediaPlayer(23152): MediaPlayer create()
04-13 10:11:42.114: INFO/MediaPlayer(23152): MediaPlayer
04-13 10:11:42.114: VERBOSE/MediaPlayerService(18229): Client(667) constructor

回答1:

James has the right idea. You're creating too many MediaPlayer instances after a while, and running out of memory. A solution I posted previously was something to this effect:

public MediaPlayer mp;
public Resources res = getResources();

View.OnClickListener listener = new View.OnClickListener() {
    public void onClick(View v) {
        try {
            int sound = map.get(v.getId());
            AssetFileDescriptor afd = res.openRawResourceFd(sound);

            mp.reset();
            mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            mp.prepare();
            mp.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
    ImageButton button = (ImageButton)findViewById(entry.getKey());
    button.setOnClickListener(listener);
}

This might not compile (I'm assuming your sound IDs are from the res/raw folder), but the idea is, just have ONE MediaPlayer instance, and whenever a button is clicked, reset that instance, set the data source to the corresponding FileDescriptor, prepare it, and start playback.



回答2:

I'm not exactly sure, but I think you only want to create the media player once for each sound and then call start, seekTo, and stop after that.