Понизить или исчезнуть звук в Android - PullRequest
6 голосов
/ 09 марта 2011

Я делаю простую викторину и запускаю зацикленный ~ 1 мин mp3-файл, когда пользователь попадает в главное меню. Звук отключается, когда пользователь нажимает на любую из кнопок в меню (т. Е. Играть в игру).

Моя проблема в том, что когда звук прекращается, его звук прерывается. Вместо .pause () или .stop (), есть ли способ заставить звук постепенно исчезать после нажатия кнопки?

Спасибо

Ответы [ 3 ]

16 голосов
/ 01 ноября 2012

РЕДАКТИРОВАТЬ (13.03.13): Обновлено с новым кодом QA'd

Это весь мой класс обработчиков для Android MediaPlayer. Посмотрите на функции play () и pause (). Оба содержат способность исчезать или нет. Функция updateVolume () была ключом для линейного увеличения / уменьшения звука.

public class MusicHandler 
{
private MediaPlayer mediaPlayer;
private Context context;
private int iVolume;

private final static int INT_VOLUME_MAX = 100;
private final static int INT_VOLUME_MIN = 0;
private final static float FLOAT_VOLUME_MAX = 1;
private final static float FLOAT_VOLUME_MIN = 0;

public MusicHandler(Context context)
{
    this.context = context;
}

public void load(String path, boolean looping)
{
    mediaPlayer = MediaPlayer.create(context, Uri.fromFile(new File(path)));
    mediaPlayer.setLooping(looping);
}

public void load(int address, boolean looping)
{
    mediaPlayer = MediaPlayer.create(context, address);
    mediaPlayer.setLooping(looping);
}

public void play(int fadeDuration)
{
    //Set current volume, depending on fade or not
    if (fadeDuration > 0) 
        iVolume = INT_VOLUME_MIN;
    else 
        iVolume = INT_VOLUME_MAX;

    updateVolume(0);

    //Play music
    if(!mediaPlayer.isPlaying()) mediaPlayer.start();

    //Start increasing volume in increments
    if(fadeDuration > 0)
    {
        final Timer timer = new Timer(true);
        TimerTask timerTask = new TimerTask() 
        {
            @Override
            public void run() 
            {
                updateVolume(1);
                if (iVolume == INT_VOLUME_MAX)
                {
                    timer.cancel();
                    timer.purge();
                }
            }
        };

        // calculate delay, cannot be zero, set to 1 if zero
        int delay = fadeDuration/INT_VOLUME_MAX;
        if (delay == 0) delay = 1;

        timer.schedule(timerTask, delay, delay);
    }
}

public void pause(int fadeDuration)
{
    //Set current volume, depending on fade or not
    if (fadeDuration > 0) 
        iVolume = INT_VOLUME_MAX;
    else 
        iVolume = INT_VOLUME_MIN;

    updateVolume(0);

    //Start increasing volume in increments
    if(fadeDuration > 0)
    {
        final Timer timer = new Timer(true);
        TimerTask timerTask = new TimerTask() 
        {
            @Override
            public void run() 
            {   
                updateVolume(-1);
                if (iVolume == INT_VOLUME_MIN)
                {
                    //Pause music
                    if (mediaPlayer.isPlaying()) mediaPlayer.pause();
                    timer.cancel();
                    timer.purge();
                }
            }
        };

        // calculate delay, cannot be zero, set to 1 if zero
        int delay = fadeDuration/INT_VOLUME_MAX;
        if (delay == 0) delay = 1;

        timer.schedule(timerTask, delay, delay);
    }           
}

private void updateVolume(int change)
{
    //increment or decrement depending on type of fade
    iVolume = iVolume + change;

    //ensure iVolume within boundaries
    if (iVolume < INT_VOLUME_MIN)
        iVolume = INT_VOLUME_MIN;
    else if (iVolume > INT_VOLUME_MAX)
        iVolume = INT_VOLUME_MAX;

    //convert to float value
    float fVolume = 1 - ((float) Math.log(INT_VOLUME_MAX - iVolume) / (float) Math.log(INT_VOLUME_MAX));

    //ensure fVolume within boundaries
    if (fVolume < FLOAT_VOLUME_MIN)
        fVolume = FLOAT_VOLUME_MIN;
    else if (fVolume > FLOAT_VOLUME_MAX)
        fVolume = FLOAT_VOLUME_MAX;     

    mediaPlayer.setVolume(fVolume, fVolume);
}
}
2 голосов
/ 25 марта 2015

https://stackoverflow.com/a/29246026/922514

private static void crossFade() {
    MediaPlayerManager.fadeOut(currentPlayer, 2000);
    MediaPlayerManager.fadeIn(auxPlayer, 2000);
    currentPlayer = auxPlayer;
    auxPlayer = null;
}

public static void fadeOut(final MediaPlayer _player, final int duration) {
    final float deviceVolume = getDeviceVolume();
    final Handler h = new Handler();
    h.postDelayed(new Runnable() {
        private float time = duration;
        private float volume = 0.0f;

        @Override
        public void run() {
            if (!_player.isPlaying())
                _player.start();
            // can call h again after work!
            time -= 100;
            volume = (deviceVolume * time) / duration;
            _player.setVolume(volume, volume);
            if (time > 0)
                h.postDelayed(this, 100);
            else {
                _player.stop();
                _player.release();
            }
        }
    }, 100); // 1 second delay (takes millis)


}

public static void fadeIn(final MediaPlayer _player, final int duration) {
    final float deviceVolume = getDeviceVolume();
    final Handler h = new Handler();
    h.postDelayed(new Runnable() {
        private float time = 0.0f;
        private float volume = 0.0f;

        @Override
        public void run() {
            if (!_player.isPlaying())
                _player.start();
            // can call h again after work!
            time += 100;
            volume = (deviceVolume * time) / duration;
            _player.setVolume(volume, volume);
            if (time < duration)
                h.postDelayed(this, 100);
        }
    }, 100); // 1 second delay (takes millis)

}
public static float getDeviceVolume() {
    int volumeLevel = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

    return (float) volumeLevel / maxVolume;
}
0 голосов
/ 09 марта 2011

Вы можете использовать AudioManager:

public static final int STEP_DOWN = 5; // how far each step goes down
// later on, and in a backgroud thread like an AsyncTask
AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
int targetVol = 0; // or whatever you wanted.
int currentVol = am.getStreamVolume(AudioManager.STREAM_MUSIC);
while(currentVol > targetVol)
{
    am.setStreamVolume(AudioManager.STREAM_MUSIC, currentVol - STEP_DOWN, 0);
    currentVol = am.getStreamVolume(AudioManager.STREAM_MUSIC);
    thread.sleep(100);   
}

Возможно, вы также захотите записать исходную громкость, на которую был установлен носитель, и сбросить ее до того уровня, когда вы выключите звук, чтобы отключить звук и остановить музыку.

Этот код может быть не точным, в настоящее время у меня нет доступа к какому-либо способу его тестирования, но я надеюсь, что он ведет вас в правильном направлении ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...