summaryrefslogtreecommitdiff
path: root/core/src/main/java/de
diff options
context:
space:
mode:
authorDomingos Lopes <domingos86lopes+github@gmail.com>2016-05-04 08:20:01 -0400
committerDomingos Lopes <domingos86lopes+github@gmail.com>2016-07-25 23:16:28 -0400
commitd18cf41f204de583f066635d4e380f465a419029 (patch)
tree4759432d221233149fa8e1ceaca14411b5f4c8fc /core/src/main/java/de
parent12d62d55191277252653c5210bd955357692373c (diff)
downloadAntennaPod-d18cf41f204de583f066635d4e380f465a419029.zip
move auto flattr and gpodnet play action inside FeedMedia
Diffstat (limited to 'core/src/main/java/de')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java54
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java20
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java108
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java10
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java19
6 files changed, 108 insertions, 111 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
index 64d4d14fd..e617d4192 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.core.feed;
+import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
@@ -14,12 +15,16 @@ import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
+import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
+import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.ChapterUtils;
+import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
import de.danoeh.antennapod.core.util.playback.Playable;
public class FeedMedia extends FeedFile implements Playable {
@@ -48,6 +53,8 @@ public class FeedMedia extends FeedFile implements Playable {
private String mime_type;
@Nullable private volatile FeedItem item;
private Date playbackCompletionDate;
+ private int startPosition = -1;
+ private int playedDurationWhenStarted;
// if null: unknown, will be checked
private Boolean hasEmbeddedPicture;
@@ -73,6 +80,7 @@ public class FeedMedia extends FeedFile implements Playable {
this.duration = duration;
this.position = position;
this.played_duration = played_duration;
+ this.playedDurationWhenStarted = played_duration;
this.size = size;
this.mime_type = mime_type;
this.playbackCompletionDate = playbackCompletionDate == null
@@ -472,15 +480,59 @@ public class FeedMedia extends FeedFile implements Playable {
}
setPosition(newPosition);
setLastPlayedTime(timeStamp);
+ if(startPosition>=0 && position > startPosition) {
+ setDuration(playedDurationWhenStarted + position - startPosition);
+ }
DBWriter.setFeedMediaPlaybackInformation(this);
}
@Override
public void onPlaybackStart() {
+ startPosition = (position > 0) ? position : 0;
+ playedDurationWhenStarted = played_duration;
}
+
@Override
- public void onPlaybackCompleted() {
+ public void onPlaybackPause(Context context) {
+ if (position > startPosition) {
+ played_duration = playedDurationWhenStarted + position - startPosition;
+ playedDurationWhenStarted = played_duration;
+ }
+ postPlaybackTasks(context, false);
+ startPosition = position;
+ }
+ @Override
+ public void onPlaybackCompleted(Context context) {
+ postPlaybackTasks(context, true);
+ startPosition = -1;
+ }
+
+ private void postPlaybackTasks(Context context, boolean completed) {
+ if (item != null) {
+ // gpodder play action
+ if (startPosition >= 0 && (completed || startPosition < position) &&
+ GpodnetPreferences.loggedIn()) {
+ GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, GpodnetEpisodeAction.Action.PLAY)
+ .currentDeviceId()
+ .currentTimestamp()
+ .started(startPosition / 1000)
+ .position((completed ? duration : position) / 1000)
+ .total(duration / 1000)
+ .build();
+ GpodnetPreferences.enqueueEpisodeAction(action);
+ }
+ // Auto flattr
+ float autoFlattrThreshold = UserPreferences.getAutoFlattrPlayedDurationThreshold();
+ if (FlattrUtils.hasToken() &&
+ UserPreferences.isAutoFlattr() &&
+ item.getPaymentLink() != null &&
+ item.getFlattrStatus().getUnflattred() &&
+ (completed && autoFlattrThreshold <= 1.0f ||
+ played_duration >= autoFlattrThreshold * duration)) {
+ DBTasks.flattrItemIfLoggedIn(context, item);
+ }
+ }
}
@Override
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
index 62e028475..4165eb84a 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java
@@ -146,6 +146,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
if (!media.getIdentifier().equals(playable.getIdentifier())) {
final Playable oldMedia = media;
executor.submit(() -> callback.onPostPlayback(oldMedia, false, true));
+ } else {
+ media.onPlaybackPause(context);
}
setPlayerStatus(PlayerStatus.INDETERMINATE, null);
@@ -253,6 +255,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
Log.d(TAG, "Pausing playback.");
mediaPlayer.pause();
setPlayerStatus(PlayerStatus.PAUSED, media);
+ media.onPlaybackPause(context.getApplicationContext());
if (abandonFocus) {
audioManager.abandonAudioFocus(audioFocusChangeListener);
@@ -370,10 +373,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
if (playerStatus == PlayerStatus.PLAYING
|| playerStatus == PlayerStatus.PAUSED
|| playerStatus == PlayerStatus.PREPARED) {
- if (!stream) {
- statusBeforeSeeking = playerStatus;
- setPlayerStatus(PlayerStatus.SEEKING, media);
- }
+ statusBeforeSeeking = playerStatus;
+ setPlayerStatus(PlayerStatus.SEEKING, media);
if(seekLatch != null && seekLatch.getCount() > 0) {
try {
seekLatch.await(3, TimeUnit.SECONDS);
@@ -382,6 +383,10 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
}
}
seekLatch = new CountDownLatch(1);
+ if (statusBeforeSeeking == PlayerStatus.PLAYING) {
+ media.setPosition(getPosition());
+ media.onPlaybackPause(context);
+ }
mediaPlayer.seekTo(t);
try {
seekLatch.await(3, TimeUnit.SECONDS);
@@ -926,7 +931,14 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
seekLatch.countDown();
}
playerLock.lock();
+ media.setPosition(getPosition());
+ if (playerStatus == PlayerStatus.PLAYING) {
+ media.onPlaybackStart();
+ }
if (playerStatus == PlayerStatus.SEEKING) {
+ if (statusBeforeSeeking == PlayerStatus.PLAYING) {
+ media.onPlaybackStart();
+ }
setPlayerStatus(statusBeforeSeeking, media);
}
playerLock.unlock();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
index f674ae9dd..5af34fd9f 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
@@ -52,9 +52,6 @@ import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
-import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
-import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction.Action;
-import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
@@ -63,7 +60,6 @@ import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.IntList;
import de.danoeh.antennapod.core.util.QueueAccess;
-import de.danoeh.antennapod.core.util.flattr.FlattrUtils;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.Playable;
@@ -206,8 +202,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
*/
private MediaSessionCompat mediaSession;
- private int startPosition;
-
private static volatile MediaType currentMediaType = MediaType.UNKNOWN;
private final IBinder mBinder = new LocalBinder();
@@ -473,7 +467,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
UserPreferences.shouldHardwareButtonSkip()) {
// assume the skip command comes from a notification or the lockscreen
// a >| skip button should actually skip
- mediaPlayer.endPlayback();
+ mediaPlayer.skip();
} else {
// assume skip command comes from a (bluetooth) media button
// user actually wants to fast-forward
@@ -530,7 +524,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
private final PlaybackServiceTaskManager.PSTMCallback taskManagerCallback = new PlaybackServiceTaskManager.PSTMCallback() {
@Override
public void positionSaverTick() {
- saveCurrentPosition(true, PlaybackServiceTaskManager.POSITION_SAVER_WAITING_INTERVAL);
+ saveCurrentPosition();
}
@Override
@@ -583,7 +577,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
case PAUSED:
taskManager.cancelPositionSaver();
- saveCurrentPosition(false, 0);
+ saveCurrentPosition();
taskManager.cancelWidgetUpdater();
if ((UserPreferences.isPersistNotify() || isCasting) &&
android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
@@ -595,22 +589,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
stopForeground(true);
}
writePlayerStatusPlaybackPreferences();
-
- final Playable playable = newInfo.playable;
-
- // Gpodder: send play action
- if(GpodnetPreferences.loggedIn() && playable instanceof FeedMedia) {
- FeedMedia media = (FeedMedia) playable;
- FeedItem item = media.getItem();
- GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, Action.PLAY)
- .currentDeviceId()
- .currentTimestamp()
- .started(startPosition / 1000)
- .position(getCurrentPosition() / 1000)
- .total(getDuration() / 1000)
- .build();
- GpodnetPreferences.enqueueEpisodeAction(action);
- }
break;
case STOPPED:
@@ -627,7 +605,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
writePlayerStatusPlaybackPreferences();
setupNotification(newInfo);
started = true;
- startPosition = mediaPlayer.getPosition();
break;
case ERROR:
@@ -790,21 +767,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
Log.d(TAG, "smart mark as played");
}
- // auto-flattr if enabled
- if (isAutoFlattrable(media) && UserPreferences.getAutoFlattrPlayedDurationThreshold() == 1.0f) {
- DBTasks.flattrItemIfLoggedIn(PlaybackService.this, item);
- }
-
- // gpodder play action
- if (GpodnetPreferences.loggedIn()) {
- GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, Action.PLAY)
- .currentDeviceId()
- .currentTimestamp()
- .started(startPosition / 1000)
- .position(((ended || smartMarkAsPlayed) ? media.getDuration() : media.getPosition()) / 1000)
- .total(media.getDuration() / 1000)
- .build();
- GpodnetPreferences.enqueueEpisodeAction(action);
+ if (ended || smartMarkAsPlayed) {
+ media.onPlaybackCompleted(getApplicationContext());
+ } else {
+ media.onPlaybackPause(getApplicationContext());
}
if (item != null) {
@@ -1234,29 +1200,13 @@ public class PlaybackService extends MediaBrowserServiceCompat {
/**
* Persists the current position and last played time of the media file.
- *
- * @param updatePlayedDuration true if played_duration should be updated. This applies only to FeedMedia objects
- * @param deltaPlayedDuration value by which played_duration should be increased.
*/
- private synchronized void saveCurrentPosition(boolean updatePlayedDuration, int deltaPlayedDuration) {
+ private synchronized void saveCurrentPosition() {
int position = getCurrentPosition();
int duration = getDuration();
- float playbackSpeed = getCurrentPlaybackSpeed();
final Playable playable = mediaPlayer.getPlayable();
if (position != INVALID_TIME && duration != INVALID_TIME && playable != null) {
Log.d(TAG, "Saving current position to " + position);
- if (updatePlayedDuration && playable instanceof FeedMedia) {
- FeedMedia media = (FeedMedia) playable;
- FeedItem item = media.getItem();
- media.setPlayedDuration(media.getPlayedDuration() + ((int) (deltaPlayedDuration * playbackSpeed)));
- // Auto flattr
- if (isAutoFlattrable(media) &&
- (media.getPlayedDuration() > UserPreferences.getAutoFlattrPlayedDurationThreshold() * duration)) {
- Log.d(TAG, "saveCurrentPosition: performing auto flattr since played duration " + Integer.toString(media.getPlayedDuration())
- + " is " + UserPreferences.getAutoFlattrPlayedDurationThreshold() * 100 + "% of file duration " + Integer.toString(duration));
- DBTasks.flattrItemIfLoggedIn(this, item);
- }
- }
playable.saveCurrentPosition(
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()),
position,
@@ -1424,7 +1374,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(intent.getAction(), ACTION_SKIP_CURRENT_EPISODE)) {
Log.d(TAG, "Received SKIP_CURRENT_EPISODE intent");
- mediaPlayer.endPlayback();
+ mediaPlayer.skip();
}
}
};
@@ -1517,26 +1467,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public void seekTo(final int t) {
- if(mediaPlayer.getPlayerStatus() == PlayerStatus.PLAYING
- && GpodnetPreferences.loggedIn()) {
- final Playable playable = mediaPlayer.getPlayable();
- if (playable instanceof FeedMedia) {
- FeedMedia media = (FeedMedia) playable;
- FeedItem item = media.getItem();
- GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, Action.PLAY)
- .currentDeviceId()
- .currentTimestamp()
- .started(startPosition / 1000)
- .position(getCurrentPosition() / 1000)
- .total(getDuration() / 1000)
- .build();
- GpodnetPreferences.enqueueEpisodeAction(action);
- }
- }
mediaPlayer.seekTo(t);
- if(mediaPlayer.getPlayerStatus() == PlayerStatus.PLAYING ) {
- startPosition = t;
- }
}
@@ -1545,10 +1476,10 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
/**
- * @see LocalPSMP#seekToChapter(de.danoeh.antennapod.core.feed.Chapter)
+ * Seek to the start of the specified chapter.
*/
public void seekToChapter(Chapter c) {
- mediaPlayer.seekToChapter(c);
+ seekTo((int) c.getStart());
}
/**
@@ -1575,15 +1506,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
return mediaPlayer.getVideoSize();
}
- private boolean isAutoFlattrable(FeedMedia media) {
- if (media != null) {
- FeedItem item = media.getItem();
- return item != null && FlattrUtils.hasToken() && UserPreferences.isAutoFlattr() && item.getPaymentLink() != null && item.getFlattrStatus().getUnflattred();
- } else {
- return false;
- }
- }
-
private final MediaSessionCompat.Callback sessionCallback = new MediaSessionCompat.Callback() {
private static final String TAG = "MediaSessionCompat";
@@ -1656,7 +1578,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public void onSkipToNext() {
Log.d(TAG, "onSkipToNext()");
if(UserPreferences.shouldHardwareButtonSkip()) {
- mediaPlayer.endPlayback();
+ mediaPlayer.skip();
} else {
seekDelta(UserPreferences.getFastFowardSecs() * 1000);
}
@@ -1699,7 +1621,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
PlaybackServiceMediaPlayer getMediaPlayer();
void setIsCasting(boolean isCasting);
void sendNotificationBroadcast(int type, int code);
- void saveCurrentPosition(boolean updatePlayedDuration, int deltaPlayedDuration);
+ void saveCurrentPosition();
void setupNotification(boolean connected, PlaybackServiceMediaPlayer.PSMPInfo info);
MediaSessionCompat getMediaSession();
Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter);
@@ -1733,8 +1655,8 @@ public class PlaybackService extends MediaBrowserServiceCompat {
}
@Override
- public void saveCurrentPosition(boolean updatePlayedDuration, int deltaPlayedDuration) {
- PlaybackService.this.saveCurrentPosition(updatePlayedDuration, deltaPlayedDuration);
+ public void saveCurrentPosition() {
+ PlaybackService.this.saveCurrentPosition();
}
@Override
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
index c76ea3889..d52d3b8bc 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java
@@ -8,7 +8,6 @@ import android.util.Log;
import android.util.Pair;
import android.view.SurfaceHolder;
-import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.util.playback.Playable;
@@ -127,13 +126,6 @@ public abstract class PlaybackServiceMediaPlayer {
public abstract void seekDelta(int d);
/**
- * Seek to the start of the specified chapter.
- */
- public void seekToChapter(@NonNull Chapter c) {
- seekTo((int) c.getStart());
- }
-
- /**
* Returns the duration of the current media object or INVALID_TIME if the duration could not be retrieved.
*/
public abstract int getDuration();
@@ -233,7 +225,7 @@ public abstract class PlaybackServiceMediaPlayer {
protected abstract void setPlayable(Playable playable);
- public void endPlayback() {
+ public void skip() {
endPlayback(true);
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java
index a37f98469..c4acdb65e 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/ExternalMedia.java
@@ -1,5 +1,6 @@
package de.danoeh.antennapod.core.util.playback;
+import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.media.MediaMetadataRetriever;
@@ -205,7 +206,12 @@ public class ExternalMedia implements Playable {
}
@Override
- public void onPlaybackCompleted() {
+ public void onPlaybackPause(Context context) {
+
+ }
+
+ @Override
+ public void onPlaybackCompleted(Context context) {
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java
index 6459d86ed..279c56338 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/Playable.java
@@ -138,14 +138,27 @@ public interface Playable extends Parcelable,
void setLastPlayedTime(long lastPlayedTimestamp);
/**
- * Is called by the PlaybackService when playback starts.
+ * This method should be called every time playback starts on this object.
+ * <p/>
+ * Position held by this Playable should be set accurately before a call to this method is made.
*/
void onPlaybackStart();
/**
- * Is called by the PlaybackService when playback is completed.
+ * This method should be called every time playback pauses or stops on this object,
+ * including just before a seeking operation is performed, after which a call to
+ * {@link #onPlaybackStart()} should be made. If playback completes, calling this method is not
+ * necessary, as long as a call to {@link #onPlaybackCompleted(Context)} is made.
+ * <p/>
+ * Position held by this Playable should be set accurately before a call to this method is made.
*/
- void onPlaybackCompleted();
+ void onPlaybackPause(Context context);
+
+ /**
+ * This method should be called when playback completes for this object.
+ * @param context
+ */
+ void onPlaybackCompleted(Context context);
/**
* Returns an integer that must be unique among all Playable classes. The