summaryrefslogtreecommitdiff
path: root/core/src/free/java/de/danoeh/antennapod
diff options
context:
space:
mode:
authorDomingos Lopes <domingos86lopes+github@gmail.com>2016-06-06 12:18:37 -0400
committerDomingos Lopes <domingos86lopes+github@gmail.com>2016-06-07 22:55:54 -0400
commit107e5c266f7e61972ce6d1b361b4287dbd8bde80 (patch)
tree75340a0a885aa3f1ae23e8b0928f40a6fc871440 /core/src/free/java/de/danoeh/antennapod
parentbcdcfe0d587445500de8681be6854708971bebf7 (diff)
downloadAntennaPod-107e5c266f7e61972ce6d1b361b4287dbd8bde80.zip
adapt FeedMedia class to different flavors
Diffstat (limited to 'core/src/free/java/de/danoeh/antennapod')
-rw-r--r--core/src/free/java/de/danoeh/antennapod/core/feed/FeedMedia.java567
-rw-r--r--core/src/free/java/de/danoeh/antennapod/core/feed/FeedMediaHelper.java10
-rw-r--r--core/src/free/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java592
3 files changed, 10 insertions, 1159 deletions
diff --git a/core/src/free/java/de/danoeh/antennapod/core/feed/FeedMedia.java b/core/src/free/java/de/danoeh/antennapod/core/feed/FeedMedia.java
deleted file mode 100644
index cde66835a..000000000
--- a/core/src/free/java/de/danoeh/antennapod/core/feed/FeedMedia.java
+++ /dev/null
@@ -1,567 +0,0 @@
-package de.danoeh.antennapod.core.feed;
-
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.database.Cursor;
-import android.media.MediaMetadataRetriever;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.annotation.Nullable;
-
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-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.DBWriter;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
-import de.danoeh.antennapod.core.util.ChapterUtils;
-import de.danoeh.antennapod.core.util.playback.Playable;
-
-public class FeedMedia extends FeedFile implements Playable {
- private static final String TAG = "FeedMedia";
-
- public static final int FEEDFILETYPE_FEEDMEDIA = 2;
- public static final int PLAYABLE_TYPE_FEEDMEDIA = 1;
-
- public static final String PREF_MEDIA_ID = "FeedMedia.PrefMediaId";
- public static final String PREF_FEED_ID = "FeedMedia.PrefFeedId";
-
- /**
- * Indicates we've checked on the size of the item via the network
- * and got an invalid response. Using Integer.MIN_VALUE because
- * 1) we'll still check on it in case it gets downloaded (it's <= 0)
- * 2) By default all FeedMedia have a size of 0 if we don't know it,
- * so this won't conflict with existing practice.
- */
- private static final int CHECKED_ON_SIZE_BUT_UNKNOWN = Integer.MIN_VALUE;
-
- private int duration;
- private int position; // Current position in file
- private long lastPlayedTime; // Last time this media was played (in ms)
- private int played_duration; // How many ms of this file have been played (for autoflattring)
- private long size; // File size in Byte
- private String mime_type;
- @Nullable private volatile FeedItem item;
- private Date playbackCompletionDate;
-
- // if null: unknown, will be checked
- private Boolean hasEmbeddedPicture;
-
- /* Used for loading item when restoring from parcel. */
- private long itemID;
-
- public FeedMedia(FeedItem i, String download_url, long size,
- String mime_type) {
- super(null, download_url, false);
- this.item = i;
- this.size = size;
- this.mime_type = mime_type;
- }
-
- public FeedMedia(long id, FeedItem item, int duration, int position,
- long size, String mime_type, String file_url, String download_url,
- boolean downloaded, Date playbackCompletionDate, int played_duration,
- long lastPlayedTime) {
- super(file_url, download_url, downloaded);
- this.id = id;
- this.item = item;
- this.duration = duration;
- this.position = position;
- this.played_duration = played_duration;
- this.size = size;
- this.mime_type = mime_type;
- this.playbackCompletionDate = playbackCompletionDate == null
- ? null : (Date) playbackCompletionDate.clone();
- this.lastPlayedTime = lastPlayedTime;
- }
-
- public FeedMedia(long id, FeedItem item, int duration, int position,
- long size, String mime_type, String file_url, String download_url,
- boolean downloaded, Date playbackCompletionDate, int played_duration,
- Boolean hasEmbeddedPicture, long lastPlayedTime) {
- this(id, item, duration, position, size, mime_type, file_url, download_url, downloaded,
- playbackCompletionDate, played_duration, lastPlayedTime);
- this.hasEmbeddedPicture = hasEmbeddedPicture;
- }
-
- public static FeedMedia fromCursor(Cursor cursor) {
- int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
- int indexPlaybackCompletionDate = cursor.getColumnIndex(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE);
- int indexDuration = cursor.getColumnIndex(PodDBAdapter.KEY_DURATION);
- int indexPosition = cursor.getColumnIndex(PodDBAdapter.KEY_POSITION);
- int indexSize = cursor.getColumnIndex(PodDBAdapter.KEY_SIZE);
- int indexMimeType = cursor.getColumnIndex(PodDBAdapter.KEY_MIME_TYPE);
- int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL);
- int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL);
- int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED);
- int indexPlayedDuration = cursor.getColumnIndex(PodDBAdapter.KEY_PLAYED_DURATION);
- int indexLastPlayedTime = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_PLAYED_TIME);
-
- long mediaId = cursor.getLong(indexId);
- Date playbackCompletionDate = null;
- long playbackCompletionTime = cursor.getLong(indexPlaybackCompletionDate);
- if (playbackCompletionTime > 0) {
- playbackCompletionDate = new Date(playbackCompletionTime);
- }
-
- Boolean hasEmbeddedPicture;
- switch(cursor.getInt(cursor.getColumnIndex(PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE))) {
- case 1:
- hasEmbeddedPicture = Boolean.TRUE;
- break;
- case 0:
- hasEmbeddedPicture = Boolean.FALSE;
- break;
- default:
- hasEmbeddedPicture = null;
- break;
- }
-
- return new FeedMedia(
- mediaId,
- null,
- cursor.getInt(indexDuration),
- cursor.getInt(indexPosition),
- cursor.getLong(indexSize),
- cursor.getString(indexMimeType),
- cursor.getString(indexFileUrl),
- cursor.getString(indexDownloadUrl),
- cursor.getInt(indexDownloaded) > 0,
- playbackCompletionDate,
- cursor.getInt(indexPlayedDuration),
- hasEmbeddedPicture,
- cursor.getLong(indexLastPlayedTime)
- );
- }
-
-
- @Override
- public String getHumanReadableIdentifier() {
- if (item != null && item.getTitle() != null) {
- return item.getTitle();
- } else {
- return download_url;
- }
- }
-
- /**
- * Uses mimetype to determine the type of media.
- */
- public MediaType getMediaType() {
- return MediaType.fromMimeType(mime_type);
- }
-
- public void updateFromOther(FeedMedia other) {
- super.updateFromOther(other);
- if (other.size > 0) {
- size = other.size;
- }
- if (other.mime_type != null) {
- mime_type = other.mime_type;
- }
- }
-
- public boolean compareWithOther(FeedMedia other) {
- if (super.compareWithOther(other)) {
- return true;
- }
- if (other.mime_type != null) {
- if (mime_type == null || !mime_type.equals(other.mime_type)) {
- return true;
- }
- }
- if (other.size > 0 && other.size != size) {
- return true;
- }
- return false;
- }
-
- /**
- * Reads playback preferences to determine whether this FeedMedia object is
- * currently being played.
- */
- public boolean isPlaying() {
- return PlaybackPreferences.getCurrentlyPlayingMedia() == FeedMedia.PLAYABLE_TYPE_FEEDMEDIA
- && PlaybackPreferences.getCurrentlyPlayingFeedMediaId() == id;
- }
-
- /**
- * Reads playback preferences to determine whether this FeedMedia object is
- * currently being played and the current player status is playing.
- */
- public boolean isCurrentlyPlaying() {
- return isPlaying() &&
- ((PlaybackPreferences.getCurrentPlayerStatus() == PlaybackPreferences.PLAYER_STATUS_PLAYING));
- }
-
- /**
- * Reads playback preferences to determine whether this FeedMedia object is
- * currently being played and the current player status is paused.
- */
- public boolean isCurrentlyPaused() {
- return isPlaying() &&
- ((PlaybackPreferences.getCurrentPlayerStatus() == PlaybackPreferences.PLAYER_STATUS_PAUSED));
- }
-
-
- public boolean hasAlmostEnded() {
- int smartMarkAsPlayedSecs = UserPreferences.getSmartMarkAsPlayedSecs();
- return this.position >= this.duration - smartMarkAsPlayedSecs * 1000;
- }
-
- @Override
- public int getTypeAsInt() {
- return FEEDFILETYPE_FEEDMEDIA;
- }
-
- public int getDuration() {
- return duration;
- }
-
- public void setDuration(int duration) {
- this.duration = duration;
- }
-
- @Override
- public void setLastPlayedTime(long lastPlayedTime) {
- this.lastPlayedTime = lastPlayedTime;
- }
-
- public int getPlayedDuration() {
- return played_duration;
- }
-
- public void setPlayedDuration(int played_duration) {
- this.played_duration = played_duration;
- }
-
- public int getPosition() {
- return position;
- }
-
- @Override
- public long getLastPlayedTime() {
- return lastPlayedTime;
- }
-
- public void setPosition(int position) {
- this.position = position;
- if(position > 0 && item != null && item.isNew()) {
- this.item.setPlayed(false);
- }
- }
-
- public long getSize() {
- return size;
- }
-
- public void setSize(long size) {
- this.size = size;
- }
-
- /**
- * Indicates we asked the service what the size was, but didn't
- * get a valid answer and we shoudln't check using the network again.
- */
- public void setCheckedOnSizeButUnknown() {
- this.size = CHECKED_ON_SIZE_BUT_UNKNOWN;
- }
-
- public boolean checkedOnSizeButUnknown() {
- return (CHECKED_ON_SIZE_BUT_UNKNOWN == this.size);
- }
-
- public String getMime_type() {
- return mime_type;
- }
-
- public void setMime_type(String mime_type) {
- this.mime_type = mime_type;
- }
-
- @Nullable
- public FeedItem getItem() {
- return item;
- }
-
- /**
- * Sets the item object of this FeedMedia. If the given
- * FeedItem object is not null, it's 'media'-attribute value
- * will also be set to this media object.
- */
- public void setItem(FeedItem item) {
- this.item = item;
- if (item != null && item.getMedia() != this) {
- item.setMedia(this);
- }
- }
-
- public Date getPlaybackCompletionDate() {
- return playbackCompletionDate == null
- ? null : (Date) playbackCompletionDate.clone();
- }
-
- public void setPlaybackCompletionDate(Date playbackCompletionDate) {
- this.playbackCompletionDate = playbackCompletionDate == null
- ? null : (Date) playbackCompletionDate.clone();
- }
-
- public boolean isInProgress() {
- return (this.position > 0);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public boolean hasEmbeddedPicture() {
- if(hasEmbeddedPicture == null) {
- checkEmbeddedPicture();
- }
- return hasEmbeddedPicture;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(id);
- dest.writeLong(item != null ? item.getId() : 0L);
-
- dest.writeInt(duration);
- dest.writeInt(position);
- dest.writeLong(size);
- dest.writeString(mime_type);
- dest.writeString(file_url);
- dest.writeString(download_url);
- dest.writeByte((byte) ((downloaded) ? 1 : 0));
- dest.writeLong((playbackCompletionDate != null) ? playbackCompletionDate.getTime() : 0);
- dest.writeInt(played_duration);
- dest.writeLong(lastPlayedTime);
- }
-
- @Override
- public void writeToPreferences(Editor prefEditor) {
- if(item != null && item.getFeed() != null) {
- prefEditor.putLong(PREF_FEED_ID, item.getFeed().getId());
- } else {
- prefEditor.putLong(PREF_FEED_ID, 0L);
- }
- prefEditor.putLong(PREF_MEDIA_ID, id);
- }
-
- @Override
- public void loadMetadata() throws PlayableException {
- if (item == null && itemID != 0) {
- item = DBReader.getFeedItem(itemID);
- }
- }
-
- @Override
- public void loadChapterMarks() {
- if (item == null && itemID != 0) {
- item = DBReader.getFeedItem(itemID);
- }
- // check if chapters are stored in db and not loaded yet.
- if (item != null && item.hasChapters() && item.getChapters() == null) {
- DBReader.loadChaptersOfFeedItem(item);
- } else if (item != null && item.getChapters() == null) {
- if(localFileAvailable()) {
- ChapterUtils.loadChaptersFromFileUrl(this);
- } else {
- ChapterUtils.loadChaptersFromStreamUrl(this);
- }
- if (getChapters() != null && item != null) {
- DBWriter.setFeedItem(item);
- }
- }
- }
-
- @Override
- public String getEpisodeTitle() {
- if (item == null) {
- return null;
- }
- if (item.getTitle() != null) {
- return item.getTitle();
- } else {
- return item.getIdentifyingValue();
- }
- }
-
- @Override
- public List<Chapter> getChapters() {
- if (item == null) {
- return null;
- }
- return item.getChapters();
- }
-
- @Override
- public String getWebsiteLink() {
- if (item == null) {
- return null;
- }
- return item.getLink();
- }
-
- @Override
- public String getFeedTitle() {
- if (item == null || item.getFeed() == null) {
- return null;
- }
- return item.getFeed().getTitle();
- }
-
- @Override
- public Object getIdentifier() {
- return id;
- }
-
- @Override
- public String getLocalMediaUrl() {
- return file_url;
- }
-
- @Override
- public String getStreamUrl() {
- return download_url;
- }
-
- @Override
- public String getPaymentLink() {
- if (item == null) {
- return null;
- }
- return item.getPaymentLink();
- }
-
- @Override
- public boolean localFileAvailable() {
- return isDownloaded() && file_url != null;
- }
-
- @Override
- public boolean streamAvailable() {
- return download_url != null;
- }
-
- @Override
- public void saveCurrentPosition(SharedPreferences pref, int newPosition, long timeStamp) {
- if(item != null && item.isNew()) {
- DBWriter.markItemPlayed(FeedItem.UNPLAYED, item.getId());
- }
- setPosition(newPosition);
- setLastPlayedTime(timeStamp);
- DBWriter.setFeedMediaPlaybackInformation(this);
- }
-
- @Override
- public void onPlaybackStart() {
- }
- @Override
- public void onPlaybackCompleted() {
-
- }
-
- @Override
- public int getPlayableType() {
- return PLAYABLE_TYPE_FEEDMEDIA;
- }
-
- @Override
- public void setChapters(List<Chapter> chapters) {
- if(item != null) {
- item.setChapters(chapters);
- }
- }
-
- @Override
- public Callable<String> loadShownotes() {
- return () -> {
- if (item == null) {
- item = DBReader.getFeedItem(
- itemID);
- }
- if (item.getContentEncoded() == null || item.getDescription() == null) {
- DBReader.loadExtraInformationOfFeedItem(
- item);
-
- }
- return (item.getContentEncoded() != null) ? item.getContentEncoded() : item.getDescription();
- };
- }
-
- public static final Parcelable.Creator<FeedMedia> CREATOR = new Parcelable.Creator<FeedMedia>() {
- public FeedMedia createFromParcel(Parcel in) {
- final long id = in.readLong();
- final long itemID = in.readLong();
- FeedMedia result = new FeedMedia(id, null, in.readInt(), in.readInt(), in.readLong(), in.readString(), in.readString(),
- in.readString(), in.readByte() != 0, new Date(in.readLong()), in.readInt(), in.readLong());
- result.itemID = itemID;
- return result;
- }
-
- public FeedMedia[] newArray(int size) {
- return new FeedMedia[size];
- }
- };
-
- @Override
- public String getImageLocation() {
- if (hasEmbeddedPicture()) {
- return getLocalMediaUrl();
- } else if(item != null) {
- return item.getImageLocation();
- } else {
- return null;
- }
- }
-
- public void setHasEmbeddedPicture(Boolean hasEmbeddedPicture) {
- this.hasEmbeddedPicture = hasEmbeddedPicture;
- }
-
- @Override
- public void setDownloaded(boolean downloaded) {
- super.setDownloaded(downloaded);
- if(item != null && downloaded) {
- item.setPlayed(false);
- }
- }
-
- @Override
- public void setFile_url(String file_url) {
- super.setFile_url(file_url);
- }
-
- public void checkEmbeddedPicture() {
- if (!localFileAvailable()) {
- hasEmbeddedPicture = Boolean.FALSE;
- return;
- }
- MediaMetadataRetriever mmr = new MediaMetadataRetriever();
- try {
- mmr.setDataSource(getLocalMediaUrl());
- byte[] image = mmr.getEmbeddedPicture();
- if(image != null) {
- hasEmbeddedPicture = Boolean.TRUE;
- } else {
- hasEmbeddedPicture = Boolean.FALSE;
- }
- } catch (Exception e) {
- e.printStackTrace();
- hasEmbeddedPicture = Boolean.FALSE;
- }
- }
-
-// @Override
-// public boolean equals(Object o) {
-// if (o instanceof RemoteMedia) {
-// return o.equals(this);
-// }
-// return super.equals(o);
-// }
-}
diff --git a/core/src/free/java/de/danoeh/antennapod/core/feed/FeedMediaHelper.java b/core/src/free/java/de/danoeh/antennapod/core/feed/FeedMediaHelper.java
new file mode 100644
index 000000000..c289d4587
--- /dev/null
+++ b/core/src/free/java/de/danoeh/antennapod/core/feed/FeedMediaHelper.java
@@ -0,0 +1,10 @@
+package de.danoeh.antennapod.core.feed;
+
+/**
+ * Implements methods for FeedMedia that are flavor dependent.
+ */
+public class FeedMediaHelper {
+ static boolean instanceOfRemoteMedia(Object o) {
+ return false;
+ }
+}
diff --git a/core/src/free/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java b/core/src/free/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java
deleted file mode 100644
index abf787ce8..000000000
--- a/core/src/free/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java
+++ /dev/null
@@ -1,592 +0,0 @@
-//package de.danoeh.antennapod.core.service.playback;
-//
-//import android.content.Context;
-//import android.media.MediaPlayer;
-//import android.support.annotation.NonNull;
-//import android.util.Log;
-//import android.util.Pair;
-//import android.view.SurfaceHolder;
-//
-//import com.google.android.gms.cast.Cast;
-//import com.google.android.gms.cast.CastStatusCodes;
-//import com.google.android.gms.cast.MediaInfo;
-//import com.google.android.gms.cast.MediaStatus;
-//import com.google.android.libraries.cast.companionlibrary.cast.exceptions.CastException;
-//import com.google.android.libraries.cast.companionlibrary.cast.exceptions.NoConnectionException;
-//import com.google.android.libraries.cast.companionlibrary.cast.exceptions.TransientNetworkDisconnectionException;
-//
-//import java.util.concurrent.atomic.AtomicBoolean;
-//
-//import de.danoeh.antennapod.core.R;
-//import de.danoeh.antennapod.core.cast.CastConsumer;
-//import de.danoeh.antennapod.core.cast.CastManager;
-//import de.danoeh.antennapod.core.cast.CastUtils;
-//import de.danoeh.antennapod.core.cast.DefaultCastConsumer;
-//import de.danoeh.antennapod.core.cast.RemoteMedia;
-//import de.danoeh.antennapod.core.feed.FeedMedia;
-//import de.danoeh.antennapod.core.feed.MediaType;
-//import de.danoeh.antennapod.core.util.RewindAfterPauseUtils;
-//import de.danoeh.antennapod.core.util.playback.Playable;
-//
-///**
-// * Implementation of PlaybackServiceMediaPlayer suitable for remote playback on Cast Devices.
-// */
-//public class RemotePSMP extends PlaybackServiceMediaPlayer {
-//
-// public static final String TAG = "RemotePSMP";
-//
-// public static final int CAST_ERROR = 3001;
-//
-// public static final int CAST_ERROR_PRIORITY_HIGH = 3005;
-//
-// private final CastManager castMgr;
-//
-// private volatile Playable media;
-// private volatile MediaInfo remoteMedia;
-// private volatile MediaType mediaType;
-//
-// private final AtomicBoolean isBuffering;
-//
-// private final AtomicBoolean startWhenPrepared;
-//
-// public RemotePSMP(@NonNull Context context, @NonNull PSMPCallback callback) {
-// super(context, callback);
-//
-// castMgr = CastManager.getInstance();
-// media = null;
-// mediaType = null;
-// startWhenPrepared = new AtomicBoolean(false);
-// isBuffering = new AtomicBoolean(false);
-//
-// try {
-// if (castMgr.isConnected() && castMgr.isRemoteMediaLoaded()) {
-// // updates the state, but does not start playing new media if it was going to
-// onRemoteMediaPlayerStatusUpdated(
-// ((p, playNextEpisode, wasSkipped, switchingPlayers) ->
-// this.callback.endPlayback(p, false, wasSkipped, switchingPlayers)));
-// }
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to do initial check for loaded media", e);
-// }
-//
-// castMgr.addCastConsumer(castConsumer);
-// //TODO
-// }
-//
-// private CastConsumer castConsumer = new DefaultCastConsumer() {
-// @Override
-// public void onRemoteMediaPlayerMetadataUpdated() {
-// RemotePSMP.this.onRemoteMediaPlayerStatusUpdated(callback::endPlayback);
-// }
-//
-// @Override
-// public void onRemoteMediaPlayerStatusUpdated() {
-// RemotePSMP.this.onRemoteMediaPlayerStatusUpdated(callback::endPlayback);
-// }
-//
-// @Override
-// public void onMediaLoadResult(int statusCode) {
-// if (playerStatus == PlayerStatus.PREPARING) {
-// if (statusCode == CastStatusCodes.SUCCESS) {
-// setPlayerStatus(PlayerStatus.PREPARED, media);
-// if (media.getDuration() == 0) {
-// Log.d(TAG, "Setting duration of media");
-// try {
-// media.setDuration((int) castMgr.getMediaDuration());
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to get remote media's duration");
-// }
-// }
-// } else if (statusCode != CastStatusCodes.REPLACED){
-// Log.d(TAG, "Remote media failed to load");
-// setPlayerStatus(PlayerStatus.INITIALIZED, media);
-// }
-// } else {
-// Log.d(TAG, "onMediaLoadResult called, but Player Status wasn't in preparing state, so we ignore the result");
-// }
-// }
-//
-// @Override
-// public void onApplicationStatusChanged(String appStatus) {
-// if (playerStatus != PlayerStatus.PLAYING) {
-// Log.d(TAG, "onApplicationStatusChanged, but no media was playing");
-// return;
-// }
-// boolean playbackEnded = false;
-// try {
-// int standbyState = castMgr.getApplicationStandbyState();
-// Log.d(TAG, "standbyState: " + standbyState);
-// playbackEnded = standbyState == Cast.STANDBY_STATE_YES;
-// } catch (IllegalStateException e) {
-// Log.d(TAG, "unable to get standbyState on onApplicationStatusChanged()");
-// }
-// if (playbackEnded) {
-// setPlayerStatus(PlayerStatus.INDETERMINATE, media);
-// callback.endPlayback(media, true, false, false);
-// }
-// }
-//
-// @Override
-// public void onFailed(int resourceId, int statusCode) {
-// callback.onMediaPlayerInfo(CAST_ERROR, resourceId);
-// }
-// };
-//
-// private void setBuffering(boolean buffering) {
-// if (buffering && isBuffering.compareAndSet(false, true)) {
-// callback.onMediaPlayerInfo(MediaPlayer.MEDIA_INFO_BUFFERING_START, 0);
-// } else if (!buffering && isBuffering.compareAndSet(true, false)) {
-// callback.onMediaPlayerInfo(MediaPlayer.MEDIA_INFO_BUFFERING_END, 0);
-// }
-// }
-//
-// private Playable localVersion(MediaInfo info){
-// if (info == null) {
-// return null;
-// }
-// if (CastUtils.matches(info, media)) {
-// return media;
-// }
-// return CastUtils.getPlayable(info, true);
-// }
-//
-// private MediaInfo remoteVersion(Playable playable) {
-// if (playable == null) {
-// return null;
-// }
-// if (CastUtils.matches(remoteMedia, playable)) {
-// return remoteMedia;
-// }
-// if (playable instanceof FeedMedia) {
-// return CastUtils.convertFromFeedMedia((FeedMedia) playable);
-// }
-// if (playable instanceof RemoteMedia) {
-// return ((RemoteMedia) playable).extractMediaInfo();
-// }
-// return null;
-// }
-//
-// private void onRemoteMediaPlayerStatusUpdated(@NonNull EndPlaybackCall endPlaybackCall) {
-// MediaStatus status = castMgr.getMediaStatus();
-// if (status == null) {
-// Log.d(TAG, "Received null MediaStatus");
-// //setBuffering(false);
-// //setPlayerStatus(PlayerStatus.INDETERMINATE, null);
-// return;
-// } else {
-// Log.d(TAG, "Received remote status/media update. New state=" + status.getPlayerState());
-// }
-// Playable currentMedia = localVersion(status.getMediaInfo());
-// boolean updateUI = currentMedia != media;
-// if (currentMedia != null) {
-// long position = status.getStreamPosition();
-// if (position > 0 && currentMedia.getPosition() == 0) {
-// currentMedia.setPosition((int) position);
-// }
-// }
-// int state = status.getPlayerState();
-// setBuffering(state == MediaStatus.PLAYER_STATE_BUFFERING);
-// switch (state) {
-// case MediaStatus.PLAYER_STATE_PLAYING:
-// setPlayerStatus(PlayerStatus.PLAYING, currentMedia);
-// break;
-// case MediaStatus.PLAYER_STATE_PAUSED:
-// setPlayerStatus(PlayerStatus.PAUSED, currentMedia);
-// break;
-// case MediaStatus.PLAYER_STATE_BUFFERING:
-// setPlayerStatus(playerStatus, currentMedia);
-// break;
-// case MediaStatus.PLAYER_STATE_IDLE:
-// int reason = status.getIdleReason();
-// switch (reason) {
-// case MediaStatus.IDLE_REASON_CANCELED:
-// // check if we're already loading something else
-// if (!updateUI || media == null) {
-// setPlayerStatus(PlayerStatus.STOPPED, currentMedia);
-// } else {
-// updateUI = false;
-// }
-// break;
-// case MediaStatus.IDLE_REASON_INTERRUPTED:
-// // check if we're already loading something else
-// if (!updateUI || media == null) {
-// setPlayerStatus(PlayerStatus.PREPARING, currentMedia);
-// } else {
-// updateUI = false;
-// }
-// break;
-// case MediaStatus.IDLE_REASON_NONE:
-// setPlayerStatus(PlayerStatus.INITIALIZED, currentMedia);
-// break;
-// case MediaStatus.IDLE_REASON_FINISHED:
-// boolean playing = playerStatus == PlayerStatus.PLAYING;
-// setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia);
-// endPlaybackCall.endPlayback(currentMedia,playing, false, false);
-// // endPlayback already updates the UI, so no need to trigger it ourselves
-// updateUI = false;
-// break;
-// case MediaStatus.IDLE_REASON_ERROR:
-// Log.w(TAG, "Got an error status from the Chromecast. Skipping, if possible, to the next episode...");
-// setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia);
-// callback.onMediaPlayerInfo(CAST_ERROR_PRIORITY_HIGH,
-// R.string.cast_failed_media_error_skipping);
-// endPlaybackCall.endPlayback(currentMedia, startWhenPrepared.get(), true, false);
-// // endPlayback already updates the UI, so no need to trigger it ourselves
-// updateUI = false;
-// }
-// break;
-// case MediaStatus.PLAYER_STATE_UNKNOWN:
-// //is this right?
-// setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia);
-// break;
-// default:
-// Log.e(TAG, "Remote media state undetermined!");
-// setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia);
-// }
-// if (updateUI) {
-// callback.onMediaChanged(true);
-// }
-// }
-//
-// @Override
-// public void playMediaObject(@NonNull final Playable playable, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) {
-// Log.d(TAG, "playMediaObject() called");
-// playMediaObject(playable, false, stream, startWhenPrepared, prepareImmediately);
-// }
-//
-// /**
-// * Internal implementation of playMediaObject. This method has an additional parameter that allows the caller to force a media player reset even if
-// * the given playable parameter is the same object as the currently playing media.
-// *
-// * @see #playMediaObject(de.danoeh.antennapod.core.util.playback.Playable, boolean, boolean, boolean)
-// */
-// private void playMediaObject(@NonNull final Playable playable, final boolean forceReset, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) {
-// if (!CastUtils.isCastable(playable)) {
-// Log.d(TAG, "media provided is not compatible with cast device");
-// callback.onMediaPlayerInfo(CAST_ERROR_PRIORITY_HIGH, R.string.cast_not_castable);
-// try {
-// playable.loadMetadata();
-// } catch (Playable.PlayableException e) {
-// Log.e(TAG, "Unable to load metadata of playable", e);
-// }
-// callback.endPlayback(playable, startWhenPrepared, true, false);
-// return;
-// }
-//
-// if (media != null) {
-// if (!forceReset && media.getIdentifier().equals(playable.getIdentifier())
-// && playerStatus == PlayerStatus.PLAYING) {
-// // episode is already playing -> ignore method call
-// Log.d(TAG, "Method call to playMediaObject was ignored: media file already playing.");
-// return;
-// } else {
-// // set temporarily to pause in order to update list with current position
-// try {
-// if (castMgr.isRemoteMediaPlaying()) {
-// setPlayerStatus(PlayerStatus.PAUSED, media);
-// }
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to determine whether media was playing, falling back to stored player status", e);
-// // this might end up just being pointless if we need to query the remote device for the position
-// if (playerStatus == PlayerStatus.PLAYING) {
-// setPlayerStatus(PlayerStatus.PAUSED, media);
-// }
-// }
-// smartMarkAsPlayed(media);
-//
-//
-// setPlayerStatus(PlayerStatus.INDETERMINATE, null);
-// }
-// }
-//
-// this.media = playable;
-// remoteMedia = remoteVersion(playable);
-// //this.stream = stream;
-// this.mediaType = media.getMediaType();
-// this.startWhenPrepared.set(startWhenPrepared);
-// setPlayerStatus(PlayerStatus.INITIALIZING, media);
-// try {
-// media.loadMetadata();
-// callback.onMediaChanged(true);
-// setPlayerStatus(PlayerStatus.INITIALIZED, media);
-// if (prepareImmediately) {
-// prepare();
-// }
-// } catch (Playable.PlayableException e) {
-// Log.e(TAG, "Error while loading media metadata", e);
-// setPlayerStatus(PlayerStatus.STOPPED, null);
-// }
-// }
-//
-// @Override
-// public void resume() {
-// try {
-// // TODO see comment on prepare()
-// // setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume());
-// if (playerStatus == PlayerStatus.PREPARED && media.getPosition() > 0) {
-// int newPosition = RewindAfterPauseUtils.calculatePositionWithRewind(
-// media.getPosition(),
-// media.getLastPlayedTime());
-// castMgr.play(newPosition);
-// }
-// castMgr.play();
-// } catch (CastException | TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to resume remote playback", e);
-// }
-// }
-//
-// @Override
-// public void pause(boolean abandonFocus, boolean reinit) {
-// try {
-// if (castMgr.isRemoteMediaPlaying()) {
-// castMgr.pause();
-// }
-// } catch (CastException | TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to pause", e);
-// }
-// }
-//
-// @Override
-// public void prepare() {
-// if (playerStatus == PlayerStatus.INITIALIZED) {
-// Log.d(TAG, "Preparing media player");
-// setPlayerStatus(PlayerStatus.PREPARING, media);
-// try {
-// int position = media.getPosition();
-// if (position > 0) {
-// position = RewindAfterPauseUtils.calculatePositionWithRewind(
-// position,
-// media.getLastPlayedTime());
-// }
-// // TODO We're not supporting user set stream volume yet, as we need to make a UI
-// // that doesn't allow changing playback speed or have different values for left/right
-// //setVolume(UserPreferences.getLeftVolume(), UserPreferences.getRightVolume());
-// castMgr.loadMedia(remoteMedia, startWhenPrepared.get(), position);
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Error loading media", e);
-// setPlayerStatus(PlayerStatus.INITIALIZED, media);
-// }
-// }
-// }
-//
-// @Override
-// public void reinit() {
-// Log.d(TAG, "reinit() called");
-// if (media != null) {
-// playMediaObject(media, true, false, startWhenPrepared.get(), false);
-// } else {
-// Log.d(TAG, "Call to reinit was ignored: media was null");
-// }
-// }
-//
-// @Override
-// public void seekTo(int t) {
-// //TODO check other seek implementations and see if there's no issue with sending too many seek commands to the remote media player
-// try {
-// if (castMgr.isRemoteMediaLoaded()) {
-// setPlayerStatus(PlayerStatus.SEEKING, media);
-// castMgr.seek(t);
-// } else if (media != null && playerStatus == PlayerStatus.INITIALIZED){
-// media.setPosition(t);
-// startWhenPrepared.set(false);
-// prepare();
-// }
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to seek", e);
-// }
-// }
-//
-// @Override
-// public void seekDelta(int d) {
-// int position = getPosition();
-// if (position != INVALID_TIME) {
-// seekTo(position + d);
-// } else {
-// Log.e(TAG, "getPosition() returned INVALID_TIME in seekDelta");
-// }
-// }
-//
-// @Override
-// public int getDuration() {
-// int retVal = INVALID_TIME;
-// boolean prepared;
-// try {
-// prepared = castMgr.isRemoteMediaLoaded();
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to check if remote media is loaded", e);
-// prepared = playerStatus.isAtLeast(PlayerStatus.PREPARED);
-// }
-// if (prepared) {
-// try {
-// retVal = (int) castMgr.getMediaDuration();
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to determine remote media's duration", e);
-// }
-// }
-// if(retVal == INVALID_TIME && media != null && media.getDuration() > 0) {
-// retVal = media.getDuration();
-// }
-// Log.d(TAG, "getDuration() -> " + retVal);
-// return retVal;
-// }
-//
-// @Override
-// public int getPosition() {
-// int retVal = INVALID_TIME;
-// boolean prepared;
-// try {
-// prepared = castMgr.isRemoteMediaLoaded();
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to check if remote media is loaded", e);
-// prepared = playerStatus.isAtLeast(PlayerStatus.PREPARED);
-// }
-// if (prepared) {
-// try {
-// retVal = (int) castMgr.getCurrentMediaPosition();
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Unable to determine remote media's position", e);
-// }
-// }
-// if(retVal <= 0 && media != null && media.getPosition() >= 0) {
-// retVal = media.getPosition();
-// }
-// Log.d(TAG, "getPosition() -> " + retVal);
-// return retVal;
-// }
-//
-// @Override
-// public boolean isStartWhenPrepared() {
-// return startWhenPrepared.get();
-// }
-//
-// @Override
-// public void setStartWhenPrepared(boolean startWhenPrepared) {
-// this.startWhenPrepared.set(startWhenPrepared);
-// }
-//
-// //TODO I believe some parts of the code make the same decision skipping this check, so that
-// //should be changed as well
-// @Override
-// public boolean canSetSpeed() {
-// return false;
-// }
-//
-// @Override
-// public void setSpeed(float speed) {
-// throw new UnsupportedOperationException("Setting playback speed unsupported for Remote Playback");
-// }
-//
-// @Override
-// public float getPlaybackSpeed() {
-// return 1;
-// }
-//
-// @Override
-// public void setVolume(float volumeLeft, float volumeRight) {
-// Log.d(TAG, "Setting the Stream volume on Remote Media Player");
-// double volume = (volumeLeft+volumeRight)/2;
-// if (volume > 1.0) {
-// volume = 1.0;
-// }
-// if (volume < 0.0) {
-// volume = 0.0;
-// }
-// try {
-// castMgr.setStreamVolume(volume);
-// } catch (TransientNetworkDisconnectionException | NoConnectionException | CastException e) {
-// Log.e(TAG, "Unable to set the volume", e);
-// }
-// }
-//
-// @Override
-// public boolean canDownmix() {
-// return false;
-// }
-//
-// @Override
-// public void setDownmix(boolean enable) {
-// throw new UnsupportedOperationException("Setting downmix unsupported in Remote Media Player");
-// }
-//
-// @Override
-// public MediaType getCurrentMediaType() {
-// return mediaType;
-// }
-//
-// @Override
-// public boolean isStreaming() {
-// return true;
-// }
-//
-// @Override
-// public void shutdown() {
-// castMgr.removeCastConsumer(castConsumer);
-// }
-//
-// @Override
-// public void shutdownQuietly() {
-// shutdown();
-// }
-//
-// @Override
-// public void setVideoSurface(SurfaceHolder surface) {
-// throw new UnsupportedOperationException("Setting Video Surface unsupported in Remote Media Player");
-// }
-//
-// @Override
-// public void resetVideoSurface() {
-// Log.e(TAG, "Resetting Video Surface unsupported in Remote Media Player");
-// }
-//
-// @Override
-// public Pair<Integer, Integer> getVideoSize() {
-// return null;
-// }
-//
-// @Override
-// public Playable getPlayable() {
-// return media;
-// }
-//
-// @Override
-// protected void setPlayable(Playable playable) {
-// if (playable != media) {
-// media = playable;
-// remoteMedia = remoteVersion(playable);
-// }
-// }
-//
-// @Override
-// public void endPlayback(boolean wasSkipped, boolean switchingPlayers) {
-// Log.d(TAG, "endPlayback() called");
-// boolean isPlaying = playerStatus == PlayerStatus.PLAYING;
-// try {
-// isPlaying = castMgr.isRemoteMediaPlaying();
-// } catch (TransientNetworkDisconnectionException | NoConnectionException e) {
-// Log.e(TAG, "Could not determine if media is playing", e);
-// }
-// // TODO make sure we stop playback whenever there's no next episode.
-// if (playerStatus != PlayerStatus.INDETERMINATE) {
-// setPlayerStatus(PlayerStatus.INDETERMINATE, media);
-// }
-// callback.endPlayback(media, isPlaying, wasSkipped, switchingPlayers);
-// }
-//
-// @Override
-// public void stop() {
-// if (playerStatus == PlayerStatus.INDETERMINATE) {
-// setPlayerStatus(PlayerStatus.STOPPED, null);
-// } else {
-// Log.d(TAG, "Ignored call to stop: Current player state is: " + playerStatus);
-// }
-// }
-//
-// @Override
-// protected boolean shouldLockWifi() {
-// return false;
-// }
-//
-// private interface EndPlaybackCall {
-// boolean endPlayback(Playable media, boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers);
-// }
-//}