2011-03-08 97 views
6

我正在製作一個簡單的瑣事遊戲,並在用戶到達主菜單時運行循環〜1分鐘的mp3文件。當用戶點擊菜單上的任何按鈕(即玩遊戲)時,聲音設置爲停止。在Android中降低或淡入聲音

我的問題是,當聲音停止時,它的一種震顫切斷。而不是做.pause()或.stop(),有沒有辦法使按鈕按下後聲音慢慢淡出?

感謝

回答

0

您可以使用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); 
} 

你可能也想記錄的原始卷他們的媒體設置爲,並將其重置爲您淡出靜音,停止後您的音樂。

這些代碼可能不準確,我目前還沒有獲得測試它的任何方式,但我希望它會導致你在正確的方向....

16

EDIT(3/13/13):用新QA代碼更新

這是我整個Android Media Player的處理程序類。看看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

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; 
}