Android Studio Mediaplayer how to fade in and out
Here's the fade-out code in case it saves someone some time.
This also includes a stopPlayer() function to release the MediaPlayer from memory. It's a good practice to do so.
// Set to the volume of the MediaPlayer
float volume = 1;
private void startFadeOut(){
// The duration of the fade
final int FADE_DURATION = 3000;
// The amount of time between volume changes. The smaller this is, the smoother the fade
final int FADE_INTERVAL = 250;
// Calculate the number of fade steps
int numberOfSteps = FADE_DURATION / FADE_INTERVAL;
// Calculate by how much the volume changes each step
final float deltaVolume = volume / numberOfSteps;
// Create a new Timer and Timer task to run the fading outside the main UI thread
final Timer timer = new Timer(true);
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
//Do a fade step
fadeOutStep(deltaVolume);
//Cancel and Purge the Timer if the desired volume has been reached
if(volume <= 0){
timer.cancel();
timer.purge();
stopPlayer();
}
}
};
timer.schedule(timerTask,FADE_INTERVAL,FADE_INTERVAL);
}
private void fadeOutStep(float deltaVolume){
player.setVolume(volume, volume);
volume -= deltaVolume;
}
// Release the player from memory
private void stopPlayer() {
if (player != null) {
player.release();
player = null;
}
}
Looking at the linked example, you would have to call fadeIn()/fadeOut() in a loop, to increase/decrease the volume over a period of time. deltaTime would be the time between each iteration of the loop.
You'd have to do this in a separate thread from your main UI thread, so you don't block it and cause your app to crash. You can do this by either putting this loop inside a new Thread/Runnable/Timer.
Here is my example for fading in (you can do a similar thing for fading out):
float volume = 0;
private void startFadeIn(){
final int FADE_DURATION = 3000; //The duration of the fade
//The amount of time between volume changes. The smaller this is, the smoother the fade
final int FADE_INTERVAL = 250;
final int MAX_VOLUME = 1; //The volume will increase from 0 to 1
int numberOfSteps = FADE_DURATION/FADE_INTERVAL; //Calculate the number of fade steps
//Calculate by how much the volume changes each step
final float deltaVolume = MAX_VOLUME / (float)numberOfSteps;
//Create a new Timer and Timer task to run the fading outside the main UI thread
final Timer timer = new Timer(true);
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
fadeInStep(deltaVolume); //Do a fade step
//Cancel and Purge the Timer if the desired volume has been reached
if(volume>=1f){
timer.cancel();
timer.purge();
}
}
};
timer.schedule(timerTask,FADE_INTERVAL,FADE_INTERVAL);
}
private void fadeInStep(float deltaVolume){
mediaPlayer.setVolume(volume, volume);
volume += deltaVolume;
}
Instead of using two separate MediaPlayer objects, I would in your case use just one and swap the track between the fades. Example:
**Audio track #1 is playing but coming to the end**
startFadeOut();
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.setDataSource(context,audiofileUri);
mediaPlayer.prepare();
mediaPlayer.start();
startFadeIn();
**Audio track #2 has faded in and is now playing**
Hope this solves your problem.