Android音乐播放声音淡入淡出的实现
思路: 调用如下API接口
MediaPlayer.setVolume(left, right);// 左右声道,值为0~1
比如,让音量从 0 增加到100%,分为10次增加,则可以调10次上面的接口(每次间隔0.2秒,一共2秒内音量增加到100%),如下所示:
MediaPlayer.setVolume(0.1, 0.1); MediaPlayer.setVolume(0.2, 0.2); MediaPlayer.setVolume(0.3, 0.3); ... MediaPlayer.setVolume(1.0, 1.0); // 音量100%
实现方式一,通过 android.os.Handler 发送 android.os.Message 消息,代码如下:
import android.os.Handler; import android.os.Message; public class MuteVolumeManager { // action private static final int ACTION_RESTORE_VALUE = 1000; private static final int ACTION_STOP_VALUE = 1001; // 淡出与淡出时间 private int restoreTime = 5000; // 恢复 淡入时间为5秒 private int stopTime = 1000; // 静音 淡出时间为1秒 private float muteCurVolume = 0f; private float muteTargetVolume = 0f; private float unMuteCurVolume = 0f; private float unMuteTargetVolume = 0f; private boolean isMuteing = false; private boolean isUnMuteing = false; // listenter private VolumeListenter volumeListenter; // handler control private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == ACTION_RESTORE_VALUE) { if (muteCurVolume < muteTargetVolume) { muteCurVolume += 0.1f; if (muteCurVolume > 1) { muteCurVolume = 1; } // Logger.d("siven","实时恢复音量 " + muteCurVolume); if (muteCurVolume < muteTargetVolume) { notifyVolumeChange(muteCurVolume);// 最大1.0,是个百分比 handler.sendEmptyMessageDelayed(ACTION_RESTORE_VALUE, restoreTime / 10); } else { muteCurVolume = muteTargetVolume; notifyVolumeChange(muteCurVolume);// 最大1.0,是个百分比 if (volumeListenter != null && isUnMuteing) volumeListenter.onCompleteUnMute(muteCurVolume); isUnMuteing = false; } } else if (muteCurVolume >= muteTargetVolume) { notifyVolumeChange(muteTargetVolume); //最大1.0,是个百分比 // Logger.d("siven","实时恢复音量 " + muteTargetVolume); if (volumeListenter != null && isUnMuteing) volumeListenter.onCompleteUnMute(muteCurVolume); isUnMuteing = false; } } else if (msg.what == ACTION_STOP_VALUE) { if (unMuteCurVolume > unMuteTargetVolume) { unMuteCurVolume -= 0.1; if (unMuteCurVolume < 0) { unMuteCurVolume = 0; } notifyVolumeChange(unMuteCurVolume); // Logger.d("siven","实时静音音量 " + unMuteCurVolume); if (unMuteCurVolume > unMuteTargetVolume) { handler.sendEmptyMessageDelayed(ACTION_STOP_VALUE, stopTime / 10);//0.5秒恢复音量100%音量 } else { if (volumeListenter != null && isMuteing) volumeListenter.onCompleteMute(unMuteCurVolume); isMuteing = false; } } else { notifyVolumeChange(0f);//静音 if (volumeListenter != null && isMuteing) volumeListenter.onCompleteMute(unMuteCurVolume); isMuteing = false; } } } }; public void setVolumeListenter(VolumeListenter volumeListenter) { this.volumeListenter = volumeListenter; } /** * 恢复音量,淡入效果 */ public void unMute(float curVolume, float tagetVolume) { if (isUnMuteing) return; isUnMuteing = true; this.muteTargetVolume = tagetVolume; this.muteCurVolume = curVolume; handler.sendEmptyMessage(ACTION_RESTORE_VALUE); } /** * 静音,淡出效果 */ public void mute(float curVolume) { if (isMuteing) return; isMuteing = true; this.unMuteCurVolume = curVolume; this.unMuteTargetVolume = 0f; handler.sendEmptyMessage(ACTION_STOP_VALUE); } private void notifyVolumeChange(float volume) { if (volumeListenter != null) { volumeListenter.onVolumeChange(volume); } } public interface VolumeListenter { void onCompleteMute(float curVolume); void onCompleteUnMute(float curVolume); void onVolumeChange(float volume); } }
调用方法示例如下:
mMediaPlayer.start(); setVolumeFade(mMediaPlayer); mMediaPlayer.setVolume(0f, 0f); volumeManager.unMute(0f, 1f); private void setVolumeFade(final IjkMediaPlayer mediaPlayer) { volumeManager.setVolumeListenter(new MuteVolumeManager.VolumeListenter() { public void onCompleteMute(float curVolume) { Log.i("siven", "静音完成,当前音量为: " + curVolume); } public void onCompleteUnMute(float curVolume) { Log.i("siven", "恢复音量完成,当前音量为: " + curVolume); } public void onVolumeChange(float volume) { if (mediaPlayer != null) { // 动态设置音量 mediaPlayer.setVolume(volume, volume); } } }); }
实现方式二,使用 android.animation.ValueAnimator 淡入淡出工具类,如下:
import android.animation.Animator; import android.animation.ValueAnimator; import android.media.MediaPlayer; import android.support.annotation.Nullable; import android.view.animation.LinearInterpolator; /** * 音量淡入 */ public class FadeIn { public static void volumeGradient(final MediaPlayer mediaPlayer, final float from, final float to) { ValueAnimator animator = ValueAnimator.ofFloat(from, to); animator.setDuration(6000); // 淡入时间 animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator it) { float volume = (float) it.getAnimatedValue(); try { // 此时可能 mediaPlayer 状态发生了改变 //,所以用try catch包裹,一旦发生错误,立马取消 mediaPlayer.setVolume(volume, volume); } catch (Exception e) { it.cancel(); } } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { // mediaPlayer.setVolume(from, from); // if (doneCallBack != null) { // doneCallBack.onComplete(); // } } @Override public void onAnimationCancel(Animator animation) { // try { // mediaPlayer.setVolume(from, from); // } catch (Exception e) { // //忽略 // } } @Override public void onAnimationRepeat(Animator animation) { } }); animator.start(); } }
调用方法如下:
FadeIn.volumeGradient(mMediaPlayer, 0f, 1f);
推荐使用第二种方式。