fix skipping episodes and unwanted reinits
This commit is contained in:
parent
9981c71bab
commit
fab2d05979
|
@ -1441,30 +1441,29 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
|
|||
*/
|
||||
private void onRemoteMediaPlayerStatusUpdated() {
|
||||
Log.d(TAG, "onRemoteMediaPlayerStatusUpdated() reached");
|
||||
if (mApiClient == null || remoteMediaPlayer == null
|
||||
|| remoteMediaPlayer.getMediaStatus() == null) {
|
||||
if (mApiClient == null || remoteMediaPlayer == null) {
|
||||
Log.d(TAG, "mApiClient or remoteMediaPlayer is null, so will not proceed");
|
||||
return;
|
||||
}
|
||||
mediaStatus = remoteMediaPlayer.getMediaStatus();
|
||||
List<MediaQueueItem> queueItems = mediaStatus.getQueueItems();
|
||||
if (queueItems != null) {
|
||||
int itemId = mediaStatus.getCurrentItemId();
|
||||
MediaQueueItem item = mediaStatus.getQueueItemById(itemId);
|
||||
int repeatMode = mediaStatus.getQueueRepeatMode();
|
||||
onQueueUpdated(queueItems, item, repeatMode, false);
|
||||
if (mediaStatus == null) {
|
||||
Log.d(TAG, "MediaStatus is null, so will not proceed");
|
||||
} else {
|
||||
onQueueUpdated(null, null, MediaStatus.REPEAT_MODE_REPEAT_OFF, false);
|
||||
}
|
||||
state = mediaStatus.getPlayerState();
|
||||
idleReason = mediaStatus.getIdleReason();
|
||||
List<MediaQueueItem> queueItems = mediaStatus.getQueueItems();
|
||||
if (queueItems != null) {
|
||||
int itemId = mediaStatus.getCurrentItemId();
|
||||
MediaQueueItem item = mediaStatus.getQueueItemById(itemId);
|
||||
int repeatMode = mediaStatus.getQueueRepeatMode();
|
||||
onQueueUpdated(queueItems, item, repeatMode, false);
|
||||
} else {
|
||||
onQueueUpdated(null, null, MediaStatus.REPEAT_MODE_REPEAT_OFF, false);
|
||||
}
|
||||
state = mediaStatus.getPlayerState();
|
||||
idleReason = mediaStatus.getIdleReason();
|
||||
|
||||
try {
|
||||
double volume = getStreamVolume();
|
||||
boolean isMute = isStreamMute();
|
||||
if (state == MediaStatus.PLAYER_STATE_PLAYING) {
|
||||
Log.d(TAG, "onRemoteMediaPlayerStatusUpdated(): Player status = playing");
|
||||
long mediaDurationLeft = getMediaTimeRemaining();
|
||||
// long mediaDurationLeft = getMediaTimeRemaining();
|
||||
//startReconnectionService(mediaDurationLeft);
|
||||
} else if (state == MediaStatus.PLAYER_STATE_PAUSED) {
|
||||
Log.d(TAG, "onRemoteMediaPlayerStatusUpdated(): Player status = paused");
|
||||
|
@ -1482,14 +1481,17 @@ public class CastManager extends BaseCastManager implements OnFailedListener {
|
|||
} else {
|
||||
Log.d(TAG, "onRemoteMediaPlayerStatusUpdated(): Player status = unknown");
|
||||
}
|
||||
}
|
||||
for (CastConsumer consumer : castConsumers) {
|
||||
consumer.onRemoteMediaPlayerStatusUpdated();
|
||||
}
|
||||
if (mediaStatus != null) {
|
||||
double volume = mediaStatus.getStreamVolume();
|
||||
boolean isMute = mediaStatus.isMute();
|
||||
for (CastConsumer consumer : castConsumers) {
|
||||
consumer.onRemoteMediaPlayerStatusUpdated();
|
||||
consumer.onStreamVolumeChanged(volume, isMute);
|
||||
}
|
||||
} catch (TransientNetworkDisconnectionException | NoConnectionException e) {
|
||||
Log.e(TAG, "Failed to get volume state due to network issues", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onRemoteMediaPreloadStatusUpdated() {
|
||||
|
|
|
@ -599,6 +599,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
|
|||
public void shutdown() {
|
||||
executor.shutdown();
|
||||
if (mediaPlayer != null) {
|
||||
removeMediaPlayerListeners(mediaPlayer);
|
||||
mediaPlayer.release();
|
||||
}
|
||||
releaseWifiLockIfNecessary();
|
||||
|
@ -762,7 +763,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
|
|||
|
||||
}
|
||||
audioManager.abandonAudioFocus(audioFocusChangeListener);
|
||||
callback.endPlayback(isPlaying, wasSkipped, switchingPlayers);
|
||||
callback.endPlayback(media, isPlaying, wasSkipped, switchingPlayers);
|
||||
|
||||
playerLock.unlock();
|
||||
});
|
||||
|
@ -821,6 +822,26 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
|
|||
return mp;
|
||||
}
|
||||
|
||||
private void removeMediaPlayerListeners(IPlayer mp) {
|
||||
if (mp == null) {
|
||||
return;
|
||||
}
|
||||
if (mp instanceof AudioPlayer) {
|
||||
((AudioPlayer) mp).setOnCompletionListener(null);
|
||||
((AudioPlayer) mp).setOnSeekCompleteListener(null);
|
||||
((AudioPlayer) mp).setOnErrorListener(null);
|
||||
((AudioPlayer) mp).setOnBufferingUpdateListener(null);
|
||||
((AudioPlayer) mp).setOnInfoListener(null);
|
||||
((AudioPlayer) mp).setOnSpeedAdjustmentAvailableChangedListener(null);
|
||||
} else {
|
||||
((VideoPlayer) mp).setOnCompletionListener(null);
|
||||
((VideoPlayer) mp).setOnSeekCompleteListener(null);
|
||||
((VideoPlayer) mp).setOnErrorListener(null);
|
||||
((VideoPlayer) mp).setOnBufferingUpdateListener(null);
|
||||
((VideoPlayer) mp).setOnInfoListener(null);
|
||||
}
|
||||
}
|
||||
|
||||
private final MediaPlayer.OnCompletionListener audioCompletionListener =
|
||||
mp -> genericOnCompletion();
|
||||
|
||||
|
|
|
@ -413,11 +413,7 @@ public class PlaybackService extends Service {
|
|||
case KeyEvent.KEYCODE_HEADSETHOOK:
|
||||
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
|
||||
if (status == PlayerStatus.PLAYING) {
|
||||
if (UserPreferences.isPersistNotify()) {
|
||||
mediaPlayer.pause(false, true);
|
||||
} else {
|
||||
mediaPlayer.pause(true, true);
|
||||
}
|
||||
mediaPlayer.pause(!UserPreferences.isPersistNotify(), true);
|
||||
} else if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
|
||||
mediaPlayer.resume();
|
||||
} else if (status == PlayerStatus.PREPARING) {
|
||||
|
@ -437,12 +433,7 @@ public class PlaybackService extends Service {
|
|||
break;
|
||||
case KeyEvent.KEYCODE_MEDIA_PAUSE:
|
||||
if (status == PlayerStatus.PLAYING) {
|
||||
mediaPlayer.pause(false, true);
|
||||
}
|
||||
if (UserPreferences.isPersistNotify()) {
|
||||
mediaPlayer.pause(false, true);
|
||||
} else {
|
||||
mediaPlayer.pause(true, true);
|
||||
mediaPlayer.pause(!UserPreferences.isPersistNotify(), true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -674,16 +665,15 @@ public class PlaybackService extends Service {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean endPlayback(boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers) {
|
||||
PlaybackService.this.endPlayback(playNextEpisode, wasSkipped, switchingPlayers);
|
||||
public boolean endPlayback(Playable media, boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers) {
|
||||
PlaybackService.this.endPlayback(media, playNextEpisode, wasSkipped, switchingPlayers);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private void endPlayback(boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers) {
|
||||
private void endPlayback(final Playable playable, boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers) {
|
||||
Log.d(TAG, "Playback ended");
|
||||
|
||||
final Playable playable = mediaPlayer.getPlayable();
|
||||
if (playable == null) {
|
||||
Log.e(TAG, "Cannot end playback: media was null");
|
||||
return;
|
||||
|
@ -698,26 +688,35 @@ public class PlaybackService extends Service {
|
|||
FeedMedia media = (FeedMedia) playable;
|
||||
FeedItem item = media.getItem();
|
||||
|
||||
try {
|
||||
final List<FeedItem> queue = taskManager.getQueue();
|
||||
isInQueue = QueueAccess.ItemListAccess(queue).contains(item.getId());
|
||||
nextItem = DBTasks.getQueueSuccessorOfItem(item.getId(), queue);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
// isInQueue remains false
|
||||
}
|
||||
if (!switchingPlayers) {
|
||||
try {
|
||||
final List<FeedItem> queue = taskManager.getQueue();
|
||||
isInQueue = QueueAccess.ItemListAccess(queue).contains(item.getId());
|
||||
nextItem = DBTasks.getQueueSuccessorOfItem(item.getId(), queue);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
// isInQueue remains false
|
||||
}
|
||||
|
||||
boolean shouldKeep = wasSkipped && UserPreferences.shouldSkipKeepEpisode();
|
||||
boolean shouldKeep = wasSkipped && UserPreferences.shouldSkipKeepEpisode();
|
||||
|
||||
if (!shouldKeep) {
|
||||
// only mark the item as played if we're not keeping it anyways
|
||||
DBWriter.markItemPlayed(item, FeedItem.PLAYED, true);
|
||||
if (!shouldKeep) {
|
||||
// only mark the item as played if we're not keeping it anyways
|
||||
DBWriter.markItemPlayed(item, FeedItem.PLAYED, true);
|
||||
|
||||
if (isInQueue) {
|
||||
DBWriter.removeQueueItem(PlaybackService.this, item, true);
|
||||
if (isInQueue) {
|
||||
DBWriter.removeQueueItem(PlaybackService.this, item, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete episode if enabled
|
||||
if (item.getFeed().getPreferences().getCurrentAutoDelete() && !shouldKeep) {
|
||||
DBWriter.deleteFeedMediaOfItem(PlaybackService.this, media.getId());
|
||||
Log.d(TAG, "Episode Deleted");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DBWriter.addItemToPlaybackHistory(media);
|
||||
|
||||
// auto-flattr if enabled
|
||||
|
@ -725,12 +724,6 @@ public class PlaybackService extends Service {
|
|||
DBTasks.flattrItemIfLoggedIn(PlaybackService.this, item);
|
||||
}
|
||||
|
||||
// Delete episode if enabled
|
||||
if(item.getFeed().getPreferences().getCurrentAutoDelete() && !shouldKeep ) {
|
||||
DBWriter.deleteFeedMediaOfItem(PlaybackService.this, media.getId());
|
||||
Log.d(TAG, "Episode Deleted");
|
||||
}
|
||||
|
||||
// gpodder play action
|
||||
if(GpodnetPreferences.loggedIn()) {
|
||||
GpodnetEpisodeAction action = new GpodnetEpisodeAction.Builder(item, Action.PLAY)
|
||||
|
@ -744,49 +737,49 @@ public class PlaybackService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
// Load next episode if previous episode was in the queue and if there
|
||||
// is an episode in the queue left.
|
||||
// Start playback immediately if continuous playback is enabled
|
||||
Playable nextMedia = null;
|
||||
boolean loadNextItem = ClientConfig.playbackServiceCallbacks.useQueue() &&
|
||||
isInQueue &&
|
||||
nextItem != null;
|
||||
if (!switchingPlayers) {
|
||||
// Load next episode if previous episode was in the queue and if there
|
||||
// is an episode in the queue left.
|
||||
// Start playback immediately if continuous playback is enabled
|
||||
Playable nextMedia = null;
|
||||
boolean loadNextItem = ClientConfig.playbackServiceCallbacks.useQueue() &&
|
||||
isInQueue &&
|
||||
nextItem != null;
|
||||
|
||||
playNextEpisode = playNextEpisode &&
|
||||
loadNextItem &&
|
||||
UserPreferences.isFollowQueue();
|
||||
playNextEpisode = playNextEpisode &&
|
||||
loadNextItem &&
|
||||
UserPreferences.isFollowQueue();
|
||||
|
||||
if (loadNextItem) {
|
||||
Log.d(TAG, "Loading next item in queue");
|
||||
nextMedia = nextItem.getMedia();
|
||||
}
|
||||
final boolean prepareImmediately;
|
||||
final boolean startWhenPrepared;
|
||||
final boolean stream;
|
||||
|
||||
if (playNextEpisode) {
|
||||
Log.d(TAG, "Playback of next episode will start immediately.");
|
||||
prepareImmediately = startWhenPrepared = true;
|
||||
} else {
|
||||
Log.d(TAG, "No more episodes available to play");
|
||||
prepareImmediately = startWhenPrepared = false;
|
||||
stopForeground(true);
|
||||
stopWidgetUpdater();
|
||||
}
|
||||
|
||||
writePlaybackPreferencesNoMediaPlaying();
|
||||
if (nextMedia != null) {
|
||||
stream = !nextMedia.localFileAvailable();
|
||||
mediaPlayer.playMediaObject(nextMedia, stream, startWhenPrepared, prepareImmediately);
|
||||
sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD,
|
||||
isCasting ? EXTRA_CODE_CAST :
|
||||
(nextMedia.getMediaType() == MediaType.VIDEO) ? EXTRA_CODE_VIDEO : EXTRA_CODE_AUDIO);
|
||||
} else {
|
||||
if (!switchingPlayers) {
|
||||
sendNotificationBroadcast(NOTIFICATION_TYPE_PLAYBACK_END, 0);
|
||||
if (loadNextItem) {
|
||||
Log.d(TAG, "Loading next item in queue");
|
||||
nextMedia = nextItem.getMedia();
|
||||
}
|
||||
final boolean prepareImmediately;
|
||||
final boolean startWhenPrepared;
|
||||
final boolean stream;
|
||||
|
||||
if (playNextEpisode) {
|
||||
Log.d(TAG, "Playback of next episode will start immediately.");
|
||||
prepareImmediately = startWhenPrepared = true;
|
||||
} else {
|
||||
Log.d(TAG, "No more episodes available to play");
|
||||
prepareImmediately = startWhenPrepared = false;
|
||||
stopForeground(true);
|
||||
stopWidgetUpdater();
|
||||
}
|
||||
|
||||
writePlaybackPreferencesNoMediaPlaying();
|
||||
if (nextMedia != null) {
|
||||
stream = !nextMedia.localFileAvailable();
|
||||
mediaPlayer.playMediaObject(nextMedia, stream, startWhenPrepared, prepareImmediately);
|
||||
sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD,
|
||||
isCasting ? EXTRA_CODE_CAST :
|
||||
(nextMedia.getMediaType() == MediaType.VIDEO) ? EXTRA_CODE_VIDEO : EXTRA_CODE_AUDIO);
|
||||
} else {
|
||||
sendNotificationBroadcast(NOTIFICATION_TYPE_PLAYBACK_END, 0);
|
||||
mediaPlayer.stop();
|
||||
//stopSelf();
|
||||
}
|
||||
mediaPlayer.stop();
|
||||
//stopSelf();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1024,8 +1017,8 @@ public class PlaybackService extends Service {
|
|||
.centerCrop()
|
||||
.into(iconSize, iconSize)
|
||||
.get();
|
||||
} catch(Throwable tr) {
|
||||
Log.e(TAG, Log.getStackTraceString(tr));
|
||||
} catch (Throwable tr) {
|
||||
Log.e(TAG, "Error loading the media icon for the notification", tr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1300,11 +1293,7 @@ public class PlaybackService extends Service {
|
|||
if (mediaPlayer.getPlayerStatus() == PlayerStatus.PLAYING) {
|
||||
transientPause = true;
|
||||
}
|
||||
if (UserPreferences.isPersistNotify()) {
|
||||
mediaPlayer.pause(false, true);
|
||||
} else {
|
||||
mediaPlayer.pause(true, true);
|
||||
}
|
||||
mediaPlayer.pause(!UserPreferences.isPersistNotify(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ public abstract class PlaybackServiceMediaPlayer {
|
|||
* @param newMedia The new playable object of the PSMP object. This can be null.
|
||||
*/
|
||||
protected synchronized final void setPlayerStatus(@NonNull PlayerStatus newStatus, Playable newMedia) {
|
||||
Log.d(TAG, "Setting player status to " + newStatus);
|
||||
Log.d(TAG, this.getClass().getSimpleName() + ": Setting player status to " + newStatus);
|
||||
|
||||
this.playerStatus = newStatus;
|
||||
setPlayable(newMedia);
|
||||
|
@ -327,7 +327,7 @@ public abstract class PlaybackServiceMediaPlayer {
|
|||
|
||||
boolean onMediaPlayerError(Object inObj, int what, int extra);
|
||||
|
||||
boolean endPlayback(boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers);
|
||||
boolean endPlayback(Playable media, boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -64,8 +64,8 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
if (castMgr.isConnected() && castMgr.isRemoteMediaLoaded()) {
|
||||
// updates the state, but does not start playing new media if it was going to
|
||||
onRemoteMediaPlayerStatusUpdated(
|
||||
((playNextEpisode, wasSkipped, switchingPlayers) ->
|
||||
this.callback.endPlayback(false, wasSkipped, switchingPlayers)));
|
||||
((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);
|
||||
|
@ -146,6 +146,7 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
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;
|
||||
|
@ -186,12 +187,12 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
case MediaStatus.IDLE_REASON_FINISHED:
|
||||
boolean playing = playerStatus == PlayerStatus.PLAYING;
|
||||
setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia);
|
||||
endPlaybackCall.endPlayback(playing, false, false);
|
||||
endPlaybackCall.endPlayback(currentMedia,playing, false, false);
|
||||
break;
|
||||
case MediaStatus.IDLE_REASON_ERROR:
|
||||
//Let's assume it's a media format error. Skipping...
|
||||
Log.w(TAG, "Got an error status from the Chromecast. Skipping, if possible, to the next episode...");
|
||||
setPlayerStatus(PlayerStatus.INDETERMINATE, currentMedia);
|
||||
endPlaybackCall.endPlayback(startWhenPrepared.get(), true, false);
|
||||
endPlaybackCall.endPlayback(currentMedia, startWhenPrepared.get(), true, false);
|
||||
}
|
||||
break;
|
||||
case MediaStatus.PLAYER_STATE_UNKNOWN:
|
||||
|
@ -286,18 +287,13 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
|
||||
@Override
|
||||
public void pause(boolean abandonFocus, boolean reinit) {
|
||||
boolean playing = true;
|
||||
try {
|
||||
playing = castMgr.isRemoteMediaPlaying();
|
||||
if (playing) {
|
||||
if (castMgr.isRemoteMediaPlaying()) {
|
||||
castMgr.pause();
|
||||
}
|
||||
} catch (CastException | TransientNetworkDisconnectionException | NoConnectionException e) {
|
||||
Log.e(TAG, "Unable to pause", e);
|
||||
}
|
||||
if (playing && reinit) {
|
||||
reinit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -325,6 +321,7 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
|
||||
@Override
|
||||
public void reinit() {
|
||||
Log.d(TAG, "reinit() called");
|
||||
if (media != null) {
|
||||
playMediaObject(media, true, false, startWhenPrepared.get(), false);
|
||||
} else {
|
||||
|
@ -513,11 +510,12 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
|
||||
@Override
|
||||
public void endPlayback(boolean wasSkipped, boolean switchingPlayers) {
|
||||
Log.d(TAG, "endPlayback() called");
|
||||
boolean isPlaying = playerStatus == PlayerStatus.PLAYING;
|
||||
if (playerStatus != PlayerStatus.INDETERMINATE) {
|
||||
setPlayerStatus(PlayerStatus.INDETERMINATE, media);
|
||||
}
|
||||
callback.endPlayback(isPlaying, wasSkipped, switchingPlayers);
|
||||
callback.endPlayback(media, isPlaying, wasSkipped, switchingPlayers);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -535,6 +533,6 @@ public class RemotePSMP extends PlaybackServiceMediaPlayer {
|
|||
}
|
||||
|
||||
private interface EndPlaybackCall {
|
||||
boolean endPlayback(boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers);
|
||||
boolean endPlayback(Playable media, boolean playNextEpisode, boolean wasSkipped, boolean switchingPlayers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package de.danoeh.antennapod.core.util;
|
||||
|
||||
public interface Supplier<T> {
|
||||
T get();
|
||||
}
|
|
@ -750,6 +750,7 @@ public abstract class PlaybackController {
|
|||
public void reinitServiceIfPaused() {
|
||||
if (playbackService != null
|
||||
&& playbackService.isStreaming()
|
||||
&& !PlaybackService.isCasting()
|
||||
&& (playbackService.getStatus() == PlayerStatus.PAUSED ||
|
||||
(playbackService.getStatus() == PlayerStatus.PREPARING &&
|
||||
!playbackService.isStartWhenPrepared()))) {
|
||||
|
|
Loading…
Reference in New Issue