首页 > 系统 > Android > 正文

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

2019-11-09 14:36:21
字体:
来源:转载
供稿:网友

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 的好习惯。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表