Android Studio Mediaplayer如何淡入淡出
Android Studio Mediaplayer how to fade in and out
我正在 android 工作室使用媒体播放器 class。我只是想淡出一种声音并淡入另一种声音,而不是使用 setVolume(0,0) 和 setVolume(1,1)。
我为此创建了两个媒体播放器,似乎我在这个线程中找到了解决方案:Android: How to create fade-in/fade-out sound effects for any music file that my app plays?但我不知道如何使用 deltaTime。
还有一些其他的解决方案,我几乎看不懂。难道没有一种简单的方法可以让两个媒体播放器交叉淡入淡出,我无法想象还没有人需要这个,或者每个人都使用强迫代码来实现它。我应该如何使用 deltaTime?
查看链接 example,您必须在循环中调用 fadeIn()/fadeOut(),以 increase/decrease 一段时间内的音量。 deltaTime 将是循环每次迭代之间的时间。
您必须在与主 UI 线程不同的线程中执行此操作,以免阻塞它并导致您的应用程序崩溃。您可以通过将此循环放在新的 Thread/Runnable/Timer.
中来做到这一点
这是我的淡入示例(您可以对淡出做类似的事情):
float volume = 0;
private void startFadeIn(){
final int FADE_DURATION = 3000; //The duration of the fade
//The amount of time between volume changes. The smaller this is, the smoother the fade
final int FADE_INTERVAL = 250;
final int MAX_VOLUME = 1; //The volume will increase from 0 to 1
int numberOfSteps = FADE_DURATION/FADE_INTERVAL; //Calculate the number of fade steps
//Calculate by how much the volume changes each step
final float deltaVolume = MAX_VOLUME / (float)numberOfSteps;
//Create a new Timer and Timer task to run the fading outside the main UI thread
final Timer timer = new Timer(true);
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
fadeInStep(deltaVolume); //Do a fade step
//Cancel and Purge the Timer if the desired volume has been reached
if(volume>=1f){
timer.cancel();
timer.purge();
}
}
};
timer.schedule(timerTask,FADE_INTERVAL,FADE_INTERVAL);
}
private void fadeInStep(float deltaVolume){
mediaPlayer.setVolume(volume, volume);
volume += deltaVolume;
}
我不会使用两个单独的 MediaPlayer 对象,在您的情况下,我会只使用一个并在淡入淡出之间交换轨道。
示例:
**Audio track #1 is playing but coming to the end**
startFadeOut();
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.setDataSource(context,audiofileUri);
mediaPlayer.prepare();
mediaPlayer.start();
startFadeIn();
**Audio track #2 has faded in and is now playing**
希望这能解决您的问题。
这是淡出代码,以防它可以节省一些人的时间。
这还包括用于从内存中释放 MediaPlayer 的 stopPlayer() 函数。这是一个很好的做法。
// Set to the volume of the MediaPlayer
float volume = 1;
private void startFadeOut(){
// The duration of the fade
final int FADE_DURATION = 3000;
// The amount of time between volume changes. The smaller this is, the smoother the fade
final int FADE_INTERVAL = 250;
// Calculate the number of fade steps
int numberOfSteps = FADE_DURATION / FADE_INTERVAL;
// Calculate by how much the volume changes each step
final float deltaVolume = volume / numberOfSteps;
// Create a new Timer and Timer task to run the fading outside the main UI thread
final Timer timer = new Timer(true);
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
//Do a fade step
fadeOutStep(deltaVolume);
//Cancel and Purge the Timer if the desired volume has been reached
if(volume <= 0){
timer.cancel();
timer.purge();
stopPlayer();
}
}
};
timer.schedule(timerTask,FADE_INTERVAL,FADE_INTERVAL);
}
private void fadeOutStep(float deltaVolume){
player.setVolume(volume, volume);
volume -= deltaVolume;
}
// Release the player from memory
private void stopPlayer() {
if (player != null) {
player.release();
player = null;
}
}
在 API 级别 26 (https://developer.android.com/guide/topics/media/volumeshaper) 中添加了 VolumeShaper class。
这是音量输出和输入的示例,您可以调整淡入或淡出速度(斜坡),向时间和音量数组添加更多点。
时间点必须从 0 开始到 1 结束,它们是音量上升的相对时间。
fun fadeOutConfig(duration: Long): VolumeShaper.Configuration {
val times = floatArrayOf(0f, 1f) // can add more points, volume points must correspond to time points
val volumes = floatArrayOf(1f, 0f)
return VolumeShaper.Configuration.Builder()
.setDuration(duration)
.setCurve(times, volumes)
.setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC)
.build()
}
fun fadeInConfig(duration: Long): VolumeShaper.Configuration {
val times = floatArrayOf(0f, 1f) // can add more points, volume points must correspond to time points
val volumes = floatArrayOf(0f, 1f)
return VolumeShaper.Configuration.Builder()
.setDuration(duration)
.setCurve(times, volumes)
.setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC)
.build()
}
fun fadeInOrOutAudio(mediaPlayer: MediaPlayer, duration: Long, out: Boolean) {
val config = if (out) fadeOutConfig(duration) else fadeInConfig(duration)
val volumeShaper = mediaPlayer.createVolumeShaper(config)
volumeShaper.apply(VolumeShaper.Operation.PLAY)
}
private void fadeOut() {
final long steps = 30;
final double stepWidth = (double) 1 / steps;
mFadeOutCriteria = 1;
handler.postDelayed(new Runnable() {
@Override
public void run() {
mFadeOutCriteria -= stepWidth;
mediaPlayer.setVolume(mFadeOutCriteria, mFadeOutCriteria);
if (mFadeOutCriteria <= 0) {
mediaPlayer.stop();
nextrunq();
mFadeOutCriteria = 0;
handler.removeCallbacks(this);
} else
handler.postDelayed(this, 100);
}
}, 100);
}
我正在 android 工作室使用媒体播放器 class。我只是想淡出一种声音并淡入另一种声音,而不是使用 setVolume(0,0) 和 setVolume(1,1)。
我为此创建了两个媒体播放器,似乎我在这个线程中找到了解决方案:Android: How to create fade-in/fade-out sound effects for any music file that my app plays?但我不知道如何使用 deltaTime。
还有一些其他的解决方案,我几乎看不懂。难道没有一种简单的方法可以让两个媒体播放器交叉淡入淡出,我无法想象还没有人需要这个,或者每个人都使用强迫代码来实现它。我应该如何使用 deltaTime?
查看链接 example,您必须在循环中调用 fadeIn()/fadeOut(),以 increase/decrease 一段时间内的音量。 deltaTime 将是循环每次迭代之间的时间。
您必须在与主 UI 线程不同的线程中执行此操作,以免阻塞它并导致您的应用程序崩溃。您可以通过将此循环放在新的 Thread/Runnable/Timer.
中来做到这一点这是我的淡入示例(您可以对淡出做类似的事情):
float volume = 0;
private void startFadeIn(){
final int FADE_DURATION = 3000; //The duration of the fade
//The amount of time between volume changes. The smaller this is, the smoother the fade
final int FADE_INTERVAL = 250;
final int MAX_VOLUME = 1; //The volume will increase from 0 to 1
int numberOfSteps = FADE_DURATION/FADE_INTERVAL; //Calculate the number of fade steps
//Calculate by how much the volume changes each step
final float deltaVolume = MAX_VOLUME / (float)numberOfSteps;
//Create a new Timer and Timer task to run the fading outside the main UI thread
final Timer timer = new Timer(true);
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
fadeInStep(deltaVolume); //Do a fade step
//Cancel and Purge the Timer if the desired volume has been reached
if(volume>=1f){
timer.cancel();
timer.purge();
}
}
};
timer.schedule(timerTask,FADE_INTERVAL,FADE_INTERVAL);
}
private void fadeInStep(float deltaVolume){
mediaPlayer.setVolume(volume, volume);
volume += deltaVolume;
}
我不会使用两个单独的 MediaPlayer 对象,在您的情况下,我会只使用一个并在淡入淡出之间交换轨道。 示例:
**Audio track #1 is playing but coming to the end**
startFadeOut();
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.setDataSource(context,audiofileUri);
mediaPlayer.prepare();
mediaPlayer.start();
startFadeIn();
**Audio track #2 has faded in and is now playing**
希望这能解决您的问题。
这是淡出代码,以防它可以节省一些人的时间。
这还包括用于从内存中释放 MediaPlayer 的 stopPlayer() 函数。这是一个很好的做法。
// Set to the volume of the MediaPlayer
float volume = 1;
private void startFadeOut(){
// The duration of the fade
final int FADE_DURATION = 3000;
// The amount of time between volume changes. The smaller this is, the smoother the fade
final int FADE_INTERVAL = 250;
// Calculate the number of fade steps
int numberOfSteps = FADE_DURATION / FADE_INTERVAL;
// Calculate by how much the volume changes each step
final float deltaVolume = volume / numberOfSteps;
// Create a new Timer and Timer task to run the fading outside the main UI thread
final Timer timer = new Timer(true);
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
//Do a fade step
fadeOutStep(deltaVolume);
//Cancel and Purge the Timer if the desired volume has been reached
if(volume <= 0){
timer.cancel();
timer.purge();
stopPlayer();
}
}
};
timer.schedule(timerTask,FADE_INTERVAL,FADE_INTERVAL);
}
private void fadeOutStep(float deltaVolume){
player.setVolume(volume, volume);
volume -= deltaVolume;
}
// Release the player from memory
private void stopPlayer() {
if (player != null) {
player.release();
player = null;
}
}
在 API 级别 26 (https://developer.android.com/guide/topics/media/volumeshaper) 中添加了 VolumeShaper class。 这是音量输出和输入的示例,您可以调整淡入或淡出速度(斜坡),向时间和音量数组添加更多点。 时间点必须从 0 开始到 1 结束,它们是音量上升的相对时间。
fun fadeOutConfig(duration: Long): VolumeShaper.Configuration {
val times = floatArrayOf(0f, 1f) // can add more points, volume points must correspond to time points
val volumes = floatArrayOf(1f, 0f)
return VolumeShaper.Configuration.Builder()
.setDuration(duration)
.setCurve(times, volumes)
.setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC)
.build()
}
fun fadeInConfig(duration: Long): VolumeShaper.Configuration {
val times = floatArrayOf(0f, 1f) // can add more points, volume points must correspond to time points
val volumes = floatArrayOf(0f, 1f)
return VolumeShaper.Configuration.Builder()
.setDuration(duration)
.setCurve(times, volumes)
.setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC)
.build()
}
fun fadeInOrOutAudio(mediaPlayer: MediaPlayer, duration: Long, out: Boolean) {
val config = if (out) fadeOutConfig(duration) else fadeInConfig(duration)
val volumeShaper = mediaPlayer.createVolumeShaper(config)
volumeShaper.apply(VolumeShaper.Operation.PLAY)
}
private void fadeOut() {
final long steps = 30;
final double stepWidth = (double) 1 / steps;
mFadeOutCriteria = 1;
handler.postDelayed(new Runnable() {
@Override
public void run() {
mFadeOutCriteria -= stepWidth;
mediaPlayer.setVolume(mFadeOutCriteria, mFadeOutCriteria);
if (mFadeOutCriteria <= 0) {
mediaPlayer.stop();
nextrunq();
mFadeOutCriteria = 0;
handler.removeCallbacks(this);
} else
handler.postDelayed(this, 100);
}
}, 100);
}