Reduce calls to mediaplayer objects

This commit is contained in:
Adrian Ulrich 2015-05-01 11:31:12 +02:00
parent 411db0bc91
commit f934160914
2 changed files with 69 additions and 23 deletions

View File

@ -669,27 +669,57 @@ public final class PlaybackService extends Service
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
return; /* setNextMediaPlayer is supported since JB */ return; /* setNextMediaPlayer is supported since JB */
// Reset any preparations boolean doGapless = false;
mMediaPlayer.setNextMediaPlayer(null);
mPreparedMediaPlayer.reset();
int fa = finishAction(mState); int fa = finishAction(mState);
Song nextSong = getSong(1); Song nextSong = getSong(1);
if( nextSong != null if( nextSong != null
&& fa != SongTimeline.FINISH_REPEAT_CURRENT && nextSong.path != null
&& fa != SongTimeline.FINISH_STOP_CURRENT && fa != SongTimeline.FINISH_REPEAT_CURRENT
&& !mTimeline.isEndOfQueue() ) { && fa != SongTimeline.FINISH_STOP_CURRENT
try { && !mTimeline.isEndOfQueue() ) {
prepareMediaPlayer(mPreparedMediaPlayer, nextSong.path); doGapless = true;
mMediaPlayer.setNextMediaPlayer(mPreparedMediaPlayer);
Log.d("VanillaMusic", "New media player prepared with path "+nextSong.path);
} catch (IOException e) {
Log.e("VanillaMusic", "IOException", e);
}
} }
else { else {
Log.d("VanillaMusic", "Must not create new media player object"); Log.d("VanillaMusic", "Must not create new media player object");
} }
Log.v("VanillaMusic", "A>> hasNext="+mMediaPlayer.hasNextMediaPlayer()+", ds="+mMediaPlayer.getDataSource()+", class="+mMediaPlayer);
Log.v("VanillaMusic", "P>> hasNext="+mPreparedMediaPlayer.hasNextMediaPlayer()+", ds="+mPreparedMediaPlayer.getDataSource()+", class="+mPreparedMediaPlayer);
if(doGapless == true) {
try {
if(nextSong.path.equals(mPreparedMediaPlayer.getDataSource()) == false) {
// Prepared MP has a different data source: We need to re-initalize
// it and set it as the next MP for the active media player
Log.v("VanillaMusic", "GAPLESS: SETTING "+nextSong.path);
mPreparedMediaPlayer.reset();
prepareMediaPlayer(mPreparedMediaPlayer, nextSong.path);
mMediaPlayer.setNextMediaPlayer(mPreparedMediaPlayer);
}
if(mMediaPlayer.hasNextMediaPlayer() == false) {
// We can reuse the prepared MediaPlayer but the current instance lacks
// a link to it
Log.v("VanillaMusic", "SETTING NEXT MP as in "+mPreparedMediaPlayer.getDataSource());
mMediaPlayer.setNextMediaPlayer(mPreparedMediaPlayer);
}
} catch (IOException e) {
Log.v("VanillaMusic", "triggerGaplessUpdate() failed with exception "+e);
mMediaPlayer.setNextMediaPlayer(null);
mPreparedMediaPlayer.reset();
}
} else {
if(mMediaPlayer.hasNextMediaPlayer()) {
Log.v("VanillaMusic", "UNCONFIGURING NEW MEDIA PLAYER");
mMediaPlayer.setNextMediaPlayer(null);
// There is no need to cleanup mPreparedMediaPlayer
}
}
Log.v("VanillaMusic", "A<< hasNext="+mMediaPlayer.hasNextMediaPlayer()+", ds="+mMediaPlayer.getDataSource()+", class="+mMediaPlayer);
Log.v("VanillaMusic", "P<< hasNext="+mPreparedMediaPlayer.hasNextMediaPlayer()+", ds="+mPreparedMediaPlayer.getDataSource()+", class="+mPreparedMediaPlayer);
} }
/** /**
@ -1180,10 +1210,12 @@ public final class PlaybackService extends Service
mMediaPlayer.reset(); mMediaPlayer.reset();
if(mPreparedMediaPlayer.isPlaying()) { if(mPreparedMediaPlayer.isPlaying()) {
// The prepared media player is playing as the previous song
// reched its end 'naturally' (-> gapless)
// We can now swap mPreparedMediaPlayer and mMediaPlayer
VanillaMediaPlayer tmpPlayer = mMediaPlayer; VanillaMediaPlayer tmpPlayer = mMediaPlayer;
mMediaPlayer = mPreparedMediaPlayer; mMediaPlayer = mPreparedMediaPlayer;
mPreparedMediaPlayer = tmpPlayer; mPreparedMediaPlayer = tmpPlayer; // this was mMediaPlayer and is in reset() state
mPreparedMediaPlayer.reset();
Log.v("VanillaMusic", "Swapped media players"); Log.v("VanillaMusic", "Swapped media players");
} }
else if(song.path != null) { else if(song.path != null) {
@ -1658,7 +1690,7 @@ public final class PlaybackService extends Service
// This might get canceled if setCurrentSong() also fired a call // This might get canceled if setCurrentSong() also fired a call
// to processSong(); // to processSong();
mHandler.removeMessages(GAPLESS_UPDATE); mHandler.removeMessages(GAPLESS_UPDATE);
mHandler.sendEmptyMessageDelayed(GAPLESS_UPDATE, 500); mHandler.sendEmptyMessageDelayed(GAPLESS_UPDATE, 100);
ArrayList<PlaybackActivity> list = sActivities; ArrayList<PlaybackActivity> list = sActivities;
for (int i = list.size(); --i != -1; ) for (int i = list.size(); --i != -1; )

View File

@ -26,13 +26,12 @@ import android.media.audiofx.AudioEffect;
import java.io.IOException; import java.io.IOException;
import android.util.Log;
public class VanillaMediaPlayer extends MediaPlayer { public class VanillaMediaPlayer extends MediaPlayer {
private Context mContext; private Context mContext;
private String mDataSource; private String mDataSource;
private boolean mHasNextMediaPlayer;
private int mClaimedAudioSessionId = 0; private int mClaimedAudioSessionId = 0;
/** /**
@ -49,6 +48,7 @@ public class VanillaMediaPlayer extends MediaPlayer {
*/ */
public void reset() { public void reset() {
mDataSource = null; mDataSource = null;
mHasNextMediaPlayer = false;
super.reset(); super.reset();
} }
@ -58,6 +58,7 @@ public class VanillaMediaPlayer extends MediaPlayer {
public void release() { public void release() {
_releaseAudioSession(); _releaseAudioSession();
mDataSource = null; mDataSource = null;
mHasNextMediaPlayer = false;
super.release(); super.release();
} }
@ -77,12 +78,27 @@ public class VanillaMediaPlayer extends MediaPlayer {
return mDataSource; return mDataSource;
} }
/**
* Sets the next media player data source
*/
public void setNextMediaPlayer(VanillaMediaPlayer next) {
super.setNextMediaPlayer(next);
mHasNextMediaPlayer = (next != null);
}
/**
* Returns true if a 'next' media player has been configured
* via setNextMediaPlayer(next)
*/
public boolean hasNextMediaPlayer() {
return mHasNextMediaPlayer;
}
/** /**
* Creates a new AudioEffect for our AudioSession * Creates a new AudioEffect for our AudioSession
*/ */
private void _claimAudioSession() { private void _claimAudioSession() {
// No active audio session -> claim one // No active audio session -> claim one
Log.v("VanillaMusic", "_claimAudioSession() -> "+mClaimedAudioSessionId+" -> "+this);
if (mClaimedAudioSessionId == 0) { if (mClaimedAudioSessionId == 0) {
mClaimedAudioSessionId = this.getAudioSessionId(); mClaimedAudioSessionId = this.getAudioSessionId();
Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
@ -96,8 +112,6 @@ public class VanillaMediaPlayer extends MediaPlayer {
* Releases a previously claimed audio session id * Releases a previously claimed audio session id
*/ */
private void _releaseAudioSession() { private void _releaseAudioSession() {
Log.v("VanillaMusic", "_releaseAudioSession() "+mClaimedAudioSessionId+" -> "+this);
if (mClaimedAudioSessionId != 0) { if (mClaimedAudioSessionId != 0) {
Intent i = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); Intent i = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mClaimedAudioSessionId); i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mClaimedAudioSessionId);