2011-07-30 32 views

回答

20

一種方式做到這一點是使用MediaPlayer.setVolume(左,右),並有遞減這些值後,每iteration..here是一個粗略的想法

float volume = 1; 
float speed = 0.05f; 

public void FadeOut(float deltaTime) 
{ 
    MediaPlayer.setVolume(volume, volume); 
    volume -= speed* deltaTime 

} 
public void FadeIn(float deltaTime) 
{ 
    MediaPlayer.setVolume(volume, volume); 
    volume += speed* deltaTime 

} 

的淡入淡出或應該叫一次您的計時器已過期,該方法不需要採取deltaTime,但它的良好做法,因爲它會降低所有設備上的音量相同速率

+0

這是什麼,我沒有想這樣做,但最終仍因做缺少更好的解決方案。我正在尋找更好更優雅的解決方案,但似乎沒有。所以我會接受這個答案。 – binW

+0

不太確定你還可以做什麼lol – Chris

+2

你可以添加更多的示例代碼嗎?我想我明白你在這個例子中駕駛的東西,但它仍然沒有點擊我。像,「deltaTime」從哪裏來?你會在一個循環中完成嗎? – bitops

24

這是我的整個Android Media Player的處理程序類。看看play()和pause()函數。兩者都包含淡化與否的能力。 updateVolume()函數是讓聲音線性增加/減少的關鍵。

package com.stackoverflow.utilities; 

import java.io.File; 
import java.util.Timer; 
import java.util.TimerTask; 

import android.content.Context; 
import android.media.MediaPlayer; 
import android.net.Uri; 

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

這是一個非常好的類sngreco。

爲了更完整,我會添加停止()功能停止與淡入淡出播放,並stopAndRelease()停止播放並釋放資源安全,當你調用活動的方法非常有用使用像onStop()或onDestroy()。

兩種方法:

public void stop(int fadeDuration) 
{ 
    try { 
     // 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 
         mediaPlayer.stop(); 
         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); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

public void stopAndRelease(int fadeDuration) { 
    try { 
     final Timer timer = new Timer(true); 
     TimerTask timerTask = new TimerTask() 
     { 
      @Override 
      public void run() 
      { 
       updateVolume(-1); 
       if (iVolume == INT_VOLUME_MIN) 
       { 
        // Stop and Release player after Pause music 
        mediaPlayer.stop(); 
        mediaPlayer.release(); 
        timer.cancel(); 
        timer.purge(); 
       } 
      } 
     }; 

     timer.schedule(timerTask, fadeDuration); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
3

我一直在此我希望它能幫助:d:

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

如果ii想要同時使用FadeOut和FadeIn,該怎麼辦。我的意思是我正在播放一首歌曲,然後我按下淡出按鈕,然後在播放音量增加的同時下一首歌曲使音量慢慢下降。當第一首歌曲音量變爲0時停止,第二首歌曲繼續播放。 –

相關問題