2011-07-30 29 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时停止,第二首歌曲继续播放。 –

相关问题