Question

I published an app recently, and users are reporting crashes because my program included the method setNextMediaPlayer(). I now realize that this only works for API 16+, and my app supports API 8+. I was wondering if there is an alternate way of achieving the same effect.

My app has some text to speech, and what I was doing was creating an ArrayList of MediaPlayers that each had a short sound file, and then playing them one after an other. If I remove this method from the code, the audio becomes too choppy to understand.

I was thinking about using the SoundPool class, but there is no OnCompleteListener, so I'm not sure how I would do it.

So basically my question is: Is there a way to transition seamlessly between audio files without using the setNextMediaPlayer() method?

Thanks very much for your time!

EDIT

I added this code that I found

    private class CompatMediaPlayer extends MediaPlayer implements OnCompletionListener {

    private boolean mCompatMode = true;
    private MediaPlayer mNextPlayer;
    private OnCompletionListener mCompletion;

    public CompatMediaPlayer() {
        try {
            MediaPlayer.class.getMethod("setNextMediaPlayer", MediaPlayer.class);
            mCompatMode = false;
        } catch (NoSuchMethodException e) {
            mCompatMode = true;
            super.setOnCompletionListener(this);
        }
    }

    public void setNextMediaPlayer(MediaPlayer next) {
        if (mCompatMode) {
            mNextPlayer = next;
        } else {
            super.setNextMediaPlayer(next);
        }
    }

    @Override
    public void setOnCompletionListener(OnCompletionListener listener) {
        if (mCompatMode) {
            mCompletion = listener;
        } else {
            super.setOnCompletionListener(listener);
        }
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        if (mNextPlayer != null) {
            // as it turns out, starting a new MediaPlayer on the completion
            // of a previous player ends up slightly overlapping the two
            // playbacks, so slightly delaying the start of the next player
            // gives a better user experience
            SystemClock.sleep(50);
            mNextPlayer.start();
        }
        mCompletion.onCompletion(this);
    }
}

But now how do I add the audio files? I tried this:

        // assigns a file to each media player
    mediaplayers = new ArrayList<CompatMediaPlayer>();
    for (int i = 0; i < files.size(); i++) {
        mediaplayers.add((CompatMediaPlayer) CompatMediaPlayer.create(this, files.get(i)));
    }

but am getting a class cast exception because MediaPlayer cannot be casted to CompatMediaPlayer.

Was it helpful?

Solution

Create Compat player that will work with onCompletionListener to start the next player like:

public void onCompletion(MediaPlayer mp) {
    if (mCompatMode && mNextPlayer != null) {
        mNextPlayer.prepare();
        mNextPlayer.start();
    }
}

Somewhere in your constructor check if there is method (or check SDK version) named "setNextMediaPlayer"

mCompatMode = Build.VERSION.SDK_INT < 16;

Define method like this one:

public void setNextMediaPlayer(MediaPlayer next) {
    if (mCompatMode) {
        mNextPlayer = next;
    } else {
        super.setNextMediaPlayer(next);
    }
}

OTHER TIPS

if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    mediaPlayer.stop();
                    mediaPlayer.release();
                    mediaPlayer = null;
                }
                mediaPlayer = new MediaPlayer();
                try {
                    AssetFileDescriptor descriptor = context.getAssets().openFd("play1.mp3");
                    mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
                    descriptor.close();
                    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    mediaPlayer.prepare();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mediaPlayer.start();
                MediaPlayer md = new MediaPlayer();
                try {
                    AssetFileDescriptor descriptor = context.getAssets().openFd("play2.mp3");
                    md.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
                    descriptor.close();
                    md.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    md.prepare();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mediaPlayer.setNextMediaPlayer(md);

                MediaPlayer md1 = new MediaPlayer();
                try {
                    AssetFileDescriptor descriptor = context.getAssets().openFd("play3.mp3");
                    md1.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
                    descriptor.close();
                    md1.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    md1.prepare();
                } catch (IOException e) {
                    e.printStackTrace();
                }                md.setNextMediaPlayer(md1);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top