}
/**
+ * Seeks the current track to a position relative to its current position
+ * If the relative position is after or before the track, it will also automatically
+ * jump to the previous or next track respectively
+ *
+ * @param deltaInMs The delta time to seek to in milliseconds
+ */
+ public void seekRelative(long deltaInMs) {
+ synchronized (this) {
+ if (mPlayer.isInitialized()) {
+ final long newPos = position() + deltaInMs;
+ final long duration = duration();
+ if (newPos < 0) {
+ prev(true);
+ // seek to the new duration + the leftover position
+ seek(duration() + newPos);
+ } else if (newPos >= duration) {
+ gotoNext(true);
+ // seek to the leftover duration
+ seek(newPos - duration);
+ } else {
+ seek(newPos);
+ }
+ }
+ }
+ }
+
+ /**
* Returns the current position in time of the currenttrack
*
* @return The current playback position in miliseconds
* {@inheritDoc}
*/
@Override
+ public void seekRelative(final long deltaInMs) throws RemoteException {
+ mService.get().seekRelative(deltaInMs);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public long getAudioId() throws RemoteException {
return mService.get().getAudioId();
}
// popup menu for pressing the menu icon
private PopupMenu mPopupMenu;
- private long mPosOverride = -1;
-
- private long mStartSeekPos = 0;
-
- private long mLastSeekEventTime;
-
private long mSelectedId = -1;
private boolean mIsPaused = false;
}
/**
- * Used to scan backwards in time through the curren track
+ * Used to seek forwards or backwards in time through the current track
*
* @param repcnt The repeat count
* @param delta The long press duration
+ * @param forwards Whether it was seeking forwards or backwards
*/
- private void scanBackward(final int repcnt, long delta) {
+ private void seekRelative(final int repcnt, long delta, boolean forwards) {
if (mService == null) {
return;
}
- if (repcnt == 0) {
- mStartSeekPos = MusicUtils.position();
- mLastSeekEventTime = 0;
- } else {
- if (delta < 5000) {
+ if (repcnt > 0) {
+ final long EXTRA_FAST_CUTOFF = 10000;
+ if (delta < EXTRA_FAST_CUTOFF) {
// seek at 10x speed for the first 5 seconds
delta = delta * 10;
} else {
// seek at 40x after that
- delta = 50000 + (delta - 5000) * 40;
- }
- long newpos = mStartSeekPos - delta;
- if (newpos < 0) {
- // move to previous track
- MusicUtils.previous(getActivity(), true);
- final long duration = MusicUtils.duration();
- mStartSeekPos += duration;
- newpos += duration;
- }
- if (delta - mLastSeekEventTime > 250 || repcnt < 0) {
- MusicUtils.seek(newpos);
- mLastSeekEventTime = delta;
- }
- if (repcnt >= 0) {
- mPosOverride = newpos;
- } else {
- mPosOverride = -1;
+ delta = EXTRA_FAST_CUTOFF * 10 + (delta - EXTRA_FAST_CUTOFF) * 40;
}
- refreshCurrentTime();
- }
- }
- /**
- * Used to scan forwards in time through the curren track
- *
- * @param repcnt The repeat count
- * @param delta The long press duration
- */
- private void scanForward(final int repcnt, long delta) {
- if (mService == null) {
- return;
- }
- if (repcnt == 0) {
- mStartSeekPos = MusicUtils.position();
- mLastSeekEventTime = 0;
- } else {
- if (delta < 5000) {
- // seek at 10x speed for the first 5 seconds
- delta = delta * 10;
- } else {
- // seek at 40x after that
- delta = 50000 + (delta - 5000) * 40;
- }
- long newpos = mStartSeekPos + delta;
- final long duration = MusicUtils.duration();
- if (newpos >= duration) {
- // move to next track
- MusicUtils.next();
- mStartSeekPos -= duration; // is OK to go negative
- newpos -= duration;
- }
- if (delta - mLastSeekEventTime > 250 || repcnt < 0) {
- MusicUtils.seek(newpos);
- mLastSeekEventTime = delta;
- }
- if (repcnt >= 0) {
- mPosOverride = newpos;
- } else {
- mPosOverride = -1;
- }
+ MusicUtils.seekRelative(forwards ? delta : -delta);
+
refreshCurrentTime();
}
}
return 500;
}
try {
- final long pos = mPosOverride < 0 ? MusicUtils.position() : mPosOverride;
+ final long pos = MusicUtils.position();
if (pos >= 0 && MusicUtils.duration() > 0) {
refreshCurrentTimeText(pos);
*/
@Override
public void onRepeat(final View v, final long howlong, final int repcnt) {
- scanBackward(repcnt, howlong);
+ seekRelative(repcnt, howlong, false);
}
};
*/
@Override
public void onRepeat(final View v, final long howlong, final int repcnt) {
- scanForward(repcnt, howlong);
+ seekRelative(repcnt, howlong, true);
}
};
}
/**
+ * Seeks the current track to a desired relative position. This can be used
+ * to simulate fastforward and rewind
+ *
+ * @param deltaInMs The delta in ms to seek from the current position
+ */
+ public static void seekRelative(final long deltaInMs) {
+ if (mService != null) {
+ try {
+ mService.seekRelative(deltaInMs);
+ } catch (final RemoteException ignored) {
+ } catch (final IllegalStateException ignored) {
+ // Illegal State Exception message is empty so logging will actually throw an
+ // exception. We should come back and figure out why we get an exception in the
+ // first place and make sure we understand it completely. I will use
+ // https://cyanogen.atlassian.net/browse/MUSIC-125 to track investigating this more
+ }
+ }
+ }
+
+ /**
* @return The current position time of the track
*/
public static final long position() {