Clean ups.
This commit is contained in:
parent
a5f8cc71c5
commit
34f8ffbaf2
3 changed files with 175 additions and 85 deletions
|
|
@ -1,11 +1,11 @@
|
|||
package com.kabouzeid.gramophone.service;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.audiofx.AudioEffect;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
|
@ -13,32 +13,30 @@ import android.util.Log;
|
|||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.service.Playback.Playback;
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* @author Andrew Neal, Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
||||
MediaPlayer.OnCompletionListener {
|
||||
public class MultiPlayer implements Playback, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
|
||||
public static final String TAG = MultiPlayer.class.getSimpleName();
|
||||
|
||||
private final WeakReference<MusicService> mService;
|
||||
private DoubleMediaPlayer mCurrentMediaPlayer = new DoubleMediaPlayer();
|
||||
private DoubleMediaPlayer mNextMediaPlayer;
|
||||
|
||||
private MediaPlayer mCurrentMediaPlayer = new MediaPlayer();
|
||||
private MediaPlayer mNextMediaPlayer;
|
||||
|
||||
private Handler mHandler;
|
||||
private Context context;
|
||||
@Nullable
|
||||
private Playback.PlaybackCallbacks callbacks;
|
||||
|
||||
private boolean mIsInitialized = false;
|
||||
|
||||
/**
|
||||
* Constructor of <code>MultiPlayer</code>
|
||||
*/
|
||||
public MultiPlayer(final MusicService service) {
|
||||
mService = new WeakReference<>(service);
|
||||
mCurrentMediaPlayer.setWakeMode(service, PowerManager.PARTIAL_WAKE_LOCK);
|
||||
public MultiPlayer(final Context context) {
|
||||
this.context = context;
|
||||
mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -47,6 +45,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
* @return True if the <code>player</code> has been prepared and is
|
||||
* ready to play, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean setDataSource(@NonNull final String path) {
|
||||
mIsInitialized = false;
|
||||
mIsInitialized = setDataSourceImpl(mCurrentMediaPlayer, path);
|
||||
|
|
@ -64,15 +63,14 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
* ready to play, false otherwise
|
||||
*/
|
||||
private boolean setDataSourceImpl(@NonNull final MediaPlayer player, @NonNull final String path) {
|
||||
MusicService service = mService.get();
|
||||
if (service == null) {
|
||||
if (context == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
player.reset();
|
||||
player.setOnPreparedListener(null);
|
||||
if (path.startsWith("content://")) {
|
||||
player.setDataSource(service, Uri.parse(path));
|
||||
player.setDataSource(context, Uri.parse(path));
|
||||
} else {
|
||||
player.setDataSource(path);
|
||||
}
|
||||
|
|
@ -85,9 +83,9 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
player.setOnErrorListener(this);
|
||||
final Intent intent = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
|
||||
intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, getAudioSessionId());
|
||||
intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, service.getPackageName());
|
||||
intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.getPackageName());
|
||||
intent.putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC);
|
||||
service.sendBroadcast(intent);
|
||||
context.sendBroadcast(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -97,9 +95,9 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
* @param path The path of the file, or the http/rtsp URL of the stream
|
||||
* you want to play
|
||||
*/
|
||||
@Override
|
||||
public void setNextDataSource(@Nullable final String path) {
|
||||
MusicService service = mService.get();
|
||||
if (service == null) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
|
@ -117,9 +115,9 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
if (path == null) {
|
||||
return;
|
||||
}
|
||||
if (PreferenceUtil.getInstance(mService.get()).gaplessPlayback()) {
|
||||
mNextMediaPlayer = new MediaPlayer();
|
||||
mNextMediaPlayer.setWakeMode(mService.get(), PowerManager.PARTIAL_WAKE_LOCK);
|
||||
if (PreferenceUtil.getInstance(context).gaplessPlayback()) {
|
||||
mNextMediaPlayer = new DoubleMediaPlayer();
|
||||
mNextMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
|
||||
mNextMediaPlayer.setAudioSessionId(getAudioSessionId());
|
||||
if (setDataSourceImpl(mNextMediaPlayer, path)) {
|
||||
try {
|
||||
|
|
@ -141,17 +139,19 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the handler
|
||||
* Sets the callbacks
|
||||
*
|
||||
* @param handler The handler to use
|
||||
* @param callbacks The callbacks to use
|
||||
*/
|
||||
public void setHandler(final Handler handler) {
|
||||
mHandler = handler;
|
||||
@Override
|
||||
public void setCallbacks(final Playback.PlaybackCallbacks callbacks) {
|
||||
this.callbacks = callbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the player is ready to go, false otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return mIsInitialized;
|
||||
}
|
||||
|
|
@ -159,6 +159,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
/**
|
||||
* Starts or resumes playback.
|
||||
*/
|
||||
@Override
|
||||
public boolean start() {
|
||||
try {
|
||||
mCurrentMediaPlayer.start();
|
||||
|
|
@ -171,6 +172,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
/**
|
||||
* Resets the MediaPlayer to its uninitialized state.
|
||||
*/
|
||||
@Override
|
||||
public void stop() {
|
||||
mCurrentMediaPlayer.reset();
|
||||
mIsInitialized = false;
|
||||
|
|
@ -179,6 +181,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
/**
|
||||
* Releases resources associated with this MediaPlayer object.
|
||||
*/
|
||||
@Override
|
||||
public void release() {
|
||||
stop();
|
||||
mCurrentMediaPlayer.release();
|
||||
|
|
@ -190,6 +193,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
/**
|
||||
* Pauses playback. Call start() to resume.
|
||||
*/
|
||||
@Override
|
||||
public boolean pause() {
|
||||
try {
|
||||
mCurrentMediaPlayer.pause();
|
||||
|
|
@ -202,6 +206,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
/**
|
||||
* Checks whether the MultiPlayer is playing.
|
||||
*/
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return mIsInitialized && mCurrentMediaPlayer.isPlaying();
|
||||
}
|
||||
|
|
@ -211,6 +216,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
*
|
||||
* @return The duration in milliseconds
|
||||
*/
|
||||
@Override
|
||||
public int duration() {
|
||||
if (!mIsInitialized) {
|
||||
return -1;
|
||||
|
|
@ -227,6 +233,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
*
|
||||
* @return The current position in milliseconds
|
||||
*/
|
||||
@Override
|
||||
public int position() {
|
||||
if (!mIsInitialized) {
|
||||
return -1;
|
||||
|
|
@ -244,6 +251,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
* @param whereto The offset in milliseconds from the start to seek to
|
||||
* @return The offset in milliseconds from the start to seek to
|
||||
*/
|
||||
@Override
|
||||
public int seek(final int whereto) {
|
||||
try {
|
||||
mCurrentMediaPlayer.seekTo(whereto);
|
||||
|
|
@ -253,6 +261,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setVolume(final float vol) {
|
||||
try {
|
||||
mCurrentMediaPlayer.setVolume(vol, vol);
|
||||
|
|
@ -267,6 +276,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
*
|
||||
* @param sessionId The audio session ID
|
||||
*/
|
||||
@Override
|
||||
public boolean setAudioSessionId(final int sessionId) {
|
||||
try {
|
||||
mCurrentMediaPlayer.setAudioSessionId(sessionId);
|
||||
|
|
@ -281,6 +291,7 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
*
|
||||
* @return The current audio session ID.
|
||||
*/
|
||||
@Override
|
||||
public int getAudioSessionId() {
|
||||
return mCurrentMediaPlayer.getAudioSessionId();
|
||||
}
|
||||
|
|
@ -292,9 +303,11 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
public boolean onError(final MediaPlayer mp, final int what, final int extra) {
|
||||
mIsInitialized = false;
|
||||
mCurrentMediaPlayer.release();
|
||||
mCurrentMediaPlayer = new MediaPlayer();
|
||||
mCurrentMediaPlayer.setWakeMode(mService.get(), PowerManager.PARTIAL_WAKE_LOCK);
|
||||
Toast.makeText(mService.get(), mService.get().getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show();
|
||||
mCurrentMediaPlayer = new DoubleMediaPlayer();
|
||||
mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
|
||||
if (context != null) {
|
||||
Toast.makeText(context, context.getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -303,21 +316,46 @@ public class MultiPlayer implements MediaPlayer.OnErrorListener,
|
|||
*/
|
||||
@Override
|
||||
public void onCompletion(final MediaPlayer mp) {
|
||||
MusicService service = mService.get();
|
||||
if (service == null) {
|
||||
return;
|
||||
}
|
||||
if (mp == mCurrentMediaPlayer && mNextMediaPlayer != null) {
|
||||
mIsInitialized = false;
|
||||
mCurrentMediaPlayer.release();
|
||||
mCurrentMediaPlayer = mNextMediaPlayer;
|
||||
mIsInitialized = true;
|
||||
mNextMediaPlayer = null;
|
||||
mHandler.sendEmptyMessage(MusicService.TRACK_WENT_TO_NEXT);
|
||||
if (callbacks != null)
|
||||
callbacks.onTrackWentToNext();
|
||||
} else {
|
||||
service.acquireWakeLock(30000);
|
||||
mHandler.sendEmptyMessage(MusicService.TRACK_ENDED);
|
||||
mHandler.sendEmptyMessage(MusicService.RELEASE_WAKELOCK);
|
||||
if (callbacks != null)
|
||||
callbacks.onTrackEnded();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DoubleMediaPlayer extends MediaPlayer implements MediaPlayer.OnCompletionListener {
|
||||
private MediaPlayer mNextPlayer;
|
||||
|
||||
private OnCompletionListener mCompletion;
|
||||
|
||||
public DoubleMediaPlayer() {
|
||||
super.setOnCompletionListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextMediaPlayer(final MediaPlayer next) {
|
||||
mNextPlayer = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnCompletionListener(final OnCompletionListener listener) {
|
||||
mCompletion = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompletion(final MediaPlayer mp) {
|
||||
if (mNextPlayer != null) {
|
||||
// SystemClock.sleep(25);
|
||||
mNextPlayer.start();
|
||||
}
|
||||
mCompletion.onCompletion(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,6 +46,7 @@ import com.kabouzeid.gramophone.model.Song;
|
|||
import com.kabouzeid.gramophone.provider.HistoryStore;
|
||||
import com.kabouzeid.gramophone.provider.MusicPlaybackQueueStore;
|
||||
import com.kabouzeid.gramophone.provider.SongPlayCountStore;
|
||||
import com.kabouzeid.gramophone.service.Playback.Playback;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
|
|
@ -57,7 +58,7 @@ import java.util.List;
|
|||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid), Andrew Neal
|
||||
*/
|
||||
public class MusicService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
public class MusicService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener, Playback.PlaybackCallbacks {
|
||||
public static final String TAG = MusicService.class.getSimpleName();
|
||||
|
||||
public static final String PHONOGRAPH_PACKAGE_NAME = "com.kabouzeid.gramophone";
|
||||
|
|
@ -100,7 +101,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
private static final int UNDUCK = 7;
|
||||
private final IBinder musicBind = new MusicBinder();
|
||||
|
||||
private MultiPlayer player;
|
||||
private Playback playback;
|
||||
private ArrayList<Song> playingQueue = new ArrayList<>();
|
||||
private ArrayList<Song> originalPlayingQueue = new ArrayList<>();
|
||||
private int position = -1;
|
||||
|
|
@ -114,7 +115,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
@SuppressWarnings("deprecation")
|
||||
private RemoteControlClient remoteControlClient;
|
||||
private PowerManager.WakeLock wakeLock;
|
||||
private MusicPlayerHandler playerHandler;
|
||||
private PlaybackHandler playerHandler;
|
||||
private final AudioManager.OnAudioFocusChangeListener audioFocusListener = new AudioManager.OnAudioFocusChangeListener() {
|
||||
@Override
|
||||
public void onAudioFocusChange(final int focusChange) {
|
||||
|
|
@ -161,17 +162,15 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
|
||||
wakeLock.setReferenceCounted(false);
|
||||
|
||||
musicPlayerHandlerThread = new HandlerThread("MusicPlayerHandler",
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
musicPlayerHandlerThread = new HandlerThread("PlaybackHandler");
|
||||
musicPlayerHandlerThread.start();
|
||||
playerHandler = new MusicPlayerHandler(this, musicPlayerHandlerThread.getLooper());
|
||||
playerHandler = new PlaybackHandler(this, musicPlayerHandlerThread.getLooper());
|
||||
|
||||
player = new MultiPlayer(this);
|
||||
player.setHandler(playerHandler);
|
||||
playback = new MultiPlayer(this);
|
||||
playback.setCallbacks(this);
|
||||
|
||||
// queue saving needs to run on a separate thread so that it doesn't block the player handler events
|
||||
queueSaveHandlerThread = new HandlerThread("QueueSaveHandler",
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
// queue saving needs to run on a separate thread so that it doesn't block the playback handler events
|
||||
queueSaveHandlerThread = new HandlerThread("QueueSaveHandler", Process.THREAD_PRIORITY_BACKGROUND);
|
||||
queueSaveHandlerThread.start();
|
||||
queueSaveHandler = new QueueSaveHandler(this, queueSaveHandlerThread.getLooper());
|
||||
|
||||
|
|
@ -326,20 +325,20 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
} else {
|
||||
queueSaveHandlerThread.quit();
|
||||
}
|
||||
player.release();
|
||||
player = null;
|
||||
playback.release();
|
||||
playback = null;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
pausedByTransientLossOfFocus = false;
|
||||
savePositionInTrack();
|
||||
player.stop();
|
||||
playback.stop();
|
||||
notifyChange(PLAY_STATE_CHANGED);
|
||||
getAudioManager().abandonAudioFocus(audioFocusListener);
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
return player.isPlaying();
|
||||
return playback.isPlaying();
|
||||
}
|
||||
|
||||
public void saveState() {
|
||||
|
|
@ -369,17 +368,13 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
return position;
|
||||
}
|
||||
|
||||
private void setPositionInternal(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public void playNextSong(boolean force) {
|
||||
playSongAt(getNextPosition(force));
|
||||
}
|
||||
|
||||
private boolean openTrackAndPrepareNextAt(int position) {
|
||||
synchronized (this) {
|
||||
setPositionInternal(position);
|
||||
this.position = position;
|
||||
boolean prepared = openCurrent();
|
||||
if (prepared) prepareNextImpl();
|
||||
notifyChange(META_CHANGED);
|
||||
|
|
@ -391,7 +386,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
private boolean openCurrent() {
|
||||
synchronized (this) {
|
||||
try {
|
||||
return player.setDataSource(getTrackUri(getCurrentSong()));
|
||||
return playback.setDataSource(getTrackUri(getCurrentSong()));
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -407,7 +402,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
synchronized (this) {
|
||||
try {
|
||||
int nextPosition = getNextPosition(false);
|
||||
player.setNextDataSource(getTrackUri(getSongAt(nextPosition)));
|
||||
playback.setNextDataSource(getTrackUri(getSongAt(nextPosition)));
|
||||
this.nextPosition = nextPosition;
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
|
|
@ -418,7 +413,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
|
||||
private void closeAudioEffectSession() {
|
||||
final Intent audioEffectsIntent = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
|
||||
audioEffectsIntent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, player.getAudioSessionId());
|
||||
audioEffectsIntent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, playback.getAudioSessionId());
|
||||
audioEffectsIntent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getPackageName());
|
||||
sendBroadcast(audioEffectsIntent);
|
||||
}
|
||||
|
|
@ -606,7 +601,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
this.originalPlayingQueue = restoredOriginalQueue;
|
||||
this.playingQueue = restoredQueue;
|
||||
|
||||
setPositionInternal(restoredPosition);
|
||||
position = restoredPosition;
|
||||
openCurrent();
|
||||
prepareNext();
|
||||
|
||||
|
|
@ -668,7 +663,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
private void rePosition(int deletedPosition) {
|
||||
int currentPosition = getPosition();
|
||||
if (deletedPosition < currentPosition) {
|
||||
setPositionInternal(currentPosition - 1);
|
||||
position = currentPosition - 1;
|
||||
} else if (deletedPosition == currentPosition) {
|
||||
if (playingQueue.size() > deletedPosition) {
|
||||
setPosition(position);
|
||||
|
|
@ -688,11 +683,11 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
originalPlayingQueue.add(to, tmpSong);
|
||||
}
|
||||
if (from > currentPosition && to <= currentPosition) {
|
||||
setPositionInternal(currentPosition + 1);
|
||||
position = currentPosition + 1;
|
||||
} else if (from < currentPosition && to >= currentPosition) {
|
||||
setPositionInternal(currentPosition - 1);
|
||||
position = currentPosition - 1;
|
||||
} else if (from == currentPosition) {
|
||||
setPositionInternal(to);
|
||||
position = to;
|
||||
}
|
||||
notifyChange(QUEUE_CHANGED);
|
||||
}
|
||||
|
|
@ -727,8 +722,8 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
|
||||
public void pause() {
|
||||
pausedByTransientLossOfFocus = false;
|
||||
if (player.isPlaying()) {
|
||||
player.pause();
|
||||
if (playback.isPlaying()) {
|
||||
playback.pause();
|
||||
notifyChange(PLAY_STATE_CHANGED);
|
||||
}
|
||||
}
|
||||
|
|
@ -736,12 +731,12 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
public void play() {
|
||||
synchronized (this) {
|
||||
if (requestFocus()) {
|
||||
if (!player.isPlaying()) {
|
||||
if (!player.isInitialized()) {
|
||||
if (!playback.isPlaying()) {
|
||||
if (!playback.isInitialized()) {
|
||||
playSongAt(getPosition());
|
||||
} else {
|
||||
registerReceiversAndRemoteControlClient();
|
||||
player.start();
|
||||
playback.start();
|
||||
if (notHandledMetaChangedForCurrentTrack) {
|
||||
handleChange(META_CHANGED);
|
||||
notHandledMetaChangedForCurrentTrack = false;
|
||||
|
|
@ -795,15 +790,15 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
}
|
||||
|
||||
public int getSongProgressMillis() {
|
||||
return player.position();
|
||||
return playback.position();
|
||||
}
|
||||
|
||||
public int getSongDurationMillis() {
|
||||
return player.duration();
|
||||
return playback.duration();
|
||||
}
|
||||
|
||||
public int seek(int millis) {
|
||||
int newPosition = player.seek(millis);
|
||||
int newPosition = playback.seek(millis);
|
||||
savePositionInTrack();
|
||||
return newPosition;
|
||||
}
|
||||
|
|
@ -842,7 +837,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
case SHUFFLE_MODE_SHUFFLE:
|
||||
this.shuffleMode = shuffleMode;
|
||||
ShuffleHelper.makeShuffleList(this.getPlayingQueue(), getPosition());
|
||||
setPositionInternal(0);
|
||||
position = 0;
|
||||
break;
|
||||
case SHUFFLE_MODE_NONE:
|
||||
this.shuffleMode = shuffleMode;
|
||||
|
|
@ -854,7 +849,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
newPosition = getPlayingQueue().indexOf(song);
|
||||
}
|
||||
}
|
||||
setPositionInternal(newPosition);
|
||||
position = newPosition;
|
||||
break;
|
||||
}
|
||||
notifyChange(SHUFFLE_MODE_CHANGED);
|
||||
|
|
@ -924,7 +919,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
}
|
||||
|
||||
public int getAudioSessionId() {
|
||||
return player.getAudioSessionId();
|
||||
return playback.getAudioSessionId();
|
||||
}
|
||||
|
||||
public void releaseWakeLock() {
|
||||
|
|
@ -944,7 +939,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
if (sharedPreferences.getBoolean(key, false)) {
|
||||
prepareNext();
|
||||
} else {
|
||||
player.setNextDataSource(null);
|
||||
playback.setNextDataSource(null);
|
||||
}
|
||||
break;
|
||||
case PreferenceUtil.ALBUM_ART_ON_LOCKSCREEN:
|
||||
|
|
@ -957,6 +952,17 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackWentToNext() {
|
||||
playerHandler.sendEmptyMessage(TRACK_WENT_TO_NEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackEnded() {
|
||||
acquireWakeLock(30000);
|
||||
playerHandler.sendEmptyMessage(TRACK_ENDED);
|
||||
}
|
||||
|
||||
private static final class QueueSaveHandler extends Handler {
|
||||
@NonNull
|
||||
private final WeakReference<MusicService> mService;
|
||||
|
|
@ -977,12 +983,12 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
}
|
||||
}
|
||||
|
||||
private static final class MusicPlayerHandler extends Handler {
|
||||
private static final class PlaybackHandler extends Handler {
|
||||
@NonNull
|
||||
private final WeakReference<MusicService> mService;
|
||||
private float currentDuckVolume = 1.0f;
|
||||
|
||||
public MusicPlayerHandler(final MusicService service, @NonNull final Looper looper) {
|
||||
public PlaybackHandler(final MusicService service, @NonNull final Looper looper) {
|
||||
super(looper);
|
||||
mService = new WeakReference<>(service);
|
||||
}
|
||||
|
|
@ -1002,7 +1008,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
} else {
|
||||
currentDuckVolume = .2f;
|
||||
}
|
||||
service.player.setVolume(currentDuckVolume);
|
||||
service.playback.setVolume(currentDuckVolume);
|
||||
break;
|
||||
|
||||
case UNDUCK:
|
||||
|
|
@ -1012,7 +1018,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
} else {
|
||||
currentDuckVolume = 1.0f;
|
||||
}
|
||||
service.player.setVolume(currentDuckVolume);
|
||||
service.playback.setVolume(currentDuckVolume);
|
||||
break;
|
||||
|
||||
case TRACK_WENT_TO_NEXT:
|
||||
|
|
@ -1020,7 +1026,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
service.pause();
|
||||
service.seek(0);
|
||||
} else {
|
||||
service.setPositionInternal(service.nextPosition);
|
||||
service.position = service.nextPosition;
|
||||
service.prepareNextImpl();
|
||||
service.notifyChange(META_CHANGED);
|
||||
}
|
||||
|
|
@ -1033,6 +1039,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
} else {
|
||||
service.playNextSong(false);
|
||||
}
|
||||
sendEmptyMessage(RELEASE_WAKELOCK);
|
||||
break;
|
||||
|
||||
case RELEASE_WAKELOCK:
|
||||
|
|
@ -1065,14 +1072,14 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
|||
break;
|
||||
|
||||
case AudioManager.AUDIOFOCUS_LOSS:
|
||||
// Lost focus for an unbounded amount of time: stop playback and release media player
|
||||
// Lost focus for an unbounded amount of time: stop playback and release media playback
|
||||
service.pause();
|
||||
service.unregisterReceiversAndRemoteControlClient();
|
||||
break;
|
||||
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
||||
// Lost focus for a short time, but we have to stop
|
||||
// playback. We don't release the media player because playback
|
||||
// playback. We don't release the media playback because playback
|
||||
// is likely to resume
|
||||
boolean wasPlaying = service.isPlaying();
|
||||
service.pause();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package com.kabouzeid.gramophone.service.Playback;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public interface Playback {
|
||||
|
||||
boolean setDataSource(String path);
|
||||
|
||||
void setNextDataSource(@Nullable String path);
|
||||
|
||||
void setCallbacks(PlaybackCallbacks callbacks);
|
||||
|
||||
boolean isInitialized();
|
||||
|
||||
boolean start();
|
||||
|
||||
void stop();
|
||||
|
||||
void release();
|
||||
|
||||
boolean pause();
|
||||
|
||||
boolean isPlaying();
|
||||
|
||||
int duration();
|
||||
|
||||
int position();
|
||||
|
||||
int seek(int whereto);
|
||||
|
||||
boolean setVolume(float vol);
|
||||
|
||||
boolean setAudioSessionId(int sessionId);
|
||||
|
||||
int getAudioSessionId();
|
||||
|
||||
interface PlaybackCallbacks {
|
||||
void onTrackWentToNext();
|
||||
|
||||
void onTrackEnded();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue