adapt FeedMedia class to different flavors
This commit is contained in:
parent
bcdcfe0d58
commit
107e5c266f
|
@ -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);
|
||||
// }
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
// }
|
||||
//}
|
|
@ -12,7 +12,6 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import de.danoeh.antennapod.core.cast.RemoteMedia;
|
||||
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
|
@ -560,7 +559,7 @@ public class FeedMedia extends FeedFile implements Playable {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof RemoteMedia) {
|
||||
if (FeedMediaHelper.instanceOfRemoteMedia(o)) {
|
||||
return o.equals(this);
|
||||
}
|
||||
return super.equals(o);
|
|
@ -0,0 +1,12 @@
|
|||
package de.danoeh.antennapod.core.feed;
|
||||
|
||||
import de.danoeh.antennapod.core.cast.RemoteMedia;
|
||||
|
||||
/**
|
||||
* Implements methods for FeedMedia that are flavor dependent.
|
||||
*/
|
||||
public class FeedMediaHelper {
|
||||
static boolean instanceOfRemoteMedia(Object o) {
|
||||
return o instanceof RemoteMedia;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue