Android Studio Mediaplayer how to fade in and out

前端 未结 3 2167
慢半拍i
慢半拍i 2021-02-20 17:08

I am working with the mediaplayer class in android studio. I simply want to fade out one sound and fade in the other sound instead of using setVolume(0,0) and setVolume(1,1).

相关标签:
3条回答
  • 2021-02-20 17:18

    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;
        }
    }
    
    0 讨论(0)
  • 2021-02-20 17:28

    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.

    0 讨论(0)
  • 2021-02-20 17:37

    There's a VolumeShaper class added in API Level 26 (https://developer.android.com/guide/topics/media/volumeshaper). Here's an example of volume out and in, you can shape the fade in or out speed (ramp) adding more points to times and volumes arrays. Time points must start at 0 and end at 1 and they are relative times of volume ramping.

    fun fadeOutConfig(duration: Long): VolumeShaper.Configuration {
            val times = floatArrayOf(0f, 1f) // can add more points, volume points must correspond to time points
            val volumes = floatArrayOf(1f, 0f)
            return VolumeShaper.Configuration.Builder()
                .setDuration(duration)
                .setCurve(times, volumes)
                .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC)
                .build()
        }
    
    fun fadeInConfig(duration: Long): VolumeShaper.Configuration {
        val times = floatArrayOf(0f, 1f) // can add more points, volume points must correspond to time points
        val volumes = floatArrayOf(0f, 1f)
        return VolumeShaper.Configuration.Builder()
            .setDuration(duration)
            .setCurve(times, volumes)
                .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC)
                .build()
    }
    
    fun fadeInOrOutAudio(mediaPlayer: MediaPlayer, duration: Long, out: Boolean) {
        val config = if (out) fadeOutConfig(duration) else fadeInConfig(duration)
        val volumeShaper = mediaPlayer.createVolumeShaper(config)
        volumeShaper.apply(VolumeShaper.Operation.PLAY)
    }
    
    0 讨论(0)
提交回复
热议问题