您的位置:首页 > 移动开发 > Android开发

Android MediaPlayer 声音渐强渐弱效果实现

2017-02-10 22:01 609 查看

Android MediaPlayer 声音渐强渐弱效果实现

1.需求描述

最近公司产品需要提高用户体验:当播放语音消息时,如果当前正在播放其他音频文件,则有一个声音逐渐降低直至暂停的效果;当播放语音消息完成后,则恢复先前的音频,继续播放,且有一个声音逐渐增大到原先音量的效果。

2.解决方案

在网上 Google 了一下,方法都是一样的:创建一个线程,不断循环逐步调节系统音量到最低,然后停止播放,核心代码大概长这样:

final int volume = audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
new Thread(){
@Override
public void run() {
super.run();
for (int i=1; i<= volume; i++) {
audioManager.setStreamVolume(AudioManager.STREAM_ALARM, i, 0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}.start();


我们觉得这套方案不够高效,可以稍微变通一下:不需要调用系统的 setStreamVolume() 方法,是直接调用 MediaPlayer 自带的 setVolume() 方法调节音量,使用系统自带的定时器 CountDownTimer 实现循环调节音量大小。

核心代码大概是这样:

//渐强的时长,单位:毫秒;默认2秒
final long duration = 2000;
//音量调节的时间间隔
long interval = duration / 10;
new CountDownTimer(duration, interval){

@Override
public void onTick(long millisUntilFinished) {
float volume = 1f - millisUntilFinished * 1.0f / duration;
mediaPlayer.setVolume(volume, volume);
}

@Override
public void onFinish() {
mediaPlayer.setVolume(1f, 1f);
}
}.start();


抱歉,最近一直在使用kotlin,即使现在也是半灌水,但 java 也不太习惯了,泪崩啊~~,下面是 kotlin 版本的代码:

/**
* 声音渐弱
*
* @param duration  渐弱的时长,单位:毫秒;默认2秒
* @param completed 完成回调
*/
fun fadeIn(duration: Long = 2000, completed: () -> Unit = {}) {
object : CountDownTimer(duration, duration / 10) {
override fun onFinish() {
mediaPlayer?.setVolume(0f, 0f)
mediaPlayer?.pause()
completed()
}

override fun onTick(millisUntilFinished: Long) {
val volume = millisUntilFinished * 1.0f / duration
mediaPlayer?.setVolume(volume, volume)
info("player controller fade in volume = $volume")
}
}.start()
}

/**
* 声音渐强
*
* @param duration  渐强的时长,单位:毫秒;默认2秒
* @param completed 完成回调
*/
fun fadeOut(duration: Long = 2000, completed: () -> Unit = {}) {
object : CountDownTimer(duration, duration / 10) {
override fun onFinish() {
mediaPlayer?.setVolume(1f, 1f)
completed()
}

override fun onTick(millisUntilFinished: Long) {
val volume = 1f - millisUntilFinished * 1.0f / duration
mediaPlayer?.setVolume(volume, volume)
}
}.start()
mediaPlayer?.start()
}


这里需要解释一下 MediaPlayer 自带的音量设置方法 setVolume() 中的参数问题:android 系统将音量从 [0~当前音量] 缩放(scale)到 [0f~1f] 的区间,所以设置音量的参数也是从 0 到 1,最大音量为当前系统音量。

3.总结

虽然代码很简单,但是还是很费心思的,希望大家都来围观,从此养成写 blog 的好习惯。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息