summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorByteHamster <ByteHamster@users.noreply.github.com>2023-02-26 16:38:31 +0100
committerGitHub <noreply@github.com>2023-02-26 16:38:31 +0100
commitccea00e4056b85d5be0ebfa898a1ac961c2e3c56 (patch)
treefa7d9bad089b25843bd55d2358962fd09f1cbe04 /core
parent3e077e5653d1c1be266d2bb5add85902c93e616e (diff)
downloadAntennaPod-ccea00e4056b85d5be0ebfa898a1ac961c2e3c56.zip
Remove deprecated media players (#6354)
Diffstat (limited to 'core')
-rw-r--r--core/build.gradle1
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java74
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/LocalPSMP.java751
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java77
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java56
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/PlaybackController.java12
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java56
-rw-r--r--core/src/main/res/values/arrays.xml12
9 files changed, 203 insertions, 844 deletions
diff --git a/core/build.gradle b/core/build.gradle
index 466b4ea74..a70a1e1c0 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -66,7 +66,6 @@ dependencies {
implementation "com.google.android.exoplayer:exoplayer-core:$exoPlayerVersion"
implementation "com.google.android.exoplayer:exoplayer-ui:$exoPlayerVersion"
implementation "com.google.android.exoplayer:extension-okhttp:$exoPlayerVersion"
- implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
// Non-free dependencies:
playApi "com.google.android.support:wearable:$wearableSupportVersion"
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
index 9856c617e..e0c5da00b 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/ExoPlayerWrapper.java
@@ -40,12 +40,10 @@ import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.core.service.download.HttpCredentialEncoder;
import de.danoeh.antennapod.core.util.NetworkUtils;
-import de.danoeh.antennapod.core.util.playback.IPlayer;
import de.danoeh.antennapod.model.playback.Playable;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
-import org.antennapod.audio.MediaPlayer;
import java.util.ArrayList;
import java.util.Collections;
@@ -53,19 +51,21 @@ import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
-public class ExoPlayerWrapper implements IPlayer {
+public class ExoPlayerWrapper {
+ public static final int BUFFERING_STARTED = -1;
+ public static final int BUFFERING_ENDED = -2;
private static final String TAG = "ExoPlayerWrapper";
public static final int ERROR_CODE_OFFSET = 1000;
+
private final Context context;
private final Disposable bufferingUpdateDisposable;
private SimpleExoPlayer exoPlayer;
private MediaSource mediaSource;
- private MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener;
- private MediaPlayer.OnCompletionListener audioCompletionListener;
+ private Runnable audioSeekCompleteListener;
+ private Runnable audioCompletionListener;
private Consumer<String> audioErrorListener;
- private MediaPlayer.OnBufferingUpdateListener bufferingUpdateListener;
+ private Consumer<Integer> bufferingUpdateListener;
private PlaybackParameters playbackParameters;
- private MediaPlayer.OnInfoListener infoListener;
private DefaultTrackSelector trackSelector;
ExoPlayerWrapper(Context context) {
@@ -76,7 +76,7 @@ public class ExoPlayerWrapper implements IPlayer {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tickNumber -> {
if (bufferingUpdateListener != null) {
- bufferingUpdateListener.onBufferingUpdate(null, exoPlayer.getBufferedPercentage());
+ bufferingUpdateListener.accept(exoPlayer.getBufferedPercentage());
}
});
}
@@ -97,11 +97,11 @@ public class ExoPlayerWrapper implements IPlayer {
@Override
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (audioCompletionListener != null && playbackState == Player.STATE_ENDED) {
- audioCompletionListener.onCompletion(null);
- } else if (infoListener != null && playbackState == Player.STATE_BUFFERING) {
- infoListener.onInfo(null, android.media.MediaPlayer.MEDIA_INFO_BUFFERING_START, 0);
- } else if (infoListener != null) {
- infoListener.onInfo(null, android.media.MediaPlayer.MEDIA_INFO_BUFFERING_END, 0);
+ audioCompletionListener.run();
+ } else if (bufferingUpdateListener != null && playbackState == Player.STATE_BUFFERING) {
+ bufferingUpdateListener.accept(BUFFERING_STARTED);
+ } else if (bufferingUpdateListener != null) {
+ bufferingUpdateListener.accept(BUFFERING_ENDED);
}
}
@@ -130,28 +130,20 @@ public class ExoPlayerWrapper implements IPlayer {
@NonNull Player.PositionInfo newPosition,
@Player.DiscontinuityReason int reason) {
if (audioSeekCompleteListener != null && reason == Player.DISCONTINUITY_REASON_SEEK) {
- audioSeekCompleteListener.onSeekComplete(null);
+ audioSeekCompleteListener.run();
}
}
});
}
- @Override
- public boolean canDownmix() {
- return false;
- }
-
- @Override
public int getCurrentPosition() {
return (int) exoPlayer.getCurrentPosition();
}
- @Override
public float getCurrentSpeedMultiplier() {
return playbackParameters.speed;
}
- @Override
public int getDuration() {
if (exoPlayer.getDuration() == C.TIME_UNSET) {
return Playable.INVALID_TIME;
@@ -159,23 +151,19 @@ public class ExoPlayerWrapper implements IPlayer {
return (int) exoPlayer.getDuration();
}
- @Override
public boolean isPlaying() {
return exoPlayer.getPlayWhenReady();
}
- @Override
public void pause() {
exoPlayer.pause();
}
- @Override
public void prepare() throws IllegalStateException {
exoPlayer.setMediaSource(mediaSource, false);
exoPlayer.prepare();
}
- @Override
public void release() {
bufferingUpdateDisposable.dispose();
if (exoPlayer != null) {
@@ -187,21 +175,18 @@ public class ExoPlayerWrapper implements IPlayer {
bufferingUpdateListener = null;
}
- @Override
public void reset() {
exoPlayer.release();
createPlayer();
}
- @Override
public void seekTo(int i) throws IllegalStateException {
exoPlayer.seekTo(i);
if (audioSeekCompleteListener != null) {
- audioSeekCompleteListener.onSeekComplete(null);
+ audioSeekCompleteListener.run();
}
}
- @Override
public void setAudioStreamType(int i) {
AudioAttributes a = exoPlayer.getAudioAttributes();
AudioAttributes.Builder b = new AudioAttributes.Builder();
@@ -235,51 +220,34 @@ public class ExoPlayerWrapper implements IPlayer {
mediaSource = f.createMediaSource(mediaItem);
}
- @Override
public void setDataSource(String s) throws IllegalArgumentException, IllegalStateException {
setDataSource(s, null, null);
}
- @Override
public void setDisplay(SurfaceHolder sh) {
exoPlayer.setVideoSurfaceHolder(sh);
}
- @Override
public void setPlaybackParams(float speed, boolean skipSilence) {
playbackParameters = new PlaybackParameters(speed, playbackParameters.pitch);
exoPlayer.setSkipSilenceEnabled(skipSilence);
exoPlayer.setPlaybackParameters(playbackParameters);
}
- @Override
- public void setDownmix(boolean b) {
-
- }
-
- @Override
public void setVolume(float v, float v1) {
exoPlayer.setVolume(v);
}
- @Override
- public void setWakeMode(Context context, int i) {
-
- }
-
- @Override
public void start() {
exoPlayer.play();
// Can't set params when paused - so always set it on start in case they changed
exoPlayer.setPlaybackParameters(playbackParameters);
}
- @Override
public void stop() {
exoPlayer.stop();
}
- @Override
public List<String> getAudioTracks() {
List<String> trackNames = new ArrayList<>();
TrackNameProvider trackNameProvider = new DefaultTrackNameProvider(context.getResources());
@@ -302,7 +270,6 @@ public class ExoPlayerWrapper implements IPlayer {
return formats;
}
- @Override
public void setAudioTrack(int track) {
MappingTrackSelector.MappedTrackInfo trackInfo = trackSelector.getCurrentMappedTrackInfo();
if (trackInfo == null) {
@@ -324,7 +291,6 @@ public class ExoPlayerWrapper implements IPlayer {
return -1;
}
- @Override
public int getSelectedAudioTrack() {
TrackSelectionArray trackSelections = exoPlayer.getCurrentTrackSelections();
List<Format> availableFormats = getFormats();
@@ -340,11 +306,11 @@ public class ExoPlayerWrapper implements IPlayer {
return -1;
}
- void setOnCompletionListener(MediaPlayer.OnCompletionListener audioCompletionListener) {
+ void setOnCompletionListener(Runnable audioCompletionListener) {
this.audioCompletionListener = audioCompletionListener;
}
- void setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener) {
+ void setOnSeekCompleteListener(Runnable audioSeekCompleteListener) {
this.audioSeekCompleteListener = audioSeekCompleteListener;
}
@@ -366,11 +332,7 @@ public class ExoPlayerWrapper implements IPlayer {
return exoPlayer.getVideoFormat().height;
}
- void setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener bufferingUpdateListener) {
+ void setOnBufferingUpdateListener(Consumer<Integer> bufferingUpdateListener) {
this.bufferingUpdateListener = bufferingUpdateListener;
}
-
- public void setOnInfoListener(MediaPlayer.OnInfoListener infoListener) {
- this.infoListener = infoListener;
- }
}
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 2945cb475..4ff4472ba 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
@@ -6,47 +6,34 @@ import android.content.res.Configuration;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Looper;
-import android.os.PowerManager;
-import androidx.annotation.NonNull;
import android.util.Log;
import android.util.Pair;
import android.view.SurfaceHolder;
-
+import androidx.annotation.NonNull;
import androidx.media.AudioAttributesCompat;
import androidx.media.AudioFocusRequestCompat;
import androidx.media.AudioManagerCompat;
+import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
import de.danoeh.antennapod.event.PlayerErrorEvent;
import de.danoeh.antennapod.event.playback.BufferUpdateEvent;
import de.danoeh.antennapod.event.playback.SpeedChangedEvent;
-import de.danoeh.antennapod.core.util.playback.MediaPlayerError;
+import de.danoeh.antennapod.model.feed.FeedMedia;
+import de.danoeh.antennapod.model.feed.FeedPreferences;
+import de.danoeh.antennapod.model.feed.VolumeAdaptionSetting;
+import de.danoeh.antennapod.model.playback.MediaType;
+import de.danoeh.antennapod.model.playback.Playable;
import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer;
import de.danoeh.antennapod.playback.base.PlayerStatus;
-import org.antennapod.audio.MediaPlayer;
+import de.danoeh.antennapod.playback.base.RewindAfterPauseUtils;
+import de.danoeh.antennapod.storage.preferences.UserPreferences;
+import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Future;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.ReentrantLock;
-
-import de.danoeh.antennapod.model.feed.FeedMedia;
-import de.danoeh.antennapod.model.feed.FeedPreferences;
-import de.danoeh.antennapod.model.playback.MediaType;
-import de.danoeh.antennapod.model.feed.VolumeAdaptionSetting;
-import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
-import de.danoeh.antennapod.storage.preferences.UserPreferences;
-import de.danoeh.antennapod.playback.base.RewindAfterPauseUtils;
-import de.danoeh.antennapod.core.util.playback.AudioPlayer;
-import de.danoeh.antennapod.core.util.playback.IPlayer;
-import de.danoeh.antennapod.model.playback.Playable;
-import de.danoeh.antennapod.core.util.playback.VideoPlayer;
-import org.greenrobot.eventbus.EventBus;
/**
* Manages the MediaPlayer object of the PlaybackService.
@@ -57,7 +44,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
private final AudioManager audioManager;
private volatile PlayerStatus statusBeforeSeeking;
- private volatile IPlayer mediaPlayer;
+ private volatile ExoPlayerWrapper mediaPlayer;
private volatile Playable media;
private volatile boolean stream;
@@ -67,100 +54,15 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
private volatile Pair<Integer, Integer> videoSize;
private final AudioFocusRequestCompat audioFocusRequest;
private final Handler audioFocusCanceller;
-
- /**
- * Some asynchronous calls might change the state of the MediaPlayer object. Therefore calls in other threads
- * have to wait until these operations have finished.
- */
- private final PlayerLock playerLock;
- private final PlayerExecutor executor;
- private boolean useCallerThread = true;
private boolean isShutDown = false;
-
-
private CountDownLatch seekLatch;
- /**
- * All ExoPlayer methods must be executed on the same thread.
- * We use the main application thread. This class allows to
- * "fake" an executor that just calls the methods on the
- * calling thread instead of submitting to an executor.
- * Other players are still executed in a background thread.
- */
- private class PlayerExecutor {
- private ThreadPoolExecutor threadPool;
-
- public Future<?> submit(Runnable r) {
- if (useCallerThread) {
- r.run();
- return new FutureTask<Void>(() -> {}, null);
- } else {
- return threadPool.submit(r);
- }
- }
-
- public void shutdown() {
- threadPool.shutdown();
- }
- }
-
- /**
- * All ExoPlayer methods must be executed on the same thread.
- * We use the main application thread. This class allows to
- * "fake" a lock that does nothing. A lock is not needed if
- * everything is called on the same thread.
- * Other players are still executed in a background thread and
- * therefore use a real lock.
- */
- private class PlayerLock {
- private ReentrantLock lock = new ReentrantLock();
-
- public void lock() {
- if (!useCallerThread) {
- lock.lock();
- }
- }
-
- public boolean tryLock(int i, TimeUnit milliseconds) throws InterruptedException {
- if (!useCallerThread) {
- return lock.tryLock(i, milliseconds);
- }
- return true;
- }
-
- public boolean tryLock() {
- if (!useCallerThread) {
- return lock.tryLock();
- }
- return true;
- }
-
- public void unlock() {
- if (!useCallerThread) {
- lock.unlock();
- }
- }
-
- public boolean isHeldByCurrentThread() {
- if (!useCallerThread) {
- return lock.isHeldByCurrentThread();
- }
- return true;
- }
- }
-
public LocalPSMP(@NonNull Context context,
@NonNull PlaybackServiceMediaPlayer.PSMPCallback callback) {
super(context, callback);
this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- this.playerLock = new PlayerLock();
this.startWhenPrepared = new AtomicBoolean(false);
audioFocusCanceller = new Handler(Looper.getMainLooper());
-
- executor = new PlayerExecutor();
- executor.threadPool = new ThreadPoolExecutor(1, 1, 5, TimeUnit.MINUTES, new LinkedBlockingDeque<>(),
- (r, executor) -> Log.d(TAG, "Rejected execution of runnable"));
-
mediaPlayer = null;
statusBeforeSeeking = null;
pausedBecauseOfTransientAudiofocusLoss = false;
@@ -207,18 +109,12 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
@Override
public void playMediaObject(@NonNull final Playable playable, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) {
Log.d(TAG, "playMediaObject(...)");
- useCallerThread = UserPreferences.useExoplayer();
- executor.submit(() -> {
- playerLock.lock();
- try {
- playMediaObject(playable, false, stream, startWhenPrepared, prepareImmediately);
- } catch (RuntimeException e) {
- e.printStackTrace();
- throw e;
- } finally {
- playerLock.unlock();
- }
- });
+ try {
+ playMediaObject(playable, false, stream, startWhenPrepared, prepareImmediately);
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ throw e;
+ }
}
/**
@@ -230,11 +126,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
* @see #playMediaObject(Playable, boolean, boolean, boolean)
*/
private void playMediaObject(@NonNull final Playable playable, final boolean forceReset, final boolean stream, final boolean startWhenPrepared, final boolean prepareImmediately) {
- if (!playerLock.isHeldByCurrentThread()) {
- throw new IllegalStateException("method requires playerLock");
- }
-
-
if (media != null) {
if (!forceReset && media.getIdentifier().equals(playable.getIdentifier())
&& playerStatus == PlayerStatus.PLAYING) {
@@ -253,7 +144,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
if (!media.getIdentifier().equals(playable.getIdentifier())) {
final Playable oldMedia = media;
- executor.submit(() -> callback.onPostPlayback(oldMedia, false, false, true));
+ callback.onPostPlayback(oldMedia, false, false, true);
}
setPlayerStatus(PlayerStatus.INDETERMINATE, null);
@@ -313,14 +204,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public void resume() {
- executor.submit(() -> {
- playerLock.lock();
- resumeSync();
- playerLock.unlock();
- });
- }
-
- private void resumeSync() {
if (playerStatus == PlayerStatus.PAUSED || playerStatus == PlayerStatus.PREPARED) {
int focusGained = AudioManagerCompat.requestAudioFocus(audioManager, audioFocusRequest);
@@ -336,7 +219,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
int newPosition = RewindAfterPauseUtils.calculatePositionWithRewind(
media.getPosition(),
media.getLastPlayedTime());
- seekToSync(newPosition);
+ seekTo(newPosition);
}
mediaPlayer.start();
@@ -363,27 +246,22 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public void pause(final boolean abandonFocus, final boolean reinit) {
- executor.submit(() -> {
- playerLock.lock();
- releaseWifiLockIfNecessary();
- if (playerStatus == PlayerStatus.PLAYING) {
- Log.d(TAG, "Pausing playback.");
- mediaPlayer.pause();
- setPlayerStatus(PlayerStatus.PAUSED, media, getPosition());
-
- if (abandonFocus) {
- abandonAudioFocus();
- pausedBecauseOfTransientAudiofocusLoss = false;
- }
- if (stream && reinit) {
- reinit();
- }
- } else {
- Log.d(TAG, "Ignoring call to pause: Player is in " + playerStatus + " state");
- }
+ releaseWifiLockIfNecessary();
+ if (playerStatus == PlayerStatus.PLAYING) {
+ Log.d(TAG, "Pausing playback.");
+ mediaPlayer.pause();
+ setPlayerStatus(PlayerStatus.PAUSED, media, getPosition());
- playerLock.unlock();
- });
+ if (abandonFocus) {
+ abandonAudioFocus();
+ pausedBecauseOfTransientAudiofocusLoss = false;
+ }
+ if (stream && reinit) {
+ reinit();
+ }
+ } else {
+ Log.d(TAG, "Ignoring call to pause: Player is in " + playerStatus + " state");
+ }
}
private void abandonAudioFocus() {
@@ -398,50 +276,30 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public void prepare() {
- executor.submit(() -> {
- playerLock.lock();
-
- if (playerStatus == PlayerStatus.INITIALIZED) {
- Log.d(TAG, "Preparing media player");
- setPlayerStatus(PlayerStatus.PREPARING, media);
- try {
- mediaPlayer.prepare();
- onPrepared(startWhenPrepared.get());
- } catch (IOException e) {
- e.printStackTrace();
- setPlayerStatus(PlayerStatus.ERROR, null);
- EventBus.getDefault().postSticky(new PlayerErrorEvent(e.getLocalizedMessage()));
- }
- }
- playerLock.unlock();
-
- });
+ if (playerStatus == PlayerStatus.INITIALIZED) {
+ Log.d(TAG, "Preparing media player");
+ setPlayerStatus(PlayerStatus.PREPARING, media);
+ mediaPlayer.prepare();
+ onPrepared(startWhenPrepared.get());
+ }
}
/**
* Called after media player has been prepared. This method is executed on the caller's thread.
*/
private void onPrepared(final boolean startWhenPrepared) {
- playerLock.lock();
-
if (playerStatus != PlayerStatus.PREPARING) {
- playerLock.unlock();
throw new IllegalStateException("Player is not in PREPARING state");
}
-
Log.d(TAG, "Resource prepared");
- if (mediaType == MediaType.VIDEO && mediaPlayer instanceof ExoPlayerWrapper) {
- ExoPlayerWrapper vp = (ExoPlayerWrapper) mediaPlayer;
- videoSize = new Pair<>(vp.getVideoWidth(), vp.getVideoHeight());
- } else if(mediaType == MediaType.VIDEO && mediaPlayer instanceof VideoPlayer) {
- VideoPlayer vp = (VideoPlayer) mediaPlayer;
- videoSize = new Pair<>(vp.getVideoWidth(), vp.getVideoHeight());
+ if (mediaType == MediaType.VIDEO) {
+ videoSize = new Pair<>(mediaPlayer.getVideoWidth(), mediaPlayer.getVideoHeight());
}
// TODO this call has no effect!
if (media.getPosition() > 0) {
- seekToSync(media.getPosition());
+ seekTo(media.getPosition());
}
if (media.getDuration() <= 0) {
@@ -451,10 +309,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
setPlayerStatus(PlayerStatus.PREPARED, media);
if (startWhenPrepared) {
- resumeSync();
+ resume();
}
-
- playerLock.unlock();
}
/**
@@ -464,35 +320,28 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public void reinit() {
- useCallerThread = UserPreferences.useExoplayer();
- executor.submit(() -> {
- playerLock.lock();
- Log.d(TAG, "reinit()");
- releaseWifiLockIfNecessary();
- if (media != null) {
- playMediaObject(media, true, stream, startWhenPrepared.get(), false);
- } else if (mediaPlayer != null) {
- mediaPlayer.reset();
- } else {
- Log.d(TAG, "Call to reinit was ignored: media and mediaPlayer were null");
- }
- playerLock.unlock();
- });
+ Log.d(TAG, "reinit()");
+ releaseWifiLockIfNecessary();
+ if (media != null) {
+ playMediaObject(media, true, stream, startWhenPrepared.get(), false);
+ } else if (mediaPlayer != null) {
+ mediaPlayer.reset();
+ } else {
+ Log.d(TAG, "Call to reinit was ignored: media and mediaPlayer were null");
+ }
}
-
/**
* Seeks to the specified position. If the PSMP object is in an invalid state, this method will do nothing.
- *
- * @param t The position to seek to in milliseconds. t < 0 will be interpreted as t = 0
- * <p/>
- * This method is executed on the caller's thread.
+ * Invalid time values (< 0) will be ignored.
+ * <p/>
+ * This method is executed on an internal executor service.
*/
- private void seekToSync(int t) {
+ @Override
+ public void seekTo(int t) {
if (t < 0) {
t = 0;
}
- playerLock.lock();
if (playerStatus == PlayerStatus.PLAYING
|| playerStatus == PlayerStatus.PAUSED
@@ -521,18 +370,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
startWhenPrepared.set(false);
prepare();
}
- playerLock.unlock();
- }
-
- /**
- * Seeks to the specified position. If the PSMP object is in an invalid state, this method will do nothing.
- * Invalid time values (< 0) will be ignored.
- * <p/>
- * This method is executed on an internal executor service.
- */
- @Override
- public void seekTo(final int t) {
- executor.submit(() -> seekToSync(t));
}
/**
@@ -542,17 +379,12 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public void seekDelta(final int d) {
- executor.submit(() -> {
- playerLock.lock();
- int currentPosition = getPosition();
- if (currentPosition != Playable.INVALID_TIME) {
- seekToSync(currentPosition + d);
- } else {
- Log.e(TAG, "getPosition() returned INVALID_TIME in seekDelta");
- }
-
- playerLock.unlock();
- });
+ int currentPosition = getPosition();
+ if (currentPosition != Playable.INVALID_TIME) {
+ seekTo(currentPosition + d);
+ } else {
+ Log.e(TAG, "getPosition() returned INVALID_TIME in seekDelta");
+ }
}
/**
@@ -560,10 +392,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public int getDuration() {
- if (!playerLock.tryLock()) {
- return Playable.INVALID_TIME;
- }
-
int retVal = Playable.INVALID_TIME;
if (playerStatus == PlayerStatus.PLAYING
|| playerStatus == PlayerStatus.PAUSED
@@ -573,8 +401,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
if (retVal <= 0 && media != null && media.getDuration() > 0) {
retVal = media.getDuration();
}
-
- playerLock.unlock();
return retVal;
}
@@ -583,14 +409,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public int getPosition() {
- try {
- if (!playerLock.tryLock(50, TimeUnit.MILLISECONDS)) {
- return Playable.INVALID_TIME;
- }
- } catch (InterruptedException e) {
- return Playable.INVALID_TIME;
- }
-
int retVal = Playable.INVALID_TIME;
if (playerStatus.isAtLeast(PlayerStatus.PREPARED)) {
retVal = mediaPlayer.getCurrentPosition();
@@ -598,8 +416,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
if (retVal <= 0 && media != null && media.getPosition() >= 0) {
retVal = media.getPosition();
}
-
- playerLock.unlock();
return retVal;
}
@@ -615,23 +431,13 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
/**
* Sets the playback speed.
- * This method is executed on the caller's thread.
- */
- private void setSpeedSyncAndSkipSilence(float speed, boolean skipSilence) {
- playerLock.lock();
- Log.d(TAG, "Playback speed was set to " + speed);
- EventBus.getDefault().post(new SpeedChangedEvent(speed));
- mediaPlayer.setPlaybackParams(speed, skipSilence);
- playerLock.unlock();
- }
-
- /**
- * Sets the playback speed.
* This method is executed on an internal executor service.
*/
@Override
public void setPlaybackParams(final float speed, final boolean skipSilence) {
- executor.submit(() -> setSpeedSyncAndSkipSilence(speed, skipSilence));
+ Log.d(TAG, "Playback speed was set to " + speed);
+ EventBus.getDefault().post(new SpeedChangedEvent(speed));
+ mediaPlayer.setPlaybackParams(speed, skipSilence);
}
/**
@@ -639,10 +445,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public float getPlaybackSpeed() {
- if (!playerLock.tryLock()) {
- return 1;
- }
-
float retVal = 1;
if ((playerStatus == PlayerStatus.PLAYING
|| playerStatus == PlayerStatus.PAUSED
@@ -650,7 +452,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
|| playerStatus == PlayerStatus.PREPARED)) {
retVal = mediaPlayer.getCurrentSpeedMultiplier();
}
- playerLock.unlock();
return retVal;
}
@@ -659,16 +460,7 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
* This method is executed on an internal executor service.
*/
@Override
- public void setVolume(final float volumeLeft, float volumeRight) {
- executor.submit(() -> setVolumeSync(volumeLeft, volumeRight));
- }
-
- /**
- * Sets the playback volume.
- * This method is executed on the caller's thread.
- */
- private void setVolumeSync(float volumeLeft, float volumeRight) {
- playerLock.lock();
+ public void setVolume(float volumeLeft, float volumeRight) {
Playable playable = getPlayable();
if (playable instanceof FeedMedia) {
FeedMedia feedMedia = (FeedMedia) playable;
@@ -680,29 +472,6 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
}
mediaPlayer.setVolume(volumeLeft, volumeRight);
Log.d(TAG, "Media player volume was set to " + volumeLeft + " " + volumeRight);
- playerLock.unlock();
- }
-
- /**
- * Returns true if the mediaplayer can mix stereo down to mono
- */
- @Override
- public boolean canDownmix() {
- boolean retVal = false;
- if (mediaPlayer != null && media != null && media.getMediaType() == MediaType.AUDIO) {
- retVal = mediaPlayer.canDownmix();
- }
- return retVal;
- }
-
- @Override
- public void setDownmix(boolean enable) {
- playerLock.lock();
- if (media != null && media.getMediaType() == MediaType.AUDIO) {
- mediaPlayer.setDownmix(enable);
- Log.d(TAG, "Media player downmix was set to " + enable);
- }
- playerLock.unlock();
}
@Override
@@ -734,35 +503,26 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
playerStatus = PlayerStatus.STOPPED;
}
isShutDown = true;
- executor.shutdown();
abandonAudioFocus();
releaseWifiLockIfNecessary();
}
@Override
public void setVideoSurface(final SurfaceHolder surface) {
- executor.submit(() -> {
- playerLock.lock();
- if (mediaPlayer != null) {
- mediaPlayer.setDisplay(surface);
- }
- playerLock.unlock();
- });
+ if (mediaPlayer != null) {
+ mediaPlayer.setDisplay(surface);
+ }
}
@Override
public void resetVideoSurface() {
- executor.submit(() -> {
- playerLock.lock();
- if (mediaType == MediaType.VIDEO) {
- Log.d(TAG, "Resetting video surface");
- mediaPlayer.setDisplay(null);
- reinit();
- } else {
- Log.e(TAG, "Resetting video surface for media of Audio type");
- }
- playerLock.unlock();
- });
+ if (mediaType == MediaType.VIDEO) {
+ Log.d(TAG, "Resetting video surface");
+ mediaPlayer.setDisplay(null);
+ reinit();
+ } else {
+ Log.e(TAG, "Resetting video surface for media of Audio type");
+ }
}
/**
@@ -774,24 +534,10 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
*/
@Override
public Pair<Integer, Integer> getVideoSize() {
- if (!playerLock.tryLock()) {
- // use cached value if lock can't be aquired
- return videoSize;
- }
- Pair<Integer, Integer> res;
- if (mediaPlayer == null || playerStatus == PlayerStatus.ERROR || mediaType != MediaType.VIDEO) {
- res = null;
- } else if (mediaPlayer instanceof ExoPlayerWrapper) {
- ExoPlayerWrapper vp = (ExoPlayerWrapper) mediaPlayer;
- videoSize = new Pair<>(vp.getVideoWidth(), vp.getVideoHeight());
- res = videoSize;
- } else {
- VideoPlayer vp = (VideoPlayer) mediaPlayer;
- videoSize = new Pair<>(vp.getVideoWidth(), vp.getVideoHeight());
- res = videoSize;
+ if (mediaPlayer != null && playerStatus != PlayerStatus.ERROR && mediaType == MediaType.VIDEO) {
+ videoSize = new Pair<>(mediaPlayer.getVideoWidth(), mediaPlayer.getVideoHeight());
}
- playerLock.unlock();
- return res;
+ return videoSize;
}
/**
@@ -832,16 +578,8 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
return;
}
- if (UserPreferences.useExoplayer()) {
- mediaPlayer = new ExoPlayerWrapper(context);
- } else if (media.getMediaType() == MediaType.VIDEO) {
- mediaPlayer = new VideoPlayer();
- } else {
- mediaPlayer = new AudioPlayer(context);
- }
-
+ mediaPlayer = new ExoPlayerWrapper(context);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
- mediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
setMediaPlayerListeners(mediaPlayer);
}
@@ -858,103 +596,94 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
return;
}
- executor.submit(() -> {
- playerLock.lock();
- if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
- Log.d(TAG, "Lost audio focus");
- pause(true, false);
- callback.shouldStop();
- } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
- && !UserPreferences.shouldPauseForFocusLoss()) {
- if (playerStatus == PlayerStatus.PLAYING) {
- Log.d(TAG, "Lost audio focus temporarily. Ducking...");
- setVolumeSync(0.25f, 0.25f);
- pausedBecauseOfTransientAudiofocusLoss = false;
- }
- } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
- || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
- if (playerStatus == PlayerStatus.PLAYING) {
- Log.d(TAG, "Lost audio focus temporarily. Pausing...");
- mediaPlayer.pause(); // Pause without telling the PlaybackService
- pausedBecauseOfTransientAudiofocusLoss = true;
-
- audioFocusCanceller.removeCallbacksAndMessages(null);
- audioFocusCanceller.postDelayed(() -> {
- if (pausedBecauseOfTransientAudiofocusLoss) {
- // Still did not get back the audio focus. Now actually pause.
- pause(true, false);
- }
- }, 10000);
- }
- } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
- Log.d(TAG, "Gained audio focus");
- audioFocusCanceller.removeCallbacksAndMessages(null);
- if (pausedBecauseOfTransientAudiofocusLoss) { // we paused => play now
- mediaPlayer.start();
- } else { // we ducked => raise audio level back
- setVolumeSync(1.0f, 1.0f);
- }
+ if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
+ Log.d(TAG, "Lost audio focus");
+ pause(true, false);
+ callback.shouldStop();
+ } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
+ && !UserPreferences.shouldPauseForFocusLoss()) {
+ if (playerStatus == PlayerStatus.PLAYING) {
+ Log.d(TAG, "Lost audio focus temporarily. Ducking...");
+ setVolume(0.25f, 0.25f);
pausedBecauseOfTransientAudiofocusLoss = false;
}
- playerLock.unlock();
- });
+ } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
+ || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
+ if (playerStatus == PlayerStatus.PLAYING) {
+ Log.d(TAG, "Lost audio focus temporarily. Pausing...");
+ mediaPlayer.pause(); // Pause without telling the PlaybackService
+ pausedBecauseOfTransientAudiofocusLoss = true;
+
+ audioFocusCanceller.removeCallbacksAndMessages(null);
+ audioFocusCanceller.postDelayed(() -> {
+ if (pausedBecauseOfTransientAudiofocusLoss) {
+ // Still did not get back the audio focus. Now actually pause.
+ pause(true, false);
+ }
+ }, 10000);
+ }
+ } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
+ Log.d(TAG, "Gained audio focus");
+ audioFocusCanceller.removeCallbacksAndMessages(null);
+ if (pausedBecauseOfTransientAudiofocusLoss) { // we paused => play now
+ mediaPlayer.start();
+ } else { // we ducked => raise audio level back
+ setVolume(1.0f, 1.0f);
+ }
+ pausedBecauseOfTransientAudiofocusLoss = false;
+ }
}
};
@Override
- protected Future<?> endPlayback(final boolean hasEnded, final boolean wasSkipped,
+ protected void endPlayback(final boolean hasEnded, final boolean wasSkipped,
final boolean shouldContinue, final boolean toStoppedState) {
- useCallerThread = UserPreferences.useExoplayer();
- return executor.submit(() -> {
- playerLock.lock();
- releaseWifiLockIfNecessary();
-
- boolean isPlaying = playerStatus == PlayerStatus.PLAYING;
-
- // we're relying on the position stored in the Playable object for post-playback processing
- if (media != null) {
- int position = getPosition();
- if (position >= 0) {
- media.setPosition(position);
- }
- }
+ releaseWifiLockIfNecessary();
- if (mediaPlayer != null) {
- mediaPlayer.reset();
- }
+ boolean isPlaying = playerStatus == PlayerStatus.PLAYING;
- abandonAudioFocus();
-
- final Playable currentMedia = media;
- Playable nextMedia = null;
-
- if (shouldContinue) {
- // 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
- nextMedia = callback.getNextInQueue(currentMedia);
- if (nextMedia != null) {
- callback.onPlaybackEnded(nextMedia.getMediaType(), false);
- // setting media to null signals to playMediaObject() that
- // we're taking care of post-playback processing
- media = null;
- playMediaObject(nextMedia, false, !nextMedia.localFileAvailable(), isPlaying, isPlaying);
- }
+ // we're relying on the position stored in the Playable object for post-playback processing
+ if (media != null) {
+ int position = getPosition();
+ if (position >= 0) {
+ media.setPosition(position);
}
- if (shouldContinue || toStoppedState) {
- if (nextMedia == null) {
- callback.onPlaybackEnded(null, true);
- stop();
- }
- final boolean hasNext = nextMedia != null;
+ }
- executor.submit(() -> callback.onPostPlayback(currentMedia, hasEnded, wasSkipped, hasNext));
- } else if (isPlaying) {
- callback.onPlaybackPause(currentMedia, currentMedia.getPosition());
+ if (mediaPlayer != null) {
+ mediaPlayer.reset();
+ }
+
+ abandonAudioFocus();
+
+ final Playable currentMedia = media;
+ Playable nextMedia = null;
+
+ if (shouldContinue) {
+ // 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
+ nextMedia = callback.getNextInQueue(currentMedia);
+ if (nextMedia != null) {
+ callback.onPlaybackEnded(nextMedia.getMediaType(), false);
+ // setting media to null signals to playMediaObject() that
+ // we're taking care of post-playback processing
+ media = null;
+ playMediaObject(nextMedia, false, !nextMedia.localFileAvailable(), isPlaying, isPlaying);
}
- playerLock.unlock();
- });
+ }
+ if (shouldContinue || toStoppedState) {
+ if (nextMedia == null) {
+ callback.onPlaybackEnded(null, true);
+ stop();
+ }
+ final boolean hasNext = nextMedia != null;
+
+ callback.onPostPlayback(currentMedia, hasEnded, wasSkipped, hasNext);
+ } else if (isPlaying) {
+ callback.onPlaybackPause(currentMedia, currentMedia.getPosition());
+ }
}
/**
@@ -964,165 +693,55 @@ public class LocalPSMP extends PlaybackServiceMediaPlayer {
* abandoning audio focus have to be done with other methods.
*/
private void stop() {
- executor.submit(() -> {
- playerLock.lock();
- releaseWifiLockIfNecessary();
-
- if (playerStatus == PlayerStatus.INDETERMINATE) {
- setPlayerStatus(PlayerStatus.STOPPED, null);
- } else {
- Log.d(TAG, "Ignored call to stop: Current player state is: " + playerStatus);
- }
- playerLock.unlock();
+ releaseWifiLockIfNecessary();
- });
+ 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(){
+ protected boolean shouldLockWifi() {
return stream;
}
- private void setMediaPlayerListeners(IPlayer mp) {
+ private void setMediaPlayerListeners(ExoPlayerWrapper mp) {
if (mp == null || media == null) {
return;
}
- if (mp instanceof VideoPlayer) {
- if (media.getMediaType() != MediaType.VIDEO) {
- Log.w(TAG, "video player, but media type is " + media.getMediaType());
- }
- VideoPlayer vp = (VideoPlayer) mp;
- vp.setOnCompletionListener(videoCompletionListener);
- vp.setOnSeekCompleteListener(videoSeekCompleteListener);
- vp.setOnErrorListener(videoErrorListener);
- vp.setOnBufferingUpdateListener(videoBufferingUpdateListener);
- vp.setOnInfoListener(videoInfoListener);
- } else if (mp instanceof AudioPlayer) {
- if (media.getMediaType() != MediaType.AUDIO) {
- Log.w(TAG, "audio player, but media type is " + media.getMediaType());
- }
- AudioPlayer ap = (AudioPlayer) mp;
- ap.setOnCompletionListener(audioCompletionListener);
- ap.setOnSeekCompleteListener(audioSeekCompleteListener);
- ap.setOnErrorListener(audioErrorListener);
- ap.setOnBufferingUpdateListener(audioBufferingUpdateListener);
- ap.setOnInfoListener(audioInfoListener);
- } else if (mp instanceof ExoPlayerWrapper) {
- ExoPlayerWrapper ap = (ExoPlayerWrapper) mp;
- ap.setOnCompletionListener(audioCompletionListener);
- ap.setOnSeekCompleteListener(audioSeekCompleteListener);
- ap.setOnBufferingUpdateListener(audioBufferingUpdateListener);
- ap.setOnErrorListener(message -> EventBus.getDefault().postSticky(new PlayerErrorEvent(message)));
- ap.setOnInfoListener(audioInfoListener);
- } else {
- Log.w(TAG, "Unknown media player: " + mp);
- }
- }
-
- private void clearMediaPlayerListeners() {
- if (mediaPlayer instanceof VideoPlayer) {
- VideoPlayer vp = (VideoPlayer) mediaPlayer;
- vp.setOnCompletionListener(x -> { });
- vp.setOnSeekCompleteListener(x -> { });
- vp.setOnErrorListener((mediaPlayer, i, i1) -> false);
- vp.setOnBufferingUpdateListener((mediaPlayer, i) -> { });
- vp.setOnInfoListener((mediaPlayer, i, i1) -> false);
- } else if (mediaPlayer instanceof AudioPlayer) {
- AudioPlayer ap = (AudioPlayer) mediaPlayer;
- ap.setOnCompletionListener(x -> { });
- ap.setOnSeekCompleteListener(x -> { });
- ap.setOnErrorListener((x, y, z) -> false);
- ap.setOnBufferingUpdateListener((arg0, percent) -> { });
- ap.setOnInfoListener((arg0, what, extra) -> false);
- } else if (mediaPlayer instanceof ExoPlayerWrapper) {
- ExoPlayerWrapper ap = (ExoPlayerWrapper) mediaPlayer;
- ap.setOnCompletionListener(x -> { });
- ap.setOnSeekCompleteListener(x -> { });
- ap.setOnBufferingUpdateListener((arg0, percent) -> { });
- ap.setOnErrorListener(x -> { });
- ap.setOnInfoListener((arg0, what, extra) -> false);
- }
- }
-
- private final MediaPlayer.OnCompletionListener audioCompletionListener =
- mp -> genericOnCompletion();
-
- private final android.media.MediaPlayer.OnCompletionListener videoCompletionListener =
- mp -> genericOnCompletion();
-
- private void genericOnCompletion() {
- endPlayback(true, false, true, true);
- }
-
- private final MediaPlayer.OnBufferingUpdateListener audioBufferingUpdateListener =
- (mp, percent) -> EventBus.getDefault().post(BufferUpdateEvent.progressUpdate(0.01f * percent));
-
- private final android.media.MediaPlayer.OnBufferingUpdateListener videoBufferingUpdateListener =
- (mp, percent) -> EventBus.getDefault().post(BufferUpdateEvent.progressUpdate(0.01f * percent));
-
- private final MediaPlayer.OnInfoListener audioInfoListener =
- (mp, what, extra) -> genericInfoListener(what);
-
- private final android.media.MediaPlayer.OnInfoListener videoInfoListener =
- (mp, what, extra) -> genericInfoListener(what);
-
- private boolean genericInfoListener(int what) {
- switch (what) {
- case android.media.MediaPlayer.MEDIA_INFO_BUFFERING_START:
+ mp.setOnCompletionListener(() -> endPlayback(true, false, true, true));
+ mp.setOnSeekCompleteListener(this::genericSeekCompleteListener);
+ mp.setOnBufferingUpdateListener(percent -> {
+ if (percent == ExoPlayerWrapper.BUFFERING_STARTED) {
EventBus.getDefault().post(BufferUpdateEvent.started());
- return true;
- case android.media.MediaPlayer.MEDIA_INFO_BUFFERING_END:
+ } else if (percent == ExoPlayerWrapper.BUFFERING_ENDED) {
EventBus.getDefault().post(BufferUpdateEvent.ended());
- return true;
- default:
- return true;
- }
+ } else {
+ EventBus.getDefault().post(BufferUpdateEvent.progressUpdate(0.01f * percent));
+ }
+ });
+ mp.setOnErrorListener(message -> EventBus.getDefault().postSticky(new PlayerErrorEvent(message)));
}
- private final MediaPlayer.OnErrorListener audioErrorListener =
- (mp, what, extra) -> {
- if(mp != null && mp.canFallback()) {
- mp.fallback();
- return true;
- } else {
- return genericOnError(mp, what, extra);
- }
- };
-
- private final android.media.MediaPlayer.OnErrorListener videoErrorListener = this::genericOnError;
-
- private boolean genericOnError(Object inObj, int what, int extra) {
- EventBus.getDefault().postSticky(new PlayerErrorEvent(MediaPlayerError.getErrorString(context, what)));
- return true;
+ private void clearMediaPlayerListeners() {
+ mediaPlayer.setOnCompletionListener(() -> { });
+ mediaPlayer.setOnSeekCompleteListener(() -> { });
+ mediaPlayer.setOnBufferingUpdateListener(percent -> { });
+ mediaPlayer.setOnErrorListener(x -> { });
}
- private final MediaPlayer.OnSeekCompleteListener audioSeekCompleteListener =
- mp -> genericSeekCompleteListener();
-
- private final android.media.MediaPlayer.OnSeekCompleteListener videoSeekCompleteListener =
- mp -> genericSeekCompleteListener();
-
private void genericSeekCompleteListener() {
Log.d(TAG, "genericSeekCompleteListener");
if (seekLatch != null) {
seekLatch.countDown();
}
-
- Runnable r = () -> {
- playerLock.lock();
- if (playerStatus == PlayerStatus.PLAYING) {
- callback.onPlaybackStart(media, getPosition());
- }
- if (playerStatus == PlayerStatus.SEEKING) {
- setPlayerStatus(statusBeforeSeeking, media, getPosition());
- }
- playerLock.unlock();
- };
-
- if (useCallerThread) {
- r.run();
- } else {
- executor.submit(r);
+ if (playerStatus == PlayerStatus.PLAYING) {
+ callback.onPlaybackStart(media, getPosition());
+ }
+ if (playerStatus == PlayerStatus.SEEKING) {
+ setPlayerStatus(statusBeforeSeeking, media, getPosition());
}
}
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 2ab0eb138..62ddf969c 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
@@ -1578,14 +1578,6 @@ public class PlaybackService extends MediaBrowserServiceCompat {
return mediaPlayer.getPlaybackSpeed();
}
- public boolean canDownmix() {
- return mediaPlayer.canDownmix();
- }
-
- public void setDownmix(boolean enable) {
- mediaPlayer.setDownmix(enable);
- }
-
public boolean isStartWhenPrepared() {
return mediaPlayer.isStartWhenPrepared();
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java
deleted file mode 100644
index 4f6b2ce3a..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/AudioPlayer.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package de.danoeh.antennapod.core.util.playback;
-
-import android.content.Context;
-import androidx.preference.PreferenceManager;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import de.danoeh.antennapod.core.ClientConfig;
-import org.antennapod.audio.MediaPlayer;
-
-import de.danoeh.antennapod.storage.preferences.UserPreferences;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-
-public class AudioPlayer extends MediaPlayer implements IPlayer {
- private static final String TAG = "AudioPlayer";
-
- public AudioPlayer(Context context) {
- super(context, true, ClientConfig.USER_AGENT);
- PreferenceManager.getDefaultSharedPreferences(context)
- .registerOnSharedPreferenceChangeListener((sharedPreferences, key) -> {
- if (UserPreferences.PREF_MEDIA_PLAYER.equals(key)) {
- checkMpi();
- }
- });
- }
-
- @Override
- public void setDisplay(SurfaceHolder sh) {
- if (sh != null) {
- Log.e(TAG, "Setting display not supported in Audio Player");
- throw new UnsupportedOperationException("Setting display not supported in Audio Player");
- }
- }
-
- @Override
- public void setPlaybackParams(float speed, boolean skipSilence) {
- if (canSetSpeed()) {
- try {
- setPlaybackSpeed(speed);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- //Default player does not support silence skipping
- }
-
- @Override
- protected boolean useSonic() {
- return UserPreferences.useSonic();
- }
-
- @Override
- protected boolean downmix() {
- return UserPreferences.stereoToMono();
- }
-
- public List<String> getAudioTracks() {
- return Collections.emptyList();
- }
-
- @Override
- public void setAudioTrack(int track) {
- }
-
- @Override
- public int getSelectedAudioTrack() {
- return -1;
- }
-
- @Override
- public void setDataSource(String streamUrl, String username, String password) throws IOException {
- setDataSource(streamUrl);
- }
-}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java
deleted file mode 100644
index c726c5b5e..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/IPlayer.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package de.danoeh.antennapod.core.util.playback;
-
-import android.content.Context;
-import android.view.SurfaceHolder;
-
-import java.io.IOException;
-import java.util.List;
-
-public interface IPlayer {
- boolean canDownmix();
-
- int getCurrentPosition();
-
- float getCurrentSpeedMultiplier();
-
- int getDuration();
-
- boolean isPlaying();
-
- void pause();
-
- void prepare() throws IllegalStateException, IOException;
-
- void release();
-
- void reset();
-
- void seekTo(int msec);
-
- void setAudioStreamType(int streamtype);
-
- void setDataSource(String path) throws IllegalStateException, IOException,
- IllegalArgumentException, SecurityException;
-
- void setDataSource(String streamUrl, String username, String password) throws IOException;
-
- void setDisplay(SurfaceHolder sh);
-
- void setPlaybackParams(float speed, boolean skipSilence);
-
- void setDownmix(boolean enable);
-
- void setVolume(float left, float right);
-
- void start();
-
- void stop();
-
- void setWakeMode(Context context, int mode);
-
- List<String> getAudioTracks();
-
- void setAudioTrack(int track);
-
- int getSelectedAudioTrack();
-}
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 c3b103501..2274dcf83 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
@@ -21,7 +21,6 @@ import de.danoeh.antennapod.event.playback.SpeedChangedEvent;
import de.danoeh.antennapod.model.playback.MediaType;
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
-import de.danoeh.antennapod.storage.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.model.playback.Playable;
import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer;
@@ -420,17 +419,6 @@ public abstract class PlaybackController {
}
}
- public boolean canDownmix() {
- return (playbackService != null && playbackService.canDownmix())
- || UserPreferences.useSonic();
- }
-
- public void setDownmix(boolean enable) {
- if (playbackService != null) {
- playbackService.setDownmix(enable);
- }
- }
-
public List<String> getAudioTracks() {
if (playbackService == null) {
return Collections.emptyList();
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java
deleted file mode 100644
index ecf47f8ae..000000000
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/VideoPlayer.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package de.danoeh.antennapod.core.util.playback;
-
-import android.media.MediaPlayer;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-
-public class VideoPlayer extends MediaPlayer implements IPlayer {
- private static final String TAG = "VideoPlayer";
-
- @Override
- public boolean canDownmix() {
- return false;
- }
-
- @Override
- public float getCurrentSpeedMultiplier() {
- return 1;
- }
-
- @Override
- public void setPlaybackParams(float speed, boolean skipSilence) {
- //Ignore this for non ExoPlayer implementations
- }
-
- @Override
- public void setDownmix(boolean b) {
- Log.e(TAG, "Setting downmix unsupported in video player");
- throw new UnsupportedOperationException("Setting downmix unsupported in video player");
- }
-
- @Override
- public void setVideoScalingMode(int mode) {
- super.setVideoScalingMode(mode);
- }
-
- public List<String> getAudioTracks() {
- return Collections.emptyList();
- }
-
- @Override
- public void setAudioTrack(int track) {
- }
-
- @Override
- public int getSelectedAudioTrack() {
- return -1;
- }
-
- @Override
- public void setDataSource(String streamUrl, String username, String password) throws IOException {
- setDataSource(streamUrl);
- }
-}
diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml
index 9d8065b86..39f62a5d7 100644
--- a/core/src/main/res/values/arrays.xml
+++ b/core/src/main/res/values/arrays.xml
@@ -216,18 +216,6 @@
<item>DownloadsSection</item>
</string-array>
- <string-array name="media_player_options">
- <item>@string/media_player_exoplayer_recommended</item>
- <item>@string/media_player_builtin</item>
- <item>@string/media_player_sonic</item>
- </string-array>
-
- <string-array name="media_player_values">
- <item>exoplayer</item>
- <item>builtin</item>
- <item>sonic</item>
- </string-array>
-
<!-- sort for podcast screen, not for queue -->
<string-array name="feed_episodes_sort_options">
<item>@string/sort_date_new_old</item>