summaryrefslogtreecommitdiff
path: root/core/src/play/java/de/danoeh/antennapod
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2020-02-22 01:09:59 +0100
committerByteHamster <info@bytehamster.com>2020-03-16 00:19:20 +0100
commitf7411d2d98033ab8bce3be9c4428b18fe5201e74 (patch)
tree6f96d51eeaa7514639875a5f5ee649684e8a6344 /core/src/play/java/de/danoeh/antennapod
parent03d1f41e9bd88e1920be306ef8bcd10642ce5527 (diff)
downloadAntennaPod-f7411d2d98033ab8bce3be9c4428b18fe5201e74.zip
Allow to stream episodes from unsubscribed podcast
Diffstat (limited to 'core/src/play/java/de/danoeh/antennapod')
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java1
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java60
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/cast/RemoteMedia.java354
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/feed/FeedMediaFlavorHelper.java2
-rw-r--r--core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java5
5 files changed, 65 insertions, 357 deletions
diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java
index 88da6a0ec..484904a9a 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java
@@ -9,6 +9,7 @@ import com.google.android.gms.cast.MediaInfo;
import com.google.android.gms.cast.MediaMetadata;
import com.google.android.gms.common.images.WebImage;
+import de.danoeh.antennapod.core.util.playback.RemoteMedia;
import java.util.Calendar;
import java.util.List;
diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java b/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java
new file mode 100644
index 000000000..91de5418d
--- /dev/null
+++ b/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java
@@ -0,0 +1,60 @@
+package de.danoeh.antennapod.core.cast;
+
+import android.net.Uri;
+import android.text.TextUtils;
+import com.google.android.gms.cast.MediaInfo;
+import com.google.android.gms.cast.MediaMetadata;
+import com.google.android.gms.common.images.WebImage;
+import de.danoeh.antennapod.core.util.playback.RemoteMedia;
+import java.util.Calendar;
+
+public class MediaInfoCreator {
+ public static MediaInfo from(RemoteMedia media) {
+ MediaMetadata metadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_GENERIC);
+
+ metadata.putString(MediaMetadata.KEY_TITLE, media.getEpisodeTitle());
+ metadata.putString(MediaMetadata.KEY_SUBTITLE, media.getFeedTitle());
+ if (!TextUtils.isEmpty(media.getImageLocation())) {
+ metadata.addImage(new WebImage(Uri.parse(media.getImageLocation())));
+ }
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(media.getPubDate());
+ metadata.putDate(MediaMetadata.KEY_RELEASE_DATE, calendar);
+ if (!TextUtils.isEmpty(media.getFeedAuthor())) {
+ metadata.putString(MediaMetadata.KEY_ARTIST, media.getFeedAuthor());
+ }
+ if (!TextUtils.isEmpty(media.getFeedUrl())) {
+ metadata.putString(CastUtils.KEY_FEED_URL, media.getFeedUrl());
+ }
+ if (!TextUtils.isEmpty(media.getFeedLink())) {
+ metadata.putString(CastUtils.KEY_FEED_WEBSITE, media.getFeedLink());
+ }
+ if (!TextUtils.isEmpty(media.getEpisodeIdentifier())) {
+ metadata.putString(CastUtils.KEY_EPISODE_IDENTIFIER, media.getEpisodeIdentifier());
+ } else {
+ metadata.putString(CastUtils.KEY_EPISODE_IDENTIFIER, media.getDownloadUrl());
+ }
+ if (!TextUtils.isEmpty(media.getEpisodeLink())) {
+ metadata.putString(CastUtils.KEY_EPISODE_LINK, media.getEpisodeLink());
+ }
+ String notes = media.getNotes();
+ if (notes != null) {
+ if (notes.length() > CastUtils.EPISODE_NOTES_MAX_LENGTH) {
+ notes = notes.substring(0, CastUtils.EPISODE_NOTES_MAX_LENGTH);
+ }
+ metadata.putString(CastUtils.KEY_EPISODE_NOTES, notes);
+ }
+ // Default id value
+ metadata.putInt(CastUtils.KEY_MEDIA_ID, 0);
+ metadata.putInt(CastUtils.KEY_FORMAT_VERSION, CastUtils.FORMAT_VERSION_VALUE);
+
+ MediaInfo.Builder builder = new MediaInfo.Builder(media.getDownloadUrl())
+ .setContentType(media.getMimeType())
+ .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
+ .setMetadata(metadata);
+ if (media.getDuration() > 0) {
+ builder.setStreamDuration(media.getDuration());
+ }
+ return builder.build();
+ }
+}
diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/RemoteMedia.java b/core/src/play/java/de/danoeh/antennapod/core/cast/RemoteMedia.java
deleted file mode 100644
index 0614e5952..000000000
--- a/core/src/play/java/de/danoeh/antennapod/core/cast/RemoteMedia.java
+++ /dev/null
@@ -1,354 +0,0 @@
-package de.danoeh.antennapod.core.cast;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import androidx.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.google.android.gms.cast.MediaInfo;
-import com.google.android.gms.cast.MediaMetadata;
-import com.google.android.gms.common.images.WebImage;
-
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import de.danoeh.antennapod.core.feed.Chapter;
-import de.danoeh.antennapod.core.feed.Feed;
-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.util.ChapterUtils;
-import de.danoeh.antennapod.core.util.playback.Playable;
-
-/**
- * Playable implementation for media on a Cast Device for which a local version of
- * {@link de.danoeh.antennapod.core.feed.FeedMedia} hasn't been found.
- */
-public class RemoteMedia implements Playable {
- public static final String TAG = "RemoteMedia";
-
- public static final int PLAYABLE_TYPE_REMOTE_MEDIA = 3;
-
- private String downloadUrl;
- private String itemIdentifier;
- private String feedUrl;
- private String feedTitle;
- private String episodeTitle;
- private String episodeLink;
- private String feedAuthor;
- private String imageUrl;
- private String feedLink;
- private String mime_type;
- private Date pubDate;
- private String notes;
- private List<Chapter> chapters;
- private int duration;
- private int position;
- private long lastPlayedTime;
-
- public RemoteMedia(String downloadUrl, String itemId, String feedUrl, String feedTitle,
- String episodeTitle, String episodeLink, String feedAuthor,
- String imageUrl, String feedLink, String mime_type, Date pubDate) {
- this.downloadUrl = downloadUrl;
- this.itemIdentifier = itemId;
- this.feedUrl = feedUrl;
- this.feedTitle = feedTitle;
- this.episodeTitle = episodeTitle;
- this.episodeLink = episodeLink;
- this.feedAuthor = feedAuthor;
- this.imageUrl = imageUrl;
- this.feedLink = feedLink;
- this.mime_type = mime_type;
- this.pubDate = pubDate;
- }
-
- public void setNotes(String notes) {
- this.notes = notes;
- }
-
- public MediaInfo extractMediaInfo() {
- MediaMetadata metadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_GENERIC);
-
- metadata.putString(MediaMetadata.KEY_TITLE, episodeTitle);
- metadata.putString(MediaMetadata.KEY_SUBTITLE, feedTitle);
- if (!TextUtils.isEmpty(imageUrl)) {
- metadata.addImage(new WebImage(Uri.parse(imageUrl)));
- }
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(pubDate);
- metadata.putDate(MediaMetadata.KEY_RELEASE_DATE, calendar);
- if (!TextUtils.isEmpty(feedAuthor)) {
- metadata.putString(MediaMetadata.KEY_ARTIST, feedAuthor);
- }
- if (!TextUtils.isEmpty(feedUrl)) {
- metadata.putString(CastUtils.KEY_FEED_URL, feedUrl);
- }
- if (!TextUtils.isEmpty(feedLink)) {
- metadata.putString(CastUtils.KEY_FEED_WEBSITE, feedLink);
- }
- if (!TextUtils.isEmpty(itemIdentifier)) {
- metadata.putString(CastUtils.KEY_EPISODE_IDENTIFIER, itemIdentifier);
- } else {
- metadata.putString(CastUtils.KEY_EPISODE_IDENTIFIER, downloadUrl);
- }
- if (!TextUtils.isEmpty(episodeLink)) {
- metadata.putString(CastUtils.KEY_EPISODE_LINK, episodeLink);
- }
- String notes = this.notes;
- if (notes != null) {
- if (notes.length() > CastUtils.EPISODE_NOTES_MAX_LENGTH) {
- notes = notes.substring(0, CastUtils.EPISODE_NOTES_MAX_LENGTH);
- }
- metadata.putString(CastUtils.KEY_EPISODE_NOTES, notes);
- }
- // Default id value
- metadata.putInt(CastUtils.KEY_MEDIA_ID, 0);
- metadata.putInt(CastUtils.KEY_FORMAT_VERSION, CastUtils.FORMAT_VERSION_VALUE);
-
- MediaInfo.Builder builder = new MediaInfo.Builder(downloadUrl)
- .setContentType(mime_type)
- .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
- .setMetadata(metadata);
- if (duration > 0) {
- builder.setStreamDuration(duration);
- }
- return builder.build();
- }
-
- public String getEpisodeIdentifier() {
- return itemIdentifier;
- }
-
- public String getFeedUrl() {
- return feedUrl;
- }
-
- @Override
- public void writeToPreferences(SharedPreferences.Editor prefEditor) {
- //it seems pointless to do it, since the session should be kept by the remote device.
- }
-
- @Override
- public void loadMetadata() throws PlayableException {
- //Already loaded
- }
-
- @Override
- public void loadChapterMarks() {
- ChapterUtils.loadChaptersFromStreamUrl(this);
- }
-
- @Override
- public String getEpisodeTitle() {
- return episodeTitle;
- }
-
- @Override
- public List<Chapter> getChapters() {
- return chapters;
- }
-
- @Override
- public String getWebsiteLink() {
- if (episodeLink != null) {
- return episodeLink;
- } else {
- return feedUrl;
- }
- }
-
- @Override
- public String getPaymentLink() {
- return null;
- }
-
- @Override
- public String getFeedTitle() {
- return feedTitle;
- }
-
- @Override
- public Object getIdentifier() {
- return itemIdentifier + "@" + feedUrl;
- }
-
- @Override
- public int getDuration() {
- return duration;
- }
-
- @Override
- public int getPosition() {
- return position;
- }
-
- @Override
- public long getLastPlayedTime() {
- return lastPlayedTime;
- }
-
- @Override
- public MediaType getMediaType() {
- return MediaType.fromMimeType(mime_type);
- }
-
- @Override
- public String getLocalMediaUrl() {
- return null;
- }
-
- @Override
- public String getStreamUrl() {
- return downloadUrl;
- }
-
- @Override
- public boolean localFileAvailable() {
- return false;
- }
-
- @Override
- public boolean streamAvailable() {
- return true;
- }
-
- @Override
- public void saveCurrentPosition(SharedPreferences pref, int newPosition, long timestamp) {
- //we're not saving playback information for this kind of items on preferences
- setPosition(newPosition);
- setLastPlayedTime(timestamp);
- }
-
- @Override
- public void setPosition(int newPosition) {
- position = newPosition;
- }
-
- @Override
- public void setDuration(int newDuration) {
- duration = newDuration;
- }
-
- @Override
- public void setLastPlayedTime(long lastPlayedTimestamp) {
- lastPlayedTime = lastPlayedTimestamp;
- }
-
- @Override
- public void onPlaybackStart() {
- // no-op
- }
-
- @Override
- public void onPlaybackPause(Context context) {
- // no-op
- }
-
- @Override
- public void onPlaybackCompleted(Context context) {
- // no-op
- }
-
- @Override
- public int getPlayableType() {
- return PLAYABLE_TYPE_REMOTE_MEDIA;
- }
-
- @Override
- public void setChapters(List<Chapter> chapters) {
- this.chapters = chapters;
- }
-
- @Override
- @Nullable
- public String getImageLocation() {
- return imageUrl;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public Callable<String> loadShownotes() {
- return () -> (notes != null) ? notes : "";
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(downloadUrl);
- dest.writeString(itemIdentifier);
- dest.writeString(feedUrl);
- dest.writeString(feedTitle);
- dest.writeString(episodeTitle);
- dest.writeString(episodeLink);
- dest.writeString(feedAuthor);
- dest.writeString(imageUrl);
- dest.writeString(feedLink);
- dest.writeString(mime_type);
- dest.writeLong(pubDate.getTime());
- dest.writeString(notes);
- dest.writeInt(duration);
- dest.writeInt(position);
- dest.writeLong(lastPlayedTime);
- }
-
- public static final Parcelable.Creator<RemoteMedia> CREATOR = new Parcelable.Creator<RemoteMedia>() {
- @Override
- public RemoteMedia createFromParcel(Parcel in) {
- RemoteMedia result = new RemoteMedia(in.readString(), in.readString(), in.readString(),
- in.readString(), in.readString(), in.readString(), in.readString(), in.readString(),
- in.readString(), in.readString(), new Date(in.readLong()));
- result.setNotes(in.readString());
- result.setDuration(in.readInt());
- result.setPosition(in.readInt());
- result.setLastPlayedTime(in.readLong());
- return result;
- }
-
- @Override
- public RemoteMedia[] newArray(int size) {
- return new RemoteMedia[size];
- }
- };
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof RemoteMedia) {
- RemoteMedia rm = (RemoteMedia) other;
- return TextUtils.equals(downloadUrl, rm.downloadUrl) &&
- TextUtils.equals(feedUrl, rm.feedUrl) &&
- TextUtils.equals(itemIdentifier, rm.itemIdentifier);
- }
- if (other instanceof FeedMedia) {
- FeedMedia fm = (FeedMedia) other;
- if (!TextUtils.equals(downloadUrl, fm.getStreamUrl())) {
- return false;
- }
- FeedItem fi = fm.getItem();
- if (fi == null || !TextUtils.equals(itemIdentifier, fi.getItemIdentifier())) {
- return false;
- }
- Feed feed = fi.getFeed();
- return feed != null && TextUtils.equals(feedUrl, feed.getDownload_url());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return new HashCodeBuilder()
- .append(downloadUrl)
- .append(feedUrl)
- .append(itemIdentifier)
- .toHashCode();
- }
-}
diff --git a/core/src/play/java/de/danoeh/antennapod/core/feed/FeedMediaFlavorHelper.java b/core/src/play/java/de/danoeh/antennapod/core/feed/FeedMediaFlavorHelper.java
index fe0f771d6..2502f17c0 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/feed/FeedMediaFlavorHelper.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/feed/FeedMediaFlavorHelper.java
@@ -1,6 +1,6 @@
package de.danoeh.antennapod.core.feed;
-import de.danoeh.antennapod.core.cast.RemoteMedia;
+import de.danoeh.antennapod.core.util.playback.RemoteMedia;
/**
* Implements methods for FeedMedia that are flavor dependent.
diff --git a/core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java b/core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java
index 7c84437e1..2a75f30a2 100644
--- a/core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java
+++ b/core/src/play/java/de/danoeh/antennapod/core/service/playback/RemotePSMP.java
@@ -15,6 +15,7 @@ import com.google.android.libraries.cast.companionlibrary.cast.exceptions.CastEx
import com.google.android.libraries.cast.companionlibrary.cast.exceptions.NoConnectionException;
import com.google.android.libraries.cast.companionlibrary.cast.exceptions.TransientNetworkDisconnectionException;
+import de.danoeh.antennapod.core.cast.MediaInfoCreator;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -24,7 +25,7 @@ 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.util.playback.RemoteMedia;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.preferences.UserPreferences;
@@ -165,7 +166,7 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
return CastUtils.convertFromFeedMedia((FeedMedia) playable);
}
if (playable instanceof RemoteMedia) {
- return ((RemoteMedia) playable).extractMediaInfo();
+ return MediaInfoCreator.from((RemoteMedia) playable);
}
return null;
}