From 07ba067ae9de79dbcbbd54f323402578d96f1282 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 18 Feb 2022 23:06:02 +0100 Subject: Decide whether or not to stream on demand Fixes a bug where local folders sometimes did not start because AntennaPod thought it needed to play locally. Also avoids situations in which it streams even though a local file is available. Simplifies the PlaybackService slightly. --- .../test/antennapod/storage/AutoDownloadTest.java | 1 - .../adapter/FeedItemlistDescriptionAdapter.java | 1 - .../adapter/actionbutton/PlayActionButton.java | 1 - .../actionbutton/PlayLocalActionButton.java | 1 - .../adapter/actionbutton/StreamActionButton.java | 1 - .../dialog/StreamingConfirmationDialog.java | 1 - .../core/preferences/PlaybackPreferences.java | 12 +--- .../core/service/playback/LocalPSMP.java | 1 - .../core/service/playback/PlaybackService.java | 82 +++++++++------------- .../core/util/playback/PlaybackController.java | 2 - .../core/util/playback/PlaybackServiceStarter.java | 16 ----- .../antennapod/core/widget/WidgetUpdater.java | 10 +-- .../core/widget/WidgetUpdaterJobService.java | 4 +- 13 files changed, 40 insertions(+), 93 deletions(-) diff --git a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java index 23c129cb1..c9b8ef371 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java @@ -100,7 +100,6 @@ public class AutoDownloadTest { new PlaybackServiceStarter(context, media) .callEvenIfRunning(true) .startWhenPrepared(true) - .shouldStream(true) .start(); Awaitility.await("episode is playing") .atMost(2000, MILLISECONDS) diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java index 5ddb6407c..6073e97be 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/FeedItemlistDescriptionAdapter.java @@ -80,7 +80,6 @@ public class FeedItemlistDescriptionAdapter extends ArrayAdapter { } new PlaybackServiceStarter(getContext(), playable) - .shouldStream(true) .startWhenPrepared(true) .callEvenIfRunning(true) .start(); diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java index 974b12bab..528f38ba7 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayActionButton.java @@ -42,7 +42,6 @@ public class PlayActionButton extends ItemActionButton { new PlaybackServiceStarter(context, media) .callEvenIfRunning(true) .startWhenPrepared(true) - .shouldStream(false) .start(); if (media.getMediaType() == MediaType.VIDEO) { diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java index ab2122b12..47cd4d66b 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/PlayLocalActionButton.java @@ -38,7 +38,6 @@ public class PlayLocalActionButton extends ItemActionButton { new PlaybackServiceStarter(context, media) .callEvenIfRunning(true) .startWhenPrepared(true) - .shouldStream(true) .start(); if (media.getMediaType() == MediaType.VIDEO) { diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java index 94c446f50..244022c1c 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/actionbutton/StreamActionButton.java @@ -48,7 +48,6 @@ public class StreamActionButton extends ItemActionButton { new PlaybackServiceStarter(context, media) .callEvenIfRunning(true) .startWhenPrepared(true) - .shouldStream(true) .start(); if (media.getMediaType() == MediaType.VIDEO) { diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java index 22f62d410..e0bd59625 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/StreamingConfirmationDialog.java @@ -33,7 +33,6 @@ public class StreamingConfirmationDialog { new PlaybackServiceStarter(context, playable) .callEvenIfRunning(true) .startWhenPrepared(true) - .shouldStream(true) .shouldStreamThisTime(true) .start(); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java index f0c61403f..b0321bff6 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java +++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/PlaybackPreferences.java @@ -44,11 +44,6 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference private static final String PREF_CURRENTLY_PLAYING_MEDIA_TYPE = "de.danoeh.antennapod.preferences.currentlyPlayingMedia"; - /** - * True if last played media was streamed. - */ - private static final String PREF_CURRENT_EPISODE_IS_STREAM = "de.danoeh.antennapod.preferences.lastIsStream"; - /** * True if last played media was a video. */ @@ -113,10 +108,6 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference return prefs.getLong(PREF_CURRENTLY_PLAYING_FEEDMEDIA_ID, NO_MEDIA_PLAYING); } - public static boolean getCurrentEpisodeIsStream() { - return prefs.getBoolean(PREF_CURRENT_EPISODE_IS_STREAM, true); - } - public static boolean getCurrentEpisodeIsVideo() { return prefs.getBoolean(PREF_CURRENT_EPISODE_IS_VIDEO, false); } @@ -138,7 +129,7 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference editor.apply(); } - public static void writeMediaPlaying(Playable playable, PlayerStatus playerStatus, boolean stream) { + public static void writeMediaPlaying(Playable playable, PlayerStatus playerStatus) { Log.d(TAG, "Writing playback preferences"); SharedPreferences.Editor editor = prefs.edit(); @@ -146,7 +137,6 @@ public class PlaybackPreferences implements SharedPreferences.OnSharedPreference writeNoMediaPlaying(); } else { editor.putLong(PREF_CURRENTLY_PLAYING_MEDIA_TYPE, playable.getPlayableType()); - editor.putBoolean(PREF_CURRENT_EPISODE_IS_STREAM, stream); editor.putBoolean(PREF_CURRENT_EPISODE_IS_VIDEO, playable.getMediaType() == MediaType.VIDEO); if (playable instanceof FeedMedia) { FeedMedia feedMedia = (FeedMedia) playable; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java index db6088d8d..1ef06c511 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java @@ -868,7 +868,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer { pausedBecauseOfTransientAudiofocusLoss = false; new PlaybackServiceStarter(context, getPlayable()) .startWhenPrepared(true) - .streamIfLastWasStream() .callEvenIfRunning(false) .start(); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java index 76fdc1040..c6cff1bd3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java @@ -108,7 +108,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { private static final String TAG = "PlaybackService"; public static final String EXTRA_PLAYABLE = "PlaybackService.PlayableExtra"; - public static final String EXTRA_SHOULD_STREAM = "extra.de.danoeh.antennapod.core.service.shouldStream"; public static final String EXTRA_ALLOW_STREAM_THIS_TIME = "extra.de.danoeh.antennapod.core.service.allowStream"; public static final String EXTRA_ALLOW_STREAM_ALWAYS = "extra.de.danoeh.antennapod.core.service.allowStreamAlways"; public static final String EXTRA_START_WHEN_PREPARED = "extra.de.danoeh.antennapod.core.service.startWhenPrepared"; @@ -522,7 +521,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { } } else { stateManager.validStartCommandWasReceived(); - boolean stream = intent.getBooleanExtra(EXTRA_SHOULD_STREAM, true); boolean allowStreamThisTime = intent.getBooleanExtra(EXTRA_ALLOW_STREAM_THIS_TIME, false); boolean allowStreamAlways = intent.getBooleanExtra(EXTRA_ALLOW_STREAM_ALWAYS, false); boolean startWhenPrepared = intent.getBooleanExtra(EXTRA_START_WHEN_PREPARED, false); @@ -531,14 +529,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { if (allowStreamAlways) { UserPreferences.setAllowMobileStreaming(true); } - boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl()); - if (stream && !NetworkUtils.isStreamingAllowed() && !allowStreamThisTime && !localFeed) { - displayStreamingNotAllowedNotification(intent); - PlaybackPreferences.writeNoMediaPlaying(); - stateManager.stopService(); - return Service.START_NOT_STICKY; - } - Observable.fromCallable( () -> { if (playable instanceof FeedMedia) { @@ -550,15 +540,9 @@ public class PlaybackService extends MediaBrowserServiceCompat { .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( - playableLoaded -> { - if (!playable.getIdentifier().equals( - PlaybackPreferences.getCurrentlyPlayingFeedMediaId())) { - PlaybackPreferences.clearCurrentlyPlayingTemporaryPlaybackSpeed(); - } - mediaPlayer.playMediaObject(playableLoaded, stream, startWhenPrepared, - prepareImmediately); - addPlayableToQueue(playableLoaded); - }, error -> { + loadedPlayable -> startPlaying(loadedPlayable, allowStreamThisTime, + startWhenPrepared, prepareImmediately), + error -> { Log.d(TAG, "Playable was not found. Stopping service."); error.printStackTrace(); stateManager.stopService(); @@ -741,32 +725,39 @@ public class PlaybackService extends MediaBrowserServiceCompat { .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( - playable -> { - boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl()); - if (PlaybackPreferences.getCurrentEpisodeIsStream() - && !NetworkUtils.isStreamingAllowed() && !localFeed) { - displayStreamingNotAllowedNotification( - new PlaybackServiceStarter(this, playable) - .prepareImmediately(true) - .startWhenPrepared(true) - .shouldStream(true) - .getIntent()); - PlaybackPreferences.writeNoMediaPlaying(); - stateManager.stopService(); - return; - } - mediaPlayer.playMediaObject(playable, PlaybackPreferences.getCurrentEpisodeIsStream(), - true, true); - stateManager.validStartCommandWasReceived(); - updateNotificationAndMediaSession(playable); - addPlayableToQueue(playable); - }, error -> { + playable -> startPlaying(playable, false, true, true), + error -> { Log.d(TAG, "Playable was not loaded from preferences. Stopping service."); error.printStackTrace(); stateManager.stopService(); }); } + private void startPlaying(Playable playable, boolean allowStreamThisTime, + boolean startWhenPrepared, boolean prepareImmediately) { + boolean localFeed = URLUtil.isContentUrl(playable.getStreamUrl()); + boolean stream = !playable.localFileAvailable() || localFeed; + if (stream && !localFeed && !NetworkUtils.isStreamingAllowed() && !allowStreamThisTime) { + displayStreamingNotAllowedNotification( + new PlaybackServiceStarter(this, playable) + .prepareImmediately(true) + .startWhenPrepared(true) + .getIntent()); + PlaybackPreferences.writeNoMediaPlaying(); + stateManager.stopService(); + return; + } + + if (!playable.getIdentifier().equals(PlaybackPreferences.getCurrentlyPlayingFeedMediaId())) { + PlaybackPreferences.clearCurrentlyPlayingTemporaryPlaybackSpeed(); + } + + mediaPlayer.playMediaObject(playable, stream, startWhenPrepared, prepareImmediately); + stateManager.validStartCommandWasReceived(); + updateNotificationAndMediaSession(playable); + addPlayableToQueue(playable); + } + /** * Called by a mediaplayer Activity as soon as it has prepared its * mediaplayer. @@ -792,7 +783,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { @Override public WidgetUpdater.WidgetState requestWidgetState() { return new WidgetUpdater.WidgetState(getPlayable(), getStatus(), - getCurrentPosition(), getDuration(), getCurrentPlaybackSpeed(), isCasting()); + getCurrentPosition(), getDuration(), getCurrentPlaybackSpeed()); } @Override @@ -814,7 +805,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { switch (newInfo.playerStatus) { case INITIALIZED: PlaybackPreferences.writeMediaPlaying(mediaPlayer.getPSMPInfo().playable, - mediaPlayer.getPSMPInfo().playerStatus, mediaPlayer.isStreaming()); + mediaPlayer.getPSMPInfo().playerStatus); updateNotificationAndMediaSession(newInfo.playable); break; case PREPARED: @@ -1005,7 +996,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { if (!UserPreferences.isFollowQueue()) { Log.d(TAG, "getNextInQueue(), but follow queue is not enabled."); - PlaybackPreferences.writeMediaPlaying(nextItem.getMedia(), PlayerStatus.STOPPED, false); + PlaybackPreferences.writeMediaPlaying(nextItem.getMedia(), PlayerStatus.STOPPED); updateNotificationAndMediaSession(nextItem.getMedia()); return null; } @@ -1016,7 +1007,6 @@ public class PlaybackService extends MediaBrowserServiceCompat { new PlaybackServiceStarter(this, nextItem.getMedia()) .prepareImmediately(true) .startWhenPrepared(true) - .shouldStream(true) .getIntent()); PlaybackPreferences.writeNoMediaPlaying(); stateManager.stopService(); @@ -1805,8 +1795,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { Log.d(TAG, "onPlayFromMediaId: mediaId: " + mediaId + " extras: " + extras.toString()); FeedMedia p = DBReader.getFeedMedia(Long.parseLong(mediaId)); if (p != null) { - mediaPlayer.playMediaObject(p, !p.localFileAvailable(), true, true); - addPlayableToQueue(p); + startPlaying(p, false, true, true); } } @@ -1817,8 +1806,7 @@ public class PlaybackService extends MediaBrowserServiceCompat { List results = FeedSearcher.searchFeedItems(getBaseContext(), query, 0); if (results.size() > 0 && results.get(0).getMedia() != null) { FeedMedia media = results.get(0).getMedia(); - mediaPlayer.playMediaObject(media, !media.localFileAvailable(), true, true); - addPlayableToQueue(media); + startPlaying(media, false, true, true); return; } onPlay(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java index 549171c76..687a0d80a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java @@ -331,7 +331,6 @@ public abstract class PlaybackController { if (playbackService == null) { new PlaybackServiceStarter(activity, media) .startWhenPrepared(true) - .streamIfLastWasStream() .start(); Log.w(TAG, "Play/Pause button was pressed, but playbackservice was null!"); return; @@ -354,7 +353,6 @@ public abstract class PlaybackController { default: new PlaybackServiceStarter(activity, media) .startWhenPrepared(true) - .streamIfLastWasStream() .callEvenIfRunning(true) .start(); Log.w(TAG, "Play/Pause button was pressed and PlaybackService state was unknown"); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java index 3efded9ed..7cf6b9adb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackServiceStarter.java @@ -5,7 +5,6 @@ import android.content.Intent; import android.os.Parcelable; import androidx.core.content.ContextCompat; -import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.model.playback.Playable; @@ -13,7 +12,6 @@ public class PlaybackServiceStarter { private final Context context; private final Playable media; private boolean startWhenPrepared = false; - private boolean shouldStream = false; private boolean shouldStreamThisTime = false; private boolean callEvenIfRunning = false; private boolean prepareImmediately = true; @@ -23,19 +21,6 @@ public class PlaybackServiceStarter { this.media = media; } - /** - * Default value: false - */ - public PlaybackServiceStarter shouldStream(boolean shouldStream) { - this.shouldStream = shouldStream; - return this; - } - - public PlaybackServiceStarter streamIfLastWasStream() { - boolean lastIsStream = PlaybackPreferences.getCurrentEpisodeIsStream(); - return shouldStream(lastIsStream); - } - /** * Default value: false */ @@ -69,7 +54,6 @@ public class PlaybackServiceStarter { Intent launchIntent = new Intent(context, PlaybackService.class); launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, (Parcelable) media); launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, startWhenPrepared); - launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream); launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, prepareImmediately); launchIntent.putExtra(PlaybackService.EXTRA_ALLOW_STREAM_THIS_TIME, shouldStreamThisTime); diff --git a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java index 2762fb9fe..1253c747b 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java +++ b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdater.java @@ -45,20 +45,17 @@ public abstract class WidgetUpdater { final int position; final int duration; final float playbackSpeed; - final boolean isCasting; - public WidgetState(Playable media, PlayerStatus status, int position, int duration, - float playbackSpeed, boolean isCasting) { + public WidgetState(Playable media, PlayerStatus status, int position, int duration, float playbackSpeed) { this.media = media; this.status = status; this.position = position; this.duration = duration; this.playbackSpeed = playbackSpeed; - this.isCasting = isCasting; } public WidgetState(PlayerStatus status) { - this(null, status, Playable.INVALID_TIME, Playable.INVALID_TIME, 1.0f, false); + this(null, status, Playable.INVALID_TIME, Playable.INVALID_TIME, 1.0f); } } @@ -71,8 +68,7 @@ public abstract class WidgetUpdater { } PendingIntent startMediaPlayer; - if (widgetState.media != null && widgetState.media.getMediaType() == MediaType.VIDEO - && !widgetState.isCasting) { + if (widgetState.media != null && widgetState.media.getMediaType() == MediaType.VIDEO) { startMediaPlayer = new VideoPlayerActivityStarter(context).getPendingIntent(); } else { startMediaPlayer = new MainActivityStarter(context).withOpenPlayer().getPendingIntent(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java index 325c508c5..598544a0c 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/widget/WidgetUpdaterJobService.java @@ -5,7 +5,6 @@ import android.content.Intent; import androidx.annotation.NonNull; import androidx.core.app.SafeJobIntentService; import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; -import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.model.playback.Playable; import de.danoeh.antennapod.core.util.playback.PlayableUtils; import de.danoeh.antennapod.playback.base.PlayerStatus; @@ -26,8 +25,7 @@ public class WidgetUpdaterJobService extends SafeJobIntentService { Playable media = PlayableUtils.createInstanceFromPreferences(getApplicationContext()); if (media != null) { WidgetUpdater.updateWidget(this, new WidgetUpdater.WidgetState(media, PlayerStatus.STOPPED, - media.getPosition(), media.getDuration(), PlaybackSpeedUtils.getCurrentPlaybackSpeed(media), - PlaybackPreferences.getCurrentEpisodeIsStream())); + media.getPosition(), media.getDuration(), PlaybackSpeedUtils.getCurrentPlaybackSpeed(media))); } else { WidgetUpdater.updateWidget(this, new WidgetUpdater.WidgetState(PlayerStatus.STOPPED)); } -- cgit v1.2.3