我正在开发一个音乐流媒体应用程序,它必须具有交叉渐变功能,例如当第一首歌结束时有5秒时它应该开始消失,下一首歌应该在同一时刻开始消失,这样片刻就会有两首音轨同时播放。
我试图使用两个MediaPlayer对象但总是只有一个播放。如果我只播放一首曲目,淡出和淡入效果的效果非常好。
我在这个runnable中检查何时开始交叉淡入淡出:
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long totalDuration = 0;
long currentDuration = 0;
if(musicPlayer.isPlaying()) {
totalDuration = musicPlayer.getDuration();
currentDuration = musicPlayer.getCurrentPosition();
// Updating progress bar
int progress = (utils.getProgressPercentage(currentDuration, totalDuration));
trackPb.setProgress(progress);
if (!trackDownloaded && currentDuration > 100) {
Log.i(TagsContainer.MUSIC_PLAYER_TAG,"next track download started");
trackDownloaded = true;
new TrackLoader().execute();
}
long crossFadeValue = currentDuration + CROSSFADE_DURATION;
if (crossFadeValue > totalDuration && !fadeStarted && currentDuration > 100) {
fadeStarted = true;
crossFade();
}
// Running this thread after 100 milliseconds
}
mHandler.postDelayed(this, 100);
}
};
Crossfade的功能如下:
private void crossFade() {
fadeOut(musicPlayer, CROSSFADE_DURATION);
fadeIn(musicPlayer2, CROSSFADE_DURATION);
}
public 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 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)
}